|
|
1.1 root 1: /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */
2:
3: /* gtk user interface */
4:
5: #include <sys/types.h>
6: #include <sys/stat.h>
7: #include <unistd.h>
8: #include <fcntl.h>
9: #include <errno.h>
10: #include <stdio.h>
11: #include <stdlib.h>
12: #include <string.h>
13: #include <pwd.h>
14:
15: #include <gtk/gtk.h>
16: #include <gdk/gdkx.h>
17:
18: #include "SDL.h"
19:
20: #include "generator.h"
21: #include "snprintf.h"
22:
23: #include "glade/interface.h"
24: #include "glade/support.h"
25:
26: #include "ui.h"
27: #include "ui-gtk.h"
28: #include "uiplot.h"
29: #include "gtkopts.h"
30:
31: #include "vdp.h"
32: #include "gensound.h"
33: #include "cpu68k.h"
34: #include "mem68k.h"
35: #include "cpuz80.h"
36: #include "event.h"
37: #include "state.h"
38: #include "initcart.h"
1.1.1.2 ! root 39: #include "patch.h"
! 40: #include "dib.h"
! 41: #include "avi.h"
1.1 root 42:
43: #define HBORDER_MAX 32
44: #define HBORDER_DEFAULT 8
45:
46: #define VBORDER_MAX 32
47: #define VBORDER_DEFAULT 8
48:
49: #define HMAXSIZE (320 + 2 * HBORDER_MAX)
50: #define VMAXSIZE (240 + 2 * VBORDER_MAX)
51:
52: #define HSIZE (320 + 2 * ui_hborder)
53: #define VSIZE ((vdp_vislines ? vdp_vislines : 224) + 2 * ui_vborder)
54:
1.1.1.2 ! root 55: #define DISSWIN_MAX 64
! 56:
1.1 root 57: typedef struct {
58: unsigned int a;
59: unsigned int b;
60: unsigned int c;
61: unsigned int up;
62: unsigned int down;
63: unsigned int left;
64: unsigned int right;
65: unsigned int start;
66: } t_gtkkeys;
67:
68: const char *ui_gtk_keys[] = {
69: "a", "b", "c", "start", "left", "right", "up", "down"
70: };
71:
72: /*** static variables ***/
73:
74: static SDL_Surface *screen = NULL; /* SDL screen */
75:
76: static char *ui_initload = NULL; /* filename to load on init */
77: static char *ui_configfile = NULL; /* configuration file */
78: static uint8 ui_plotfield = 0; /* flag indicating plotting this field */
79: static uint8 ui_vdpsimple = 0; /* 0=raster, 1=cell based plotter */
80: static int ui_running = 0; /* running a game */
81: static GtkWidget *ui_win_main; /* main window */
82: static GtkWidget *ui_win_about; /* about window */
83: static GtkWidget *ui_win_console; /* console window */
84: static GtkWidget *ui_win_opts; /* options window */
1.1.1.2 ! root 85: static GtkWidget *ui_win_codes; /* game genie codes window */
1.1 root 86: static GtkWidget *ui_win_filesel; /* file selection window */
87: static int ui_filesel_type; /* selection type: 0=rom, 1=state */
88: static int ui_filesel_save; /* 0=load, 1=save */
89: static GtkWidget *ui_gtk_dialog(const char *msg);
90: static uint8 ui_frameskip = 0; /* 0 for dynamic */
91: static uint8 ui_actualskip = 0; /* the last skip we did (1..) */
92: static uint8 ui_statusbar = 1; /* status-bar? */
93: static uint8 ui_screen[3][4 * HMAXSIZE * VMAXSIZE]; /* screen buffers */
94: static uint8 *ui_screen0; /* pointer to screen block for bank 0 */
95: static uint8 *ui_screen1; /* pointer to screen block for bank 1 */
96: static uint8 *ui_newscreen; /* pointer to new screen block */
97: static int ui_whichbank; /* current viewed screen */
98: static int ui_locksurface; /* lock SDL surface? */
99: static unsigned int ui_hborder = HBORDER_DEFAULT; /* horizontal border */
100: static unsigned int ui_vborder = VBORDER_DEFAULT; /* vertical border */
101: static int ui_query_response = -1; /* query response */
1.1.1.2 ! root 102: static t_gtkkeys ui_cont[2]; /* keyboard key codes */
1.1 root 103: static int ui_musicfile = -1; /* fd of output file for GYM/GNM logging */
1.1.1.2 ! root 104: static int ui_joysticks = 0; /* number of joysticks */
! 105: static SDL_Joystick *js_handle[2] = { NULL, NULL }; /* SDL handles */
! 106: static t_aviinfo ui_aviinfo; /* AVI information */
! 107: static t_avi *ui_avi = NULL; /* Current AVI writer if applicable */
! 108: static uint8 *ui_avivideo; /* video buffer */
! 109: static uint8 *ui_aviaudio; /* audio buffer */
! 110: static GtkWidget *ui_disswins[DISSWIN_MAX]; /* disassembly windows */
! 111: static GdkFont *ui_dissfont; /* disassembly window font */
1.1 root 112:
113: static enum {
114: SCREEN_100, SCREEN_200, SCREEN_FULL
115: } ui_screenmode = SCREEN_100;
116:
117: t_interlace ui_interlace = DEINTERLACE_WEAVEFILTER;
118:
119: /*** Forward references ***/
120:
121: static void ui_usage(void);
122: static void ui_gtk_filesel_ok(GtkFileSelection * obj, gpointer user_data);
123: static void ui_gtk_sizechange(void);
124: static void ui_newframe(void);
125: static void ui_rendertoscreen(void);
126: static gint ui_gtk_configuremain(GtkWidget * widget,
127: GdkEventConfigure * event);
128: static int ui_topbit(unsigned long int bits);
129: static void ui_gtk_opts_to_window(void);
130: static void ui_gtk_opts_from_window(void);
131: static int ui_gtk_query(const char *msg, int style);
132: static void ui_gtk_opts_to_menu(void);
133: static void ui_simpleplot(void);
1.1.1.2 ! root 134: static void ui_sdl_events(void);
1.1 root 135:
136: /*** Program entry point ***/
137:
138: int ui_init(int argc, char *argv[])
139: {
1.1.1.2 ! root 140: int ch;
1.1 root 141: GtkWidget *button, *draw, *obj;
142: struct passwd *passwd;
143: struct stat statbuf;
1.1.1.2 ! root 144: int i;
! 145: const char *name;
1.1 root 146:
147: gtk_set_locale();
148: gtk_init(&argc, &argv);
149:
1.1.1.2 ! root 150: fprintf(stderr, "Generator is (c) James Ponder 1997-2003, all rights "
! 151: "reserved. v" VERSION "\n\n");
! 152:
1.1 root 153: while ((ch = getopt(argc, argv, "?dc:w:")) != -1) {
154: switch (ch) {
155: case 'd': /* turn on debug mode */
156: gen_debugmode = 1;
157: break;
158: case 'c': /* configuration file */
159: ui_configfile = optarg;
160: break;
161: case 'w': /* saved game work dir */
162: chdir(optarg); /* for the moment this will do */
163: break;
164: case '?':
165: default:
166: ui_usage();
167: }
168: }
169: argc -= optind;
170: argv += optind;
171:
172: if (argc > 0) {
173: ui_initload = argv[0];
174: argc--;
175: argv++;
176: }
177:
178: if (argc != 0)
179: ui_usage();
180:
181: if (ui_configfile == NULL) {
182: if ((passwd = getpwuid(getuid())) == NULL) {
183: fprintf(stderr, "Who are you? (getpwent failed)\n");
184: exit(1);
185: }
186: ui_configfile = malloc(strlen(passwd->pw_dir) + sizeof("/.genrc"));
187: sprintf(ui_configfile, "%s/.genrc", passwd->pw_dir);
188: }
189: if (stat(ui_configfile, &statbuf) != 0) {
190: fprintf(stderr, "No configuration file found, using defaults.\n");
191: } else {
192: if (gtkopts_load(ui_configfile) != 0)
193: fprintf(stderr, "Error loading configuration file, using defaults.\n");
194: }
195:
196: /* create gtk windows */
197:
198: ui_win_main = create_mainwin();
199: ui_win_about = create_about();
200: ui_win_console = create_console();
201: ui_win_opts = create_opts();
1.1.1.2 ! root 202: ui_win_codes = create_codes();
1.1 root 203: ui_win_filesel = gtk_file_selection_new("Select file...");
204: button = GTK_FILE_SELECTION(ui_win_filesel)->ok_button;
205: gtk_signal_connect(GTK_OBJECT(button), "clicked",
206: GTK_SIGNAL_FUNC(ui_gtk_filesel_ok), NULL);
207: button = GTK_FILE_SELECTION(ui_win_filesel)->cancel_button;
208: gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
209: GTK_SIGNAL_FUNC(gtk_widget_hide),
210: GTK_OBJECT(ui_win_filesel));
211:
1.1.1.2 ! root 212: /* load our font */
! 213: ui_dissfont = gdk_font_load
! 214: ("-*-fixed-medium-r-normal-*-*-*-*-*-*-80-iso8859-1");
! 215: gdk_font_ref(ui_dissfont);
! 216:
! 217: /* set codes window so that code list is reorderable */
! 218:
! 219: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_codes),
! 220: "clist_codes"));
! 221: gtk_clist_set_reorderable(GTK_CLIST(obj), 1);
! 222:
1.1 root 223: /* open main window */
224:
225: gtk_widget_add_events(ui_win_main, GDK_KEY_RELEASE_MASK);
226: gtk_window_set_title(GTK_WINDOW(ui_win_main), "Generator/gtk " VERSION);
227: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_main), "debug"));
228: if (!gen_debugmode)
229: gtk_widget_hide(obj);
230: gtk_widget_show(ui_win_main);
231: draw = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_main),
232: "drawingarea_main"));
233: gtk_signal_connect(GTK_OBJECT(ui_win_main), "configure_event",
234: GTK_SIGNAL_FUNC(ui_gtk_configuremain), 0);
235: {
236: char SDL_windowhack[32];
237: snprintf(SDL_windowhack, sizeof(SDL_windowhack), "SDL_WINDOWID=%ld",
238: GDK_WINDOW_XWINDOW(draw->window));
239: putenv(SDL_windowhack);
240: }
1.1.1.2 ! root 241: if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0) {
1.1 root 242: fprintf(stderr, "Couldn't initialise SDL: %s\n", SDL_GetError());
243: return -1;
244: }
1.1.1.2 ! root 245: ui_joysticks = SDL_NumJoysticks();
! 246: /* Print information about the joysticks */
! 247: fprintf(stderr, "%d joysticks detected\n", ui_joysticks);
! 248: for (i = 0; i < ui_joysticks; i++) {
! 249: name = SDL_JoystickName(i);
! 250: fprintf(stderr, "Joystick %d: %s\n", i,
! 251: name ? name : "Unknown Joystick");
! 252: }
! 253: js_handle[0] = SDL_JoystickOpen(0);
! 254: js_handle[1] = SDL_JoystickOpen(1);
! 255: SDL_JoystickEventState(SDL_ENABLE);
! 256:
1.1 root 257: ui_gtk_sizechange();
258: ui_gtk_newoptions();
259: ui_gtk_opts_to_menu();
260:
261: /* ui_newscreen is where the emulation data is rendered to - it is
262: then compared with ui_screen0 or ui_screen1 depending on which
263: screen bank it is being written to, and the delta changes are sent
264: to screen memory. The ui_screenX and ui_newscreen pointers are then
265: switched, and the next frame/field begins... */
266: memset(ui_screen[0], 0, sizeof(ui_screen[0]));
267: memset(ui_screen[1], 0, sizeof(ui_screen[1]));
268: ui_screen0 = ui_screen[0];
269: ui_screen1 = ui_screen[1];
270: ui_newscreen = ui_screen[2];
271: ui_whichbank = 0; /* viewing 0 */
1.1.1.2 ! root 272: fprintf(stderr, "Please use the GTK menu to quit this program properly.\n");
1.1 root 273: return 0;
274: }
275:
276: static void ui_usage(void)
277: {
278: fprintf(stderr, "generator [options] [<rom>]\n\n");
279: fprintf(stderr, " -d debug mode\n");
280: fprintf(stderr, " -w <work dir> set work directory\n");
281: fprintf(stderr, " -c <config file> use alternative config file\n\n");
282: fprintf(stderr, " ROM types supported: .rom or .smd interleaved "
283: "(autodetected)\n");
284: exit(1);
285: }
286:
287: void ui_final(void)
288: {
1.1.1.2 ! root 289: gdk_font_unref(ui_dissfont);
! 290: gdk_key_repeat_restore();
1.1 root 291: SDL_Quit();
1.1.1.2 ! root 292: gtk_exit(0);
1.1 root 293: }
294:
295: int ui_loop(void)
296: {
297: char *p;
298:
299: if (ui_initload) {
300: p = gen_loadimage(ui_initload);
301: if (p)
302: ui_gtk_dialog(p);
303: } else {
304: gen_loadmemrom(initcart, initcart_len);
305: }
306: while (!gen_quit) {
307: if (ui_running) {
308: while (gtk_events_pending())
309: gtk_main_iteration_do(0);
1.1.1.2 ! root 310: ui_sdl_events();
1.1 root 311: ui_newframe();
312: event_doframe();
313: } else {
314: gtk_main();
315: }
316: }
317: return 0;
318: }
319:
320: void ui_newframe(void)
321: {
322: static int vmode = -1;
323: static int pal = -1;
324: static int skipcount = 0;
325: static char frameplots[60]; /* 60 for NTSC, 50 for PAL */
326: static unsigned int frameplots_i = 0;
327: unsigned int i;
328: int fps;
329: char fps_string[8];
330: GtkWidget *entry_fps;
331: static int lasttype = -1;
332:
333: if (frameplots_i > vdp_framerate)
334: frameplots_i = 0;
335: if (((vdp_reg[12] >> 1) & 3) && vdp_oddframe) {
336: /* interlace mode, and we're about to do an odd field - we always leave
337: ui_plotfield alone so we do fields in pairs, this stablises the
338: display, reduces blurring */
339: } else {
340: ui_plotfield = 0;
341: if (ui_frameskip == 0) {
342: if (sound_feedback != -1)
343: ui_plotfield = 1;
344: } else {
345: if (cpu68k_frames % ui_frameskip == 0)
346: ui_plotfield = 1;
347: }
348: }
349: if (!ui_plotfield) {
350: skipcount++;
351: frameplots[frameplots_i++] = 0;
352: return;
353: }
354: lasttype = vdp_oddframe;
355: /* check for ROM or user changing the vertical size */
356: if (vmode == (int)(vdp_reg[1] & (1 << 3)) || pal != (int)vdp_pal) {
357: vdp_setupvideo();
358: vmode = vdp_reg[1] & (1 << 3);
359: pal = vdp_pal;
360: }
361: /* count the frames we've plotted in the last vdp_framerate real frames */
362: fps = 0;
363: for (i = 0; i < vdp_framerate; i++) {
364: if (frameplots[i])
365: fps++;
366: }
367: frameplots[frameplots_i++] = 1;
368: if (!ui_statusbar)
369: return;
370: snprintf(fps_string, sizeof(fps_string), "%d", fps);
371: entry_fps = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_main),
372: "entry_fps"));
373: gtk_entry_set_text(GTK_ENTRY(entry_fps), fps_string);
374: skipcount = 0;
375: }
376:
377: /* ui_line is called for all vdp_totlines but is offset so that line=0
378: is the first line, line=(vdp_totlines-vdp_visstartline)-1 is the
379: last */
380:
381: void ui_line(int line)
382: {
383: static uint8 gfx[320];
384: unsigned int width = (vdp_reg[12] & 1) ? 320 : 256;
385: unsigned int offset = ui_hborder + ((vdp_reg[12] & 1) ? 0 : 32);
386: uint8 bg;
387: uint32 bgpix;
388: uint8 *location;
389: unsigned int i;
390:
391: if (!ui_plotfield)
392: return;
393: if (ui_vdpsimple) {
394: if (line == (int)(vdp_vislines >> 1))
395: /* if we're in simple cell-based mode, plot when half way down screen */
396: ui_simpleplot();
397: return;
398: }
399: if (line < -(int)ui_vborder || line >= (int)(vdp_vislines + ui_vborder))
400: return;
401:
402: bg = (vdp_reg[7] & 63);
403: uiplot_checkpalcache(0);
404: bgpix = uiplot_palcache[bg];
405: location = ui_newscreen +
406: (line + ui_vborder) * HMAXSIZE * screen->format->BytesPerPixel;
407: if (line < 0 || line >= (int)vdp_vislines) {
408: /* in border */
409: switch (screen->format->BytesPerPixel) {
410: case 2:
411: for (i = 0; i < HSIZE; i++) {
412: ((uint16 *)location)[i] = bgpix;
413: }
414: break;
415: case 4:
416: for (i = 0; i < HSIZE; i++) {
417: ((uint32 *)location)[i] = bgpix;
418: }
419: break;
420: }
421: return;
422: }
423: /* normal line */
424: switch ((vdp_reg[12] >> 1) & 3) {
425: case 0: /* normal */
426: case 1: /* interlace simply doubled up */
427: case 2: /* invalid */
428: vdp_renderline(line, gfx, 0);
429: break;
430: case 3: /* interlace with double resolution */
431: vdp_renderline(line, gfx, vdp_oddframe);
432: break;
433: }
434: switch (screen->format->BytesPerPixel) {
435: case 2:
436: uiplot_convertdata16(gfx, ((uint16 *)location) + offset, width);
437: for (i = 0; i < offset; i++) {
438: ((uint16 *)location)[i] = bgpix;
439: ((uint16 *)location)[i + offset + width] = bgpix;
440: }
441: break;
442: case 4:
443: uiplot_convertdata32(gfx, ((uint32 *)location) + offset, width);
444: for (i = 0; i < offset; i++) {
445: ((uint32 *)location)[i] = bgpix;
446: ((uint32 *)location)[i + offset + width] = bgpix;
447: }
448: break;
449: }
450: }
451:
452: static void ui_simpleplot(void)
453: {
454: static uint8 gfx[(320 + 16) * (240 + 16)];
455: unsigned int width = (vdp_reg[12] & 1) ? 320 : 256;
456: unsigned int offset = ui_hborder + ((vdp_reg[12] & 1) ? 0 : 32);
457: unsigned int line, i;
458: uint8 *location, *location2;
459: uint8 bg;
460: uint32 bgpix;
461: /* cell mode - entire frame done here */
462: bg = (vdp_reg[7] & 63);
463: uiplot_checkpalcache(0);
464: bgpix = uiplot_palcache[bg];
465: vdp_renderframe(gfx + (8 * (320 + 16)) + 8, 320 + 16); /* plot frame */
466: location = ui_newscreen +
467: ui_vborder * HMAXSIZE * screen->format->BytesPerPixel;
468: switch (screen->format->BytesPerPixel) {
469: case 2:
470: for (line = 0; line < vdp_vislines; line++) {
471: for (i = 0; i < offset; i++) {
472: ((uint16 *)location)[i] = bgpix;
473: ((uint16 *)location)[width + offset + i] = bgpix;
474: }
475: uiplot_convertdata16(gfx + 8 + (line + 8) * (320 + 16),
476: ((uint16 *)location) + offset, width);
477: location += HMAXSIZE * 2;
478: }
479: break;
480: case 4:
481: for (line = 0; line < vdp_vislines; line++) {
482: for (i = 0; i < offset; i++) {
483: ((uint32 *)location)[i] = bgpix;
484: ((uint32 *)location)[width + offset + i] = bgpix;
485: }
486: uiplot_convertdata32(gfx + 8 + (line + 8) * (320 + 16),
487: ((uint32 *)location) + offset, width);
488: location += HMAXSIZE * 4;
489: }
490: break;
491: }
492: location = ui_newscreen;
493: location2 = ui_newscreen + (ui_vborder + vdp_vislines) *
494: HMAXSIZE * screen->format->BytesPerPixel;
495: switch (screen->format->BytesPerPixel) {
496: case 2:
497: for (line = 0; line < ui_vborder; line++) {
498: for (i = 0; i < HSIZE; i++) {
499: ((uint16 *)location)[i] = bgpix;
500: ((uint16 *)location2)[i] = bgpix;
501: }
502: location += HMAXSIZE * 2;
503: location2 += HMAXSIZE * 2;
504: }
505: break;
506: case 4:
507: for (line = 0; line < ui_vborder; line++) {
508: for (i = 0; i < HSIZE; i++) {
509: ((uint32 *)location)[i] = bgpix;
510: ((uint32 *)location2)[i] = bgpix;
511: }
512: location += HMAXSIZE * 4;
513: location2 += HMAXSIZE * 4;
514: }
515: break;
516: }
517: }
518:
1.1.1.2 ! root 519: static void ui_makeavivideo(void)
! 520: {
! 521: unsigned int line;
! 522: SDL_PixelFormat *f = screen->format;
! 523: uint8 *linep = ui_newscreen;
! 524: uint8 *video;
! 525: uint32 c;
! 526: unsigned int x;
! 527:
! 528: video = ui_avivideo;
! 529: switch (screen->format->BytesPerPixel) {
! 530: case 2:
! 531: for (line = 0; line < ui_avi->info.height; line++) {
! 532: for (x = 0; x < ui_avi->info.width; x++) {
! 533: c = ((uint16 *)linep)[x];
! 534: *video++ = ((c & f->Rmask) >> f->Rshift) << f->Rloss;
! 535: *video++ = ((c & f->Gmask) >> f->Gshift) << f->Gloss;
! 536: *video++ = ((c & f->Bmask) >> f->Bshift) << f->Bloss;
! 537: }
! 538: linep+= (HMAXSIZE * 2);
! 539: }
! 540: break;
! 541: case 4:
! 542: for (line = 0; line < ui_avi->info.height; line++) {
! 543: for (x = 0; x < ui_avi->info.width; x++) {
! 544: c = ((uint32 *)linep)[x];
! 545: *video++ = ((c & f->Rmask) >> f->Rshift) << f->Rloss;
! 546: *video++ = ((c & f->Gmask) >> f->Gshift) << f->Gloss;
! 547: *video++ = ((c & f->Bmask) >> f->Bshift) << f->Bloss;
! 548: }
! 549: linep+= (HMAXSIZE * 4);
! 550: }
! 551: break;
! 552: }
! 553: avi_video(ui_avi, ui_avivideo);
! 554: }
! 555:
! 556: static void ui_makeaviaudio(void)
! 557: {
! 558: unsigned int i;
! 559:
! 560: /* 22050 doesn't divide nicely into 60 fields - that means 367.50 samples
! 561: per field. So we need to compensate by adding in a byte every now and
! 562: again */
! 563:
! 564: /* audio buffer gensound_soundbuf is in local endian - avi is little */
! 565: for (i = 0; i < sound_sampsperfield; i++) {
! 566: ((uint16 *)ui_aviaudio)[i * 2] = LOCENDIAN16L(sound_soundbuf[0][i]);
! 567: ((uint16 *)ui_aviaudio)[i * 2 + 1] = LOCENDIAN16L(sound_soundbuf[1][i]);
! 568: }
! 569: /* duplicate last byte */
! 570: ((uint16 *)ui_aviaudio)[i * 2] = LOCENDIAN16L(sound_soundbuf[0][i - 1]);
! 571: ((uint16 *)ui_aviaudio)[i * 2 + 1] = LOCENDIAN16L(sound_soundbuf[1][i - 1]);
! 572:
! 573: /* get partial bytes per second we should be outputting in 1000ths */
! 574: ui_avi->error+= (ui_avi->info.sampspersec * 1000 / vdp_framerate) % 1000;
! 575: if (ui_avi->error > 1000) {
! 576: ui_avi->error-= 1000;
! 577: avi_audio(ui_avi, ui_aviaudio, sound_sampsperfield + 1);
! 578: } else {
! 579: avi_audio(ui_avi, ui_aviaudio, sound_sampsperfield);
! 580: }
! 581: }
! 582:
1.1 root 583: /*** ui_endfield - end of field reached ***/
584:
585: void ui_endfield(void)
586: {
587: static int counter = 0;
588:
1.1.1.2 ! root 589: if (ui_avi)
! 590: ui_makeaviaudio();
! 591:
! 592: if (ui_plotfield)
1.1 root 593: ui_rendertoscreen(); /* plot ui_newscreen to screen */
1.1.1.2 ! root 594:
1.1 root 595: if (ui_frameskip == 0) {
596: /* dynamic frame skipping */
597: counter++;
598: if (sound_feedback >= 0) {
599: ui_actualskip = counter;
600: counter = 0;
601: }
602: } else {
603: ui_actualskip = ui_frameskip;
604: }
605: }
606:
607: void ui_rendertoscreen(void)
608: {
609: uint8 **oldscreenpp = ui_whichbank ? &ui_screen1 : &ui_screen0;
610: uint8 *scrtmp;
611: uint8 *newlinedata, *oldlinedata;
612: unsigned int line;
613: uint8 *location;
614: uint8 *evenscreen; /* interlace: lines 0,2,etc. */
615: uint8 *oddscreen; /* lines 1,3,etc. */
616:
617: if (ui_locksurface && SDL_LockSurface(screen) != 0)
618: ui_err("Failed to lock SDL surface");
619: for (line = 0; line < VSIZE; line++) {
620: newlinedata = ui_newscreen +
621: line * HMAXSIZE * screen->format->BytesPerPixel;
622: oldlinedata = *oldscreenpp +
623: line * HMAXSIZE * screen->format->BytesPerPixel;
624: switch (ui_screenmode) {
625: case SCREEN_100:
626: location = screen->pixels + line * screen->pitch;
627: /* we could use uiplot_renderXX_x1 routines here, but SDL wouldn't
628: pick up our delta changes so we don't */
629: memcpy(location, newlinedata, HSIZE * screen->format->BytesPerPixel);
630: break;
631: case SCREEN_200:
632: location = screen->pixels + 2 * line * screen->pitch;
633: if (screen->format->BytesPerPixel != 2 &&
634: screen->format->BytesPerPixel != 4)
635: ui_err("unsupported mode for 200%% scaling\n");
636: switch ((vdp_reg[12] >> 1) & 3) { /* interlace mode */
637: case 0:
638: case 1:
639: case 2:
640: switch (screen->format->BytesPerPixel) {
641: case 2:
642: uiplot_render16_x2((uint16 *)newlinedata, NULL, location,
643: screen->pitch, HSIZE);
644: break;
645: case 4:
646: uiplot_render32_x2((uint32 *)newlinedata, NULL, location,
647: screen->pitch, HSIZE);
648: break;
649: }
650: break;
651: case 3:
652: /* work out which buffer contains the odd and even fields */
653: if (vdp_oddframe) {
654: oddscreen = ui_newscreen;
655: evenscreen = ui_whichbank ? ui_screen0 : ui_screen1;
656: } else {
657: evenscreen = ui_newscreen;
658: oddscreen = ui_whichbank ? ui_screen0 : ui_screen1;
659: }
660: switch (ui_interlace) {
661: case DEINTERLACE_BOB:
662: switch (screen->format->BytesPerPixel) {
663: case 2:
664: uiplot_render16_x2((uint16 *)newlinedata, NULL, location,
665: screen->pitch, HSIZE);
666: break;
667: case 4:
668: uiplot_render32_x2((uint32 *)newlinedata, NULL, location,
669: screen->pitch, HSIZE);
670: break;
671: }
672: break;
673: case DEINTERLACE_WEAVE:
674: evenscreen += line * HMAXSIZE * screen->format->BytesPerPixel;
675: oddscreen += line * HMAXSIZE * screen->format->BytesPerPixel;
676: switch (screen->format->BytesPerPixel) {
677: case 2:
678: uiplot_render16_x2h((uint16 *)evenscreen, NULL, location, HSIZE);
679: uiplot_render16_x2h((uint16 *)oddscreen, NULL,
680: location + screen->pitch, HSIZE);
681: break;
682: case 4:
683: uiplot_render32_x2h((uint32 *)evenscreen, NULL, location, HSIZE);
684: uiplot_render32_x2h((uint32 *)oddscreen, NULL,
685: location + screen->pitch, HSIZE);
686: break;
687: }
688: break;
689: case DEINTERLACE_WEAVEFILTER:
690: evenscreen += line * HMAXSIZE * screen->format->BytesPerPixel;
691: oddscreen += line * HMAXSIZE * screen->format->BytesPerPixel;
692: switch (screen->format->BytesPerPixel) {
693: case 2:
694: /* lines line+0 and line+1 */
695: uiplot_irender16_weavefilter((uint16 *)evenscreen,
696: (uint16 *)oddscreen,
697: location, HSIZE);
698: /* lines line+1 and line+2 */
699: uiplot_irender16_weavefilter((uint16 *)oddscreen,
700: ((uint16 *)evenscreen) + HMAXSIZE,
701: location + screen->pitch, HSIZE);
702: break;
703: case 4:
704: /* lines line+0 and line+1 */
705: uiplot_irender32_weavefilter((uint32 *)evenscreen,
706: (uint32 *)oddscreen,
707: location, HSIZE);
708: /* lines line+1 and line+2 */
709: uiplot_irender32_weavefilter((uint32 *)oddscreen,
710: ((uint32 *)evenscreen) + HMAXSIZE,
711: location + screen->pitch, HSIZE);
712: break;
713: }
714: }
715: break;
716: }
717: break;
718: case SCREEN_FULL:
719: default:
720: ui_err("invalid screen mode\n");
721: }
722: }
723: if (ui_locksurface)
724: SDL_UnlockSurface(screen);
725: SDL_UpdateRect(screen, 0, 0, screen->w, screen->h);
1.1.1.2 ! root 726: if (ui_avi)
! 727: ui_makeavivideo();
1.1 root 728: ui_whichbank ^= 1;
729: // if (ui_vsync)
730: // uip_vsync();
731: /* swap ui_screenX and ui_newscreen pointers */
732: scrtmp = *oldscreenpp;
733: *oldscreenpp = ui_newscreen;
734: ui_newscreen = scrtmp;
735: }
736:
737: /*** logging functions ***/
738:
739: /* logging is done this way because this was the best I could come up with
740: whilst battling with macros that can only take fixed numbers of arguments */
741:
742: #define LOG_FUNC(name,level,txt) void ui_log_ ## name ## (const char *text, ...) \
743: { \
744: va_list ap; \
745: if (gen_loglevel >= level) { \
746: printf("[%s] ", txt); \
747: va_start(ap, text); \
748: vprintf(text, ap); \
749: va_end(ap); \
750: putchar(10); \
751: } \
752: }
753:
754: /* *INDENT-OFF* */
755:
756: LOG_FUNC(debug3, 7, "DEBG ");
757: LOG_FUNC(debug2, 6, "DEBG ");
758: LOG_FUNC(debug1, 5, "DEBG ");
759: LOG_FUNC(user, 4, "USER ");
760: LOG_FUNC(verbose, 3, "---- ");
761: LOG_FUNC(normal, 2, "---- ");
762: LOG_FUNC(critical, 1, "CRIT ");
763: LOG_FUNC(request, 0, "---- "); /* this generates a warning, such is life */
764:
765: /* *INDENT-ON* */
766:
767: /*** ui_err - log error message and quit ***/
768:
769: void ui_err(const char *text, ...)
770: {
771: va_list ap;
772:
773: printf("ERROR: ");
774:
775: va_start(ap, text);
776: vfprintf(stderr, text, ap);
777: va_end(ap);
778: putc(10, stderr);
779: exit(0);
780: }
781:
782: /*** ui_topbit - given an integer return the top most bit set ***/
783:
784: int ui_topbit(unsigned long int bits)
785: {
786: long int bit = 31;
787: unsigned long int mask = 1 << 31;
788:
789: for (; bit >= 0; bit--, mask >>= 1) {
790: if (bits & mask)
791: return bit;
792: }
793: return -1;
794: }
795:
796: /*** ui_setinfo - there is new cart information ***/
797:
798: char *ui_setinfo(t_cartinfo *cartinfo)
799: {
800: (void)cartinfo;
801: return NULL;
802: }
803:
804: /*** gtk functions ***/
805:
1.1.1.2 ! root 806: gint ui_gtk_configuremain(GtkWidget *widget, GdkEventConfigure *event)
1.1 root 807: {
808: (void)widget;
809: (void)event;
810: /* if we were allowing resizing this is where we'd do it, but note
811: to check whether it's just the location or the size being changed
812: as a call to SDL to set the video mode will erase the screen and
813: then everything would go black */
814: return TRUE;
815: }
816:
1.1.1.2 ! root 817: void ui_gtk_filesel_ok(GtkFileSelection *obj, gpointer user_data)
1.1 root 818: {
819: char msg[512];
820: char buf[8];
821: char *file, *p;
822: int fd;
823: struct stat s;
1.1.1.2 ! root 824: int avi_skip, avi_jpeg;
1.1 root 825:
826: (void)obj;
827: (void)user_data;
828: file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(ui_win_filesel));
829: gtk_widget_hide(ui_win_filesel);
830:
831: if (ui_filesel_save) {
832: if (stat(file, &s) == 0) {
833: snprintf(msg, sizeof(msg), "The file '%s' already exists - overwrite?",
834: file);
835: if (ui_gtk_query(msg, 0) != 0)
836: return;
837: }
838: }
839: *msg = '\0';
840:
841: switch ((ui_filesel_type << 1) | ui_filesel_save) {
842: case 0:
843: p = gen_loadimage(file);
844: if (p)
845: snprintf(msg, sizeof(msg), "An error occured whilst tring to load "
846: "the ROM '%s': %s", file, p);
847: break;
848: case 1:
849: if (cpu68k_rom == NULL || cpu68k_romlen == 0) {
850: snprintf(msg, sizeof(msg), "There is no ROM currently in memory to "
851: "save!");
852: break;
853: }
1.1.1.2 ! root 854: if (gen_modifiedrom) {
! 855: if (ui_gtk_query("The ROM in memory has been modified by cheat "
! 856: "codes - are you really sure you want to save"
! 857: "this ROM?", 0) != 0)
! 858: break;
! 859: }
1.1 root 860: if ((fd = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0777)) == -1
861: || write(fd, cpu68k_rom, cpu68k_romlen) == -1 || close(fd) == -1) {
862: snprintf(msg, sizeof(msg), "An error occured whilst trying to save the "
863: "ROM as '%s': %s", file, strerror(errno));
864: }
865: break;
866: case 2:
867: if (stat(file, &s) != 0) {
868: snprintf(msg, sizeof(msg), "%s: %s", file, strerror(errno));
869: break;
870: }
871: if (state_loadfile(file) != 0)
872: snprintf(msg, sizeof(msg), "An error occured whilst trying to load "
873: "state from '%s': %s", file, strerror(errno));
874: break;
875: case 3:
876: if (state_savefile(file) != 0)
877: snprintf(msg, sizeof(msg), "An error occured whilst trying to save "
878: "state to '%s': %s", file, strerror(errno));
879: break;
880: case 5:
881: if (ui_musicfile != -1) {
882: snprintf(msg, sizeof(msg), "There is already a music log in progress");
883: break;
884: }
885: if ((ui_musicfile = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0777)) == -1) {
886: snprintf(msg, sizeof(msg), "An error occured whilst trying to start "
887: "a GYM log to '%s': %s", file, strerror(errno));
888: }
889: gen_musiclog = 1;
890: break;
891: case 7:
892: if (ui_musicfile != -1) {
893: snprintf(msg, sizeof(msg), "There is already a music log in progress");
894: break;
895: }
896: if ((ui_musicfile = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0777)) == -1) {
897: snprintf(msg, sizeof(msg), "An error occured whilst trying to start "
898: "a GNM log to '%s': %s", file, strerror(errno));
899: }
900: buf[0] = 'G'; buf[1] = 'N'; buf[2] = 'M';
901: buf[3] = vdp_framerate;
902: write(ui_musicfile, buf, 4);
903: gen_musiclog = 2;
904: break;
1.1.1.2 ! root 905: case 8:
! 906: if (stat(file, &s) != 0) {
! 907: snprintf(msg, sizeof(msg), "%s: %s", file, strerror(errno));
! 908: break;
! 909: }
! 910: if (patch_loadfile(file) != 0)
! 911: snprintf(msg, sizeof(msg), "An error occured whilst trying to load "
! 912: "state from '%s': %s", file, strerror(errno));
! 913: break;
! 914: case 9:
! 915: if (patch_savefile(file) != 0)
! 916: snprintf(msg, sizeof(msg), "An error occured whilst trying to save "
! 917: "state to '%s': %s", file, strerror(errno));
! 918: break;
! 919: case 11:
! 920: if (ui_avi) {
! 921: snprintf(msg, sizeof(msg), "There is already an avi in progress");
! 922: break;
! 923: }
! 924: avi_skip = atoi(gtkopts_getvalue("aviframeskip"));
! 925: avi_jpeg = !strcasecmp(gtkopts_getvalue("aviformat"), "jpeg");
! 926: ui_aviinfo.width = HSIZE;
! 927: ui_aviinfo.height = VSIZE;
! 928: ui_aviinfo.sampspersec = sound_speed;
! 929: ui_aviinfo.fps = (vdp_framerate * 1000) / avi_skip;
! 930: ui_aviinfo.jpegquality = atoi(gtkopts_getvalue("jpegquality"));
! 931: if ((ui_avi = avi_open(file, &ui_aviinfo, avi_jpeg)) == NULL) {
! 932: snprintf(msg, sizeof(msg), "An error occured whilst trying to start "
! 933: "the AVI: %s", strerror(errno));
! 934: break;
! 935: }
! 936: if ((ui_aviaudio = malloc((sound_sampsperfield + 1) * 4)) == NULL ||
! 937: (ui_avivideo = malloc(ui_avi->linebytes * VSIZE)) == NULL)
! 938: ui_err("out of memory");
! 939: ui_frameskip = avi_skip;
! 940: break;
1.1 root 941: default:
942: strcpy(msg, "Not implemented.");
943: break;
944: }
945: if (msg[0])
946: ui_gtk_dialog(msg);
947: }
948:
949: GtkWidget *ui_gtk_dialog(const char *msg)
950: {
951: GtkWidget *dialog, *label, *button_ok;
952:
953: dialog = gtk_dialog_new();
954: label = gtk_label_new(msg);
955: gtk_label_set_line_wrap(GTK_LABEL(label), 1);
956: button_ok = gtk_button_new_with_label("OK");
957: gtk_signal_connect_object(GTK_OBJECT(button_ok), "clicked",
958: GTK_SIGNAL_FUNC(gtk_widget_destroy),
959: GTK_OBJECT(dialog));
960: gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
961: button_ok);
962: gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
963: gtk_window_set_modal(GTK_WINDOW(dialog), 1);
964: gtk_window_set_default_size(GTK_WINDOW(dialog), 350, 150);
965: gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
966: gtk_widget_show_all(dialog);
967: return dialog;
968: }
969:
970: /* supporting function for ui_gtk_query */
971:
972: static void ui_gtk_response(GtkButton *button, gpointer func_data)
973: {
974: (void)button;
975: ui_query_response = GPOINTER_TO_INT(func_data);
1.1.1.2 ! root 976: if (gtk_main_level() > 0)
! 977: gtk_main_quit();
1.1 root 978: }
979:
980: /* ask a question and return 0 for OK/Yes, -1 for Cancel/No */
981:
982: static int ui_gtk_query(const char *msg, int style)
983: {
984: GtkWidget *dialog, *label, *button_a, *button_b, *hbox;
985:
986: dialog = gtk_dialog_new();
987: label = gtk_label_new(msg);
988: hbox = gtk_hbox_new(1, 8);
989: gtk_label_set_line_wrap(GTK_LABEL(label), 1);
990: switch (style) {
991: default:
992: case 0:
993: button_a = gtk_button_new_with_label("OK");
994: button_b = gtk_button_new_with_label("Cancel");
995: break;
996: case 1:
997: button_a = gtk_button_new_with_label("Yes");
998: button_b = gtk_button_new_with_label("No");
999: break;
1000: }
1001: gtk_box_pack_end(GTK_BOX(hbox), button_b, 0, 1, 0);
1002: gtk_box_pack_end(GTK_BOX(hbox), button_a, 0, 1, 0);
1003: gtk_signal_connect(GTK_OBJECT(button_a), "clicked",
1004: GTK_SIGNAL_FUNC(ui_gtk_response),
1005: GINT_TO_POINTER(0));
1006: gtk_signal_connect(GTK_OBJECT(button_b), "clicked",
1007: GTK_SIGNAL_FUNC(ui_gtk_response),
1008: GINT_TO_POINTER(-1));
1009: gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
1010: hbox);
1011: gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
1012: gtk_window_set_modal(GTK_WINDOW(dialog), 1);
1013: gtk_window_set_default_size(GTK_WINDOW(dialog), 350, 150);
1014: gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
1015: gtk_widget_show_all(dialog);
1016: ui_query_response = -1;
1017: gtk_main();
1018: gtk_widget_destroy(dialog);
1019: return ui_query_response;
1020: }
1021:
1022: void ui_gtk_filesel(int type, int save)
1023: {
1024: ui_filesel_type = type;
1025: ui_filesel_save = save;
1026:
1027: switch ((type << 1) | save) {
1028: case 0:
1029: gtk_window_set_title(GTK_WINDOW(ui_win_filesel),
1030: "Choose ROM file (BIN or SMD format) to load");
1031: break;
1032: case 1:
1033: gtk_window_set_title(GTK_WINDOW(ui_win_filesel),
1034: "Choose filename to save ROM file (BIN format) to");
1035: break;
1036: case 2:
1037: gtk_window_set_title(GTK_WINDOW(ui_win_filesel),
1038: "Choose state file to load");
1039: break;
1040: case 3:
1041: gtk_window_set_title(GTK_WINDOW(ui_win_filesel),
1042: "Choose filename to save state to");
1043: break;
1044: case 5:
1045: gtk_window_set_title(GTK_WINDOW(ui_win_filesel),
1046: "Choose where to start GYM logging");
1047: break;
1048: case 7:
1049: gtk_window_set_title(GTK_WINDOW(ui_win_filesel),
1050: "Choose where to start GNM logging");
1051: break;
1052: }
1053: gtk_widget_show(ui_win_filesel);
1054: }
1055:
1056: void ui_gtk_about(void)
1057: {
1058: gtk_widget_show(ui_win_about);
1059: }
1060:
1061: void ui_gtk_options(void)
1062: {
1063: ui_gtk_opts_to_window();
1064: gtk_widget_show(ui_win_opts);
1065: }
1066:
1067: void ui_gtk_console(void)
1068: {
1069: gtk_widget_show(ui_win_console);
1070: }
1071:
1072: void ui_gtk_quit(void)
1073: {
1074: gen_quit = 1;
1.1.1.2 ! root 1075: if (gtk_main_level() > 0)
! 1076: gtk_main_quit();
1.1 root 1077: }
1078:
1079: void ui_gtk_closeconsole(void)
1080: {
1081: gtk_widget_hide(ui_win_console);
1082: }
1083:
1084: void ui_gtk_play(void)
1085: {
1086: if (ui_running) {
1087: ui_gtk_dialog("Generator is already playing a ROM");
1088: return;
1089: }
1090: if (cpu68k_rom == NULL || cpu68k_romlen == 0) {
1091: ui_gtk_dialog("You must load a ROM into Generator");
1092: return;
1093: }
1094: /* start running the game */
1095: ui_running = 1;
1096: ui_gtk_sizechange();
1.1.1.2 ! root 1097: if (gtk_main_level() > 0)
! 1098: gtk_main_quit();
1.1 root 1099: }
1100:
1101: void ui_gtk_pause(void)
1102: {
1103: if (!ui_running) {
1104: ui_gtk_dialog("Generator is not playing a ROM");
1105: return;
1106: }
1107: ui_running = 0;
1108: }
1109:
1110: void ui_gtk_softreset(void)
1111: {
1112: gen_softreset();
1113: }
1114:
1115: void ui_gtk_hardreset(void)
1116: {
1117: gen_reset();
1118: }
1119:
1120: /* set main window size from current parameters */
1121:
1122: void ui_gtk_sizechange(void)
1123: {
1124: GtkWidget *w;
1125:
1126: w = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_main),
1127: "drawingarea_main"));
1128: switch (ui_screenmode) {
1129: case SCREEN_100:
1130: gtk_widget_set_usize(w, HSIZE, VSIZE);
1131: screen = SDL_SetVideoMode(HSIZE, VSIZE, 0, 0);
1132: break;
1133: case SCREEN_200:
1134: gtk_widget_set_usize(w, HSIZE * 2, VSIZE * 2);
1135: screen = SDL_SetVideoMode(HSIZE * 2, VSIZE * 2, 0, 0);
1136: break;
1137: default:
1138: ui_err("invalid screen mode\n");
1139: }
1140: w = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_main), "hbox_bottom"));
1141: if (ui_statusbar)
1142: gtk_widget_show(w);
1143: else
1144: gtk_widget_hide(w);
1145: ui_locksurface = SDL_MUSTLOCK(screen);
1146: uiplot_setshifts(ui_topbit(screen->format->Rmask) - 4,
1147: ui_topbit(screen->format->Gmask) - 4,
1148: ui_topbit(screen->format->Bmask) - 4);
1149: }
1150:
1151: void ui_gtk_newoptions(void)
1152: {
1153: char buf[32];
1154: const char *v;
1155: int i, c;
1156: unsigned int old_ui_screenmode = ui_screenmode;
1157: unsigned int old_sound_minfields = sound_minfields;
1158: unsigned int old_sound_maxfields = sound_maxfields;
1159: unsigned int old_ui_hborder = ui_hborder;
1160: unsigned int old_ui_vborder = ui_vborder;
1161: unsigned int old_ui_statusbar = ui_statusbar;
1162:
1163: i = atoi(gtkopts_getvalue("view"));
1164: ui_screenmode = (i == 200) ? SCREEN_200 : SCREEN_100;
1165:
1166: v = gtkopts_getvalue("region");
1167: vdp_overseas = !strcasecmp(v, "overseas");
1168:
1169: v = gtkopts_getvalue("videostd");
1170: vdp_pal = !strcasecmp(v, "pal");
1171:
1172: v = gtkopts_getvalue("autodetect");
1173: gen_autodetect = !strcasecmp(v, "on");
1174:
1175: v = gtkopts_getvalue("plotter");
1176: ui_vdpsimple = !strcasecmp(v, "cell");
1177:
1178: v = gtkopts_getvalue("interlace");
1179: if (!strcasecmp(v, "weave"))
1180: ui_interlace = DEINTERLACE_WEAVE;
1181: else if (!strcasecmp(v, "weave-filter"))
1182: ui_interlace = DEINTERLACE_WEAVEFILTER;
1183: else
1184: ui_interlace = DEINTERLACE_BOB;
1185:
1186: v = gtkopts_getvalue("frameskip");
1187: if (!strcasecmp(v, "auto")) {
1188: ui_frameskip = 0;
1189: } else {
1190: ui_frameskip = atoi(v);
1191: }
1192:
1193: v = gtkopts_getvalue("hborder");
1194: ui_hborder = atoi(v);
1195: if (ui_hborder > HBORDER_MAX)
1196: ui_hborder = HBORDER_MAX;
1197:
1198: v = gtkopts_getvalue("vborder");
1199: ui_vborder = atoi(v);
1200: if (ui_vborder > VBORDER_MAX)
1201: ui_vborder = VBORDER_MAX;
1202:
1203: v = gtkopts_getvalue("z80");
1204: cpuz80_on = !strcasecmp(v, "on");
1205:
1206: v = gtkopts_getvalue("sound");
1207: sound_on = !strcasecmp(v, "on");
1208:
1209: v = gtkopts_getvalue("fm");
1210: sound_fm = !strcasecmp(v, "on");
1211:
1212: v = gtkopts_getvalue("psg");
1213: sound_psg = !strcasecmp(v, "on");
1214:
1215: v = gtkopts_getvalue("sound_minfields");
1216: sound_minfields = atoi(v);
1217:
1218: v = gtkopts_getvalue("sound_maxfields");
1219: sound_maxfields = atoi(v);
1220:
1.1.1.2 ! root 1221: v = gtkopts_getvalue("lowpassfilter");
! 1222: sound_filter = atoi(v);
! 1223:
1.1 root 1224: v = gtkopts_getvalue("loglevel");
1225: gen_loglevel = atoi(v);
1226:
1227: v = gtkopts_getvalue("statusbar");
1228: ui_statusbar = !strcasecmp(v, "on");
1229:
1230: for (c = 0; c < 2; c++) {
1231: snprintf(buf, sizeof(buf), "key%d_a", c + 1);
1232: v = gtkopts_getvalue(buf);
1233: ui_cont[c].a = gdk_keyval_from_name(v);
1234: snprintf(buf, sizeof(buf), "key%d_b", c + 1);
1235: v = gtkopts_getvalue(buf);
1236: ui_cont[c].b = gdk_keyval_from_name(v);
1237: snprintf(buf, sizeof(buf), "key%d_c", c + 1);
1238: v = gtkopts_getvalue(buf);
1239: ui_cont[c].c = gdk_keyval_from_name(v);
1240: snprintf(buf, sizeof(buf), "key%d_up", c + 1);
1241: v = gtkopts_getvalue(buf);
1242: ui_cont[c].up = gdk_keyval_from_name(v);
1243: snprintf(buf, sizeof(buf), "key%d_down", c + 1);
1244: v = gtkopts_getvalue(buf);
1245: ui_cont[c].down = gdk_keyval_from_name(v);
1246: snprintf(buf, sizeof(buf), "key%d_left", c + 1);
1247: v = gtkopts_getvalue(buf);
1248: ui_cont[c].left = gdk_keyval_from_name(v);
1249: snprintf(buf, sizeof(buf), "key%d_right", c + 1);
1250: v = gtkopts_getvalue(buf);
1251: ui_cont[c].right = gdk_keyval_from_name(v);
1252: snprintf(buf, sizeof(buf), "key%d_start", c + 1);
1253: v = gtkopts_getvalue(buf);
1254: ui_cont[c].start = gdk_keyval_from_name(v);
1255: }
1256: if (ui_screenmode != old_ui_screenmode ||
1257: ui_hborder != old_ui_hborder ||
1258: ui_vborder != old_ui_vborder || ui_statusbar != old_ui_statusbar)
1259: ui_gtk_sizechange();
1260:
1261: if (sound_minfields != old_sound_minfields ||
1262: sound_maxfields != old_sound_maxfields) {
1263: sound_reset();
1264: }
1265: }
1266:
1267: static void ui_gtk_opts_from_window(void)
1268: {
1269: GtkWidget *obj, *active;
1270: char buf[64];
1271: int c;
1272: const char *v;
1273: const char **key;
1274:
1275: /* hardware - region */
1276:
1277: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1278: "radiobutton_domestic"));
1279: if (GTK_TOGGLE_BUTTON(obj)->active)
1280: gtkopts_setvalue("region", "domestic");
1281: else
1282: gtkopts_setvalue("region", "overseas");
1283:
1284: /* hardware - video standard */
1285:
1286: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1287: "radiobutton_pal"));
1288: if (GTK_TOGGLE_BUTTON(obj)->active)
1289: gtkopts_setvalue("videostd", "pal");
1290: else
1291: gtkopts_setvalue("videostd", "ntsc");
1292:
1293: /* hardware - auto detect */
1294:
1295: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1296: "checkbutton_autodetect"));
1297: if (GTK_TOGGLE_BUTTON(obj)->active)
1298: gtkopts_setvalue("autodetect", "on");
1299: else
1300: gtkopts_setvalue("autodetect", "off");
1301:
1302: /* video - plotter */
1303:
1304: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1305: "radiobutton_line"));
1306: if (GTK_TOGGLE_BUTTON(obj)->active)
1307: gtkopts_setvalue("plotter", "line");
1308: else
1309: gtkopts_setvalue("plotter", "cell");
1310:
1311: /* video - interlace mode */
1312:
1313: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1314: "optionmenu_interlace"));
1315: /* now get active widget on menu */
1316: obj = GTK_BIN(GTK_OPTION_MENU(obj))->child;
1317: gtkopts_setvalue("interlace", GTK_LABEL(obj)->label);
1318:
1319: /* video - frame skip */
1320:
1321: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1322: "checkbutton_auto"));
1323: if (GTK_TOGGLE_BUTTON(obj)->active) {
1324: gtkopts_setvalue("frameskip", "auto");
1325: } else {
1326: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1327: "hscale_skip"));
1328: snprintf(buf, sizeof(buf), "%d",
1329: (int)(gtk_range_get_adjustment(GTK_RANGE(obj))->value));
1330: gtkopts_setvalue("frameskip", buf);
1331: }
1332:
1333: /* video - hborder */
1334:
1335: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1336: "spinbutton_hborder"));
1337: snprintf(buf, sizeof(buf), "%d",
1338: gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(obj)));
1339: gtkopts_setvalue("hborder", buf);
1340:
1341: /* video - vborder */
1342:
1343: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1344: "spinbutton_vborder"));
1345: snprintf(buf, sizeof(buf), "%d",
1346: gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(obj)));
1347: gtkopts_setvalue("vborder", buf);
1348:
1349: /* sound - z80 */
1350:
1351: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1352: "checkbutton_z80"));
1353: if (GTK_TOGGLE_BUTTON(obj)->active)
1354: gtkopts_setvalue("z80", "on");
1355: else
1356: gtkopts_setvalue("z80", "off");
1357:
1358: /* sound - on/off */
1359:
1360: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1361: "checkbutton_sound"));
1362: if (GTK_TOGGLE_BUTTON(obj)->active)
1363: gtkopts_setvalue("sound", "on");
1364: else
1365: gtkopts_setvalue("sound", "off");
1366:
1367: /* sound - psg */
1368:
1369: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1370: "checkbutton_psg"));
1371: if (GTK_TOGGLE_BUTTON(obj)->active)
1372: gtkopts_setvalue("psg", "on");
1373: else
1374: gtkopts_setvalue("psg", "off");
1375:
1376: /* sound - fm */
1377:
1378: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1379: "checkbutton_fm"));
1380: if (GTK_TOGGLE_BUTTON(obj)->active)
1381: gtkopts_setvalue("fm", "on");
1382: else
1383: gtkopts_setvalue("fm", "off");
1384:
1385: /* sound - min fields */
1386:
1387: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1388: "spinbutton_minfields"));
1389: snprintf(buf, sizeof(buf), "%d",
1390: gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(obj)));
1391: gtkopts_setvalue("sound_minfields", buf);
1392:
1.1.1.2 ! root 1393: /* sound - max fields */
1.1 root 1394:
1395: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1396: "spinbutton_maxfields"));
1397: snprintf(buf, sizeof(buf), "%d",
1398: gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(obj)));
1399: gtkopts_setvalue("sound_maxfields", buf);
1400:
1.1.1.2 ! root 1401: /* sound - filter */
! 1402:
! 1403: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
! 1404: "spinbutton_filter"));
! 1405: snprintf(buf, sizeof(buf), "%d",
! 1406: gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(obj)));
! 1407: gtkopts_setvalue("lowpassfilter", buf);
! 1408:
! 1409: /* logging - verbosity */
1.1 root 1410:
1411: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1412: "optionmenu_level"));
1413: obj = GTK_OPTION_MENU(obj)->menu;
1414: /* now get active widget on menu */
1415: active = gtk_menu_get_active(GTK_MENU(obj));
1416: snprintf(buf, sizeof(buf), "%d",
1417: g_list_index(GTK_MENU_SHELL(obj)->children, active));
1418: gtkopts_setvalue("loglevel", buf);
1419:
1.1.1.2 ! root 1420: /* logging - sound */
1.1 root 1421:
1422: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1423: "checkbutton_debugsound"));
1424: if (GTK_TOGGLE_BUTTON(obj)->active)
1425: gtkopts_setvalue("debugsound", "on");
1426: else
1427: gtkopts_setvalue("debugsound", "off");
1428:
1.1.1.2 ! root 1429: /* logging - status bar */
! 1430:
1.1 root 1431: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1432: "checkbutton_statusbar"));
1433: if (GTK_TOGGLE_BUTTON(obj)->active)
1434: gtkopts_setvalue("statusbar", "on");
1435: else
1436: gtkopts_setvalue("statusbar", "off");
1437:
1.1.1.2 ! root 1438: /* logging - avi format */
! 1439:
! 1440: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
! 1441: "optionmenu_aviformat"));
! 1442: /* now get active widget on menu */
! 1443: obj = GTK_BIN(GTK_OPTION_MENU(obj))->child;
! 1444: gtkopts_setvalue("aviformat", GTK_LABEL(obj)->label);
! 1445:
! 1446: /* logging - avi frame skip */
! 1447:
! 1448: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
! 1449: "hscale_avi"));
! 1450: snprintf(buf, sizeof(buf), "%d",
! 1451: (int)(gtk_range_get_adjustment(GTK_RANGE(obj))->value));
! 1452: gtkopts_setvalue("aviframeskip", buf);
! 1453:
! 1454: /* logging - jpeg quality */
! 1455:
! 1456: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
! 1457: "spinbutton_jpegquality"));
! 1458: snprintf(buf, sizeof(buf), "%d",
! 1459: gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(obj)));
! 1460: gtkopts_setvalue("jpegquality", buf);
! 1461:
1.1 root 1462: /* controls */
1463:
1464: for (c = 1; c <= 2; c++) {
1465: for (key = ui_gtk_keys;
1466: (char *)key < ((char *)ui_gtk_keys + sizeof(ui_gtk_keys));
1467: key++) {
1468: snprintf(buf, sizeof(buf), "entry_player%d_%s", c, *key);
1469: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts), buf));
1470: v = gtk_entry_get_text(GTK_ENTRY(obj));
1471: snprintf(buf, sizeof(buf), "key%d_%s", c, *key);
1472: gtkopts_setvalue(buf, v);
1473: }
1474: }
1475: }
1476:
1477: static void ui_gtk_opts_to_window(void)
1478: {
1479: GtkWidget *obj;
1480: const char *v;
1481: const char **key;
1482: int i, c;
1483: char buf[32];
1484:
1485: /* hardware - region */
1486:
1487: v = gtkopts_getvalue("region");
1488: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1489: "radiobutton_domestic"));
1490: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obj),
1491: !strcasecmp(v, "domestic"));
1492: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1493: "radiobutton_overseas"));
1494: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obj),
1495: !strcasecmp(v, "overseas"));
1496:
1497: /* hardware - video standard */
1498:
1499: v = gtkopts_getvalue("videostd");
1500: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1501: "radiobutton_pal"));
1502: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obj), !strcasecmp(v, "pal"));
1503: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1504: "radiobutton_ntsc"));
1505: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obj),
1506: !strcasecmp(v, "ntsc"));
1507:
1508: /* hardware - auto detect */
1509:
1510: v = gtkopts_getvalue("autodetect");
1511: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1512: "checkbutton_autodetect"));
1513: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obj), !strcasecmp(v, "on"));
1514:
1515: /* video - plotter */
1516:
1517: v = gtkopts_getvalue("plotter");
1518: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1519: "radiobutton_line"));
1520: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obj),
1521: !strcasecmp(v, "line"));
1522: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1523: "radiobutton_cell"));
1524: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obj),
1525: !strcasecmp(v, "cell"));
1526:
1527: /* video - interlace mode */
1528:
1529: v = gtkopts_getvalue("interlace");
1530: if (!strcasecmp(v, "bob")) {
1531: i = 0;
1532: } else if (!strcasecmp(v, "weave")) {
1533: i = 1;
1534: } else {
1535: i = 2;
1536: }
1537: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1538: "optionmenu_interlace"));
1539: gtk_option_menu_set_history(GTK_OPTION_MENU(obj), i);
1540:
1541: /* video - frame skip */
1542:
1543: v = gtkopts_getvalue("frameskip");
1544: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1545: "checkbutton_auto"));
1546: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obj),
1547: !strcasecmp(v, "auto"));
1548: i = atoi(v);
1549: if (i < 1)
1550: i = 1;
1551: if (i > 10)
1552: i = 10;
1553: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1554: "hscale_skip"));
1555: gtk_adjustment_set_value(gtk_range_get_adjustment(GTK_RANGE(obj)), i);
1556:
1557: /* video - hborder */
1558:
1559: v = gtkopts_getvalue("hborder");
1560: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1561: "spinbutton_hborder"));
1562: i = atoi(v);
1563: if (i < 0)
1564: i = 0;
1565: if (i > HBORDER_MAX)
1566: i = HBORDER_MAX;
1567: gtk_spin_button_set_value(GTK_SPIN_BUTTON(obj), i);
1568:
1569: /* video - vborder */
1570:
1571: v = gtkopts_getvalue("vborder");
1572: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1573: "spinbutton_vborder"));
1574: i = atoi(v);
1575: if (i < 0)
1576: i = 0;
1577: if (i > VBORDER_MAX)
1578: i = VBORDER_MAX;
1579: gtk_spin_button_set_value(GTK_SPIN_BUTTON(obj), i);
1580:
1581: /* sound - z80 */
1582:
1583: v = gtkopts_getvalue("z80");
1584: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1585: "checkbutton_z80"));
1586: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obj), !strcasecmp(v, "on"));
1587:
1588: /* sound - on/off */
1589:
1590: v = gtkopts_getvalue("sound");
1591: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1592: "checkbutton_sound"));
1593: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obj), !strcasecmp(v, "on"));
1594:
1595: /* sound - psg */
1596:
1597: v = gtkopts_getvalue("psg");
1598: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1599: "checkbutton_psg"));
1600: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obj), !strcasecmp(v, "on"));
1601:
1602: /* sound - fm */
1603:
1604: v = gtkopts_getvalue("fm");
1605: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1606: "checkbutton_fm"));
1607: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obj), !strcasecmp(v, "on"));
1608:
1609: /* sound - min fields */
1610:
1611: v = gtkopts_getvalue("sound_minfields");
1612: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1613: "spinbutton_minfields"));
1614: i = atoi(v);
1615: if (i < 1)
1616: i = 1;
1617: gtk_spin_button_set_value(GTK_SPIN_BUTTON(obj), i);
1618:
1619: /* sound - max fields */
1620:
1621: v = gtkopts_getvalue("sound_maxfields");
1622: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1623: "spinbutton_maxfields"));
1624: i = atoi(v);
1625: if (i < 1)
1626: i = 1;
1627: gtk_spin_button_set_value(GTK_SPIN_BUTTON(obj), i);
1628:
1.1.1.2 ! root 1629: /* sound - filter */
! 1630:
! 1631: v = gtkopts_getvalue("lowpassfilter");
! 1632: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
! 1633: "spinbutton_filter"));
! 1634: i = atoi(v);
! 1635: if (i < 1)
! 1636: i = 1;
! 1637: gtk_spin_button_set_value(GTK_SPIN_BUTTON(obj), i);
! 1638:
! 1639: /* logging - verbosity */
1.1 root 1640:
1641: v = gtkopts_getvalue("loglevel");
1642: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1643: "optionmenu_level"));
1644: i = atoi(v);
1645: gtk_option_menu_set_history(GTK_OPTION_MENU(obj), i);
1646:
1.1.1.2 ! root 1647: /* logging - sound */
1.1 root 1648:
1649: v = gtkopts_getvalue("debugsound");
1650: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1651: "checkbutton_debugsound"));
1652: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obj), !strcasecmp(v, "on"));
1653:
1.1.1.2 ! root 1654: /* logging - status bar */
1.1 root 1655:
1656: v = gtkopts_getvalue("statusbar");
1657: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
1658: "checkbutton_statusbar"));
1659: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obj), !strcasecmp(v, "on"));
1660:
1.1.1.2 ! root 1661: /* logging - avi format */
! 1662:
! 1663: v = gtkopts_getvalue("aviformat");
! 1664: if (!strcasecmp(v, "rgb")) {
! 1665: i = 0;
! 1666: } else {
! 1667: i = 1;
! 1668: }
! 1669: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
! 1670: "optionmenu_aviformat"));
! 1671: gtk_option_menu_set_history(GTK_OPTION_MENU(obj), i);
! 1672:
! 1673: /* logging - avi frame skip */
! 1674:
! 1675: i = atoi(gtkopts_getvalue("aviframeskip"));
! 1676: if (i < 1)
! 1677: i = 1;
! 1678: if (i > 10)
! 1679: i = 10;
! 1680: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
! 1681: "hscale_avi"));
! 1682: gtk_adjustment_set_value(gtk_range_get_adjustment(GTK_RANGE(obj)), i);
! 1683:
! 1684: /* logging - jpeg quality */
! 1685:
! 1686: v = gtkopts_getvalue("jpegquality");
! 1687: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts),
! 1688: "spinbutton_jpegquality"));
! 1689: i = atoi(v);
! 1690: if (i < 1)
! 1691: i = 1;
! 1692: gtk_spin_button_set_value(GTK_SPIN_BUTTON(obj), i);
! 1693:
1.1 root 1694: /* controls */
1695:
1696: for (c = 1; c <= 2; c++) {
1697: for (key = ui_gtk_keys;
1698: (char *)key < ((char *)ui_gtk_keys + sizeof(ui_gtk_keys));
1699: key++) {
1700: snprintf(buf, sizeof(buf), "key%d_%s", c, *key);
1701: v = gtkopts_getvalue(buf);
1702: i = gdk_keyval_from_name(v);
1703: if (i) {
1704: v = gdk_keyval_name(i); /* just incase case is different etc. */
1705: } else {
1706: v = "";
1707: }
1708: snprintf(buf, sizeof(buf), "entry_player%d_%s", c, *key);
1709: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_opts), buf));
1710: gtk_entry_set_text(GTK_ENTRY(obj), v);
1711: }
1712: }
1713: }
1714:
1715: void ui_gtk_applyoptions(void)
1716: {
1717: ui_gtk_opts_from_window();
1718: gtk_widget_hide(ui_win_opts);
1719: ui_gtk_newoptions();
1720: ui_gtk_opts_to_menu();
1721: }
1722:
1723: void ui_gtk_saveoptions(void)
1724: {
1725: char buf[256];
1726:
1727: ui_gtk_opts_from_window();
1728: if (gtkopts_save(ui_configfile) != 0) {
1729: snprintf(buf, sizeof(buf), "Failed to save configuration to '%s': %s",
1730: ui_configfile, strerror(errno));
1731: ui_gtk_dialog(buf);
1732: return;
1733: }
1734: gtk_widget_hide(ui_win_opts);
1735: ui_gtk_newoptions();
1736: ui_gtk_opts_to_menu();
1737: }
1738:
1739: void ui_gtk_redraw(void)
1740: {
1741: SDL_UpdateRect(screen, 0, 0, screen->w, screen->h);
1742: }
1743:
1744: void ui_gtk_key(unsigned long key, int press)
1745: {
1746: t_gtkkeys *cont;
1747: int c;
1748:
1749: for (c = 0; c < 2; c++) {
1750: cont = &ui_cont[c];
1751: if (key == cont->a) {
1752: mem68k_cont[c].a = press;
1753: } else if (key == cont->b) {
1754: mem68k_cont[c].b = press;
1755: } else if (key == cont->c) {
1756: mem68k_cont[c].c = press;
1757: } else if (key == cont->left) {
1758: mem68k_cont[c].left = press;
1759: } else if (key == cont->right) {
1760: mem68k_cont[c].right = press;
1761: } else if (key == cont->up) {
1762: mem68k_cont[c].up = press;
1763: } else if (key == cont->down) {
1764: mem68k_cont[c].down = press;
1765: } else if (key == cont->start) {
1766: mem68k_cont[c].start = press;
1767: }
1768: }
1769: }
1770:
1.1.1.2 ! root 1771: static void ui_sdl_events (void)
! 1772: {
! 1773: SDL_Event event;
! 1774: #define LEFT(event) ((event.jaxis.value < -16384) ? 1 : 0)
! 1775: #define RIGHT(event) ((event.jaxis.value > 16384) ? 1 : 0)
! 1776: #define UP(event) ((event.jaxis.value < -16384) ? 1 : 0)
! 1777: #define DOWN(event) ((event.jaxis.value > 16384) ? 1 : 0)
! 1778: #define PRESS(event) ((event.type == SDL_JOYBUTTONDOWN) ? 1 : 0)
! 1779:
! 1780: while (SDL_PollEvent(&event)) {
! 1781: switch (event.type) {
! 1782: case SDL_JOYAXISMOTION:
! 1783: if (event.jaxis.which > 1)
! 1784: break;
! 1785: switch (event.jaxis.axis) {
! 1786: case 0: /* left & right */
! 1787: mem68k_cont[event.jaxis.which].left = LEFT(event);
! 1788: mem68k_cont[event.jaxis.which].right = RIGHT(event);
! 1789: break;
! 1790: case 1: /* up & down */
! 1791: mem68k_cont[event.jaxis.which].up = UP(event);
! 1792: mem68k_cont[event.jaxis.which].down = DOWN(event);
! 1793: break;
! 1794: default:
! 1795: break;
! 1796: }
! 1797: break;
! 1798: case SDL_JOYBUTTONDOWN:
! 1799: case SDL_JOYBUTTONUP:
! 1800: if (event.jbutton.which > 1)
! 1801: break;
! 1802: switch (event.jbutton.button) {
! 1803: case 0:
! 1804: mem68k_cont[event.jbutton.which].a = PRESS(event);
! 1805: break;
! 1806: case 1:
! 1807: mem68k_cont[event.jbutton.which].b = PRESS(event);
! 1808: break;
! 1809: case 2:
! 1810: mem68k_cont[event.jbutton.which].c = PRESS(event);
! 1811: break;
! 1812: case 3:
! 1813: mem68k_cont[event.jbutton.which].start = PRESS(event);
! 1814: break;
! 1815: default:
! 1816: break;
! 1817: }
! 1818: break;
! 1819: default:
! 1820: break;
! 1821: }
! 1822: }
! 1823: }
! 1824:
1.1 root 1825: void ui_gtk_mainenter(void)
1826: {
1827: /* clear out current state */
1828: memset(mem68k_cont, 0, sizeof(mem68k_cont));
1.1.1.2 ! root 1829: gdk_key_repeat_disable();
1.1 root 1830: }
1831:
1832: void ui_gtk_mainleave(void)
1833: {
1.1.1.2 ! root 1834: gdk_key_repeat_restore();
1.1 root 1835: }
1836:
1837: static void ui_gtk_opts_to_menu(void)
1838: {
1839: GtkWidget *obj;
1840: const char *v;
1841:
1842: /* view */
1843:
1844: v = gtkopts_getvalue("view");
1845: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_main), "_100"));
1846: gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(obj),
1847: !strcasecmp(v, "100"));
1848: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_main), "_200"));
1849: gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(obj),
1850: !strcasecmp(v, "200"));
1851: }
1852:
1853: void ui_musiclog(uint8 *data, unsigned int length)
1854: {
1855: if (ui_musicfile != -1)
1856: write(ui_musicfile, data, length);
1857: }
1858:
1859: void ui_gtk_closemusiclog(void)
1860: {
1861: if (ui_musicfile == -1) {
1862: ui_gtk_dialog("There is no log to close");
1863: return;
1864: }
1865: close(ui_musicfile);
1866: ui_musicfile = -1;
1867: gen_musiclog = 0;
1868: }
1.1.1.2 ! root 1869:
! 1870: static void ui_gtk_codes_to_window(void)
! 1871: {
! 1872: GtkWidget *obj;
! 1873: t_patchlist *ent;
! 1874: char *data[2];
! 1875:
! 1876: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_codes),
! 1877: "clist_codes"));
! 1878: gtk_clist_clear(GTK_CLIST(obj));
! 1879: for (ent = patch_patchlist; ent; ent = ent->next) {
! 1880: data[0] = ent->code;
! 1881: data[1] = ent->action;
! 1882: gtk_clist_append(GTK_CLIST(obj), data);
! 1883: }
! 1884: }
! 1885:
! 1886: void ui_gtk_codes(void)
! 1887: {
! 1888: ui_gtk_codes_to_window();
! 1889: gtk_widget_show(ui_win_codes);
! 1890: }
! 1891:
! 1892: void ui_gtk_codes_add(void)
! 1893: {
! 1894: GtkWidget *obj;
! 1895: char *data[2];
! 1896: char *code, *action;
! 1897:
! 1898: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_codes),
! 1899: "entry_code"));
! 1900: code = gtk_entry_get_text(GTK_ENTRY(obj));
! 1901: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_codes),
! 1902: "entry_action"));
! 1903: action = gtk_entry_get_text(GTK_ENTRY(obj));
! 1904: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_codes),
! 1905: "clist_codes"));
! 1906: data[0] = (char *)code;
! 1907: data[1] = (char *)action;
! 1908: gtk_clist_append(GTK_CLIST(obj), data);
! 1909: }
! 1910:
! 1911: void ui_gtk_codes_delete(void)
! 1912: {
! 1913: GtkWidget *obj;
! 1914: GList *slist;
! 1915:
! 1916: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_codes),
! 1917: "clist_codes"));
! 1918: while ((slist = GTK_CLIST(obj)->selection) != NULL) {
! 1919: gtk_clist_remove(GTK_CLIST(obj), (int)slist->data);
! 1920: }
! 1921: }
! 1922:
! 1923: void ui_gtk_codes_deleteall(void)
! 1924: {
! 1925: GtkWidget *obj;
! 1926:
! 1927: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_codes),
! 1928: "clist_codes"));
! 1929: gtk_clist_clear(GTK_CLIST(obj));
! 1930: }
! 1931:
! 1932: void ui_gtk_codes_clearsel(void)
! 1933: {
! 1934: GtkWidget *obj;
! 1935:
! 1936: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_codes),
! 1937: "clist_codes"));
! 1938: gtk_clist_unselect_all(GTK_CLIST(obj));
! 1939: }
! 1940:
! 1941: void ui_gtk_codes_ok(void)
! 1942: {
! 1943: GtkWidget *obj;
! 1944: int i;
! 1945: char *code, *action;
! 1946:
! 1947: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_codes),
! 1948: "clist_codes"));
! 1949: patch_clearlist();
! 1950: for (i = 0;; i++) {
! 1951: if (gtk_clist_get_text(GTK_CLIST(obj), i, 0, &code) != 1 ||
! 1952: gtk_clist_get_text(GTK_CLIST(obj), i, 1, &action) != 1)
! 1953: break;
! 1954: patch_addcode(code, action);
! 1955: }
! 1956: gtk_widget_hide(ui_win_codes);
! 1957: }
! 1958:
! 1959: void ui_gtk_codes_apply(void)
! 1960: {
! 1961: GtkWidget *obj;
! 1962: GList *slist;
! 1963: char *code, *action;
! 1964: int failed = 0;
! 1965:
! 1966: obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(ui_win_codes),
! 1967: "clist_codes"));
! 1968: slist = GTK_CLIST(obj)->selection;
! 1969: for (; slist; slist = slist->next) {
! 1970: if (gtk_clist_get_text(GTK_CLIST(obj), (int)slist->data, 0, &code) != 1 ||
! 1971: gtk_clist_get_text(GTK_CLIST(obj), (int)slist->data, 1, &action) != 1) {
! 1972: failed = 1;
! 1973: break;
! 1974: }
! 1975: if (patch_apply(code, action) != 0)
! 1976: failed = 1;
! 1977: }
! 1978: if (failed)
! 1979: ui_gtk_dialog("Unable to apply one or more cheats (either invalid cheat "
! 1980: "code or out of bounds for currently loaded ROM)");
! 1981: cpu68k_clearcache();
! 1982: }
! 1983:
! 1984: void ui_gtk_closeavi(void)
! 1985: {
! 1986: if (ui_avi == NULL) {
! 1987: ui_gtk_dialog("There is no avi to close");
! 1988: return;
! 1989: }
! 1990: if (avi_close(ui_avi) != 0) {
! 1991: ui_gtk_dialog(strerror(errno));
! 1992: return;
! 1993: }
! 1994: free(ui_avivideo);
! 1995: free(ui_aviaudio);
! 1996: ui_avi = NULL;
! 1997: ui_avivideo = NULL;
! 1998: ui_aviaudio = NULL;
! 1999: ui_gtk_newoptions(); /* restore ui_frameskip */
! 2000: }
! 2001:
! 2002: GtkWidget *ui_gtk_newdiss(unsigned int type)
! 2003: {
! 2004: GtkWidget *disswin, *obj;
! 2005: GtkStyle *style;
! 2006: unsigned int i;
! 2007: GtkWidget **dw;
! 2008:
! 2009: disswin = create_diss();
! 2010: gtk_object_set_data(GTK_OBJECT(disswin), "generator_diss_type",
! 2011: GINT_TO_POINTER(type));
! 2012: gtk_object_set_data(GTK_OBJECT(disswin), "generator_diss_offset",
! 2013: GINT_TO_POINTER(0));
! 2014:
! 2015: /* store in our list */
! 2016: dw = ui_disswins;
! 2017: for (i = 0; i < DISSWIN_MAX; i++, dw++) {
! 2018: if (*dw == NULL) {
! 2019: *dw = disswin;
! 2020: break;
! 2021: }
! 2022: }
! 2023: if (i == DISSWIN_MAX) {
! 2024: ui_gtk_dialog("Too many disassembly windows!");
! 2025: gtk_widget_destroy(disswin);
! 2026: return NULL;
! 2027: }
! 2028: return disswin;
! 2029: }
! 2030:
! 2031: int ui_gtk_destroydiss(GtkWidget *disswin)
! 2032: {
! 2033: unsigned int i;
! 2034: GtkWidget **dw;
! 2035:
! 2036: dw = ui_disswins;
! 2037: for (i = 0; i < DISSWIN_MAX; i++, dw++) {
! 2038: if (*dw == disswin) {
! 2039: gtk_widget_destroy(disswin);
! 2040: *dw = NULL;
! 2041: return 0;
! 2042: }
! 2043: }
! 2044: return -1;
! 2045: }
! 2046:
! 2047: //{
! 2048: // GtkWidget *adj, *scrollbar;
! 2049: //
! 2050: // scrollbar = lookup_widget(disswin, "vscrollbar_diss");
! 2051: // adj = gtk_range_get_adjustment(GTK_RANGE(scrollbar));
! 2052: //}
! 2053: //scrollbar = lookup_widget(disswin, "vscrollbar_diss");
! 2054: //gtk_signal_connect(GTK_OBJECT(GTK_RANGE(scrollbar)->adjustment),
! 2055: // "changed", GTK_SIGNAL_FUNC(on_adjustment_changed), NULL);
! 2056:
! 2057: void ui_gtk_redrawdiss(GtkWidget *canvas, GdkEventExpose *event)
! 2058: {
! 2059: GdkRectangle *rect = &event->area;
! 2060: GtkWidget *obj, *disswin;
! 2061: signed int yoff = -2;
! 2062: signed int y;
! 2063: unsigned int y_start, y_end, fontheight, i;
! 2064: uint8 *mem_where;
! 2065: uint32 mem_start;
! 2066: uint32 mem_len;
! 2067: uint32 type, offset;
! 2068: char dumpline[256];
! 2069: char *p;
! 2070: int words;
! 2071:
! 2072: disswin = gtk_widget_get_toplevel(canvas);
! 2073: offset = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(disswin),
! 2074: "generator_diss_offset"));
! 2075: type = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(disswin),
! 2076: "generator_diss_type"));
! 2077: switch (type) {
! 2078: case 0:
! 2079: mem_where = cpu68k_rom;
! 2080: mem_start = 0;
! 2081: mem_len = cpu68k_romlen;
! 2082: break;
! 2083: case 1:
! 2084: mem_where = cpu68k_ram;
! 2085: mem_start = 0xFF0000;
! 2086: mem_len = 0x10000;
! 2087: break;
! 2088: case 2:
! 2089: mem_where = vdp_vram;
! 2090: mem_start = 0x0;
! 2091: mem_len = LEN_VRAM;
! 2092: break;
! 2093: case 3:
! 2094: mem_where = vdp_cram;
! 2095: mem_start = 0x0;
! 2096: mem_len = LEN_CRAM;
! 2097: break;
! 2098: case 4:
! 2099: mem_where = vdp_vsram;
! 2100: mem_start = 0x0;
! 2101: mem_len = LEN_VSRAM;
! 2102: break;
! 2103: case 5:
! 2104: mem_where = cpuz80_ram;
! 2105: mem_start = 0x0;
! 2106: mem_len = LEN_SRAM;
! 2107: break;
! 2108: default:
! 2109: return;
! 2110: }
! 2111:
! 2112: fontheight = ui_dissfont->ascent + ui_dissfont->descent;
! 2113: if ((y = rect->y - yoff) < 0)
! 2114: y = 0;
! 2115: y_start = y / fontheight;
! 2116: y_end = (y + rect->height) / fontheight;
! 2117: offset+= y_start * 2;
! 2118: for (i = y_start; i <= y_end; i++) {
! 2119: printf("offset=%X\n", offset);
! 2120: p = dumpline;
! 2121: *p++ = '>';
! 2122: *p++ = ' ';
! 2123: if (offset >= mem_len) {
! 2124: } else {
! 2125: words = diss68k_getdumpline(mem_start + offset, mem_where + offset, p);
! 2126: offset+= words * 2;
! 2127: }
! 2128: gdk_draw_rectangle(canvas->window,
! 2129: canvas->style->bg_gc[GTK_WIDGET_STATE(canvas)],
! 2130: TRUE, 0, i * fontheight + yoff,
! 2131: 4096, fontheight);
! 2132: gdk_draw_text(canvas->window, ui_dissfont,
! 2133: canvas->style->fg_gc[GTK_WIDGET_STATE(canvas)],
! 2134: 2, i * fontheight + yoff + fontheight, dumpline,
! 2135: strlen(dumpline));
! 2136: }
! 2137: /*
! 2138: printf("x = %d\ny = %d\nwidth = %d\nheight = %d\noff=%f\n\n", rect->x,
! 2139: rect->y, rect->width, rect->height, adj->value);
! 2140: */
! 2141:
! 2142:
! 2143: }
! 2144:
! 2145: //void ui_gtk_redrawdiss(GtkWidget *canvas, GdkEventExpose *event)
! 2146: //{
! 2147: // GdkRectangle *rect = &event->area;
! 2148: // GtkWidget *obj, *disswin;
! 2149: // GtkAdjustment *adj;
! 2150: // signed int y, ypos;
! 2151: // unsigned int y_start, y_end, fontheight, i;
! 2152: //
! 2153: // disswin = gtk_widget_get_toplevel(canvas);
! 2154: // obj = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(disswin),
! 2155: // "scrolledwindow_diss"));
! 2156: // adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(obj));
! 2157: //
! 2158: // fontheight = ui_dissfont->ascent + ui_dissfont->descent;
! 2159: // if ((y = rect->y - 2) < 0)
! 2160: // y = 0;
! 2161: // printf("y = %d\n", y);
! 2162: // y_start = (y + (int)adj->value) / fontheight;
! 2163: // y_end = (y + (int)adj->value + rect->height) / fontheight;
! 2164: // printf("val = %f start = %d height = %d\n", adj->value, y_start, fontheight);
! 2165: // ypos = -adj->value + y_start * fontheight;
! 2166: // printf("< %d %d >\n", y_start, y_end);
! 2167: // for (i = y_start; i < y_end; i++, ypos+= fontheight) {
! 2168: // gdk_draw_text(canvas->window, ui_dissfont,
! 2169: // cavas->style->fg_gc[GTK_WIDGET_STATE(canvas)],
! 2170: // 0, ypos);
! 2171: //
! 2172: // printf("[%d] %d\n", i, ypos);
! 2173: // }
! 2174: // /*
! 2175: // printf("x = %d\ny = %d\nwidth = %d\nheight = %d\noff=%f\n\n", rect->x,
! 2176: // rect->y, rect->width, rect->height, adj->value);
! 2177: // */
! 2178: //
! 2179: //
! 2180: //}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.