1 /*
2 * UAE - the Un*x Amiga Emulator
3 *
4 * Yet Another User Interface for the X11 version
5 *
6 * Copyright 1997, 1998 Bernd Schmidt
7 * Copyright 1998 Michael Krause
8 * Copyright 2003-2007 Richard Drummond
9 * Copyright 2009-2010 Mustafa TUFAN
10 *
11 * The Tk GUI doesn't work.
12 * The X Forms Library isn't available as source, and there aren't any
13 * binaries compiled against glibc
14 *
15 * So let's try this...
16 */
17
18 #include "sysconfig.h"
19 #include "sysdeps.h"
20
21 #include "autoconf.h"
22 #include "options.h"
23 #include "uae.h"
24 #include "memory_uae.h"
25 #include "custom.h"
26 #include "gui.h"
27 #include "newcpu.h"
28 #include "filesys.h"
29 #include "threaddep/thread.h"
30 #include "audio.h"
31 #include "savestate.h"
32 #include "debug.h"
33 #include "inputdevice.h"
34 #include "xwin.h"
35 #include "picasso96.h"
36 #include "gcc_warnings.h"
37
38 GCC_DIAG_OFF(strict-prototypes)
39 #include <gtk/gtk.h>
40 #include <gdk/gdk.h>
41 #include <gdk/gdkkeysyms.h>
42 GCC_DIAG_ON(strict-prototypes)
43
44 #include "gui-gtk/cputypepanel.h"
45 #include "gui-gtk/cpuspeedpanel.h"
46 #include "gui-gtk/floppyfileentry.h"
47 #include "gui-gtk/led.h"
48 #include "gui-gtk/chipsettypepanel.h"
49 #include "gui-gtk/chipsetspeedpanel.h"
50 #include "gui-gtk/util.h"
51
52 //#define GUI_DEBUG
53 #ifdef GUI_DEBUG
54 #define DEBUG_LOG write_log ( "%s: ", __func__); write_log
55 #else
56 #define DEBUG_LOG(...) { }
57 #endif
58
59 /* internal types */
60 static int gui_active;
61
62 static int gui_available;
63 unsigned int pause_uae = 0;
64
65 static GtkWidget *gui_window;
66
67 static GtkWidget *start_uae_widget;
68 static GtkWidget *stop_uae_widget;
69 static GtkWidget *pause_uae_widget;
70 static GtkWidget *reset_uae_widget;
71 static GtkWidget *debug_uae_widget;
72
73 static GtkWidget *chipsize_widget[5];
74 static GtkWidget *bogosize_widget[4];
75 static GtkWidget *fastsize_widget[5];
76 static GtkWidget *z3size_widget[10];
77 #ifdef PICASSO96
78 static GtkWidget *p96size_widget[7];
79 #endif
80 static GtkWidget *rom_text_widget;
81 static GtkWidget *rom_change_widget;
82 static GtkWidget *sstate_text_widget, *sstate_change_widget, *sstate_load_widget, *sstate_save_widget;
83
84 static GtkWidget *floppy_widget[4];
85 static char *new_disk_string[4];
86
87 static gpointer power_led;
88
89 static GtkWidget *ctpanel;
90 static GtkWidget *ftpanel;
91 static GtkWidget *cspanel;
92 static GtkWidget *chipsettype_panel;
93 static GtkWidget *chipsetspeed_panel;
94
95 static GtkWidget *hdpanel;
96 static GtkWidget *memorypanel;
97
98 static GtkWidget *sound_widget[4], *sound_ch_widget[3], *sound_in_widget[3], *sound_fl_widget[5];
99 static GtkWidget *drvspeed_widget[5];
100 static GtkWidget *cpu_widget[6], *fpu_widget[4];
101
102 #ifdef JIT
103 static GtkWidget *jit_page;
104 static GtkWidget *compbyte_widget[4], *compword_widget[4], *complong_widget[4];
105 static GtkWidget *compaddr_widget[4];
106 static GtkWidget *compnf_widget[2];
107 static GtkWidget *compfpu_widget[2], *comp_hardflush_widget[2];
108 static GtkWidget *comp_constjump_widget[2];
109 static GtkAdjustment *cachesize_adj;
110 #endif
111
112 #ifdef XARCADE
113 # define JOY_WIDGET_COUNT 9
114 #else
115 # define JOY_WIDGET_COUNT 7
116 #endif
117 static GtkWidget *joy_widget[2][JOY_WIDGET_COUNT];
118
119 static unsigned int prevledstate;
120
121 static GtkWidget *hdlist_widget;
122 static int selected_hd_row;
123 static GtkWidget *hdchange_button, *hddel_button;
124 static GtkWidget *devname_entry, *volname_entry, *path_entry;
125 static GtkWidget *readonly_widget, *bootpri_widget;
126 static GtkWidget *leds_on_screen_widget;
127 static GtkWidget *dirdlg;
128 static GtkWidget *dirdlg_ok;
129 static char dirdlg_devname[256], dirdlg_volname[256], dirdlg_path[256], floppydlg_path[256];
130
131 enum hdlist_cols {
132 HDLIST_DEVICE,
133 HDLIST_VOLUME,
134 HDLIST_PATH,
135 HDLIST_READONLY,
136 HDLIST_HEADS,
137 HDLIST_CYLS,
138 HDLIST_SECS,
139 HDLIST_RSRVD,
140 HDLIST_SIZE,
141 HDLIST_BLKSIZE,
142 HDLIST_BOOTPRI,
143 // HDLIST_DONOTMOUNT,
144 // HDLIST_AUTOBOOT,
145 // HDLIST_FILESYSDIR,
146 // HDLIST_HDC,
147 // HDLIST_FLAGS,
148 HDLIST_MAX_COLS
149 };
150
151 static const char *hdlist_col_titles[] = {
152 "Device",
153 "Volume",
154 "File/Directory",
155 "R/O",
156 "Heads",
157 "Cyl.",
158 "Sec.",
159 "Rsrvd",
160 "Size",
161 "Blksize",
162 "Boot Pri",
163 // "Donotmount",
164 // "Autoboot",
165 // "Filesysdir?"
166 // "HDC"
167 // "Flags"
168 NULL
169 };
170
171
172 static smp_comm_pipe to_gui_pipe; // For sending messages to the GUI from UAE
173 static smp_comm_pipe from_gui_pipe; // For sending messages from the GUI to UAE
174
175 /*
176 * Messages sent to GUI from UAE via to_gui_pipe
177 */
178 enum gui_commands {
179 GUICMD_STATE_CHANGE, // Tell GUI about change in emulator state.
180 GUICMD_SHOW, // Show yourself
181 GUICMD_UPDATE, // Refresh your state from changed preferences
182 GUICMD_DISKCHANGE, // Hey! A disk has been changed. Do something!
183 GUICMD_MSGBOX, // Display a message box for me, please
184 GUICMD_NEW_ROMLIST, // The ROM list has been updated.
185 GUICMD_FLOPPYDLG, // Open a floppy insert dialog
186 GUICMD_FULLSCREEN, // Fullscreen mode was toggled; update checkboxes
187 GUICMD_PAUSE, // We're now paused, in case you didn't notice
188 GUICMD_UNPAUSE // We're now running.
189 };
190
191 enum uae_commands {
192 UAECMD_START,
193 UAECMD_STOP,
194 UAECMD_QUIT,
195 UAECMD_RESET,
196 UAECMD_PAUSE,
197 UAECMD_RESUME,
198 UAECMD_DEBUG,
199 UAECMD_SAVE_CONFIG,
200 UAECMD_EJECTDISK,
201 UAECMD_INSERTDISK,
202 UAECMD_SELECT_ROM,
203 UAECMD_SAVESTATE_LOAD,
204 UAECMD_SAVESTATE_SAVE
205 };
206
207
208 static uae_sem_t gui_sem; // For mutual exclusion on various prefs settings
209 static uae_sem_t gui_update_sem; // For synchronization between gui_update() and the GUI thread
210 static uae_sem_t gui_init_sem; // For the GUI thread to tell UAE that it's ready.
211 static uae_sem_t gui_quit_sem; // For the GUI thread to tell UAE that it's quitting.
212
213 static volatile int quit_gui = 0, quitted_gui = 0;
214
215
216 /* internal prototypes */
217 static void create_guidlg (void);
218
219 static void do_message_box (const gchar *title, const gchar *message, gboolean modal, gboolean wait);
220 static void handle_message_box_request (smp_comm_pipe *msg_pipe);
221 static GtkWidget *make_message_box (const gchar *title, const gchar *message, int modal, uae_sem_t *sem);
222 void on_message_box_quit (GtkWidget *w, gpointer user_data);
223 void on_vstat_toggle(GtkWidget *widget, gpointer statusbar);
224
225 /* external prototypes */
226 extern void clearallkeys (void);
227
228
229
uae_pause(void)230 static void uae_pause (void)
231 {
232 write_comm_pipe_int (&from_gui_pipe, GUICMD_PAUSE , 1);
233 }
234
uae_resume(void)235 static void uae_resume (void)
236 {
237 write_comm_pipe_int (&to_gui_pipe, GUICMD_UNPAUSE, 1);
238 }
239
set_mem32_widgets_state(void)240 static void set_mem32_widgets_state (void)
241 {
242 int enable = changed_prefs.cpu_model >= 68020 && ! changed_prefs.address_space_24;
243
244 #ifdef AUTOCONFIG
245 unsigned int i;
246
247 for (i = 0; i < 10; i++)
248 gtk_widget_set_sensitive (z3size_widget[i], enable);
249
250 # ifdef PICASSO96
251 for (i = 0; i < 7; i++)
252 gtk_widget_set_sensitive (p96size_widget[i], enable);
253 #endif
254 #endif
255 #ifdef JIT
256 gtk_widget_set_sensitive (jit_page, changed_prefs.cpu_model >= 68020);
257 #endif
258 }
259
set_cpu_state(void)260 static void set_cpu_state (void)
261 {
262 /*
263 int i;
264 unsigned int lvl;
265 lvl = (changed_prefs.cpu_model - 68000) / 10;
266
267 DEBUG_LOG ("set_cpu_state: %d %d %d\n", lvl,
268 changed_prefs.address_space_24, changed_prefs.m68k_speed);
269
270 cputypepanel_set_cpulevel (CPUTYPEPANEL (ctpanel), lvl);
271 cputypepanel_set_addr24bit (CPUTYPEPANEL (ctpanel), changed_prefs.address_space_24);
272
273 cpuspeedpanel_set_cpuspeed (CPUSPEEDPANEL (cspanel), changed_prefs.m68k_speed);
274 cpuspeedpanel_set_cpuidle (CPUSPEEDPANEL (cspanel), changed_prefs.cpu_idle);
275 set_mem32_widgets_state ();
276 */
277 }
278
set_fpu_state(void)279 static void set_fpu_state (void)
280 {
281 #ifdef FPU
282
283 #endif
284 }
285
set_chipset_state(void)286 static void set_chipset_state (void)
287 {
288 chipsettypepanel_set_chipset_mask (CHIPSETTYPEPANEL (chipsettype_panel), currprefs.chipset_mask);
289 chipsettypepanel_set_ntscmode (CHIPSETTYPEPANEL (chipsettype_panel), currprefs.ntscmode);
290 chipsetspeedpanel_set_framerate (CHIPSETSPEEDPANEL (chipsetspeed_panel), currprefs.gfx_framerate);
291 chipsetspeedpanel_set_collision_level (CHIPSETSPEEDPANEL (chipsetspeed_panel), currprefs.collision_level);
292 chipsetspeedpanel_set_immediate_blits (CHIPSETSPEEDPANEL (chipsetspeed_panel), currprefs.immediate_blits);
293 }
294
set_sound_state(void)295 static void set_sound_state (void)
296 {
297 int stereo = currprefs.sound_stereo + currprefs.sound_mixed_stereo_delay;
298 unsigned int i;
299
300 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_widget[currprefs.produce_sound]), 1);
301 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_ch_widget[stereo]), 1);
302 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_in_widget[currprefs.sound_interpol]), 1);
303
304 if (currprefs.sound_filter == FILTER_SOUND_OFF) {
305 i = 0;
306 } else {
307 if (currprefs.sound_filter_type == FILTER_SOUND_TYPE_A500) i = 1;
308 if (currprefs.sound_filter_type == FILTER_SOUND_TYPE_A1200) i = 3;
309 if (currprefs.sound_filter == FILTER_SOUND_ON) i++;
310 }
311 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_fl_widget[i]), 1);
312 }
313
set_mem_state(void)314 static void set_mem_state (void)
315 {
316 int t, t2;
317
318 t = 0;
319 t2 = currprefs.chipmem_size;
320 while (t < 4 && t2 > 0x80000)
321 t++, t2 >>= 1;
322 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chipsize_widget[t]), 1);
323
324 t = 0;
325 t2 = currprefs.bogomem_size;
326 while (t < 3 && t2 >= 0x80000)
327 t++, t2 >>= 1;
328 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bogosize_widget[t]), 1);
329
330 t = 0;
331 t2 = currprefs.fastmem_size;
332 while (t < 4 && t2 >= 0x100000)
333 t++, t2 >>= 1;
334 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fastsize_widget[t]), 1);
335
336 t = 0;
337 t2 = currprefs.z3fastmem_size;
338 while (t < 9 && t2 >= 0x100000)
339 t++, t2 >>= 1;
340 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (z3size_widget[t]), 1);
341
342 #ifdef PICASSO96
343 t = 0;
344 t2 = currprefs.rtgmem_size;
345 while (t < 6 && t2 >= 0x100000)
346 t++, t2 >>= 1;
347 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (p96size_widget[t]), 1);
348 #endif
349
350 gtk_label_set_text (GTK_LABEL (rom_text_widget), changed_prefs.romfile[0]!='\0' ?
351 changed_prefs.romfile : currprefs.romfile);
352 }
353
354 #ifdef JIT
set_comp_state(void)355 static void set_comp_state (void)
356 {
357 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (compbyte_widget[currprefs.comptrustbyte]), 1);
358 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (compword_widget[currprefs.comptrustword]), 1);
359 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (complong_widget[currprefs.comptrustlong]), 1);
360 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (compaddr_widget[currprefs.comptrustnaddr]), 1);
361 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (compnf_widget[currprefs.compnf]), 1);
362 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (comp_hardflush_widget[currprefs.comp_hardflush]), 1);
363 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (comp_constjump_widget[currprefs.comp_constjump]), 1);
364 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (compfpu_widget[currprefs.compfpu]), 1);
365 }
366 #endif
367
set_misc_state(void)368 static void set_misc_state (void)
369 {
370 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (leds_on_screen_widget), currprefs.leds_on_screen);
371 }
372
373 /*
374 * Temporary hacks for joystick widgets
375 */
376
377 /*
378 * widget 0 = none
379 * 1 = joy 0
380 * 2 = joy 1
381 * 3 = mouse
382 * 4 = numpad
383 * 5 = cursor
384 * 6 = other
385 * 7 = xarcade1
386 * 8 = xarcade2
387 */
map_jsem_to_widget(int jsem)388 static int map_jsem_to_widget (int jsem)
389 {
390 int widget = 0;
391
392 if (jsem == JSEM_END)
393 widget = 0;
394 else if (jsem == JSEM_MICE)
395 widget = 3;
396 else if (jsem == JSEM_JOYS || jsem == JSEM_JOYS + 1 )
397 widget = jsem - JSEM_JOYS + 1;
398 else if (jsem >= JSEM_KBDLAYOUT)
399 widget = jsem - JSEM_KBDLAYOUT + 4;
400
401 return widget;
402 }
403
map_widget_to_jsem(int widget)404 static int map_widget_to_jsem (int widget)
405 {
406 int jsem;
407
408 switch (widget) {
409 default:
410 case 0: jsem = JSEM_END; break;
411 case 1: jsem = JSEM_JOYS; break;
412 case 2: jsem = JSEM_JOYS + 1; break;
413 case 3: jsem = JSEM_MICE; break;
414 case 4: jsem = JSEM_KBDLAYOUT; break;
415 case 5: jsem = JSEM_KBDLAYOUT + 1; break;
416 case 6: jsem = JSEM_KBDLAYOUT + 2; break;
417 case 7: jsem = JSEM_KBDLAYOUT + 3; break;
418 case 8: jsem = JSEM_KBDLAYOUT + 4; break;
419 }
420
421 return jsem;
422 }
423
set_joy_state(void)424 static void set_joy_state (void)
425 {
426 int j0t = map_jsem_to_widget (changed_prefs.jports[0].id);
427 int j1t = map_jsem_to_widget (changed_prefs.jports[1].id);
428
429 int joy_count = inputdevice_get_device_total (IDTYPE_JOYSTICK);
430 int i;
431
432 if (j0t != 0 && j0t == j1t) {
433 /* Can't happen */
434 j0t++;
435 j0t %= 7;
436 }
437
438 for (i = 0; i < JOY_WIDGET_COUNT; i++) {
439 if (i == 1 && joy_count == 0) continue;
440 if (i == 2 && joy_count <= 1) continue;
441
442 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (joy_widget[0][i]), j0t == i);
443 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (joy_widget[1][i]), j1t == i);
444 gtk_widget_set_sensitive (joy_widget[0][i], i == 0 || j1t != i);
445 gtk_widget_set_sensitive (joy_widget[1][i], i == 0 || j0t != i);
446 }
447 }
448
449 #ifdef FILESYS
set_hd_state(void)450 static void set_hd_state (void)
451 {
452 char texts[HDLIST_MAX_COLS][256];
453 char *tptrs[HDLIST_MAX_COLS];
454 int nr = nr_units ();
455 int i;
456 // UnitInfo *ui;
457
458 DEBUG_LOG ("set_hd_state\n");
459 for (i=0; i<HDLIST_MAX_COLS; i++)
460 tptrs[i] = texts[i];
461
462 gtk_clist_freeze (GTK_CLIST (hdlist_widget));
463 gtk_clist_clear (GTK_CLIST (hdlist_widget));
464
465 for (i = 0; i < nr; i++) {
466 int secspertrack=0, surfaces=0, reserved=0, blocksize=0, bootpri=0;
467 uae_u64 size = 0;
468 int cylinders=0, readonly=0, flags=0;
469 char *devname=NULL, *volname=NULL, *rootdir=NULL, *filesysdir=NULL;
470 int ret = 0;
471
472 /* We always use currprefs.mountinfo for the GUI. The filesystem
473 code makes a private copy which is updated every reset. */
474 struct mountedinfo mi;
475 ret = get_filesys_unitconfig (&currprefs, i, &mi);
476 /* failure = get_filesys_unit (i,
477 &devname, &volname, &rootdir, &readonly,
478 &secspertrack, &surfaces, &reserved,
479 &cylinders, &size, &blocksize, &bootpri,
480 &filesysdir, &flags); */
481
482 if (ret == FILESYS_HARDDRIVE)
483 write_log ("Get Filesys Unit: HDD\n");
484 if (ret == FILESYS_HARDFILE_RDB)
485 write_log ("Get Filesys Unit: HF RDB\n");
486 if (ret == FILESYS_VIRTUAL)
487 write_log ("Get Filesys Unit: VIRT\n");
488
489 // ui = &mountinfo.ui[i]
490 if (secspertrack == 0)
491 strcpy (texts[HDLIST_DEVICE], "N/A" );
492 else
493 strncpy (texts[HDLIST_DEVICE], devname, 255);
494 if (volname)
495 strncpy (texts[HDLIST_VOLUME], volname, 255);
496
497 sprintf (texts[HDLIST_HEADS], "%d", surfaces);
498 sprintf (texts[HDLIST_CYLS], "%d", cylinders);
499 sprintf (texts[HDLIST_SECS], "%d", secspertrack);
500 sprintf (texts[HDLIST_RSRVD], "%d", reserved);
501 sprintf (texts[HDLIST_SIZE], "%lu", size);
502 sprintf (texts[HDLIST_BLKSIZE], "%d", blocksize);
503
504 if (rootdir)
505 strcpy (texts[HDLIST_PATH], rootdir);
506 strcpy (texts[HDLIST_READONLY], readonly ? "Y" : "N");
507 sprintf (texts[HDLIST_BOOTPRI], "%d", bootpri);
508
509 gtk_clist_append (GTK_CLIST (hdlist_widget), tptrs);
510 }
511 gtk_clist_thaw (GTK_CLIST (hdlist_widget));
512 gtk_widget_set_sensitive (hdchange_button, false);
513 gtk_widget_set_sensitive (hddel_button, false);
514 DEBUG_LOG ("set_hd_state done\n");
515 }
516 #endif
517
set_floppy_state(void)518 static void set_floppy_state( void )
519 {
520 unsigned int i;
521 switch (currprefs.floppy_speed) {
522 case 0: i = 0;
523 case 100: i = 1;
524 case 200: i = 2;
525 case 400: i = 3;
526 case 800: i = 4;
527 default: i = 1;
528 }
529 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (drvspeed_widget[i]), 1);
530
531 floppyfileentry_set_filename (FLOPPYFILEENTRY (floppy_widget[0]), currprefs.floppyslots[0].df);
532 floppyfileentry_set_filename (FLOPPYFILEENTRY (floppy_widget[1]), currprefs.floppyslots[1].df);
533 floppyfileentry_set_filename (FLOPPYFILEENTRY (floppy_widget[2]), currprefs.floppyslots[2].df);
534 floppyfileentry_set_filename (FLOPPYFILEENTRY (floppy_widget[3]), currprefs.floppyslots[3].df);
535 }
536
update_state(void)537 static void update_state (void)
538 {
539 set_cpu_state ();
540 #ifdef FPU
541 set_fpu_state ();
542 #endif
543 set_joy_state ();
544 set_sound_state ();
545 #ifdef JIT
546 set_comp_state ();
547 #endif
548 set_mem_state ();
549 set_floppy_state ();
550 #ifdef FILESYS
551 set_hd_state ();
552 #endif
553 set_chipset_state ();
554 set_misc_state ();
555 }
556
update_buttons(void)557 static void update_buttons (void)
558 {
559 if (gui_window) {
560 int running = pause_uae ? 0 : 1;
561 int paused = pause_uae ? 1 : 0;
562
563 gtk_widget_set_sensitive (start_uae_widget, !running && !paused);
564 gtk_widget_set_sensitive (stop_uae_widget, running || paused);
565 gtk_widget_set_sensitive (pause_uae_widget, running || paused);
566 gtk_widget_set_sensitive (reset_uae_widget, running);
567
568 gtk_widget_set_sensitive (hdpanel, !running && !paused);
569 gtk_widget_set_sensitive (memorypanel, !running && !paused);
570 gtk_widget_set_sensitive (rom_change_widget, !running && !paused);
571 // gtk_widget_set_sensitive (sstate_change_widget, !running && !paused);
572
573 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pause_uae_widget), paused);
574 }
575 }
576
577
578 #define MY_IDLE_PERIOD 250
579 #define LEDS_CALLBACK_PERIOD 1000
580 /*
581 * my_idle()
582 *
583 * This function is added as a callback to the GTK+ mainloop
584 * and is run every 250ms. It handles messages sent from UAE.
585 */
my_idle(void)586 static int my_idle (void)
587 {
588 if (quit_gui) {
589 gtk_main_quit ();
590 return 0;
591 }
592
593 while (comm_pipe_has_data (&to_gui_pipe)) {
594 int cmd = read_comm_pipe_int_blocking (&to_gui_pipe);
595 int n;
596 DEBUG_LOG ("GUI got command:%d\n", cmd);
597 switch (cmd) {
598 case GUICMD_STATE_CHANGE: {
599 int state = read_comm_pipe_int_blocking (&to_gui_pipe);
600 update_buttons ();
601 break;
602 }
603 case GUICMD_SHOW:
604 case GUICMD_FLOPPYDLG:
605 if (!gui_window) {
606 create_guidlg ();
607 update_state ();
608 update_buttons (); //FIXME
609 }
610 if (cmd == GUICMD_SHOW) {
611 gtk_widget_show (gui_window);
612 #if GTK_MAJOR_VERSION >= 2
613 gtk_window_present (GTK_WINDOW (gui_window));
614 gui_active = 1;
615 #endif
616 } else {
617 n = read_comm_pipe_int_blocking (&to_gui_pipe);
618 floppyfileentry_do_dialog (FLOPPYFILEENTRY (floppy_widget[n]));
619 }
620 break;
621 case GUICMD_DISKCHANGE:
622 n = read_comm_pipe_int_blocking (&to_gui_pipe);
623 if (floppy_widget[n])
624 floppyfileentry_set_filename (FLOPPYFILEENTRY (floppy_widget[n]), currprefs.floppyslots[n].df);
625 break;
626 case GUICMD_UPDATE:
627 update_state ();
628 uae_sem_post (&gui_update_sem);
629 gui_active = 1;
630 DEBUG_LOG ("GUICMD_UPDATE done\n");
631 break;
632 case GUICMD_MSGBOX:
633 handle_message_box_request(&to_gui_pipe);
634 break;
635 #if 0
636 case GUICMD_FLOPPYDLG:
637 n = read_comm_pipe_int_blocking (&to_gui_pipe);
638 floppyfileentry_do_dialog (FLOPPYFILEENTRY (floppy_widget[n]));
639 break;
640 #endif
641 }
642 }
643 gui_handle_events();
644 return 1;
645 }
646
leds_callback(void)647 static int leds_callback (void)
648 {
649 unsigned int leds = 0; //= gui_ledstate;
650 unsigned int i = 0;
651
652 if (!quit_gui) {
653 for ( ; i < 5; i++) {
654 GtkWidget *widget = i ? floppy_widget[i-1] : power_led;
655 unsigned int mask = 1 << i;
656 unsigned int on = leds & mask;
657
658 if (!widget)
659 continue;
660
661 if (on == (prevledstate & mask))
662 continue;
663
664 if (i > 0)
665 floppyfileentry_set_led (FLOPPYFILEENTRY (widget), on);
666 else {
667 static GdkColor red = {0, 0xffff, 0x0000, 0x0000};
668 static GdkColor black = {0, 0x0000, 0x0000, 0x0000};
669 led_set_color (LED (widget), on ? red : black);
670 }
671 }
672 prevledstate = leds;
673 }
674 return 1;
675 }
676
find_current_toggle(GtkWidget ** widgets,int count)677 static int find_current_toggle (GtkWidget **widgets, int count)
678 {
679 int i;
680 for (i = 0; i < count; i++)
681 if (GTK_TOGGLE_BUTTON (*widgets++)->active)
682 return i;
683 DEBUG_LOG ("GTKUI: Can't happen!\n");
684 return -1;
685 }
686
joy_changed(void)687 static void joy_changed (void)
688 {
689 if (! gui_active)
690 return;
691 changed_prefs.jports[0].id = map_widget_to_jsem (find_current_toggle (joy_widget[0], JOY_WIDGET_COUNT));
692 changed_prefs.jports[1].id = map_widget_to_jsem (find_current_toggle (joy_widget[1], JOY_WIDGET_COUNT));
693
694 // write_log("Joystick Port 0: %d\n", changed_prefs.jports[0].id);
695 // write_log("Joystick Port 1: %d\n", changed_prefs.jports[1].id);
696
697 if (changed_prefs.jports[0].id != currprefs.jports[0].id || changed_prefs.jports[1].id != currprefs.jports[1].id)
698 inputdevice_config_change();
699
700 set_joy_state ();
701 }
702
chipsize_changed(void)703 static void chipsize_changed (void)
704 {
705 int t = find_current_toggle (chipsize_widget, 5);
706 changed_prefs.chipmem_size = 0x80000 << t;
707 for (t = 0; t < 5; t++)
708 gtk_widget_set_sensitive (fastsize_widget[t], changed_prefs.chipmem_size <= 0x200000);
709 if (changed_prefs.chipmem_size > 0x200000) {
710 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fastsize_widget[0]), 1);
711 changed_prefs.fastmem_size = 0;
712 }
713 }
714
bogosize_changed(void)715 static void bogosize_changed (void)
716 {
717 int t = find_current_toggle (bogosize_widget, 4);
718 switch (t) {
719 case 0: changed_prefs.bogomem_size = 0; break;
720 case 1: changed_prefs.bogomem_size = 0x080000; break;
721 case 2: changed_prefs.bogomem_size = 0x100000; break;
722 case 3: changed_prefs.bogomem_size = 0x1C0000; break;
723 }
724 }
725
fastsize_changed(void)726 static void fastsize_changed (void)
727 {
728 int t = find_current_toggle (fastsize_widget, 5);
729 changed_prefs.fastmem_size = (0x80000 << t) & ~0x80000;
730 }
731
z3size_changed(void)732 static void z3size_changed (void)
733 {
734 int t = find_current_toggle (z3size_widget, 10);
735 changed_prefs.z3fastmem_size = (0x80000 << t) & ~0x80000;
736 }
737
738 #ifdef PICASSO96
p96size_changed(void)739 static void p96size_changed (void)
740 {
741 int t = find_current_toggle (p96size_widget, 7);
742 changed_prefs.rtgmem_size = (0x80000 << t) & ~0x80000;
743 }
744 #endif
745
drvspeed_changed(void)746 static void drvspeed_changed (void)
747 {
748 switch (find_current_toggle (sound_widget, 5)) {
749 case 0: changed_prefs.floppy_speed = 0;
750 case 1: changed_prefs.floppy_speed = 100;
751 case 2: changed_prefs.floppy_speed = 200;
752 case 3: changed_prefs.floppy_speed = 400;
753 case 4: changed_prefs.floppy_speed = 800;
754 }
755 }
756
sound_changed(void)757 static void sound_changed (void)
758 {
759 changed_prefs.produce_sound = find_current_toggle (sound_widget, 4);
760 changed_prefs.sound_stereo = find_current_toggle (sound_ch_widget, 3);
761 changed_prefs.sound_mixed_stereo_delay = 0;
762 if (changed_prefs.sound_stereo == 2)
763 changed_prefs.sound_mixed_stereo_delay = changed_prefs.sound_stereo = 1;
764 changed_prefs.sound_interpol = find_current_toggle (sound_in_widget, 3);
765 int t = find_current_toggle (sound_fl_widget, 5);
766
767 if (t == 0)
768 changed_prefs.sound_filter = FILTER_SOUND_OFF;
769 else {
770 changed_prefs.sound_filter = (t & 1) ? FILTER_SOUND_EMUL : FILTER_SOUND_ON;
771 changed_prefs.sound_filter_type = (t > 2 ? FILTER_SOUND_TYPE_A1200 : FILTER_SOUND_TYPE_A500);
772 }
773 }
774
775 #ifdef JIT
comp_changed(void)776 static void comp_changed (void)
777 {
778 changed_prefs.cachesize=cachesize_adj->value;
779 changed_prefs.comptrustbyte = find_current_toggle (compbyte_widget, 4);
780 changed_prefs.comptrustword = find_current_toggle (compword_widget, 4);
781 changed_prefs.comptrustlong = find_current_toggle (complong_widget, 4);
782 changed_prefs.comptrustnaddr = find_current_toggle (compaddr_widget, 4);
783 changed_prefs.compnf = find_current_toggle (compnf_widget, 2);
784 changed_prefs.comp_hardflush = find_current_toggle (comp_hardflush_widget, 2);
785 changed_prefs.comp_constjump = find_current_toggle (comp_constjump_widget, 2);
786 changed_prefs.compfpu= find_current_toggle (compfpu_widget, 2);
787 }
788 #endif
789
cpu_changed(void)790 static void cpu_changed (void)
791 {
792 }
793
fpu_changed(void)794 static void fpu_changed (void)
795 {
796 }
797
on_start_clicked(void)798 static void on_start_clicked (void)
799 {
800 DEBUG_LOG ("Start button clicked.\n");
801
802 write_comm_pipe_int (&from_gui_pipe, UAECMD_START, 1);
803 }
804
on_stop_clicked(void)805 static void on_stop_clicked (void)
806 {
807 DEBUG_LOG ("Stop button clicked.\n");
808
809 write_comm_pipe_int (&from_gui_pipe, UAECMD_STOP, 1);
810 }
811
on_reset_clicked(void)812 static void on_reset_clicked (void)
813 {
814 DEBUG_LOG ("Reset button clicked.\n");
815
816 if (!quit_gui)
817 write_comm_pipe_int (&from_gui_pipe, UAECMD_RESET, 1);
818 }
819
820 #ifdef DEBUGGER
on_debug_clicked(void)821 static void on_debug_clicked (void)
822 {
823 DEBUG_LOG ("Called\n");
824
825 if (!quit_gui)
826 write_comm_pipe_int (&from_gui_pipe, UAECMD_DEBUG, 1);
827 }
828 #endif
829
on_quit_clicked(void)830 static void on_quit_clicked (void)
831 {
832 DEBUG_LOG ("Quit button clicked.\n");
833
834 if (!quit_gui)
835 write_comm_pipe_int (&from_gui_pipe, UAECMD_QUIT, 1);
836 }
837
on_pause_clicked(GtkWidget * widget,gpointer data)838 static void on_pause_clicked (GtkWidget *widget, gpointer data)
839 {
840 DEBUG_LOG ("Called with %d\n", GTK_TOGGLE_BUTTON (widget)->active == true );
841
842 if (!quit_gui) {
843 write_comm_pipe_int (&from_gui_pipe, GTK_TOGGLE_BUTTON (widget)->active ? UAECMD_PAUSE : UAECMD_RESUME, 1);
844 }
845 }
846
847
848 static char *gui_romname;
849 static char *gui_sstate_name;
850
disc_changed(FloppyFileEntry * ffe,gpointer p)851 static void disc_changed (FloppyFileEntry *ffe, gpointer p)
852 {
853 int num = GPOINTER_TO_INT(p);
854 char *s = floppyfileentry_get_filename(ffe);
855 int len;
856
857 if (quit_gui)
858 return;
859
860 if(s == NULL || strlen(s) == 0) {
861 write_comm_pipe_int (&from_gui_pipe, UAECMD_EJECTDISK, 0);
862 write_comm_pipe_int (&from_gui_pipe, GPOINTER_TO_INT(p), 1);
863 } else {
864 /* Get the pathname, not including the filename
865 * Set floppydlg_path to this, so that when the requester
866 * dialog pops up again, we don't have to navigate to the same place. */
867 len = strrchr(s, '/') - s;
868 if (len > 254) len = 254;
869 strncpy(floppydlg_path, s, len);
870 floppydlg_path[len] = '\0';
871
872 uae_sem_wait (&gui_sem);
873 if (new_disk_string[num] != 0)
874 xfree (new_disk_string[num]);
875 new_disk_string[num] = strdup (s);
876 uae_sem_post (&gui_sem);
877 write_comm_pipe_int (&from_gui_pipe, UAECMD_INSERTDISK, 0);
878 write_comm_pipe_int (&from_gui_pipe, num, 1);
879 }
880 }
881
882 static char fsbuffer[100];
883
make_file_selector(const char * title,void (* insertfunc)(GtkObject *),void (* closefunc)(gpointer))884 static GtkWidget *make_file_selector (const char *title,
885 void (*insertfunc)(GtkObject *),
886 void (*closefunc)(gpointer))
887 {
888 GtkWidget *p = gtk_file_selection_new (title);
889 gtk_signal_connect (GTK_OBJECT (p), "destroy", (GtkSignalFunc) closefunc, p);
890
891 gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (p)->ok_button),
892 "clicked", (GtkSignalFunc) insertfunc,
893 GTK_OBJECT (p));
894 gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (p)->cancel_button),
895 "clicked", (GtkSignalFunc) gtk_widget_destroy,
896 GTK_OBJECT (p));
897
898 #if 0
899 gtk_window_set_title (GTK_WINDOW (p), title);
900 #endif
901
902 gtk_widget_show (p);
903 return p;
904 }
905
filesel_set_path(GtkWidget * p,const char * path)906 static void filesel_set_path (GtkWidget *p, const char *path)
907 {
908 size_t len = strlen (path);
909 if (len > 0 && ! access (path, R_OK)) {
910 char *tmp = xmalloc (char, len + 2);
911 strcpy (tmp, path);
912 strcat (tmp, "/");
913 gtk_file_selection_set_filename (GTK_FILE_SELECTION (p),
914 tmp);
915 }
916 }
917
918 static GtkWidget *rom_selector;
919
did_close_rom(gpointer gdata)920 static void did_close_rom (gpointer gdata)
921 {
922 gtk_widget_set_sensitive (rom_change_widget, 1);
923 }
924
did_rom_select(GtkObject * o)925 static void did_rom_select (GtkObject *o)
926 {
927 const char *s = gtk_file_selection_get_filename (GTK_FILE_SELECTION (rom_selector));
928
929 if (quit_gui)
930 return;
931
932 gtk_widget_set_sensitive (rom_change_widget, 1);
933
934 uae_sem_wait (&gui_sem);
935 gui_romname = strdup (s);
936 uae_sem_post (&gui_sem);
937 gtk_label_set_text (GTK_LABEL (rom_text_widget), gui_romname);
938 write_comm_pipe_int (&from_gui_pipe, UAECMD_SELECT_ROM, 0);
939 gtk_widget_destroy (rom_selector);
940 }
941
did_romchange(GtkWidget * w,gpointer data)942 static void did_romchange (GtkWidget *w, gpointer data)
943 {
944 gtk_widget_set_sensitive (rom_change_widget, 0);
945
946 rom_selector = make_file_selector ("Select a ROM file", did_rom_select, did_close_rom);
947 filesel_set_path (rom_selector, currprefs.path_rom.path[0]);
948 }
949
add_empty_vbox(GtkWidget * tobox)950 static void add_empty_vbox (GtkWidget *tobox)
951 {
952 GtkWidget *thing = gtk_vbox_new (false, 0);
953 gtk_widget_show (thing);
954 gtk_box_pack_start (GTK_BOX (tobox), thing, true, true, 0);
955 }
956
add_empty_hbox(GtkWidget * tobox)957 static void add_empty_hbox (GtkWidget *tobox)
958 {
959 GtkWidget *thing = gtk_hbox_new (false, 0);
960 gtk_widget_show (thing);
961 gtk_box_pack_start (GTK_BOX (tobox), thing, true, true, 0);
962 }
963
add_centered_to_vbox(GtkWidget * vbox,GtkWidget * w)964 static void add_centered_to_vbox (GtkWidget *vbox, GtkWidget *w)
965 {
966 GtkWidget *hbox = gtk_hbox_new (true, 0);
967 gtk_widget_show (hbox);
968 gtk_box_pack_start (GTK_BOX (hbox), w, true, false, 0);
969 gtk_box_pack_start (GTK_BOX (vbox), hbox, false, true, 0);
970 }
971
make_labelled_widget(const char * str,GtkWidget * thing)972 static GtkWidget *make_labelled_widget (const char *str, GtkWidget *thing)
973 {
974 GtkWidget *label = gtk_label_new (str);
975 GtkWidget *hbox2 = gtk_hbox_new (false, 4);
976
977 gtk_widget_show (label);
978 gtk_widget_show (thing);
979
980 gtk_box_pack_start (GTK_BOX (hbox2), label, false, true, 0);
981 gtk_box_pack_start (GTK_BOX (hbox2), thing, false, true, 0);
982
983 return hbox2;
984 }
985
add_labelled_widget_centered(const char * str,GtkWidget * thing,GtkWidget * vbox)986 static GtkWidget *add_labelled_widget_centered (const char *str, GtkWidget *thing, GtkWidget *vbox)
987 {
988 GtkWidget *w = make_labelled_widget (str, thing);
989 gtk_widget_show (w);
990 add_centered_to_vbox (vbox, w);
991 return w;
992 }
993
make_radio_group(const char ** labels,GtkWidget * tobox,GtkWidget ** saveptr,gint t1,gint t2,void (* sigfunc)(void),int count,GSList * group)994 static int make_radio_group (const char **labels, GtkWidget *tobox,
995 GtkWidget **saveptr, gint t1, gint t2,
996 void (*sigfunc) (void), int count, GSList *group)
997 {
998 int t = 0;
999
1000 while (*labels && (count == -1 || count-- > 0)) {
1001 GtkWidget *thing = gtk_radio_button_new_with_label (group, *labels++);
1002 group = gtk_radio_button_group (GTK_RADIO_BUTTON (thing));
1003
1004 *saveptr++ = thing;
1005 gtk_widget_show (thing);
1006 gtk_box_pack_start (GTK_BOX (tobox), thing, t1, t2, 0);
1007 gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) sigfunc, NULL);
1008 t++;
1009 }
1010 return t;
1011 }
1012
make_radio_group_box(const char * title,const char ** labels,GtkWidget ** saveptr,int horiz,void (* sigfunc)(void))1013 static GtkWidget *make_radio_group_box (const char *title, const char **labels,
1014 GtkWidget **saveptr, int horiz,
1015 void (*sigfunc) (void))
1016 {
1017 GtkWidget *frame, *newbox;
1018
1019 frame = gtk_frame_new (title);
1020 newbox = (horiz ? gtk_hbox_new : gtk_vbox_new) (false, 4);
1021 gtk_widget_show (newbox);
1022 gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
1023 gtk_container_add (GTK_CONTAINER (frame), newbox);
1024 make_radio_group (labels, newbox, saveptr, horiz, !horiz, sigfunc, -1, NULL);
1025 return frame;
1026 }
1027
make_radio_group_box_1(const char * title,const char ** labels,GtkWidget ** saveptr,int horiz,void (* sigfunc)(void),int elts_per_column)1028 static GtkWidget *make_radio_group_box_1 (const char *title, const char **labels,
1029 GtkWidget **saveptr, int horiz,
1030 void (*sigfunc) (void), int elts_per_column)
1031 {
1032 GtkWidget *frame, *newbox;
1033 GtkWidget *column;
1034 GSList *group = 0;
1035
1036 frame = gtk_frame_new (title);
1037 column = (horiz ? gtk_vbox_new : gtk_hbox_new) (false, 4);
1038 gtk_container_add (GTK_CONTAINER (frame), column);
1039 gtk_widget_show (column);
1040
1041 while (*labels) {
1042 int count;
1043 newbox = (horiz ? gtk_hbox_new : gtk_vbox_new) (false, 4);
1044 gtk_widget_show (newbox);
1045 gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
1046 gtk_container_add (GTK_CONTAINER (column), newbox);
1047 count = make_radio_group (labels, newbox, saveptr, horiz, !horiz, sigfunc, elts_per_column, group);
1048 labels += count;
1049 saveptr += count;
1050 group = gtk_radio_button_group (GTK_RADIO_BUTTON (saveptr[-1]));
1051 }
1052 return frame;
1053 }
1054
1055
make_file_container(const char * title,GtkWidget * vbox)1056 static GtkWidget *make_file_container (const char *title, GtkWidget *vbox)
1057 {
1058 GtkWidget *thing = gtk_frame_new (title);
1059 GtkWidget *buttonbox = gtk_hbox_new (false, 4);
1060
1061 gtk_container_set_border_width (GTK_CONTAINER (buttonbox), 4);
1062 gtk_container_add (GTK_CONTAINER (thing), buttonbox);
1063 gtk_box_pack_start (GTK_BOX (vbox), thing, false, true, 0);
1064 gtk_widget_show (buttonbox);
1065 gtk_widget_show (thing);
1066
1067 return buttonbox;
1068 }
1069
make_file_widget(GtkWidget * buttonbox)1070 static GtkWidget *make_file_widget (GtkWidget *buttonbox)
1071 {
1072 GtkWidget *thing, *subthing;
1073 GtkWidget *subframe = gtk_frame_new (NULL);
1074
1075 gtk_frame_set_shadow_type (GTK_FRAME (subframe), GTK_SHADOW_ETCHED_OUT);
1076 gtk_box_pack_start (GTK_BOX (buttonbox), subframe, true, true, 0);
1077 gtk_widget_show (subframe);
1078 subthing = gtk_vbox_new (false, 0);
1079 gtk_widget_show (subthing);
1080 gtk_container_add (GTK_CONTAINER (subframe), subthing);
1081 thing = gtk_label_new ("");
1082 gtk_widget_show (thing);
1083 gtk_box_pack_start (GTK_BOX (subthing), thing, true, true, 0);
1084
1085 return thing;
1086 }
1087
make_floppy_disks(GtkWidget * vbox)1088 static void make_floppy_disks (GtkWidget *vbox)
1089 {
1090 char buf[5];
1091 unsigned int i;
1092 static const char *drv_speed_labels[] = { "Turbo", "100% (Compatible)", "200%", "400%", "800%", NULL };
1093
1094 add_empty_vbox (vbox);
1095 GtkWidget *frame = make_radio_group_box ("Floppy Drive Speed", drv_speed_labels, drvspeed_widget, 1, drvspeed_changed);
1096 gtk_widget_show (frame);
1097 gtk_box_pack_start (GTK_BOX (vbox), frame, false, true, 0);
1098
1099 add_empty_vbox (vbox);
1100 for (i = 0; i < 4; i++) {
1101 sprintf (buf, "DF%d:", i);
1102
1103 floppy_widget[i] = floppyfileentry_new ();
1104 if (currprefs.floppyslots[i].dfxtype == -1)
1105 gtk_widget_set_sensitive(floppy_widget[i], 0);
1106 floppyfileentry_set_drivename (FLOPPYFILEENTRY (floppy_widget[i]), buf);
1107 floppyfileentry_set_label (FLOPPYFILEENTRY (floppy_widget[i]), buf);
1108 floppyfileentry_set_currentdir (FLOPPYFILEENTRY (floppy_widget[i]), currprefs.path_floppy.path[i]);
1109 gtk_box_pack_start (GTK_BOX (vbox), floppy_widget[i], false, true, 0);
1110 gtk_widget_show (floppy_widget[i]);
1111 gtk_signal_connect (GTK_OBJECT (floppy_widget[i]), "disc-changed", (GtkSignalFunc) disc_changed, GINT_TO_POINTER (i));
1112 }
1113
1114 add_empty_vbox (vbox);
1115 }
1116
1117 static GtkWidget *sstate_selector;
1118
did_close_sstate(gpointer gdata)1119 static void did_close_sstate (gpointer gdata)
1120 {
1121 gtk_widget_set_sensitive (sstate_change_widget, 1);
1122 }
1123
did_sstate_select(GtkObject * o)1124 static void did_sstate_select (GtkObject *o)
1125 {
1126 const char *s = gtk_file_selection_get_filename (GTK_FILE_SELECTION (sstate_selector));
1127
1128 if (quit_gui)
1129 return;
1130
1131 gtk_widget_set_sensitive (sstate_change_widget, 1);
1132
1133 uae_sem_wait (&gui_sem);
1134 gui_sstate_name = strdup (s);
1135 uae_sem_post (&gui_sem);
1136 gtk_label_set_text (GTK_LABEL (sstate_text_widget), gui_sstate_name);
1137 gtk_widget_destroy (sstate_selector);
1138 }
1139
did_sstate_change(GtkWidget * w,gpointer data)1140 static void did_sstate_change (GtkWidget *w, gpointer data)
1141 {
1142 gtk_widget_set_sensitive (sstate_change_widget, 0);
1143
1144 sstate_selector = make_file_selector ("Select a Savestate file", did_sstate_select, did_close_sstate);
1145 // filesel_set_path (sstate_selector, currprefs.path_savestate);
1146 }
1147
did_sstate_load(GtkWidget * w,gpointer data)1148 static void did_sstate_load (GtkWidget *w, gpointer data)
1149 {
1150 if ((int)strlen(gui_sstate_name) == 0) {
1151 ;// writelog ("SaveState Load: Select a Savestate first\n");
1152 } else {
1153 write_comm_pipe_int (&from_gui_pipe, UAECMD_SAVESTATE_LOAD, 0);
1154 }
1155 }
1156
did_sstate_save(GtkWidget * w,gpointer data)1157 static void did_sstate_save (GtkWidget *w, gpointer data)
1158 {
1159 if ((int)strlen(gui_sstate_name) == 0) {
1160 ;// writelog ("SaveState Save: Select a Savestate first\n");
1161 } else {
1162 write_comm_pipe_int (&from_gui_pipe, UAECMD_SAVESTATE_SAVE, 0);
1163 }
1164 }
1165
make_ss_widgets(GtkWidget * vbox)1166 static void make_ss_widgets (GtkWidget *vbox)
1167 {
1168 GtkWidget *hbox = gtk_hbox_new (false, 10);
1169
1170 add_empty_vbox (vbox);
1171
1172 GtkWidget *buttonbox = make_file_container ("Savestate file:", vbox);
1173 GtkWidget *thing = gtk_button_new_with_label ("Select");
1174 GtkWidget *thing_load = gtk_button_new_with_label ("Load");
1175 GtkWidget *thing_save = gtk_button_new_with_label ("Save");
1176
1177 /* Current file display */
1178 sstate_text_widget = make_file_widget (buttonbox);
1179
1180 gtk_box_pack_start (GTK_BOX (buttonbox), thing, false, true, 0);
1181 gtk_widget_show (thing);
1182 gtk_box_pack_start (GTK_BOX (buttonbox), thing_load, false, true, 0);
1183 gtk_widget_show (thing_load);
1184 gtk_box_pack_start (GTK_BOX (buttonbox), thing_save, false, true, 0);
1185 gtk_widget_show (thing_save);
1186
1187 sstate_change_widget = thing;
1188 sstate_load_widget = thing_load;
1189 sstate_save_widget = thing_save;
1190 gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_sstate_change, 0);
1191 gtk_signal_connect (GTK_OBJECT (thing_load), "clicked", (GtkSignalFunc) did_sstate_load, 0);
1192 gtk_signal_connect (GTK_OBJECT (thing_save), "clicked", (GtkSignalFunc) did_sstate_save, 0);
1193
1194 gtk_widget_show (hbox);
1195 add_centered_to_vbox (vbox, hbox);
1196 }
1197
leds_on_screen_changed(void)1198 static void leds_on_screen_changed (void)
1199 {
1200 currprefs.leds_on_screen = GTK_TOGGLE_BUTTON(leds_on_screen_widget)->active;
1201 DEBUG_LOG("leds_on_screen = %d\n", currprefs.leds_on_screen);
1202 }
1203
make_misc_widgets(GtkWidget * vbox)1204 static void make_misc_widgets (GtkWidget *vbox)
1205 {
1206 GtkWidget *hbox = gtk_hbox_new (false, 10);
1207
1208 add_empty_vbox (vbox);
1209
1210 leds_on_screen_widget = gtk_check_button_new_with_label ("Status Line");
1211 gtk_signal_connect (GTK_OBJECT (leds_on_screen_widget), "clicked", (GtkSignalFunc) leds_on_screen_changed, 0);
1212 gtk_widget_show (leds_on_screen_widget);
1213 gtk_box_pack_start (GTK_BOX (hbox), leds_on_screen_widget, false, true, 0);
1214
1215 gtk_widget_show (hbox);
1216 add_centered_to_vbox (vbox, hbox);
1217 }
1218 /*
1219 * CPU configuration page
1220 */
on_cputype_changed(void)1221 static void on_cputype_changed (void)
1222 {
1223 int i;
1224 unsigned int mdl;
1225
1226 mdl = cputypepanel_get_cpulevel (CPUTYPEPANEL (ctpanel));
1227 mdl = (mdl * 10) + 68000;
1228
1229 DEBUG_LOG ("called\n");
1230
1231 changed_prefs.cpu_model = mdl;
1232 changed_prefs.cpu_cycle_exact = CPUTYPEPANEL (ctpanel)->cycleexact;
1233
1234 set_mem32_widgets_state ();
1235
1236 DEBUG_LOG ("cpu_model=%d address_space24=%d cpu_compatible=%d cpu_cycle_exact=%d\n",
1237 changed_prefs.cpu_model, changed_prefs.address_space_24,
1238 changed_prefs.cpu_compatible, changed_prefs.cpu_cycle_exact);
1239 }
1240
on_addr24bit_changed(void)1241 static void on_addr24bit_changed (void)
1242 {
1243 int i;
1244
1245 DEBUG_LOG ("called\n");
1246
1247 changed_prefs.address_space_24 = (cputypepanel_get_addr24bit (CPUTYPEPANEL (ctpanel)) != 0);
1248 set_mem32_widgets_state ();
1249
1250 DEBUG_LOG ("address_space_24=%d\n", changed_prefs.address_space_24);
1251 }
1252
on_cpuspeed_changed(void)1253 static void on_cpuspeed_changed (void)
1254 {
1255 DEBUG_LOG ("called\n");
1256
1257 changed_prefs.m68k_speed = CPUSPEEDPANEL (cspanel)->cpuspeed;
1258
1259 DEBUG_LOG ("m68k_speed=%d\n", changed_prefs.m68k_speed);
1260 }
1261
on_cpuidle_changed(void)1262 static void on_cpuidle_changed (void)
1263 {
1264 DEBUG_LOG ("called\n");
1265
1266 changed_prefs.cpu_idle = CPUSPEEDPANEL (cspanel)->cpuidle;
1267
1268 DEBUG_LOG ("cpu_idle=%d\n", changed_prefs.cpu_idle);
1269 }
1270
make_cpu_widgets(GtkWidget * vbox)1271 static void make_cpu_widgets (GtkWidget *vbox)
1272 {
1273 GtkWidget *table;
1274
1275 table = make_xtable (5, 7);
1276 add_table_padding (table, 0, 0);
1277 add_table_padding (table, 4, 4);
1278 add_table_padding (table, 1, 2);
1279 gtk_box_pack_start (GTK_BOX (vbox), table, true, true, 0);
1280
1281 ctpanel = cputypepanel_new();
1282 gtk_table_attach (GTK_TABLE (table), ctpanel, 1, 4, 1, 2,
1283 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1284 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1285 gtk_widget_show (ctpanel);
1286
1287 ftpanel = fputypepanel_new();
1288 gtk_table_attach (GTK_TABLE (table), ftpanel, 1, 4, 3, 4,
1289 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1290 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1291 gtk_widget_show (ftpanel);
1292
1293 cspanel = cpuspeedpanel_new();
1294 gtk_table_attach (GTK_TABLE (table), cspanel, 1, 4, 5, 6,
1295 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1296 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1297 gtk_widget_show (cspanel);
1298
1299 gtk_signal_connect (GTK_OBJECT (ctpanel), "cputype-changed",
1300 GTK_SIGNAL_FUNC (on_cputype_changed),
1301 NULL);
1302 gtk_signal_connect (GTK_OBJECT (ctpanel), "addr24bit-changed",
1303 GTK_SIGNAL_FUNC (on_addr24bit_changed),
1304 NULL);
1305 gtk_signal_connect (GTK_OBJECT (cspanel), "cpuspeed-changed",
1306 GTK_SIGNAL_FUNC (on_cpuspeed_changed),
1307 NULL);
1308 gtk_signal_connect (GTK_OBJECT (cspanel), "cpuidle-changed",
1309 GTK_SIGNAL_FUNC (on_cpuidle_changed),
1310 NULL);
1311 }
1312
on_chipset_changed(void)1313 static void on_chipset_changed (void)
1314 {
1315 changed_prefs.chipset_mask = CHIPSETTYPEPANEL (chipsettype_panel)->chipset_mask;
1316 changed_prefs.ntscmode = CHIPSETTYPEPANEL (chipsettype_panel)->ntscmode;
1317 }
1318
on_framerate_changed(void)1319 static void on_framerate_changed (void)
1320 {
1321 changed_prefs.gfx_framerate = CHIPSETSPEEDPANEL (chipsetspeed_panel)->framerate;
1322 DEBUG_LOG("gfx_framerate = %d\n", changed_prefs.gfx_framerate);
1323 }
1324
on_collision_level_changed(void)1325 static void on_collision_level_changed (void)
1326 {
1327 changed_prefs.collision_level = CHIPSETSPEEDPANEL (chipsetspeed_panel)->collision_level;
1328 DEBUG_LOG("collision_level = %d\n", changed_prefs.collision_level);
1329 }
1330
on_immediate_blits_changed(void)1331 static void on_immediate_blits_changed (void)
1332 {
1333 changed_prefs.immediate_blits = CHIPSETSPEEDPANEL (chipsetspeed_panel)->immediate_blits;
1334 DEBUG_LOG("immediate_blits = %d\n", changed_prefs.immediate_blits);
1335 }
1336
make_chipset_widgets(GtkWidget * vbox)1337 static void make_chipset_widgets (GtkWidget *vbox)
1338 {
1339 GtkWidget *table;
1340
1341 table = make_xtable (5, 7);
1342 add_table_padding (table, 0, 0);
1343 add_table_padding (table, 4, 4);
1344 add_table_padding (table, 1, 2);
1345 gtk_box_pack_start (GTK_BOX (vbox), table, true, true, 0);
1346
1347 chipsettype_panel = chipsettypepanel_new ();
1348 gtk_table_attach (GTK_TABLE (table), chipsettype_panel, 1, 4, 1, 2,
1349 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1350 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1351 gtk_widget_show (chipsettype_panel);
1352
1353 chipsetspeed_panel = chipsetspeedpanel_new ();
1354 gtk_table_attach (GTK_TABLE (table), chipsetspeed_panel, 1, 4, 3, 4,
1355 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1356 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1357 gtk_widget_show (chipsetspeed_panel);
1358
1359
1360 gtk_signal_connect (GTK_OBJECT (chipsettype_panel), "chipset-changed", GTK_SIGNAL_FUNC (on_chipset_changed), NULL);
1361 gtk_signal_connect (GTK_OBJECT (chipsetspeed_panel), "framerate-changed", GTK_SIGNAL_FUNC (on_framerate_changed), NULL);
1362 gtk_signal_connect (GTK_OBJECT (chipsetspeed_panel), "sprite-collisions-changed", GTK_SIGNAL_FUNC (on_collision_level_changed), NULL);
1363 gtk_signal_connect (GTK_OBJECT (chipsetspeed_panel), "immediate-blits-changed", GTK_SIGNAL_FUNC (on_immediate_blits_changed), NULL);
1364 }
1365
make_cpu_widgets2(GtkWidget * vbox)1366 static void make_cpu_widgets2 (GtkWidget *vbox)
1367 {
1368 static const char *cpu_labels[] = {
1369 "68000", "68010", "68020", "68030", "68040", "68060", NULL
1370 }, *fpu_labels[] = {
1371 "None", "68881", "68882", "CPU Internal", NULL
1372 };
1373
1374 GtkWidget *hbox = gtk_hbox_new (false, 10);
1375 GtkWidget *frame, *newbox, *newbox2;
1376 add_empty_vbox (vbox);
1377
1378 gtk_widget_show (hbox);
1379 add_centered_to_vbox (vbox, hbox);
1380 add_empty_vbox (vbox);
1381
1382 //cpu emulation
1383 newbox = make_radio_group_box ("CPU", cpu_labels, cpu_widget, 0, cpu_changed);
1384 gtk_widget_show (newbox);
1385 gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1386
1387 newbox2 = gtk_check_button_new_with_label ("24-bit addressing");
1388 gtk_widget_show (newbox2);
1389 gtk_box_pack_start (GTK_BOX (newbox), newbox2, false, true, 0);
1390
1391 newbox2 = gtk_check_button_new_with_label ("More compatible");
1392 gtk_widget_show (newbox2);
1393 gtk_box_pack_start (GTK_BOX (newbox), newbox2, false, true, 0);
1394
1395 newbox = gtk_check_button_new_with_label ("JIT");
1396 gtk_widget_show (newbox);
1397 gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1398
1399 newbox = gtk_check_button_new_with_label ("68040 MMU");
1400 gtk_widget_show (newbox);
1401 gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1402
1403 //fpu mode
1404 newbox = make_radio_group_box ("FPU", fpu_labels, fpu_widget, 0, fpu_changed);
1405 gtk_widget_show (newbox);
1406 gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1407
1408 newbox = gtk_check_button_new_with_label ("More compatible");
1409 gtk_widget_show (newbox);
1410 gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1411 }
1412
make_sound_widgets(GtkWidget * vbox)1413 static void make_sound_widgets (GtkWidget *vbox)
1414 {
1415 static const char *snd_em_labels[] = {
1416 "Disabled", "Disabled, but Emulated", "Enabled", "Enabled, 100% Accurate", NULL
1417 }, *snd_in_labels[] = {
1418 "Disabled", "None", "Sinc", "RH", "Anti", NULL
1419 }, *snd_fl_labels[] = {
1420 "Disabled", "A500 (Power Led)", "A500 (Always on)", "A1200 (Power Led)", "A1200 (Always on)", NULL
1421 }, *snd_ch_labels[] = {
1422 "Mono", "Stereo", "Mixed", NULL
1423 };
1424
1425 GtkWidget *hbox = gtk_hbox_new (false, 10);
1426 GtkWidget *frame, *newbox;
1427 add_empty_vbox (vbox);
1428
1429 gtk_widget_show (hbox);
1430 add_centered_to_vbox (vbox, hbox);
1431 add_empty_vbox (vbox);
1432
1433 //sound emulation
1434 newbox = make_radio_group_box ("Sound Emulation", snd_em_labels, sound_widget, 0, sound_changed);
1435 gtk_widget_set_sensitive (sound_widget[2], sound_available);
1436 gtk_widget_set_sensitive (sound_widget[3], sound_available);
1437 gtk_widget_show (newbox);
1438 gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1439
1440 //channel mode
1441 newbox = make_radio_group_box ("Channels", snd_ch_labels, sound_ch_widget, 0, sound_changed);
1442 gtk_widget_set_sensitive (newbox, sound_available);
1443 gtk_widget_show (newbox);
1444 gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1445
1446 //interpolation
1447 newbox = make_radio_group_box ("Interpolation", snd_in_labels, sound_in_widget, 0, sound_changed);
1448 gtk_widget_set_sensitive (newbox, sound_available);
1449 gtk_widget_show (newbox);
1450 gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1451
1452 //audio filter
1453 newbox = make_radio_group_box ("Audio Filter", snd_fl_labels, sound_fl_widget, 0, sound_changed);
1454 gtk_widget_set_sensitive (newbox, sound_available);
1455 gtk_widget_show (newbox);
1456 gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1457 }
1458
make_mem_widgets(GtkWidget * vbox)1459 static void make_mem_widgets (GtkWidget *vbox)
1460 {
1461 GtkWidget *hbox = gtk_hbox_new (false, 10);
1462 GtkWidget *label, *frame;
1463
1464 static const char *chiplabels[] = {
1465 "512 KB", "1 MB", "2 MB", "4 MB", "8 MB", NULL
1466 };
1467 static const char *bogolabels[] = {
1468 "None", "512 KB", "1 MB", "1.8 MB", NULL
1469 };
1470 static const char *fastlabels[] = {
1471 "None", "1 MB", "2 MB", "4 MB", "8 MB", NULL
1472 };
1473 static const char *z3labels[] = {
1474 "None", "1 MB", "2 MB", "4 MB", "8 MB",
1475 "16 MB", "32 MB", "64 MB", "128 MB", "256 MB",
1476 NULL
1477 };
1478 static const char *p96labels[] = {
1479 "None", "1 MB", "2 MB", "4 MB", "8 MB", "16 MB", "32 MB", NULL
1480 };
1481
1482 add_empty_vbox (vbox);
1483
1484 {
1485 GtkWidget *buttonbox = make_file_container ("Kickstart ROM file:", vbox);
1486 GtkWidget *thing = gtk_button_new_with_label ("Change");
1487
1488 /* Current file display */
1489 rom_text_widget = make_file_widget (buttonbox);
1490
1491 gtk_box_pack_start (GTK_BOX (buttonbox), thing, false, true, 0);
1492 gtk_widget_show (thing);
1493 rom_change_widget = thing;
1494 gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_romchange, 0);
1495 }
1496
1497 gtk_widget_show (hbox);
1498 add_centered_to_vbox (vbox, hbox);
1499
1500 add_empty_vbox (vbox);
1501
1502 frame = make_radio_group_box ("Chip Mem", chiplabels, chipsize_widget, 0, chipsize_changed);
1503 gtk_widget_show (frame);
1504 gtk_box_pack_start (GTK_BOX (hbox), frame, false, true, 0);
1505
1506 frame = make_radio_group_box ("Slow Mem", bogolabels, bogosize_widget, 0, bogosize_changed);
1507 gtk_widget_show (frame);
1508 gtk_box_pack_start (GTK_BOX (hbox), frame, false, true, 0);
1509
1510 frame = make_radio_group_box ("Fast Mem", fastlabels, fastsize_widget, 0, fastsize_changed);
1511 gtk_widget_show (frame);
1512 gtk_box_pack_start (GTK_BOX (hbox), frame, false, true, 0);
1513
1514 frame = make_radio_group_box_1 ("Z3 Mem", z3labels, z3size_widget, 0, z3size_changed, 5);
1515 gtk_widget_show (frame);
1516 gtk_box_pack_start (GTK_BOX (hbox), frame, false, true, 0);
1517
1518 #ifdef PICASSO96
1519 frame = make_radio_group_box_1 ("P96 RAM", p96labels, p96size_widget, 0, p96size_changed, 4);
1520 gtk_widget_show (frame);
1521 gtk_box_pack_start (GTK_BOX (hbox), frame, false, true, 0);
1522 #endif
1523
1524 memorypanel = hbox;
1525 }
1526
1527 #ifdef JIT
make_comp_widgets(GtkWidget * vbox)1528 static void make_comp_widgets (GtkWidget *vbox)
1529 {
1530 GtkWidget *newbox;
1531 static const char *complabels1[] = {
1532 "Direct", "Indirect", "Indirect for KS", "Direct after Picasso",
1533 NULL
1534 },*complabels2[] = {
1535 "Direct", "Indirect", "Indirect for KS", "Direct after Picasso",
1536 NULL
1537 },*complabels3[] = {
1538 "Direct", "Indirect", "Indirect for KS", "Direct after Picasso",
1539 NULL
1540 },*complabels3a[] = {
1541 "Direct", "Indirect", "Indirect for KS", "Direct after Picasso",
1542 NULL
1543 }, *complabels4[] = {
1544 "Always generate", "Only generate when needed",
1545 NULL
1546 }, *complabels5[] = {
1547 "Disable", "Enable",
1548 NULL
1549 }, *complabels6[] = {
1550 "Disable", "Enable",
1551 NULL
1552 }, *complabels7[] = {
1553 "Disable", "Enable",
1554 NULL
1555 }, *complabels8[] = {
1556 "Soft", "Hard",
1557 NULL
1558 }, *complabels9[] = {
1559 "Disable", "Enable",
1560 NULL
1561 };
1562 GtkWidget *thing;
1563
1564 add_empty_vbox (vbox);
1565
1566 newbox = make_radio_group_box ("Byte access", complabels1, compbyte_widget, 1, comp_changed);
1567 gtk_widget_show (newbox);
1568 add_centered_to_vbox (vbox, newbox);
1569 newbox = make_radio_group_box ("Word access", complabels2, compword_widget, 1, comp_changed);
1570 gtk_widget_show (newbox);
1571 add_centered_to_vbox (vbox, newbox);
1572 newbox = make_radio_group_box ("Long access", complabels3, complong_widget, 1, comp_changed);
1573 gtk_widget_show (newbox);
1574 add_centered_to_vbox (vbox, newbox);
1575 newbox = make_radio_group_box ("Address lookup", complabels3a, compaddr_widget, 1, comp_changed);
1576 gtk_widget_show (newbox);
1577 add_centered_to_vbox (vbox, newbox);
1578
1579 newbox = make_radio_group_box ("Flags", complabels4, compnf_widget, 1, comp_changed);
1580 gtk_widget_show (newbox);
1581 add_centered_to_vbox (vbox, newbox);
1582
1583 newbox = make_radio_group_box ("Icache flushes", complabels8, comp_hardflush_widget, 1, comp_changed);
1584 gtk_widget_show (newbox);
1585 add_centered_to_vbox (vbox, newbox);
1586
1587 newbox = make_radio_group_box ("Compile through uncond branch", complabels9, comp_constjump_widget, 1, comp_changed);
1588 gtk_widget_show (newbox);
1589 add_centered_to_vbox (vbox, newbox);
1590
1591 newbox = make_radio_group_box ("JIT FPU compiler", complabels7, compfpu_widget, 1, comp_changed);
1592 gtk_widget_show (newbox);
1593 add_centered_to_vbox (vbox, newbox);
1594
1595 cachesize_adj = GTK_ADJUSTMENT (gtk_adjustment_new (currprefs.cachesize, 0.0, 16385.0, 1.0, 1.0, 1.0));
1596 gtk_signal_connect (GTK_OBJECT (cachesize_adj), "value_changed",
1597 GTK_SIGNAL_FUNC (comp_changed), NULL);
1598
1599 thing = gtk_hscale_new (cachesize_adj);
1600 gtk_range_set_update_policy (GTK_RANGE (thing), GTK_UPDATE_DELAYED);
1601 gtk_scale_set_digits (GTK_SCALE (thing), 0);
1602 gtk_scale_set_value_pos (GTK_SCALE (thing), GTK_POS_RIGHT);
1603 gtk_widget_set_usize (thing, 180, -1); // Hack!
1604 add_labelled_widget_centered ("Translation buffer(kB):", thing, vbox);
1605
1606 add_empty_vbox (vbox);
1607
1608 /* Kludge - remember pointer to JIT page, so that we can easily disable it */
1609 jit_page = vbox;
1610 }
1611 #endif
1612
make_joy_widgets(GtkWidget * dvbox)1613 static void make_joy_widgets (GtkWidget *dvbox)
1614 {
1615 int i;
1616 int joy_count = inputdevice_get_device_total (IDTYPE_JOYSTICK);
1617 GtkWidget *hbox = gtk_hbox_new (false, 12);
1618
1619 static const char *joylabels[] = {
1620 "None",
1621 "Joystick 0",
1622 "Joystick 1",
1623 "Mouse",
1624 "Keyboard Layout A (NumPad, 0 & 5 = Fire)",
1625 "Keyboard Layout B (Cursor, RCtrl & Alt = Fire)",
1626 "Keyboard Layout C (WASD, LAlt = Fire)",
1627 #ifdef XARCADE
1628 "X-Arcade (Left)",
1629 "X-Arcade (Right)",
1630 #endif
1631 NULL
1632 };
1633
1634 add_empty_vbox (dvbox);
1635 gtk_widget_show (hbox);
1636 add_centered_to_vbox (dvbox, hbox);
1637
1638 for (i = 0; i < 2; i++) {
1639 GtkWidget *frame;
1640 char buffer[20];
1641
1642 sprintf (buffer, "Port %d", i);
1643 frame = make_radio_group_box (buffer, joylabels, joy_widget[i], 0, joy_changed);
1644 gtk_widget_show (frame);
1645 gtk_box_pack_start (GTK_BOX (hbox), frame, false, true, 0);
1646
1647 if (joy_count < 2)
1648 gtk_widget_set_sensitive (joy_widget[i][2], 0);
1649 if (joy_count == 0)
1650 gtk_widget_set_sensitive (joy_widget[i][1], 0);
1651 }
1652
1653 add_empty_vbox (dvbox);
1654 }
1655
1656 #ifdef FILESYS
1657 static int hd_change_mode;
1658
newdir_ok(void)1659 static void newdir_ok (void)
1660 {
1661 int n;
1662 int readonly = GTK_TOGGLE_BUTTON (readonly_widget)->active;
1663 int bootpri = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (bootpri_widget));
1664 strcpy (dirdlg_devname, gtk_entry_get_text (GTK_ENTRY (devname_entry)));
1665 strcpy (dirdlg_volname, gtk_entry_get_text (GTK_ENTRY (volname_entry)));
1666 strcpy (dirdlg_path, gtk_entry_get_text (GTK_ENTRY (path_entry)));
1667
1668 unsigned int secspertrack = 0;
1669 unsigned int surfaces = 0;
1670 unsigned int reserved = 0;
1671 unsigned int blocksize = 0;
1672 unsigned int flags = 0;
1673 unsigned int donotmount = 0;
1674 unsigned int autoboot = 129;
1675 unsigned int hdc = 0;
1676
1677 n = strlen (dirdlg_volname);
1678 /* Strip colons from the end. */
1679 if (n > 0) {
1680 if (dirdlg_volname[n - 1] == ':')
1681 dirdlg_volname[n - 1] = '\0';
1682 }
1683 /* Do device name too */
1684 n = strlen (dirdlg_devname);
1685 if (n > 0) {
1686 if (dirdlg_devname[n - 1] == ':')
1687 dirdlg_devname[n - 1] = '\0';
1688 }
1689 if (strlen (dirdlg_volname) == 0 || strlen (dirdlg_path) == 0) {
1690 /* Uh, no messageboxes in gtk? */
1691 /// FIXME: set_filesys_unit() needs uaedev_config_info* !
1692 #if 0
1693 } else if (hd_change_mode) {
1694 set_filesys_unit (selected_hd_row, dirdlg_devname, dirdlg_volname, dirdlg_path,
1695 readonly, 0, secspertrack, surfaces, reserved, blocksize, bootpri,
1696 donotmount, autoboot, (TCHAR*)NULL, hdc, flags);
1697 set_hd_state ();
1698 #endif // 0
1699 /// FIXME: add_filesys_unit() needs uaedev_config_info* !
1700 #if 0
1701 } else {
1702 add_filesys_unit (dirdlg_devname, dirdlg_volname, dirdlg_path, readonly,
1703 0, secspertrack, surfaces, reserved, blocksize, bootpri,
1704 donotmount, autoboot, (TCHAR*)NULL, hdc, flags);
1705 set_hd_state ();
1706 #endif // 0
1707 }
1708 gtk_widget_destroy (dirdlg);
1709 }
1710
1711
1712 GtkWidget *path_selector;
1713
did_dirdlg_done_select(GtkObject * o,gpointer entry)1714 static void did_dirdlg_done_select (GtkObject *o, gpointer entry )
1715 {
1716 assert (GTK_IS_ENTRY (entry));
1717
1718 gtk_entry_set_text (GTK_ENTRY (entry), gtk_file_selection_get_filename (GTK_FILE_SELECTION (path_selector)));
1719 }
1720
did_dirdlg_select(GtkObject * o,gpointer entry)1721 static void did_dirdlg_select (GtkObject *o, gpointer entry )
1722 {
1723 assert( GTK_IS_ENTRY(entry) );
1724 path_selector = gtk_file_selection_new ("Select a folder to mount");
1725 gtk_file_selection_set_filename (GTK_FILE_SELECTION (path_selector), gtk_entry_get_text (GTK_ENTRY (entry)));
1726 gtk_window_set_modal (GTK_WINDOW (path_selector), true);
1727
1728 gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(path_selector)->ok_button),
1729 "clicked", GTK_SIGNAL_FUNC (did_dirdlg_done_select),
1730 (gpointer) entry);
1731 gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(path_selector)->ok_button),
1732 "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
1733 (gpointer) path_selector);
1734 gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(path_selector)->cancel_button),
1735 "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
1736 (gpointer) path_selector);
1737
1738 /* Gtk1.2 doesn't have a directory chooser widget, so we fake one from the
1739 * file dialog by hiding the widgets related to file selection */
1740 gtk_widget_hide ((GTK_FILE_SELECTION(path_selector)->file_list)->parent);
1741 gtk_widget_hide (GTK_FILE_SELECTION(path_selector)->fileop_del_file);
1742 gtk_widget_hide (GTK_FILE_SELECTION(path_selector)->fileop_ren_file);
1743 gtk_widget_hide (GTK_FILE_SELECTION(path_selector)->selection_entry);
1744 gtk_entry_set_text (GTK_ENTRY (GTK_FILE_SELECTION(path_selector)->selection_entry), "" );
1745
1746 gtk_widget_show (path_selector);
1747 }
1748
dirdlg_on_change(GtkObject * o,gpointer data)1749 static void dirdlg_on_change (GtkObject *o, gpointer data)
1750 {
1751 int can_complete = (strlen (gtk_entry_get_text (GTK_ENTRY(path_entry))) !=0)
1752 && (strlen (gtk_entry_get_text (GTK_ENTRY(volname_entry))) != 0)
1753 && (strlen (gtk_entry_get_text (GTK_ENTRY(devname_entry))) != 0);
1754
1755 gtk_widget_set_sensitive (dirdlg_ok, can_complete);
1756 }
1757
create_dirdlg(const char * title)1758 static void create_dirdlg (const char *title)
1759 {
1760 GtkWidget *dialog_vbox, *dialog_hbox, *vbox, *frame, *table, *hbox, *thing, *label, *button;
1761
1762 dirdlg = gtk_dialog_new ();
1763
1764 gtk_window_set_title (GTK_WINDOW (dirdlg), title);
1765 gtk_window_set_position (GTK_WINDOW (dirdlg), GTK_WIN_POS_MOUSE);
1766 gtk_window_set_modal (GTK_WINDOW (dirdlg), true);
1767 gtk_widget_show (dirdlg);
1768
1769 dialog_vbox = GTK_DIALOG (dirdlg)->vbox;
1770 gtk_widget_show (dialog_vbox);
1771
1772 vbox = gtk_vbox_new (false, 0);
1773 gtk_widget_show (vbox);
1774 gtk_box_pack_start (GTK_BOX (dialog_vbox), vbox, true, false, 0);
1775
1776 frame = gtk_frame_new ("Mount host folder");
1777 gtk_widget_show (frame);
1778 gtk_box_pack_start (GTK_BOX (vbox), frame, false, false, 0);
1779 gtk_container_set_border_width (GTK_CONTAINER (frame), 8);
1780
1781 hbox = gtk_hbox_new (false, 4);
1782 gtk_widget_show (hbox);
1783 gtk_container_add (GTK_CONTAINER (frame), hbox);
1784 gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
1785
1786 label = gtk_label_new ("Path");
1787 gtk_box_pack_start (GTK_BOX (hbox), label, false, false, 0);
1788 gtk_widget_show (label);
1789
1790 thing = gtk_entry_new_with_max_length (255);
1791 gtk_signal_connect (GTK_OBJECT (thing), "changed", (GtkSignalFunc) dirdlg_on_change, (gpointer) NULL);
1792 gtk_box_pack_start (GTK_BOX (hbox), thing, true, true, 0);
1793 gtk_widget_show (thing);
1794 path_entry = thing;
1795
1796 button = gtk_button_new_with_label ("Select...");
1797 gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) did_dirdlg_select, (gpointer) path_entry);
1798 gtk_box_pack_start (GTK_BOX (hbox), button, false, false, 0);
1799 gtk_widget_show (button);
1800
1801 frame = gtk_frame_new ("As Amiga disk");
1802 gtk_widget_show (frame);
1803 gtk_box_pack_start (GTK_BOX (vbox), frame, false, false, 0);
1804 gtk_container_set_border_width (GTK_CONTAINER (frame), 8);
1805
1806 table = gtk_table_new (3, 4, false);
1807 gtk_widget_show (table);
1808 gtk_container_add (GTK_CONTAINER (frame), table);
1809 gtk_container_set_border_width (GTK_CONTAINER (table), 8);
1810 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
1811 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
1812
1813 label = gtk_label_new ("Device name");
1814 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1815 gtk_widget_show (label);
1816 thing = gtk_entry_new_with_max_length (255);
1817 gtk_signal_connect (GTK_OBJECT (thing), "changed", (GtkSignalFunc) dirdlg_on_change, (gpointer) NULL);
1818 gtk_widget_show (thing);
1819 gtk_table_attach (GTK_TABLE (table), thing, 1, 2, 0, 1, (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1820 gtk_widget_set_usize (thing, 200, -1);
1821 devname_entry = thing;
1822
1823 label = gtk_label_new ("Volume name");
1824 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1825 gtk_widget_show (label);
1826 thing = gtk_entry_new_with_max_length (255);
1827 gtk_signal_connect (GTK_OBJECT (thing), "changed", (GtkSignalFunc) dirdlg_on_change, (gpointer) NULL);
1828 gtk_table_attach (GTK_TABLE (table), thing, 1, 2, 1, 2, (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1829 gtk_widget_show (thing);
1830 gtk_widget_set_usize (thing, 200, -1);
1831 volname_entry = thing;
1832
1833 label = gtk_label_new ("Boot priority");
1834 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1835 gtk_widget_show (label);
1836 thing = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -128, 127, 1, 5, 5)), 1, 0);
1837 gtk_table_attach (GTK_TABLE (table), thing, 3, 4, 0, 2, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1838 gtk_widget_show (thing);
1839 bootpri_widget = thing;
1840
1841 readonly_widget = gtk_check_button_new_with_label ("Read only");
1842 gtk_table_attach (GTK_TABLE (table), readonly_widget, 0, 4, 2, 3, (GtkAttachOptions) (GTK_EXPAND), (GtkAttachOptions) (0), 0, 0);
1843 gtk_widget_show (readonly_widget);
1844
1845 dialog_hbox = GTK_DIALOG (dirdlg)->action_area;
1846
1847 hbox = gtk_hbutton_box_new();
1848 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
1849 gtk_box_pack_start (GTK_BOX (dialog_hbox), hbox, true, true, 0);
1850 gtk_widget_show (hbox);
1851
1852 button = gtk_button_new_with_label ("OK");
1853 gtk_widget_set_sensitive (GTK_WIDGET (button), false);
1854 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC(newdir_ok), NULL);
1855 gtk_box_pack_start (GTK_BOX (hbox), button, true, true, 0);
1856 gtk_widget_show (button);
1857 dirdlg_ok = button;
1858
1859 button = gtk_button_new_with_label ("Cancel");
1860 gtk_signal_connect_object (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (dirdlg));
1861 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1862 gtk_box_pack_start (GTK_BOX (hbox), button, true, true, 0);
1863 gtk_widget_grab_default (button);
1864 gtk_widget_show (button);
1865 }
1866
did_newdir(void)1867 static void did_newdir (void)
1868 {
1869 hd_change_mode = 0;
1870 create_dirdlg ("Add a hard disk");
1871 }
did_newhdf(void)1872 static void did_newhdf (void)
1873 {
1874 hd_change_mode = 0;
1875 }
1876
did_hdchange(void)1877 static void did_hdchange (void)
1878 {
1879 int secspertrack=0, surfaces=0, reserved=0, blocksize=0, bootpri=0;
1880 uae_u64 size=0;
1881 int cylinders=0, readonly=0, flags=0;
1882 char *devname=NULL, *volname=NULL, *rootdir=NULL, *filesysdir=NULL;
1883 const char *failure;
1884
1885 /* failure = get_filesys_unit (selected_hd_row,
1886 &devname, &volname, &rootdir, &readonly,
1887 &secspertrack, &surfaces, &reserved,
1888 &cylinders, &size, &blocksize, &bootpri,
1889 &filesysdir, &flags);
1890 */
1891 hd_change_mode = 1;
1892 if (is_hardfile (selected_hd_row)) {
1893 } else {
1894 create_dirdlg ("Hard disk properties");
1895 gtk_entry_set_text (GTK_ENTRY (devname_entry), devname);
1896 gtk_entry_set_text (GTK_ENTRY (volname_entry), volname);
1897 gtk_entry_set_text (GTK_ENTRY (path_entry), rootdir);
1898 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (readonly_widget), readonly);
1899 gtk_spin_button_set_value (GTK_SPIN_BUTTON (bootpri_widget), bootpri);
1900 }
1901 }
did_hddel(void)1902 static void did_hddel (void)
1903 {
1904 kill_filesys_unitconfig (&currprefs, selected_hd_row);
1905 set_hd_state ();
1906 }
1907
hdselect(GtkWidget * widget,gint row,gint column,GdkEventButton * bevent,gpointer user_data)1908 static void hdselect (GtkWidget *widget, gint row, gint column, GdkEventButton *bevent,
1909 gpointer user_data)
1910 {
1911 selected_hd_row = row;
1912 gtk_widget_set_sensitive (hdchange_button, true);
1913 gtk_widget_set_sensitive (hddel_button, true);
1914 }
1915
hdunselect(GtkWidget * widget,gint row,gint column,GdkEventButton * bevent,gpointer user_data)1916 static void hdunselect (GtkWidget *widget, gint row, gint column, GdkEventButton *bevent,
1917 gpointer user_data)
1918 {
1919 gtk_widget_set_sensitive (hdchange_button, false);
1920 gtk_widget_set_sensitive (hddel_button, false);
1921 }
1922 #endif // FILESYS
1923
make_buttons(const char * label,GtkWidget * box,void (* sigfunc)(void),GtkWidget * (* create)(const char * label))1924 static GtkWidget *make_buttons (const char *label, GtkWidget *box, void (*sigfunc) (void), GtkWidget *(*create)(const char *label))
1925 {
1926 GtkWidget *thing = create (label);
1927 gtk_widget_show (thing);
1928 gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) sigfunc, NULL);
1929 gtk_box_pack_start (GTK_BOX (box), thing, true, true, 0);
1930
1931 return thing;
1932 }
1933 #define make_button(label, box, sigfunc) make_buttons(label, box, sigfunc, gtk_button_new_with_label)
1934
1935 #ifdef FILESYS
make_hd_widgets(GtkWidget * dvbox)1936 static void make_hd_widgets (GtkWidget *dvbox)
1937 {
1938 GtkWidget *frame, *vbox, *scrollbox, *thing, *buttonbox, *hbox;
1939 // char *titles [] = {
1940 // "Volume", "File/Directory", "R/O", "Heads", "Cyl.", "Sec.", "Rsrvd", "Size", "Blksize"
1941 // };
1942
1943
1944 frame = gtk_frame_new (NULL);
1945 gtk_widget_show (frame);
1946 gtk_box_pack_start (GTK_BOX (dvbox), frame, true, true, 0);
1947 gtk_container_set_border_width (GTK_CONTAINER (frame), 8);
1948
1949 vbox = gtk_vbox_new (false, 0);
1950 gtk_widget_show (vbox);
1951 gtk_container_add (GTK_CONTAINER (frame), vbox);
1952
1953 scrollbox = gtk_scrolled_window_new (NULL, NULL);
1954 gtk_widget_show (scrollbox);
1955 gtk_box_pack_start (GTK_BOX (vbox), scrollbox, true, true, 0);
1956 gtk_container_set_border_width (GTK_CONTAINER (scrollbox), 8);
1957 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollbox), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1958
1959 thing = gtk_clist_new_with_titles (HDLIST_MAX_COLS, (gchar **)hdlist_col_titles );
1960 gtk_clist_set_selection_mode (GTK_CLIST (thing), GTK_SELECTION_SINGLE);
1961 gtk_signal_connect (GTK_OBJECT (thing), "select_row", (GtkSignalFunc) hdselect, NULL);
1962 gtk_signal_connect (GTK_OBJECT (thing), "unselect_row", (GtkSignalFunc) hdunselect, NULL);
1963 hdlist_widget = thing;
1964 gtk_widget_set_usize (thing, -1, 200);
1965 gtk_widget_show (thing);
1966 gtk_container_add (GTK_CONTAINER (scrollbox), thing);
1967
1968 /* The buttons */
1969 buttonbox = gtk_hbutton_box_new ();
1970 gtk_widget_show (buttonbox);
1971 gtk_box_pack_start (GTK_BOX (vbox), buttonbox, false, false, 0);
1972 gtk_container_set_border_width (GTK_CONTAINER (buttonbox), 8);
1973 gtk_button_box_set_layout (GTK_BUTTON_BOX (buttonbox), GTK_BUTTONBOX_SPREAD);
1974
1975 make_button ("Add...", buttonbox, did_newdir);
1976 #if 0 /* later... */
1977 make_button ("New hardfile...", buttonbox, did_newhdf);
1978 #endif
1979 hdchange_button = make_button ("Properties...", buttonbox, did_hdchange);
1980 hddel_button = make_button ("Remove", buttonbox, did_hddel);
1981
1982 hdpanel = frame;
1983 }
1984 #endif
1985
make_about_widgets(GtkWidget * dvbox)1986 static void make_about_widgets (GtkWidget *dvbox)
1987 {
1988 GtkWidget *thing;
1989 //fixme
1990 #if GTK_MAJOR_VERSION >= 2
1991 const char title[] = "<span font_desc=\"Sans 24\">2.5.0</span>";
1992 #else
1993 const char title[] = "2.5.0";
1994 #endif
1995
1996 add_empty_vbox (dvbox);
1997
1998 #if GTK_MAJOR_VERSION >= 2
1999 thing = gtk_label_new (NULL);
2000 gtk_label_set_markup (GTK_LABEL (thing), title);
2001 #else
2002 thing = gtk_label_new (title);
2003 {
2004 GdkFont *font = gdk_font_load ("-*-helvetica-medium-r-normal--*-240-*-*-*-*-*-*");
2005 if (font) {
2006 GtkStyle *style = gtk_style_copy (GTK_WIDGET (thing)->style);
2007 gdk_font_unref (style->font);
2008 gdk_font_ref (font);
2009 style->font = font;
2010 gtk_widget_set_style (thing, style);
2011 }
2012 }
2013 #endif
2014 gtk_widget_show (thing);
2015 add_centered_to_vbox (dvbox, thing);
2016
2017 #ifdef PACKAGE_VERSION
2018 thing = gtk_label_new ("Version " PACKAGE_VERSION );
2019 gtk_widget_show (thing);
2020 add_centered_to_vbox (dvbox, thing);
2021 #endif
2022
2023 add_empty_vbox (dvbox);
2024 }
2025
did_guidlg_delete(GtkWidget * window,GdkEventAny * e,gpointer data)2026 static gint did_guidlg_delete (GtkWidget* window, GdkEventAny* e, gpointer data)
2027 {
2028 if (!quit_gui)
2029 write_comm_pipe_int (&from_gui_pipe, UAECMD_QUIT, 1);
2030 gui_window = 0;
2031 return false;
2032 }
2033
on_menu_saveconfig(void)2034 static void on_menu_saveconfig (void)
2035 {
2036 DEBUG_LOG ("Save config...\n");
2037 if (!quit_gui)
2038 write_comm_pipe_int (&from_gui_pipe, UAECMD_SAVE_CONFIG, 1);
2039 }
2040
on_vstat_toggle(GtkWidget * widget,gpointer statusbar)2041 void on_vstat_toggle(GtkWidget *widget, gpointer statusbar)
2042 {
2043 if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
2044 gtk_widget_show(statusbar);
2045 } else {
2046 gtk_widget_hide(statusbar);
2047 }
2048 }
2049
create_guidlg(void)2050 static void create_guidlg (void)
2051 {
2052 GtkWidget *window, *notebook;
2053 GtkWidget *buttonbox, *vbox, *hbox;
2054 GtkWidget *thing;
2055 GtkWidget *menubar, *menuitem, *menuitem_menu;
2056 GtkWidget *statusbar, *vstatusbar;
2057
2058 unsigned int i;
2059 static const struct _pages {
2060 const char *title;
2061 void (*createfunc)(GtkWidget *);
2062 } pages[] = {
2063 { "Floppy disks", make_floppy_disks },
2064 { "Memory", make_mem_widgets },
2065 { "CPU", make_cpu_widgets2 },
2066 { "Chipset", make_chipset_widgets },
2067 { "Sound", make_sound_widgets },
2068 #ifdef JIT
2069 { "JIT", make_comp_widgets },
2070 #endif
2071 { "Game ports", make_joy_widgets },
2072 #ifdef FILESYS
2073 { "Hard disks", make_hd_widgets },
2074 #endif
2075 #ifdef SAVESTATE
2076 { "Savestate", make_ss_widgets },
2077 #endif
2078 { "Misc", make_misc_widgets },
2079 { "About", make_about_widgets }
2080 };
2081
2082 DEBUG_LOG ("Entered\n");
2083
2084 gui_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2085 gtk_window_set_title (GTK_WINDOW (gui_window), PACKAGE_NAME " control");
2086 gtk_signal_connect (GTK_OBJECT(gui_window), "delete_event", GTK_SIGNAL_FUNC(did_guidlg_delete), NULL);
2087
2088 vbox = gtk_vbox_new (false, 5);
2089 gtk_container_add (GTK_CONTAINER (gui_window), vbox);
2090 gtk_container_set_border_width (GTK_CONTAINER (gui_window), 10);
2091
2092 /* Quick and dirty menu bar */
2093 menubar = gtk_menu_bar_new();
2094 gtk_widget_show (menubar);
2095 gtk_box_pack_start (GTK_BOX (vbox), menubar, false, false, 0);
2096
2097 menuitem = gtk_menu_item_new_with_mnemonic ("_File");
2098 gtk_widget_show (menuitem);
2099 gtk_container_add (GTK_CONTAINER (menubar), menuitem);
2100
2101 menuitem_menu = gtk_menu_new ();
2102 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menuitem_menu);
2103
2104 thing = gtk_menu_item_new_with_mnemonic ("Save config");
2105 gtk_widget_show (thing);
2106 gtk_container_add (GTK_CONTAINER (menuitem_menu), thing);
2107 gtk_signal_connect (GTK_OBJECT(thing), "activate", GTK_SIGNAL_FUNC(on_menu_saveconfig), NULL);
2108
2109 vstatusbar = gtk_check_menu_item_new_with_label("View Statusbar");
2110 gtk_widget_show (vstatusbar);
2111 gtk_container_add (GTK_CONTAINER (menuitem_menu), vstatusbar);
2112 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(vstatusbar), true);
2113
2114 thing = gtk_separator_menu_item_new ();
2115 gtk_widget_show (thing);
2116 gtk_container_add (GTK_CONTAINER (menuitem_menu), thing);
2117
2118 thing = gtk_menu_item_new_with_mnemonic ("Quit");
2119 gtk_widget_show (thing);
2120 gtk_container_add (GTK_CONTAINER (menuitem_menu), thing);
2121 gtk_signal_connect (GTK_OBJECT(thing), "activate", GTK_SIGNAL_FUNC(on_quit_clicked), NULL);
2122
2123 /* First line - buttons and power LED */
2124 hbox = gtk_hbox_new (false, 10);
2125 gtk_widget_show (hbox);
2126 gtk_box_pack_start (GTK_BOX (vbox), hbox, false, true, 0);
2127
2128 /* The buttons */
2129 buttonbox = gtk_hbox_new (true, 6);
2130 gtk_widget_show (buttonbox);
2131 gtk_box_pack_start (GTK_BOX (hbox), buttonbox, true, true, 0);
2132 start_uae_widget = make_button ("Start", buttonbox, on_start_clicked);
2133 stop_uae_widget = make_button ("Stop", buttonbox, on_stop_clicked);
2134 pause_uae_widget = make_buttons ("Pause", buttonbox, (void (*) (void))on_pause_clicked, gtk_toggle_button_new_with_label);
2135 #ifdef DEBUGGER
2136 //FIXME debug_uae_widget = make_button ("Debug", buttonbox, on_debug_clicked);
2137 #endif
2138 reset_uae_widget = make_button ("Reset", buttonbox, on_reset_clicked);
2139 make_button ("Quit", buttonbox, on_quit_clicked);
2140
2141 /* The LED */
2142 power_led = led_new();
2143 gtk_widget_show(power_led);
2144 thing = gtk_vbox_new(false, 4);
2145 add_empty_hbox(thing);
2146 gtk_container_add(GTK_CONTAINER(thing), power_led);
2147 add_empty_hbox(thing);
2148 thing = make_labelled_widget ("Power:", thing);
2149 gtk_widget_show (thing);
2150 gtk_box_pack_start (GTK_BOX (hbox), thing, false, true, 0);
2151
2152 /* More buttons */
2153 buttonbox = gtk_hbox_new (true, 4);
2154 gtk_widget_show (buttonbox);
2155 gtk_box_pack_start (GTK_BOX (vbox), buttonbox, false, false, 0);
2156
2157 /* Place a separator below those buttons. */
2158 thing = gtk_hseparator_new ();
2159 gtk_box_pack_start (GTK_BOX (vbox), thing, false, true, 0);
2160 gtk_widget_show (thing);
2161
2162 /* Now the notebook */
2163 notebook = gtk_notebook_new ();
2164 gtk_box_pack_start (GTK_BOX (vbox), notebook, true, true, 0);
2165 gtk_widget_show (notebook);
2166
2167 for (i = 0; i < sizeof pages / sizeof (struct _pages); i++) {
2168 thing = gtk_vbox_new (false, 4);
2169 gtk_widget_show (thing);
2170 gtk_container_set_border_width (GTK_CONTAINER (thing), 10);
2171 pages[i].createfunc (thing);
2172 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), thing, gtk_label_new (pages[i].title));
2173 }
2174
2175 /* Put "about" screen first. */
2176 gtk_notebook_set_page (GTK_NOTEBOOK (notebook), i - 1);
2177
2178 /* Statusbar for FPS etc */
2179 statusbar = gtk_statusbar_new();
2180 gtk_box_pack_end(GTK_BOX(vbox), statusbar, false, true, 1);
2181 gtk_widget_show(statusbar);
2182 g_signal_connect(G_OBJECT(vstatusbar), "activate", G_CALLBACK(on_vstat_toggle), statusbar);
2183
2184 gtk_widget_show (vbox);
2185
2186 gtk_timeout_add (1000, (GtkFunction)leds_callback, 0);
2187 }
2188
2189 /*
2190 * gtk_gui_thread()
2191 *
2192 * This is launched as a separate thread to the main UAE thread
2193 * to create and handle the GUI. After the GUI has been set up,
2194 * this calls the standard GTK+ event processing loop.
2195 *
2196 */
gtk_gui_thread(void * dummy)2197 static void *gtk_gui_thread (void *dummy)
2198 {
2199 /* fake args for gtk_init() */
2200 int argc = 1;
2201 char *a[] = {"UAE"};
2202 char **argv = a;
2203
2204 DEBUG_LOG ("Started\n");
2205
2206 gui_active = 0;
2207
2208 if (gtk_init_check (&argc, &argv)) {
2209 DEBUG_LOG ("gtk_init() successful\n");
2210
2211 gtk_rc_parse ("uaegtkrc");
2212 gui_available = 1;
2213
2214 /* Add callback to GTK+ mainloop to handle messages from UAE */
2215 gtk_timeout_add (250, (GtkFunction)my_idle, 0);
2216
2217 /* We're ready - tell the world */
2218 uae_sem_post (&gui_init_sem);
2219
2220 /* Enter GTK+ main loop */
2221 DEBUG_LOG ("Entering GTK+ main loop\n");
2222 gtk_main ();
2223
2224 /* Main loop has exited, so the GUI will quit */
2225 quitted_gui = 1;
2226 uae_sem_post (&gui_quit_sem);
2227 DEBUG_LOG ("Exiting\n");
2228 } else {
2229 DEBUG_LOG ("gtk_init() failed\n");
2230 /* If GTK+ can't display, we still need to say we're done */
2231 uae_sem_post (&gui_init_sem);
2232 }
2233 return 0;
2234 }
2235
gui_fps(int fps,int idle,int color)2236 void gui_fps (int fps, int idle, int color)
2237 {
2238 gui_data.fps = fps;
2239 gui_data.idle = idle;
2240 // gui_led (LED_FPS, 0);
2241 // gui_led (LED_CPU, 0);
2242 // gui_led (LED_SND, gui_data.sndbuf_status > 1 || gui_data.sndbuf_status < 0);
2243
2244 //gchar *str;
2245 //str = g_strdup_printf("FPS: %d",fps);
2246 //gtk_statusbar_push(GTK_STATUSBAR(window),gtk_statusbar_get_context_id(GTK_STATUSBAR(window),str), str);
2247 }
2248
2249 /*
2250 * gui_led()
2251 *
2252 * Called from the main UAE thread to inform the GUI
2253 * of disk activity so that indicator LEDs may be refreshed.
2254 *
2255 * We don't respond to this, since our LEDs are updated
2256 * periodically by my_idle()
2257 */
gui_led(int num,int on)2258 void gui_led (int num, int on)
2259 {
2260 }
2261
2262
2263 /*
2264 * gui_filename()
2265 *
2266 * This is called from the main UAE thread to inform
2267 * the GUI that a floppy disk has been inserted or ejected.
2268 */
gui_filename(int num,const char * name)2269 void gui_filename (int num, const char *name)
2270 {
2271 if (!gui_available)
2272 return;
2273
2274 write_comm_pipe_int (&to_gui_pipe, GUICMD_DISKCHANGE, 0);
2275 write_comm_pipe_int (&to_gui_pipe, num, 1);
2276 }
2277
2278
2279 /*
2280 * gui_handle_events()
2281 *
2282 * This is called from the main UAE thread to handle the
2283 * processing of GUI-related events sent from the GUI thread.
2284 *
2285 * If the UAE emulation proper is not running yet or is paused,
2286 * this loops continuously waiting for and responding to events
2287 * until the emulation is started or resumed, respectively. When
2288 * the emulation is running, this is called periodically from
2289 * the main UAE event loop.
2290 */
gui_handle_events(void)2291 void gui_handle_events (void)
2292 {
2293 if (!gui_available)
2294 return;
2295
2296 while (comm_pipe_has_data (&from_gui_pipe)) {
2297 int cmd = read_comm_pipe_int_blocking (&from_gui_pipe);
2298
2299 switch (cmd) {
2300 case UAECMD_EJECTDISK: {
2301 int n = read_comm_pipe_int_blocking (&from_gui_pipe);
2302 uae_sem_wait (&gui_sem);
2303 changed_prefs.floppyslots[n].df[0] = '\0';
2304 uae_sem_post (&gui_sem);
2305 if (pause_uae) {
2306 /* When UAE is running it will notify the GUI when a disk has been inserted
2307 * or removed itself. When UAE is paused, however, we need to do this ourselves
2308 * or the change won't be realized in the GUI until UAE is resumed */
2309 write_comm_pipe_int (&to_gui_pipe, GUICMD_DISKCHANGE, 0);
2310 write_comm_pipe_int (&to_gui_pipe, n, 1);
2311 }
2312 break;
2313 }
2314 case UAECMD_INSERTDISK: {
2315 int n = read_comm_pipe_int_blocking (&from_gui_pipe);
2316 uae_sem_wait (&gui_sem);
2317 strncpy (changed_prefs.floppyslots[n].df, new_disk_string[n], 255);
2318 xfree (new_disk_string[n]);
2319 new_disk_string[n] = 0;
2320 changed_prefs.floppyslots[n].df[255] = '\0';
2321 uae_sem_post (&gui_sem);
2322 if (pause_uae) {
2323 /* When UAE is running it will notify the GUI when a disk has been inserted
2324 * or removed itself. When UAE is paused, however, we need to do this ourselves
2325 * or the change won't be realized in the GUI until UAE is resumed */
2326 write_comm_pipe_int (&to_gui_pipe, GUICMD_DISKCHANGE, 0);
2327 write_comm_pipe_int (&to_gui_pipe, n, 1);
2328 }
2329 break;
2330 }
2331 case UAECMD_RESET:
2332 uae_reset (0, 0);
2333 break;
2334 #ifdef DEBUGGER
2335 case UAECMD_DEBUG:
2336 activate_debugger ();
2337 break;
2338 #endif
2339 case UAECMD_QUIT:
2340 uae_quit ();
2341 break;
2342 case UAECMD_PAUSE:
2343 pause_uae = 1;
2344 uae_pause ();
2345 break;
2346 case UAECMD_RESUME:
2347 pause_uae = 0;
2348 uae_resume ();
2349 break;
2350 case UAECMD_SAVE_CONFIG:
2351 uae_sem_wait (&gui_sem);
2352 //uae_save_config ();
2353 uae_sem_post (&gui_sem);
2354 break;
2355 case UAECMD_SELECT_ROM:
2356 uae_sem_wait (&gui_sem);
2357 strncpy (changed_prefs.romfile, gui_romname, 255);
2358 changed_prefs.romfile[255] = '\0';
2359 xfree (gui_romname);
2360 uae_sem_post (&gui_sem);
2361 break;
2362 #ifdef SAVESTATE
2363 case UAECMD_SAVESTATE_LOAD:
2364 uae_sem_wait (&gui_sem);
2365 savestate_initsave (gui_sstate_name, 0, 0, 0);
2366 savestate_state = STATE_DORESTORE;
2367 write_log ("Restoring state from '%s'...\n", gui_sstate_name);
2368 uae_sem_post (&gui_sem);
2369 break;
2370 case UAECMD_SAVESTATE_SAVE:
2371 uae_sem_wait (&gui_sem);
2372 savestate_initsave (gui_sstate_name, 0, 0, 0);
2373 save_state (gui_sstate_name, "puae");
2374 write_log ("Saved state to '%s'...\n", gui_sstate_name);
2375 uae_sem_post (&gui_sem);
2376 break;
2377 #endif
2378 /* case UAECMD_START:
2379 uae_start ();
2380 break;
2381 case UAECMD_STOP:
2382 uae_stop ();
2383 break;*/
2384 }
2385 }
2386 }
2387
2388 /*
2389 * gui_update()
2390 *
2391 * This is called from the main UAE thread to tell the GUI to update itself
2392 * using the current state of currprefs. This function will block
2393 * until it receives a message from the GUI telling it that the update
2394 * is complete.
2395 */
gui_update(void)2396 int gui_update (void)
2397 {
2398 DEBUG_LOG( "Entered\n" );
2399 return 0;
2400 if (gui_available) {
2401 write_comm_pipe_int (&to_gui_pipe, GUICMD_UPDATE, 1);
2402 uae_sem_wait (&gui_update_sem);
2403 }
2404 return 0;
2405 }
2406
2407
2408 /*
2409 * gui_exit()
2410 *
2411 * This called from the main UAE thread to tell the GUI to gracefully
2412 * quit. We don't need to do anything here for now. Our main() takes
2413 * care of putting the GUI to bed.
2414 */
gui_exit(void)2415 void gui_exit (void)
2416 {
2417 }
2418
2419 /*
2420 * gui_shutdown()
2421 *
2422 * Tell the GUI thread it's time to say goodnight...
2423 */
gui_shutdown(void)2424 static void gui_shutdown (void)
2425 {
2426 DEBUG_LOG( "Entered\n" );
2427
2428 if (gui_available) {
2429 if (!quit_gui) {
2430 quit_gui = 1;
2431 DEBUG_LOG( "Waiting for GUI thread to quit.\n" );
2432 uae_sem_wait (&gui_quit_sem);
2433 }
2434 }
2435 }
2436
gui_flicker_led2(int led,int unitnum,int status)2437 static void gui_flicker_led2 (int led, int unitnum, int status)
2438 {
2439 static int resetcounter[LED_MAX];
2440 uae_s8 old;
2441 uae_s8 *p;
2442
2443 if (led == LED_HD)
2444 p = &gui_data.hd;
2445 else if (led == LED_CD)
2446 p = &gui_data.cd;
2447 else if (led == LED_MD)
2448 p = &gui_data.md;
2449 else
2450 return;
2451 old = *p;
2452 if (status == 0) {
2453 resetcounter[led]--;
2454 if (resetcounter[led] > 0)
2455 return;
2456 }
2457 #ifdef RETROPLATFORM
2458 if (led == LED_HD)
2459 rp_hd_activity (unitnum, status ? 1 : 0, status == 2 ? 1 : 0);
2460 else if (led == LED_CD)
2461 rp_cd_activity (unitnum, status);
2462 #endif
2463 *p = status;
2464 resetcounter[led] = 6;
2465 if (old != *p)
2466 gui_led (led, *p);
2467 }
2468
gui_flicker_led(int led,int unitnum,int status)2469 void gui_flicker_led (int led, int unitnum, int status)
2470 {
2471 if (led < 0) {
2472 gui_flicker_led2 (LED_HD, 0, 0);
2473 gui_flicker_led2 (LED_CD, 0, 0);
2474 gui_flicker_led2 (LED_MD, 0, 0);
2475 } else {
2476 gui_flicker_led2 (led, unitnum, status);
2477 }
2478 }
2479
gui_display(int shortcut)2480 void gui_display (int shortcut)
2481 {
2482 DEBUG_LOG ("called with shortcut=%d\n", shortcut);
2483
2484 if (gui_available) {
2485 /* If running fullscreen, then we must try to switched to windowed
2486 * mode before activating the GUI */
2487 if (is_fullscreen ()) {
2488 toggle_fullscreen (0);
2489 if (is_fullscreen ()) {
2490 write_log ("Cannot activate GUI in full-screen mode\n");
2491 return;
2492 }
2493 }
2494
2495 if (shortcut == -1)
2496 write_comm_pipe_int (&to_gui_pipe, GUICMD_SHOW, 1);
2497
2498 if (shortcut >=0 && shortcut <4) {
2499 /* In this case, shortcut is the drive number to display
2500 * the insert requester for */
2501 write_comm_pipe_int (&to_gui_pipe, GUICMD_FLOPPYDLG, 0);
2502 write_comm_pipe_int (&to_gui_pipe, shortcut, 1);
2503 }
2504 }
2505
2506 inputdevice_copyconfig (&changed_prefs, &currprefs);
2507 inputdevice_config_change_test ();
2508 clearallkeys ();
2509 inputdevice_acquire (true);
2510 setmouseactive (1);
2511 }
2512
gui_message(const char * format,...)2513 void gui_message (const char *format,...)
2514 {
2515 char msg[2048];
2516 va_list parms;
2517
2518 va_start (parms,format);
2519 vsprintf ( msg, format, parms);
2520 va_end (parms);
2521
2522 if (gui_available)
2523 do_message_box (NULL, msg, true, true);
2524
2525 write_log ("%s", msg);
2526 }
2527
2528 /*
2529 * do_message_box()
2530 *
2531 * This makes up for GTK's lack of a function for creating simple message dialogs.
2532 * It can be called from any context. gui_init() must have been called at some point
2533 * previously.
2534 *
2535 * title - will be displayed in the dialog's titlebar (or NULL for default)
2536 * message - the message itself
2537 * modal - should the dialog block input to the rest of the GUI
2538 * wait - should the dialog wait until the user has acknowledged it
2539 */
do_message_box(const gchar * title,const gchar * message,gboolean modal,gboolean wait)2540 static void do_message_box (const gchar *title, const gchar *message, gboolean modal, gboolean wait )
2541 {
2542 uae_sem_t msg_quit_sem = {0};
2543
2544 // If we a need reply, then this semaphore which will be used
2545 // to signal us when the dialog has been exited.
2546 uae_sem_init (&msg_quit_sem, 0, 0);
2547
2548 write_comm_pipe_int (&to_gui_pipe, GUICMD_MSGBOX, 0);
2549 write_comm_pipe_pvoid (&to_gui_pipe, (void *) title, 0);
2550 write_comm_pipe_pvoid (&to_gui_pipe, (void *) message, 0);
2551 write_comm_pipe_int (&to_gui_pipe, (int) modal, 0);
2552 write_comm_pipe_pvoid (&to_gui_pipe, wait?&msg_quit_sem:NULL, 1);
2553
2554 if (wait)
2555 uae_sem_wait (&msg_quit_sem);
2556
2557 DEBUG_LOG ("do_message_box() done");
2558 return;
2559 }
2560
2561 /*
2562 * handle_message_box_request()
2563 *
2564 * This is called from the GUI's context in repsonse to do_message_box()
2565 * to actually create the dialog box
2566 */
handle_message_box_request(smp_comm_pipe * msg_pipe)2567 static void handle_message_box_request (smp_comm_pipe *msg_pipe)
2568 {
2569 const gchar *title = (const gchar *) read_comm_pipe_pvoid_blocking (msg_pipe);
2570 const gchar *msg = (const gchar *) read_comm_pipe_pvoid_blocking (msg_pipe);
2571 int modal = read_comm_pipe_int_blocking (msg_pipe);
2572 uae_sem_t *msg_quit_sem = (uae_sem_t *) read_comm_pipe_pvoid_blocking (msg_pipe);
2573
2574 GtkWidget *dialog = make_message_box (title, msg, modal, msg_quit_sem);
2575 }
2576
2577 /*
2578 * on_message_box_quit()
2579 *
2580 * Handler called when message box is exited. Signals anybody that cares
2581 * via the semaphore it is supplied.
2582 */
on_message_box_quit(GtkWidget * w,gpointer user_data)2583 void on_message_box_quit (GtkWidget *w, gpointer user_data)
2584 {
2585 uae_sem_post ((uae_sem_t *)user_data);
2586 }
2587
2588 /*
2589 * make_message_box()
2590 *
2591 * This does the actual work of constructing the message dialog.
2592 *
2593 * title - displayed in the dialog's titlebar
2594 * message - the message itself
2595 * modal - whether the dialog should block input to the rest of the GUI
2596 * sem - semaphore used for signalling that the dialog's finished
2597 *
2598 * TODO: Make that semaphore go away. We shouldn't need to know about it here.
2599 */
make_message_box(const gchar * title,const gchar * message,int modal,uae_sem_t * sem)2600 static GtkWidget *make_message_box (const gchar *title, const gchar *message, int modal, uae_sem_t *sem )
2601 {
2602 GtkWidget *dialog;
2603 GtkWidget *vbox;
2604 GtkWidget *label;
2605 GtkWidget *hseparator;
2606 GtkWidget *hbuttonbox;
2607 GtkWidget *button;
2608 guint key;
2609 GtkAccelGroup *accel_group;
2610
2611 accel_group = gtk_accel_group_new ();
2612
2613 dialog = gtk_window_new ( GTK_WINDOW_TOPLEVEL /*GTK_WINDOW_DIALOG*/);
2614 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
2615 if (title==NULL || (title!=NULL && strlen(title)==0))
2616 title = PACKAGE_NAME " information";
2617 gtk_window_set_title (GTK_WINDOW (dialog), title);
2618 gtk_window_set_modal (GTK_WINDOW (dialog), modal);
2619 gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
2620
2621 vbox = gtk_vbox_new (false, 0);
2622 gtk_widget_show (vbox);
2623 gtk_container_add (GTK_CONTAINER (dialog), vbox);
2624
2625 label = gtk_label_new (message);
2626 gtk_widget_show (label);
2627 gtk_box_pack_start (GTK_BOX (vbox), label, true, true, 0);
2628 gtk_label_set_line_wrap (GTK_LABEL (label), true);
2629
2630 hseparator = gtk_hseparator_new ();
2631 gtk_widget_show (hseparator);
2632 gtk_box_pack_start (GTK_BOX (vbox), hseparator, false, false, 8);
2633
2634 hbuttonbox = gtk_hbutton_box_new ();
2635 gtk_widget_show (hbuttonbox);
2636 gtk_box_pack_start (GTK_BOX (vbox), hbuttonbox, false, false, 0);
2637 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END);
2638 gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox), 4);
2639
2640 button = make_labelled_button ("_Okay", accel_group);
2641 gtk_widget_show (button);
2642 gtk_container_add (GTK_CONTAINER (hbuttonbox), button);
2643 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2644
2645 if (sem)
2646 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (on_message_box_quit), sem);
2647 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2648 GTK_SIGNAL_FUNC (gtk_widget_destroy),
2649 GTK_OBJECT (dialog));
2650
2651 gtk_widget_grab_default (button);
2652 gtk_window_add_accel_group (GTK_WINDOW (dialog), accel_group);
2653 gtk_widget_show( dialog );
2654
2655 return dialog;
2656 }
2657
gui_init(void)2658 int gui_init (void)
2659 {
2660 uae_thread_id tid;
2661
2662 /* Check whether we are running with SUID bit set */
2663 if (getuid() == geteuid()) {
2664 /*
2665 * Only try to start Gtk+ GUI if SUID bit is not set
2666 */
2667
2668 init_comm_pipe (&to_gui_pipe, 20, 1);
2669 init_comm_pipe (&from_gui_pipe, 20, 1);
2670 uae_sem_init (&gui_sem, 0, 1); // Unlock mutex on prefs $
2671 uae_sem_init (&gui_update_sem, 0, 0);
2672 uae_sem_init (&gui_init_sem, 0, 0);
2673 uae_sem_init (&gui_quit_sem, 0, 0);
2674
2675 /* Start GUI thread to construct GUI */
2676 uae_start_thread ("GTK-GUI", gtk_gui_thread, NULL, &tid);
2677
2678 /* Wait until GUI thread is ready */
2679 DEBUG_LOG ("Waiting for GUI thread\n");
2680 uae_sem_wait (&gui_init_sem);
2681 DEBUG_LOG ("Okay\n");
2682 }
2683 return 1;
2684 }
2685
gui_disk_image_change(int unitnum,const TCHAR * name,bool writeprotected)2686 void gui_disk_image_change (int unitnum, const TCHAR *name, bool writeprotected) {}
gui_lock(void)2687 void gui_lock (void) {}
gui_unlock(void)2688 void gui_unlock (void) {}
2689 static int guijoybutton[MAX_JPORTS];
2690 static int guijoyaxis[MAX_JPORTS][4];
2691 static bool guijoychange;
gui_gameport_button_change(int port,int button,int onoff)2692 void gui_gameport_button_change (int port, int button, int onoff)
2693 {
2694 //write_log ("%d %d %d\n", port, button, onoff);
2695 #ifdef RETROPLATFORM
2696 int mask = 0;
2697 if (button == JOYBUTTON_CD32_PLAY)
2698 mask = RP_JOYSTICK_BUTTON5;
2699 if (button == JOYBUTTON_CD32_RWD)
2700 mask = RP_JOYSTICK_BUTTON6;
2701 if (button == JOYBUTTON_CD32_FFW)
2702 mask = RP_JOYSTICK_BUTTON7;
2703 if (button == JOYBUTTON_CD32_GREEN)
2704 mask = RP_JOYSTICK_BUTTON4;
2705 if (button == JOYBUTTON_3 || button == JOYBUTTON_CD32_YELLOW)
2706 mask = RP_JOYSTICK_BUTTON3;
2707 if (button == JOYBUTTON_1 || button == JOYBUTTON_CD32_RED)
2708 mask = RP_JOYSTICK_BUTTON1;
2709 if (button == JOYBUTTON_2 || button == JOYBUTTON_CD32_BLUE)
2710 mask = RP_JOYSTICK_BUTTON2;
2711 rp_update_gameport (port, mask, onoff);
2712 #endif
2713 if (onoff)
2714 guijoybutton[port] |= 1 << button;
2715 else
2716 guijoybutton[port] &= ~(1 << button);
2717 guijoychange = true;
2718 }
2719
gui_gameport_axis_change(int port,int axis,int state,int max)2720 void gui_gameport_axis_change (int port, int axis, int state, int max)
2721 {
2722 int onoff = state ? 100 : 0;
2723 if (axis < 0 || axis > 3)
2724 return;
2725 if (max < 0) {
2726 if (guijoyaxis[port][axis] == 0)
2727 return;
2728 if (guijoyaxis[port][axis] > 0)
2729 guijoyaxis[port][axis]--;
2730 } else {
2731 if (state > max)
2732 state = max;
2733 if (state < 0)
2734 state = 0;
2735 guijoyaxis[port][axis] = max ? state * 127 / max : onoff;
2736 #ifdef RETROPLATFORM
2737 if (axis == DIR_LEFT_BIT)
2738 rp_update_gameport (port, RP_JOYSTICK_LEFT, onoff);
2739 if (axis == DIR_RIGHT_BIT)
2740 rp_update_gameport (port, DIR_RIGHT_BIT, onoff);
2741 if (axis == DIR_UP_BIT)
2742 rp_update_gameport (port, DIR_UP_BIT, onoff);
2743 if (axis == DIR_DOWN_BIT)
2744 rp_update_gameport (port, DIR_DOWN_BIT, onoff);
2745 #endif
2746 }
2747 guijoychange = true;
2748 }
2749