mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-02-18 12:30:33 +00:00
- Only start the emulator if requested (click on the "Start" button)
- Rewrote dispatch loop to accomodate GTK+1.2 for MacOS X (which doesn't like threads nor forks(!)). The latter also requires an additional patch to the version 0.7 available on SourceForge - Run-time detect JIT capability so that we could hopefully use the ppc GUI on intel based Macs (check!)
This commit is contained in:
parent
02c24ed6c2
commit
3fda1a3af7
@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
// Global variables
|
// Global variables
|
||||||
static GtkWidget *win; // Preferences window
|
static GtkWidget *win; // Preferences window
|
||||||
static bool start_clicked = true; // Return value of PrefsEditor() function
|
static bool start_clicked = false; // Return value of PrefsEditor() function
|
||||||
|
|
||||||
|
|
||||||
// Prototypes
|
// Prototypes
|
||||||
@ -712,6 +712,27 @@ static GtkWidget *w_jit_cache_size;
|
|||||||
static GtkWidget *w_jit_lazy_flush;
|
static GtkWidget *w_jit_lazy_flush;
|
||||||
static GtkWidget *w_jit_follow_const_jumps;
|
static GtkWidget *w_jit_follow_const_jumps;
|
||||||
|
|
||||||
|
// Are we running a JIT capable CPU?
|
||||||
|
static bool is_jit_capable(void)
|
||||||
|
{
|
||||||
|
#if USE_JIT && (defined __i386__ || defined __x86_64__)
|
||||||
|
return true;
|
||||||
|
#elif defined __APPLE__ && defined __MACH__
|
||||||
|
// XXX run-time detect so that we can use a PPC GUI prefs editor
|
||||||
|
static char cpu[10];
|
||||||
|
if (cpu[0] == 0) {
|
||||||
|
FILE *fp = popen("uname -p", "r");
|
||||||
|
if (fp == NULL)
|
||||||
|
return false;
|
||||||
|
fgets(cpu, sizeof(cpu) - 1, fp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
if (cpu[0] == 'i' && cpu[2] == '8' && cpu[3] == '6') // XXX assuming i?86
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Set sensitivity of widgets
|
// Set sensitivity of widgets
|
||||||
static void set_jit_sensitive(void)
|
static void set_jit_sensitive(void)
|
||||||
{
|
{
|
||||||
@ -750,19 +771,19 @@ static void tb_jit_follow_const_jumps(GtkWidget *widget)
|
|||||||
// Read settings from widgets and set preferences
|
// Read settings from widgets and set preferences
|
||||||
static void read_jit_settings(void)
|
static void read_jit_settings(void)
|
||||||
{
|
{
|
||||||
#if USE_JIT
|
bool jit_enabled = is_jit_capable() && PrefsFindBool("jit");
|
||||||
bool jit_enabled = PrefsFindBool("jit");
|
|
||||||
if (jit_enabled) {
|
if (jit_enabled) {
|
||||||
const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_jit_cache_size)->entry));
|
const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_jit_cache_size)->entry));
|
||||||
PrefsReplaceInt32("jitcachesize", atoi(str));
|
PrefsReplaceInt32("jitcachesize", atoi(str));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create "JIT Compiler" pane
|
// Create "JIT Compiler" pane
|
||||||
static void create_jit_pane(GtkWidget *top)
|
static void create_jit_pane(GtkWidget *top)
|
||||||
{
|
{
|
||||||
#if USE_JIT
|
if (!is_jit_capable())
|
||||||
|
return;
|
||||||
|
|
||||||
GtkWidget *box, *table, *label, *menu;
|
GtkWidget *box, *table, *label, *menu;
|
||||||
char str[32];
|
char str[32];
|
||||||
|
|
||||||
@ -788,7 +809,6 @@ static void create_jit_pane(GtkWidget *top)
|
|||||||
w_jit_follow_const_jumps = make_checkbox(box, STR_JIT_FOLLOW_CONST_JUMPS, "jitinline", GTK_SIGNAL_FUNC(tb_jit_follow_const_jumps));
|
w_jit_follow_const_jumps = make_checkbox(box, STR_JIT_FOLLOW_CONST_JUMPS, "jitinline", GTK_SIGNAL_FUNC(tb_jit_follow_const_jumps));
|
||||||
|
|
||||||
set_jit_sensitive();
|
set_jit_sensitive();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1540,6 +1560,13 @@ uint8 XPRAM[XPRAM_SIZE];
|
|||||||
void MountVolume(void *fh) { }
|
void MountVolume(void *fh) { }
|
||||||
void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size) { }
|
void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size) { }
|
||||||
|
|
||||||
|
#if defined __APPLE__ && defined __MACH__
|
||||||
|
void DarwinAddCDROMPrefs(void) { }
|
||||||
|
void DarwinAddFloppyPrefs(void) { }
|
||||||
|
void DarwinAddSerialPrefs(void) { }
|
||||||
|
bool DarwinCDReadTOC(char *, uint8 *) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display alert
|
* Display alert
|
||||||
@ -1668,28 +1695,27 @@ int main(int argc, char *argv[])
|
|||||||
char gui_connection_path[64];
|
char gui_connection_path[64];
|
||||||
sprintf(gui_connection_path, "/org/BasiliskII/GUI/%d", getpid());
|
sprintf(gui_connection_path, "/org/BasiliskII/GUI/%d", getpid());
|
||||||
|
|
||||||
int pid = fork();
|
// Search and run the BasiliskII executable
|
||||||
if (pid == 0) { // Child
|
// XXX it can be in a bundle on MacOS X
|
||||||
char b2_path[PATH_MAX];
|
char b2_path[PATH_MAX];
|
||||||
strcpy(b2_path, argv[0]);
|
strcpy(b2_path, argv[0]);
|
||||||
char *p = strrchr(b2_path, '/');
|
char *p = strrchr(b2_path, '/');
|
||||||
p = p ? p + 1 : b2_path;
|
p = p ? p + 1 : b2_path;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
strcat(b2_path, "BasiliskII");
|
strcat(b2_path, "BasiliskII");
|
||||||
execl(b2_path, b2_path, "--gui-connection", gui_connection_path, (char *)NULL);
|
|
||||||
|
|
||||||
char str[256];
|
int pid = fork();
|
||||||
sprintf(str, GetString(STR_NO_B2_EXE_FOUND), b2_path, strerror(errno));
|
if (pid == 0) {
|
||||||
ErrorAlert(str);
|
execl(b2_path, b2_path, "--gui-connection", gui_connection_path, (char *)NULL);
|
||||||
return 1;
|
return -errno;
|
||||||
}
|
}
|
||||||
else { // Parent
|
|
||||||
|
// Establish a connection to Basilisk II
|
||||||
rpc_connection_t *connection;
|
rpc_connection_t *connection;
|
||||||
if ((connection = rpc_init_server(gui_connection_path)) == NULL) {
|
if ((connection = rpc_init_server(gui_connection_path)) == NULL) {
|
||||||
printf("ERROR: failed to initialize GUI-side RPC server connection\n");
|
printf("ERROR: failed to initialize GUI-side RPC server connection\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const rpc_method_descriptor_t vtable[] = {
|
static const rpc_method_descriptor_t vtable[] = {
|
||||||
{ RPC_METHOD_ERROR_ALERT, handle_ErrorAlert },
|
{ RPC_METHOD_ERROR_ALERT, handle_ErrorAlert },
|
||||||
{ RPC_METHOD_WARNING_ALERT, handle_WarningAlert },
|
{ RPC_METHOD_WARNING_ALERT, handle_WarningAlert },
|
||||||
@ -1699,21 +1725,62 @@ int main(int argc, char *argv[])
|
|||||||
printf("ERROR: failed to setup GUI method callbacks\n");
|
printf("ERROR: failed to setup GUI method callbacks\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
int socket;
|
||||||
if (rpc_listen(connection) < 0) {
|
if ((socket = rpc_listen_socket(connection)) < 0) {
|
||||||
printf("ERROR: failed to initialize RPC server thread\n");
|
printf("ERROR: failed to initialize RPC server thread\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int status, ret = -1;
|
int child_status = 1;
|
||||||
while (waitpid(pid, &status, 0) != pid)
|
GMainLoop *loop = g_main_new(TRUE);
|
||||||
;
|
while (g_main_is_running(loop)) {
|
||||||
if (WIFEXITED(status))
|
|
||||||
ret = WEXITSTATUS(status);
|
// Process a few events pending
|
||||||
|
const int N_EVENTS_DISPATCH = 10;
|
||||||
|
for (int i = 0; i < N_EVENTS_DISPATCH; i++) {
|
||||||
|
if (!g_main_iteration(FALSE))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the child has terminated
|
||||||
|
int status = 1;
|
||||||
|
int ret = waitpid(pid, &status, WNOHANG);
|
||||||
|
if (ret == pid || (ret < 0 && errno == ECHILD)) {
|
||||||
|
if (WIFEXITED(status)) {
|
||||||
|
child_status = WEXITSTATUS(status);
|
||||||
|
if (child_status & 0x80)
|
||||||
|
child_status |= -1 ^0xff;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for RPC events
|
||||||
|
// XXX implement an rpc_try_dispatch(connection, timeout)
|
||||||
|
fd_set rfds;
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(socket, &rfds);
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = 1;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
ret = select(socket + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
|
if (ret == 0)
|
||||||
|
continue;
|
||||||
|
rpc_dispatch(connection);
|
||||||
|
}
|
||||||
|
|
||||||
rpc_exit(connection);
|
rpc_exit(connection);
|
||||||
return ret;
|
|
||||||
|
// Report failure to execute the BasiliskII binary
|
||||||
|
if (child_status < 0) {
|
||||||
|
char str[256];
|
||||||
|
sprintf(str, GetString(STR_NO_B2_EXE_FOUND), b2_path, strerror(-child_status));
|
||||||
|
ErrorAlert(str);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return child_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user