|
|
1.1 root 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
1.1.1.2 root 7: * Copyright 1998 Michael Krause
1.1 root 8: *
9: * The Tk GUI doesn't work.
10: * The X Forms Library isn't available as source, and there aren't any
11: * binaries compiled against glibc
12: *
13: * So let's try this...
14: */
15:
16: #include "sysconfig.h"
17: #include "sysdeps.h"
18:
19: #include "config.h"
20: #include "options.h"
21: #include "uae.h"
22: #include "memory.h"
23: #include "custom.h"
24: #include "gui.h"
25: #include "newcpu.h"
26: #include "threaddep/penguin.h"
1.1.1.2 root 27: #include "sounddep/sound.h"
1.1 root 28:
29: #include <gtk/gtk.h>
30:
1.1.1.4 root 31: /* One of the 1.1.6 "features" is a gratuitous name change */
32: #ifndef HAVE_GTK_FEATURES_1_1_6
33: #define gtk_container_set_border_width gtk_container_border_width
34: #endif
35: /* Likewise for 1.1.8. */
36: #ifndef HAVE_GTK_FEATURES_1_1_8
37: #define gtk_label_set_text gtk_label_set
38: #endif
1.1.1.5 root 39: /* This is beginning to suck... */
40: #ifndef HAVE_GTK_FEATURES_1_1_13
41: #define gtk_toggle_button_set_active gtk_toggle_button_set_state
42: #endif
1.1.1.4 root 43:
1.1 root 44: static int gui_active;
45:
1.1.1.6 root 46: static GtkWidget *pause_uae_widget;
47:
1.1 root 48: static GtkWidget *disk_insert_widget[4], *disk_eject_widget[4], *disk_text_widget[4];
49: static char *new_disk_string[4];
50:
51: static GtkAdjustment *cpuspeed_adj;
1.1.1.3 root 52: static GtkWidget *cpuspeed_widgets[4], *cpuspeed_scale;
1.1.1.8 ! root 53: static GtkWidget *cpu_widget[5], *a24m_widget, *ccpu_widget;
1.1.1.2 root 54: static GtkWidget *sound_widget[4], *sound_bits_widget[2], *sound_freq_widget[3], *sound_ch_widget[2];
1.1 root 55:
56: static GtkAdjustment *framerate_adj;
1.1.1.7 root 57: static GtkWidget *bimm_widget, *b32_widget, *afscr_widget, *pfscr_widget;
1.1 root 58:
59: static GtkWidget *joy_widget[2][6];
60:
61: static GtkWidget *led_widgets[5];
62: static GdkColor led_on[5], led_off[5];
63: static unsigned int prevledstate;
64:
1.1.1.2 root 65: static smp_comm_pipe to_gui_pipe, from_gui_pipe;
66: static uae_sem_t gui_sem, gui_quit_sem; /* gui_sem protects the DFx fields */
67:
68: static volatile int quit_gui = 0, quitted_gui = 0;
69:
1.1 root 70: static void save_config (void)
71: {
72: FILE *f;
73: char tmp[257];
74:
75: /* Backup the options file. */
76: strcpy (tmp, optionsfile);
77: strcat (tmp, "~");
78: rename (optionsfile, tmp);
79:
80: f = fopen (optionsfile, "w");
81: if (f == NULL) {
1.1.1.2 root 82: fprintf (stderr, "Error saving options file!\n");
1.1 root 83: return;
84: }
1.1.1.4 root 85: save_options (f, &currprefs);
1.1 root 86: fclose (f);
87: }
88:
89: static int nr_for_led (GtkWidget *led)
90: {
91: int i;
92: i = 0;
93: while (led_widgets[i] != led)
94: i++;
95: return i;
96: }
97:
98: static void enable_disk_buttons (int enable)
99: {
100: int i;
101: for (i = 0; i < 4; i++) {
102: gtk_widget_set_sensitive (disk_insert_widget[i], enable);
103: gtk_widget_set_sensitive (disk_eject_widget[i], enable);
104: }
105: }
106:
107: static void set_cpu_state (void)
108: {
1.1.1.5 root 109: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (a24m_widget), changed_prefs.address_space_24 != 0);
1.1.1.8 ! root 110: gtk_widget_set_sensitive (a24m_widget, changed_prefs.cpu_level > 1 && changed_prefs.cpu_level < 4);
1.1.1.5 root 111: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ccpu_widget), changed_prefs.cpu_compatible != 0);
1.1 root 112: gtk_widget_set_sensitive (ccpu_widget, changed_prefs.cpu_level == 0);
1.1.1.3 root 113: gtk_widget_set_sensitive (cpuspeed_scale, changed_prefs.m68k_speed > 0);
1.1 root 114: }
115:
116: static void set_cpu_widget (void)
117: {
118: int nr = changed_prefs.cpu_level;
1.1.1.5 root 119: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cpu_widget[nr]), TRUE);
1.1.1.3 root 120: nr = currprefs.m68k_speed + 1 < 3 ? currprefs.m68k_speed + 1 : 2;
1.1.1.5 root 121: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cpuspeed_widgets[nr]), TRUE);
1.1 root 122: }
123:
124: static void set_gfx_state (void)
125: {
1.1.1.5 root 126: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bimm_widget), currprefs.immediate_blits != 0);
127: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b32_widget), currprefs.blits_32bit_enabled != 0);
1.1.1.7 root 128: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (afscr_widget), currprefs.gfx_afullscreen != 0);
129: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pfscr_widget), currprefs.gfx_pfullscreen != 0);
1.1 root 130: }
131:
1.1.1.2 root 132: static void set_sound_state (void)
133: {
1.1.1.5 root 134: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_widget[currprefs.produce_sound]), 1);
135: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_ch_widget[currprefs.stereo]), 1);
136: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_bits_widget[currprefs.sound_bits == 16]), 1);
1.1.1.2 root 137: }
138:
1.1 root 139: static void set_joy_state (void)
140: {
1.1.1.4 root 141: int j0t = changed_prefs.jport0;
142: int j1t = changed_prefs.jport1;
1.1 root 143: int i;
144:
145: if (j0t == j1t) {
146: /* Can't happen */
147: j0t++;
148: j0t %= 6;
149: }
150: for (i = 0; i < 6; i++) {
1.1.1.5 root 151: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (joy_widget[0][i]), j0t == i);
152: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (joy_widget[1][i]), j1t == i);
1.1 root 153: gtk_widget_set_sensitive (joy_widget[0][i], j1t != i);
154: gtk_widget_set_sensitive (joy_widget[1][i], j0t != i);
155: }
156: }
157:
158: static void draw_led (int nr)
159: {
160: GtkWidget *thing = led_widgets[nr];
161: GdkWindow *window = thing->window;
162: GdkGC *gc = gdk_gc_new (window);
163: GdkColor *col;
164:
165: if (gui_ledstate & (1 << nr))
166: col = led_on + nr;
167: else
168: col = led_off + nr;
169: gdk_gc_set_foreground (gc, col);
170: gdk_draw_rectangle (window, gc, 1, 0, 0, -1, -1);
171: gdk_gc_destroy (gc);
172: }
173:
174: static int my_idle (void)
175: {
176: unsigned int leds = gui_ledstate;
177: int i;
178:
179: if (quit_gui) {
180: /*printf("Foo...\n");*/
181: gtk_main_quit ();
182: goto out;
183: }
184: while (comm_pipe_has_data (&to_gui_pipe)) {
185: int cmd = read_comm_pipe_int_blocking (&to_gui_pipe);
186: int n;
187: /*printf ("cmd %d\n", cmd);*/
188: switch (cmd) {
189: case 0:
190: n = read_comm_pipe_int_blocking (&to_gui_pipe);
1.1.1.4 root 191: gtk_label_set_text (GTK_LABEL (disk_text_widget[n]), currprefs.df[n]);
1.1 root 192: break;
193: case 1:
194: /* Initialization. */
195: set_cpu_widget ();
196: set_cpu_state ();
197: set_gfx_state ();
198: set_joy_state ();
1.1.1.2 root 199: set_sound_state ();
1.1.1.3 root 200:
1.1 root 201: gui_active = 1;
202: break;
203: }
204: }
205:
206: for (i = 0; i < 5; i++) {
207: unsigned int mask = 1 << i;
1.1.1.2 root 208: unsigned int on = leds & mask;
1.1 root 209:
210: if (on == (prevledstate & mask))
211: continue;
212:
213: /* printf(": %d %d\n", i, on);*/
214: draw_led (i);
215: }
216: prevledstate = leds;
217: out:
218: return 1;
219: }
220:
1.1.1.2 root 221: static int find_current_toggle (GtkWidget **widgets, int count)
222: {
223: int i;
224: for (i = 0; i < count; i++)
225: if (GTK_TOGGLE_BUTTON (*widgets++)->active)
226: return i;
227: fprintf (stderr, "GTKUI: Can't happen!\n");
228: return -1;
229: }
230:
1.1 root 231: static void joy_changed (void)
232: {
233: if (! gui_active)
234: return;
235:
1.1.1.4 root 236: changed_prefs.jport0 = find_current_toggle (joy_widget[0], 6);
237: changed_prefs.jport1 = find_current_toggle (joy_widget[1], 6);
1.1 root 238: set_joy_state ();
239: }
240:
1.1.1.2 root 241: static void custom_changed (void)
1.1 root 242: {
1.1.1.6 root 243: changed_prefs.gfx_framerate = framerate_adj->value;
1.1 root 244: changed_prefs.blits_32bit_enabled = GTK_TOGGLE_BUTTON (b32_widget)->active;
245: changed_prefs.immediate_blits = GTK_TOGGLE_BUTTON (bimm_widget)->active;
1.1.1.7 root 246: changed_prefs.gfx_afullscreen = GTK_TOGGLE_BUTTON (afscr_widget)->active;
247: changed_prefs.gfx_pfullscreen = GTK_TOGGLE_BUTTON (pfscr_widget)->active;
1.1 root 248: }
249:
250: static void cpuspeed_changed (void)
251: {
1.1.1.3 root 252: int which = find_current_toggle (cpuspeed_widgets, 3);
253: changed_prefs.m68k_speed = (which == 0 ? -1
254: : which == 1 ? 0
255: : cpuspeed_adj->value);
256: set_cpu_state ();
1.1 root 257: }
258:
259: static void cputype_changed (void)
260: {
261: int i, oldcl;
262: if (! gui_active)
263: return;
264:
265: oldcl = changed_prefs.cpu_level;
266:
1.1.1.8 ! root 267: changed_prefs.cpu_level = find_current_toggle (cpu_widget, 5);
1.1 root 268: changed_prefs.cpu_compatible = GTK_TOGGLE_BUTTON (ccpu_widget)->active;
269: changed_prefs.address_space_24 = GTK_TOGGLE_BUTTON (a24m_widget)->active;
270:
271: if (changed_prefs.cpu_level != 0)
272: changed_prefs.cpu_compatible = 0;
273: /* 68000/68010 always have a 24 bit address space. */
274: if (changed_prefs.cpu_level < 2)
275: changed_prefs.address_space_24 = 1;
276: /* Changing from 68000/68010 to 68020 should set a sane default. */
277: else if (oldcl < 2)
278: changed_prefs.address_space_24 = 0;
1.1.1.8 ! root 279:
1.1 root 280: set_cpu_state ();
281: }
282:
1.1.1.2 root 283: static void sound_changed (void)
284: {
285: changed_prefs.produce_sound = find_current_toggle (sound_widget, 4);
286: changed_prefs.stereo = find_current_toggle (sound_ch_widget, 2);
287: changed_prefs.sound_bits = (find_current_toggle (sound_bits_widget, 2) + 1) * 8;
288: }
289:
1.1 root 290: static void did_reset (void)
291: {
292: if (quit_gui)
293: return;
294:
295: write_comm_pipe_int (&from_gui_pipe, 2, 1);
296: }
297:
298: static void did_debug (void)
299: {
300: if (quit_gui)
301: return;
302:
303: write_comm_pipe_int (&from_gui_pipe, 3, 1);
304: }
305:
306: static void did_quit (void)
307: {
308: if (quit_gui)
309: return;
310:
311: write_comm_pipe_int (&from_gui_pipe, 4, 1);
312: }
313:
1.1.1.2 root 314: static void did_eject (GtkWidget *w, gpointer data)
315: {
1.1 root 316: if (quit_gui)
317: return;
318:
319: write_comm_pipe_int (&from_gui_pipe, 0, 0);
1.1.1.2 root 320: write_comm_pipe_int (&from_gui_pipe, (int)data, 1);
1.1 root 321: }
322:
1.1.1.6 root 323: static void pause_uae (GtkWidget *widget, gpointer data)
324: {
325: if (quit_gui)
326: return;
327:
328: write_comm_pipe_int (&from_gui_pipe, GTK_TOGGLE_BUTTON (widget)->active ? 5 : 6, 1);
329: }
330:
331: static void end_pause_uae (void)
332: {
333: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pause_uae_widget), FALSE);
334: }
335:
1.1 root 336: static int filesel_active = -1;
337: static GtkWidget *selector;
338:
339: static void did_close_insert (GtkObject *o, GtkWidget *w)
340: {
341: filesel_active = -1;
342: enable_disk_buttons (1);
343: gtk_widget_hide (selector);
344: }
345:
346: static void did_cancel_insert (GtkObject *o)
347: {
348: filesel_active = -1;
349: enable_disk_buttons (1);
350: gtk_widget_hide (selector);
351: }
352:
353: static void did_insert_select (GtkObject *o)
354: {
355: char *s = gtk_file_selection_get_filename (GTK_FILE_SELECTION (selector));
356: printf ("%s\n", s);
357: if (quit_gui)
358: return;
359:
360: uae_sem_wait (&gui_sem);
361: if (new_disk_string[filesel_active] != 0)
362: free (new_disk_string[filesel_active]);
363: new_disk_string[filesel_active] = strdup (s);
364: uae_sem_post (&gui_sem);
365: write_comm_pipe_int (&from_gui_pipe, 1, 0);
366: write_comm_pipe_int (&from_gui_pipe, filesel_active, 1);
367: filesel_active = -1;
368: enable_disk_buttons (1);
369: gtk_widget_hide (selector);
370: }
371:
372: static char fsbuffer[100];
373:
1.1.1.2 root 374: static void did_insert (GtkWidget *w, gpointer data)
1.1 root 375: {
1.1.1.2 root 376: int n = (int)data;
1.1 root 377: if (filesel_active != -1)
378: return;
379: filesel_active = n;
380: enable_disk_buttons (0);
381:
382: sprintf (fsbuffer, "Select a disk image file for DF%d", n);
383: gtk_window_set_title (GTK_WINDOW (selector), fsbuffer);
384:
385: /*printf("%p\n", selector);*/
386: gtk_widget_show (selector);
387: }
388:
389: static gint driveled_event (GtkWidget *thing, GdkEvent *event)
390: {
391: int lednr = nr_for_led (thing);
392:
393: switch (event->type) {
394: case GDK_MAP:
395: draw_led (lednr);
396: break;
397: case GDK_EXPOSE:
398: draw_led (lednr);
399: break;
400: default:
401: break;
402: }
403:
404: return 0;
405: }
406:
1.1.1.2 root 407: static void add_empty_vbox (GtkWidget *tobox)
408: {
409: GtkWidget *thing = gtk_vbox_new (FALSE, 0);
410: gtk_widget_show (thing);
411: gtk_box_pack_start (GTK_BOX (tobox), thing, TRUE, TRUE, 0);
412: }
413:
1.1.1.3 root 414: static void add_empty_hbox (GtkWidget *tobox)
415: {
416: GtkWidget *thing = gtk_hbox_new (FALSE, 0);
417: gtk_widget_show (thing);
418: gtk_box_pack_start (GTK_BOX (tobox), thing, TRUE, TRUE, 0);
419: }
420:
1.1.1.2 root 421: static void add_centered_to_vbox (GtkWidget *vbox, GtkWidget *w)
422: {
423: GtkWidget *hbox = gtk_hbox_new (TRUE, 0);
424: gtk_widget_show (hbox);
425: gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, FALSE, 0);
426: gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
427: }
428:
429: static GtkWidget *make_labelled_widget (const char *str, GtkWidget *thing)
430: {
431: GtkWidget *label = gtk_label_new (str);
432: GtkWidget *hbox2 = gtk_hbox_new (FALSE, 4);
433:
434: gtk_widget_show (label);
435: gtk_widget_show (thing);
436:
437: gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
438: gtk_box_pack_start (GTK_BOX (hbox2), thing, FALSE, TRUE, 0);
439:
440: return hbox2;
441: }
442:
1.1.1.3 root 443: static GtkWidget *add_labelled_widget_centered (const char *str, GtkWidget *thing, GtkWidget *vbox)
1.1.1.2 root 444: {
445: GtkWidget *w = make_labelled_widget (str, thing);
446: gtk_widget_show (w);
447: add_centered_to_vbox (vbox, w);
1.1.1.3 root 448: return w;
1.1.1.2 root 449: }
450:
451: static void make_radio_group (const char **labels, GtkWidget *tobox,
452: GtkWidget **saveptr, gint t1, gint t2,
453: void (*sigfunc) (void))
454: {
455: GtkWidget *thing = NULL;
456:
457: while (*labels) {
458: thing = gtk_radio_button_new_with_label ((thing
459: ? gtk_radio_button_group (GTK_RADIO_BUTTON (thing))
460: : 0),
461: *labels++);
462: *saveptr++ = thing;
463: gtk_widget_show (thing);
464: gtk_box_pack_start (GTK_BOX (tobox), thing, t1, t2, 0);
465: gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) sigfunc, NULL);
466: }
467: }
468:
469: static GtkWidget *make_radio_group_box (const char *title, const char **labels,
470: GtkWidget **saveptr, int horiz,
471: void (*sigfunc) (void))
472: {
473: GtkWidget *frame, *newbox;
474:
475: frame = gtk_frame_new (title);
476: newbox = (horiz ? gtk_hbox_new : gtk_vbox_new) (FALSE, 4);
477: gtk_widget_show (newbox);
1.1.1.4 root 478: gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
1.1.1.2 root 479: gtk_container_add (GTK_CONTAINER (frame), newbox);
480: make_radio_group (labels, newbox, saveptr, horiz, !horiz, sigfunc);
481: return frame;
482: }
483:
1.1 root 484: static GtkWidget *make_led (int nr)
485: {
486: GtkWidget *subframe, *the_led, *thing;
487: GdkColormap *colormap;
488:
489: the_led = gtk_vbox_new (FALSE, 0);
490: gtk_widget_show (the_led);
491:
492: thing = gtk_preview_new (GTK_PREVIEW_COLOR);
493: gtk_box_pack_start (GTK_BOX (the_led), thing, TRUE, TRUE, 0);
494: gtk_widget_show (thing);
495:
496: subframe = gtk_frame_new (NULL);
497: gtk_box_pack_start (GTK_BOX (the_led), subframe, TRUE, TRUE, 0);
498: gtk_widget_show (subframe);
499:
500: thing = gtk_drawing_area_new ();
501: gtk_drawing_area_size (GTK_DRAWING_AREA (thing), 20, 5);
502: gtk_widget_set_events (thing, GDK_EXPOSURE_MASK);
503: gtk_container_add (GTK_CONTAINER (subframe), thing);
504: colormap = gtk_widget_get_colormap (thing);
505: led_on[nr].red = nr == 0 ? 0xEEEE : 0xCCCC;
506: led_on[nr].green = nr == 0 ? 0: 0xFFFF;
507: led_on[nr].blue = 0;
508: led_on[nr].pixel = 0;
509: led_off[nr].red = 0;
510: led_off[nr].green = 0;
511: led_off[nr].blue = 0;
512: led_off[nr].pixel = 0;
513: gdk_color_alloc (colormap, led_on + nr);
514: gdk_color_alloc (colormap, led_off + nr);
515: led_widgets[nr] = thing;
516: gtk_signal_connect (GTK_OBJECT (thing), "event",
517: (GtkSignalFunc) driveled_event, (gpointer) thing);
518: gtk_widget_show (thing);
519:
520: thing = gtk_preview_new (GTK_PREVIEW_COLOR);
521: gtk_box_pack_start (GTK_BOX (the_led), thing, TRUE, TRUE, 0);
522: gtk_widget_show (thing);
523:
524: return the_led;
525: }
526:
527: static void make_floppy_disks (GtkWidget *vbox)
528: {
1.1.1.2 root 529: GtkWidget *thing, *subthing, *subframe, *buttonbox;
530: char buf[5];
1.1 root 531: int i;
1.1.1.2 root 532:
533: add_empty_vbox (vbox);
534:
1.1 root 535: for (i = 0; i < 4; i++) {
1.1.1.2 root 536: /* Frame with an hbox and the "DFx:" title */
1.1 root 537: sprintf (buf, "DF%d:", i);
1.1.1.2 root 538: thing = gtk_frame_new (buf);
539: buttonbox = gtk_hbox_new (FALSE, 4);
1.1.1.4 root 540: gtk_container_set_border_width (GTK_CONTAINER (buttonbox), 4);
1.1.1.2 root 541: gtk_container_add (GTK_CONTAINER (thing), buttonbox);
542: gtk_box_pack_start (GTK_BOX (vbox), thing, FALSE, TRUE, 0);
1.1 root 543: gtk_widget_show (buttonbox);
544: gtk_widget_show (thing);
545:
1.1.1.2 root 546: /* LED */
1.1 root 547: subthing = make_led (i + 1);
548: gtk_box_pack_start (GTK_BOX (buttonbox), subthing, FALSE, TRUE, 0);
549:
1.1.1.2 root 550: /* Current file display */
1.1 root 551: subframe = gtk_frame_new (NULL);
552: gtk_frame_set_shadow_type (GTK_FRAME (subframe), GTK_SHADOW_ETCHED_OUT);
1.1.1.2 root 553: gtk_box_pack_start (GTK_BOX (buttonbox), subframe, TRUE, TRUE, 0);
1.1 root 554: gtk_widget_show (subframe);
555: subthing = gtk_vbox_new (FALSE, 0);
556: gtk_widget_show (subthing);
557: gtk_container_add (GTK_CONTAINER (subframe), subthing);
558: thing = gtk_label_new ("");
559: disk_text_widget[i] = thing;
560: gtk_widget_show (thing);
1.1.1.2 root 561: gtk_box_pack_start (GTK_BOX (subthing), thing, TRUE, TRUE, 0);
1.1 root 562:
563: /* Now, the buttons. */
564: thing = gtk_button_new_with_label ("Eject");
565: gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
566: gtk_widget_show (thing);
567: disk_eject_widget[i] = thing;
1.1.1.2 root 568: gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_eject, (gpointer) i);
1.1 root 569:
570: thing = gtk_button_new_with_label ("Insert");
571: gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
572: gtk_widget_show (thing);
573: disk_insert_widget[i] = thing;
1.1.1.2 root 574: gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_insert, (gpointer) i);
1.1 root 575: }
1.1.1.2 root 576:
577: add_empty_vbox (vbox);
1.1 root 578: }
579:
1.1.1.3 root 580: static GtkWidget *make_cpu_speed_sel (void)
581: {
582: static const char *labels[] = {
583: "Optimize for host CPU speed","Approximate 68000/7MHz speed", "Adjustable",
584: NULL
585: };
586: GtkWidget *frame, *newbox;
587:
588: frame = gtk_frame_new ("CPU speed");
589: newbox = gtk_vbox_new (FALSE, 4);
590: gtk_widget_show (newbox);
1.1.1.4 root 591: gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
1.1.1.3 root 592: gtk_container_add (GTK_CONTAINER (frame), newbox);
593: make_radio_group (labels, newbox, cpuspeed_widgets, 0, 1, cpuspeed_changed);
594:
595: cpuspeed_adj = GTK_ADJUSTMENT (gtk_adjustment_new (currprefs.m68k_speed, 1.0, 10.0, 1.0, 1.0, 1.0));
596: gtk_signal_connect (GTK_OBJECT (cpuspeed_adj), "value_changed",
597: GTK_SIGNAL_FUNC (cpuspeed_changed), NULL);
598:
599: cpuspeed_scale = gtk_hscale_new (cpuspeed_adj);
600: gtk_range_set_update_policy (GTK_RANGE (cpuspeed_scale), GTK_UPDATE_DELAYED);
601: gtk_scale_set_digits (GTK_SCALE (cpuspeed_scale), 0);
602: gtk_scale_set_value_pos (GTK_SCALE (cpuspeed_scale), GTK_POS_RIGHT);
603: cpuspeed_scale = add_labelled_widget_centered ("Cycles per instruction:", cpuspeed_scale, newbox);
604:
605: return frame;
606: }
607:
1.1.1.2 root 608: static void make_cpu_widgets (GtkWidget *vbox)
1.1 root 609: {
610: int i;
1.1.1.3 root 611: GtkWidget *newbox, *hbox, *frame;
1.1 root 612: GtkWidget *thing;
1.1.1.2 root 613: static const char *radiolabels[] = {
1.1.1.8 ! root 614: "68000", "68010", "68020", "68020+68881", "68040",
1.1.1.2 root 615: NULL
616: };
617:
618: add_empty_vbox (vbox);
619:
1.1.1.3 root 620: hbox = gtk_hbox_new (FALSE, 0);
621: add_empty_vbox (hbox);
622:
623: newbox = make_radio_group_box ("CPU type", radiolabels, cpu_widget, 0, cputype_changed);
1.1.1.2 root 624: gtk_widget_show (newbox);
1.1.1.3 root 625: gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, FALSE, 0);
626:
627: newbox = make_cpu_speed_sel ();
628: gtk_widget_show (newbox);
629: gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, FALSE, 0);
630:
631: add_empty_vbox (hbox);
632: gtk_widget_show (hbox);
633: gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1.1 root 634:
635: frame = gtk_frame_new ("CPU flags");
1.1.1.2 root 636: add_centered_to_vbox (vbox, frame);
1.1 root 637: gtk_widget_show (frame);
1.1.1.2 root 638: newbox = gtk_vbox_new (FALSE, 4);
639: gtk_widget_show (newbox);
1.1.1.4 root 640: gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
1.1.1.2 root 641: gtk_container_add (GTK_CONTAINER (frame), newbox);
1.1 root 642:
643: a24m_widget = gtk_check_button_new_with_label ("24 bit address space");
1.1.1.2 root 644: add_centered_to_vbox (newbox, a24m_widget);
1.1 root 645: gtk_widget_show (a24m_widget);
646: ccpu_widget = gtk_check_button_new_with_label ("Slow but compatible");
1.1.1.2 root 647: add_centered_to_vbox (newbox, ccpu_widget);
1.1 root 648: gtk_widget_show (ccpu_widget);
1.1.1.8 ! root 649:
1.1.1.2 root 650: add_empty_vbox (vbox);
651:
1.1 root 652: gtk_signal_connect (GTK_OBJECT (ccpu_widget), "clicked",
653: (GtkSignalFunc) cputype_changed, NULL);
654: gtk_signal_connect (GTK_OBJECT (a24m_widget), "clicked",
655: (GtkSignalFunc) cputype_changed, NULL);
656: }
657:
1.1.1.2 root 658: static void make_gfx_widgets (GtkWidget *vbox)
1.1 root 659: {
660: GtkWidget *thing;
661:
1.1.1.2 root 662: add_empty_vbox (vbox);
1.1 root 663:
1.1.1.6 root 664: framerate_adj = GTK_ADJUSTMENT (gtk_adjustment_new (currprefs.gfx_framerate, 1.0, 21.0, 1.0, 1.0, 1.0));
1.1 root 665: gtk_signal_connect (GTK_OBJECT (framerate_adj), "value_changed",
1.1.1.2 root 666: GTK_SIGNAL_FUNC (custom_changed), NULL);
1.1 root 667:
668: thing = gtk_hscale_new (framerate_adj);
669: gtk_range_set_update_policy (GTK_RANGE (thing), GTK_UPDATE_DELAYED);
670: gtk_scale_set_digits (GTK_SCALE (thing), 0);
671: gtk_scale_set_value_pos (GTK_SCALE (thing), GTK_POS_RIGHT);
1.1.1.2 root 672: add_labelled_widget_centered ("Framerate:", thing, vbox);
1.1 root 673:
674: b32_widget = gtk_check_button_new_with_label ("32 bit blitter");
1.1.1.2 root 675: add_centered_to_vbox (vbox, b32_widget);
1.1.1.7 root 676: #if 0
1.1 root 677: gtk_widget_show (b32_widget);
1.1.1.7 root 678: #endif
1.1 root 679: bimm_widget = gtk_check_button_new_with_label ("Immediate blits");
1.1.1.2 root 680: add_centered_to_vbox (vbox, bimm_widget);
1.1 root 681: gtk_widget_show (bimm_widget);
682:
1.1.1.7 root 683: afscr_widget = gtk_check_button_new_with_label ("Amiga modes fullscreen");
684: add_centered_to_vbox (vbox, afscr_widget);
685: #if 0
686: gtk_widget_show (afscr_widget);
687: #endif
688: pfscr_widget = gtk_check_button_new_with_label ("Picasso modes fullscreen");
689: add_centered_to_vbox (vbox, pfscr_widget);
690: #if 0
691: gtk_widget_show (pfscr_widget);
692: #endif
1.1.1.2 root 693: add_empty_vbox (vbox);
694:
1.1 root 695: gtk_signal_connect (GTK_OBJECT (bimm_widget), "clicked",
1.1.1.2 root 696: (GtkSignalFunc) custom_changed, NULL);
1.1 root 697: gtk_signal_connect (GTK_OBJECT (b32_widget), "clicked",
1.1.1.2 root 698: (GtkSignalFunc) custom_changed, NULL);
1.1.1.7 root 699: gtk_signal_connect (GTK_OBJECT (afscr_widget), "clicked",
700: (GtkSignalFunc) custom_changed, NULL);
701: gtk_signal_connect (GTK_OBJECT (pfscr_widget), "clicked",
702: (GtkSignalFunc) custom_changed, NULL);
1.1.1.2 root 703: }
704:
705: static void make_sound_widgets (GtkWidget *vbox)
706: {
707: GtkWidget *frame, *newbox;
708: int i;
709: GtkWidget *hbox;
710: static const char *soundlabels1[] = {
711: "None", "No output", "Normal", "Accurate",
712: NULL
713: }, *soundlabels2[] = {
714: "8 bit", "16 bit",
715: NULL
716: }, *soundlabels3[] = {
717: "Mono", "Stereo",
718: NULL
719: };
720:
721: add_empty_vbox (vbox);
722:
723: newbox = make_radio_group_box ("Mode", soundlabels1, sound_widget, 1, sound_changed);
724: gtk_widget_show (newbox);
725: add_centered_to_vbox (vbox, newbox);
726:
727: hbox = gtk_hbox_new (FALSE, 10);
728: gtk_widget_show (hbox);
729: add_centered_to_vbox (vbox, hbox);
730: newbox = make_radio_group_box ("Channels", soundlabels3, sound_ch_widget, 1, sound_changed);
731: gtk_widget_show (newbox);
732: gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
733: newbox = make_radio_group_box ("Resolution", soundlabels2, sound_bits_widget, 1, sound_changed);
734: gtk_widget_show (newbox);
735: gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
1.1.1.3 root 736:
1.1.1.2 root 737: add_empty_vbox (vbox);
1.1 root 738: }
739:
1.1.1.2 root 740: static void make_joy_widgets (GtkWidget *dvbox)
1.1 root 741: {
742: int i;
1.1.1.2 root 743: GtkWidget *hbox = gtk_hbox_new (FALSE, 10);
744: static const char *joylabels[] = {
745: "Joystick 0", "Joystick 1", "Mouse", "Numeric pad",
746: "Cursor keys/Right Ctrl", "T/F/H/B/Left Alt",
747: NULL
748: };
749:
750: add_empty_vbox (dvbox);
751: gtk_widget_show (hbox);
752: add_centered_to_vbox (dvbox, hbox);
1.1 root 753:
754: for (i = 0; i < 2; i++) {
755: GtkWidget *vbox, *frame;
756: GtkWidget *thing;
757: char buffer[20];
758: int j;
759:
760: sprintf (buffer, "Port %d", i);
1.1.1.2 root 761: frame = make_radio_group_box (buffer, joylabels, joy_widget[i], 0, joy_changed);
1.1 root 762: gtk_widget_show (frame);
1.1.1.2 root 763: gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
1.1 root 764: }
1.1.1.2 root 765:
766: add_empty_vbox (dvbox);
767: }
768:
1.1.1.6 root 769: static GtkWidget *make_buttons (const char *label, GtkWidget *box, void (*sigfunc) (void), GtkWidget *(*create)(const char *label))
1.1.1.2 root 770: {
1.1.1.6 root 771: GtkWidget *thing = create (label);
1.1.1.2 root 772: gtk_widget_show (thing);
773: gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) sigfunc, NULL);
774: gtk_box_pack_start (GTK_BOX (box), thing, TRUE, TRUE, 0);
1.1.1.6 root 775:
776: return thing;
1.1 root 777: }
1.1.1.6 root 778: #define make_button(label, box, sigfunc) make_buttons(label, box, sigfunc, gtk_button_new_with_label)
1.1 root 779:
780: static void *gtk_penguin (void *dummy)
781: {
782: GtkWidget *window, *notebook;
1.1.1.2 root 783: GtkWidget *buttonbox, *vbox, *hbox;
1.1 root 784: GtkWidget *thing;
785: int i;
786: int argc = 1;
787: char *a[] = {"UAE"};
788: char **argv = a;
1.1.1.2 root 789: static const struct _pages {
790: const char *title;
791: void (*createfunc)(GtkWidget *);
792: } pages[] = {
793: { "Floppy disks", make_floppy_disks },
794: { "CPU emulation", make_cpu_widgets },
795: { "Graphics", make_gfx_widgets },
796: { "Sound", make_sound_widgets },
797: { "Game ports", make_joy_widgets }
798: };
1.1 root 799:
800: gtk_init (&argc, &argv);
801: gtk_rc_parse ("uaegtkrc");
802:
803: window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1.1.1.2 root 804: gtk_window_set_title (GTK_WINDOW (window), "UAE control");
1.1 root 805:
806: vbox = gtk_vbox_new (FALSE, 4);
807: gtk_container_add (GTK_CONTAINER (window), vbox);
1.1.1.4 root 808: gtk_container_set_border_width (GTK_CONTAINER (window), 10);
1.1 root 809:
1.1.1.2 root 810: /* First line - buttons and power LED */
811: hbox = gtk_hbox_new (FALSE, 10);
812: gtk_widget_show (hbox);
813: gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
1.1 root 814:
1.1.1.2 root 815: /* The buttons */
816: buttonbox = gtk_hbox_new (TRUE, 4);
1.1 root 817: gtk_widget_show (buttonbox);
1.1.1.2 root 818: gtk_box_pack_start (GTK_BOX (hbox), buttonbox, TRUE, TRUE, 0);
819: make_button ("Reset", buttonbox, did_reset);
820: make_button ("Debug", buttonbox, did_debug);
821: make_button ("Quit", buttonbox, did_quit);
822: make_button ("Save config", buttonbox, save_config);
1.1.1.6 root 823: pause_uae_widget = make_buttons ("Pause", buttonbox, pause_uae, gtk_toggle_button_new_with_label);
1.1 root 824:
1.1.1.2 root 825: /* The LED */
826: thing = make_led (0);
827: thing = make_labelled_widget ("Power:", thing);
1.1 root 828: gtk_widget_show (thing);
1.1.1.2 root 829: gtk_box_pack_start (GTK_BOX (hbox), thing, FALSE, TRUE, 0);
1.1 root 830:
1.1.1.2 root 831: /* Place a separator below those buttons. */
1.1 root 832: thing = gtk_hseparator_new ();
833: gtk_box_pack_start (GTK_BOX (vbox), thing, FALSE, TRUE, 0);
834: gtk_widget_show (thing);
835:
1.1.1.2 root 836: /* Now the notebook */
1.1 root 837: notebook = gtk_notebook_new ();
1.1.1.2 root 838: gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
1.1 root 839: gtk_widget_show (notebook);
840:
1.1.1.2 root 841: for (i = 0; i < sizeof pages / sizeof (struct _pages); i++) {
842: thing = gtk_vbox_new (FALSE, 4);
843: gtk_widget_show (thing);
1.1.1.4 root 844: gtk_container_set_border_width (GTK_CONTAINER (thing), 10);
1.1.1.2 root 845: pages[i].createfunc (thing);
846: gtk_notebook_append_page (GTK_NOTEBOOK (notebook), thing, gtk_label_new (pages[i].title));
847: }
1.1 root 848:
849: enable_disk_buttons (1);
850:
851: gtk_widget_show (vbox);
852: gtk_widget_show (window);
853:
854: /* We're going to need that later. */
855: selector = gtk_file_selection_new ("");
856: gtk_signal_connect (GTK_OBJECT (selector), "destroy",
857: (GtkSignalFunc) did_close_insert, selector);
858:
859: gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (selector)->ok_button),
860: "clicked", (GtkSignalFunc) did_insert_select,
861: GTK_OBJECT (selector));
862: gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (selector)->cancel_button),
863: "clicked", (GtkSignalFunc) did_cancel_insert,
864: GTK_OBJECT (selector));
865: filesel_active = -1;
866:
867: gtk_timeout_add (1000, (GtkFunction)my_idle, 0);
868: gtk_main ();
869:
870: quitted_gui = 1;
871: uae_sem_post (&gui_quit_sem);
872: return 0;
873: }
874:
875: void gui_changesettings(void)
876: {
877:
878: }
879:
880: int gui_init (void)
881: {
882: penguin_id tid;
883:
884: gui_active = 0;
885:
886: init_comm_pipe (&to_gui_pipe, 20, 1);
887: init_comm_pipe (&from_gui_pipe, 20, 1);
888: uae_sem_init (&gui_sem, 0, 1);
889: uae_sem_init (&gui_quit_sem, 0, 0);
890: start_penguin (gtk_penguin, NULL, &tid);
891: return 1;
892: }
893:
894: int gui_update (void)
895: {
896: if (no_gui)
897: return 0;
898:
899: write_comm_pipe_int (&to_gui_pipe, 1, 1);
900: return 0;
901: }
902:
903: void gui_exit (void)
904: {
905: if (no_gui)
906: return;
907:
908: quit_gui = 1;
909: uae_sem_wait (&gui_quit_sem);
910: }
911:
1.1.1.4 root 912: void gui_fps (int x)
913: {
914: }
915:
916: void gui_led (int num, int on)
1.1 root 917: {
918: if (no_gui)
919: return;
920:
921: /* if (num == 0)
922: return;
923: printf("LED %d %d\n", num, on);
924: write_comm_pipe_int (&to_gui_pipe, 1, 0);
925: write_comm_pipe_int (&to_gui_pipe, num == 0 ? 4 : num - 1, 0);
926: write_comm_pipe_int (&to_gui_pipe, on, 1);
927: printf("#LED %d %d\n", num, on);*/
928: }
929:
930: void gui_filename(int num, const char *name)
931: {
932: if (no_gui)
933: return;
934:
935: write_comm_pipe_int (&to_gui_pipe, 0, 0);
936: write_comm_pipe_int (&to_gui_pipe, num, 1);
937:
938: /* gui_update ();*/
939: }
940:
941: void gui_handle_events(void)
942: {
1.1.1.6 root 943: int pause_uae = FALSE;
944:
1.1 root 945: if (no_gui)
946: return;
947:
1.1.1.6 root 948: do {
949: while (pause_uae || comm_pipe_has_data (&from_gui_pipe)) {
950: int cmd = read_comm_pipe_int_blocking (&from_gui_pipe);
951: int n;
952: switch (cmd) {
953: case 0:
954: n = read_comm_pipe_int_blocking (&from_gui_pipe);
955: changed_prefs.df[n][0] = '\0';
956: break;
957: case 1:
958: n = read_comm_pipe_int_blocking (&from_gui_pipe);
959: uae_sem_wait (&gui_sem);
960: strncpy (changed_prefs.df[n], new_disk_string[n], 255);
961: changed_prefs.df[n][255] = '\0';
962: uae_sem_post (&gui_sem);
963: break;
964: case 2:
965: uae_reset ();
966: end_pause_uae ();
967: break;
968: case 3:
969: activate_debugger ();
970: end_pause_uae ();
971: break;
972: case 4:
973: uae_quit ();
974: end_pause_uae ();
975: break;
976: case 5:
977: pause_uae = TRUE;
978: break;
979: case 6:
980: pause_uae = FALSE;
981: break;
982: }
983: }
984: } while (pause_uae);
1.1 root 985: }
1.1.1.7 root 986:
987: void gui_update_gfx (void)
988: {
989: #if 0 /* This doesn't work... */
990: set_gfx_state ();
991: #endif
992: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.