New makefile solution: A single invocation of 'make' to build the entire tree. Fully...
[kugel-rb.git] / apps / plugins / zxbox / spmain.c
blobbc5df4805948cd87d9b4e881a7a4deb493b893c8
1 /*
2 * Copyright (C) 1996-1998 Szeredi Miklos
3 * Email: mszeredi@inf.bme.hu
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version. See the file COPYING.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "zxmisc.h"
21 #include "zxconfig.h"
22 #include "lib/configfile.h"
23 #include "lib/oldmenuapi.h"
25 #include "spperif.h"
26 #include "z80.h"
27 #include "spmain.h"
28 #include "sptiming.h"
29 #include "spscr.h"
30 #include "spkey_p.h"
31 #include "spkey.h"
32 #include "sptape.h"
33 #include "spsound.h"
34 #include "snapshot.h"
36 #include "spconf.h"
38 #include "interf.h"
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <errno.h>
45 #ifdef USE_GREY
46 #include "lib/grey.h"
47 #endif
49 #include "zxbox_keyb.h"
51 int endofsingle IBSS_ATTR;
53 int sp_nosync IBSS_ATTR = 0;
55 int showframe IBSS_ATTR = 1;
56 int load_immed = 1;
58 qbyte sp_int_ctr IBSS_ATTR = 0;
59 int intkeys[5] IBSS_ATTR;
61 #ifdef USE_DJGPP
62 #define DOS
63 #endif
65 #define GLOBALCFG "zxbox.cfg"
67 /* here goes settings hadling */
69 /*static struct zxbox_settings settings;*/
70 static struct zxbox_settings old_settings;
72 static char* noyes_options[] = { "No", "Yes" };
73 /*static char* kempston_options[] = { "No", "Yes" };
74 static char* showfps_options[] = {"No", "Yes"};*/
76 static struct configdata config[] =
78 {TYPE_ENUM, 0, 2, &settings.invert_colors, "Invert Colors", noyes_options, NULL},
79 {TYPE_ENUM, 0, 2, &settings.kempston, "Map keys to kempston", noyes_options, NULL},
80 {TYPE_ENUM, 0, 2, &settings.showfps, "Show Speed", noyes_options, NULL},
81 {TYPE_ENUM, 0, 2, &settings.sound, "Sound", noyes_options, NULL},
82 {TYPE_INT, 0, 9, &settings.frameskip, "Frameskip", NULL, NULL},
83 {TYPE_INT, 1, 10, &settings.volume, "Volume", NULL, NULL},
84 {TYPE_STRING, 0, 5, NULL,"Key Mapping", NULL, (char*)&settings.keymap},
86 int spcf_read_conf_file(const char *filename)
88 settings.volume = 10;
89 settings.showfps=1;
90 settings.keymap[0]='2';
91 settings.keymap[1]='w';
92 settings.keymap[2]='9';
93 settings.keymap[3]='0';
94 settings.keymap[4]='z';
95 settings.kempston = 1 ;
96 settings.invert_colors=0;
97 settings.sound = 0;
98 settings.frameskip = 0;
101 configfile_init(rb);
102 if (configfile_load(filename, config,
103 sizeof(config)/sizeof(*config),
104 SETTINGS_MIN_VERSION
105 ) < 0)
107 /* If the loading failed, save a new config file (as the disk is
108 already spinning) */
109 configfile_save(filename, config,
110 sizeof(config)/sizeof(*config),
111 SETTINGS_VERSION);
113 /* Keep a copy of the saved version of the settings - so we can check if
114 the settings have changed when we quit */
115 old_settings = settings;
116 sound_on = settings.sound;
117 showframe = settings.frameskip+1;
118 int i;
119 for ( i=0 ; i<5 ; i++){
120 if (settings.keymap[i] == 'E')
121 intkeys[i]=SK_KP_Enter;
122 else if ( settings.keymap[i] == 'S' )
123 intkeys[i]=SK_KP_Space;
124 else
125 intkeys[i] = (unsigned) settings.keymap[i];
127 return 1;
130 /* and here it stops (settings loading ;) )*/
132 /* set keys */
133 static void set_keys(void){
134 int m;
135 char c;
136 int result;
137 int menu_quit=0;
138 static const struct menu_item items[] = {
139 { "Map Up key", NULL },
140 { "Map Down key", NULL },
141 { "Map Left key", NULL },
142 { "Map Right key", NULL },
143 { "Map Fire/Jump key", NULL },
146 m = menu_init(rb,items, sizeof(items) / sizeof(*items),
147 NULL, NULL, NULL, NULL);
149 rb->button_clear_queue();
151 while (!menu_quit) {
152 result=menu_show(m);
154 switch(result)
156 case 0:
157 if (!zx_kbd_input((char*) &c))
159 settings.keymap[0]=c;
161 break;
162 case 1:
163 if (!zx_kbd_input((char*) &c))
165 settings.keymap[1]=c;
167 break;
168 case 2:
169 if (!zx_kbd_input((char*) &c))
171 settings.keymap[2]=c;
173 break;
174 case 3:
175 if (!zx_kbd_input((char*) &c))
177 settings.keymap[3]=c;
179 break;
180 case 4:
181 if (!zx_kbd_input((char*) &c))
183 settings.keymap[4]=c;
185 break;
186 default:
187 menu_quit=1;
188 break;
192 menu_exit(m);
195 /* select predefined keymap */
196 static void select_keymap(void){
197 int m;
198 int result;
199 int menu_quit=0;
200 static const struct menu_item items[] = {
201 { "2w90z", NULL },
202 { "qaopS", NULL },
203 { "7658S", NULL },
206 m = menu_init(rb,items, sizeof(items) / sizeof(*items),
207 NULL, NULL, NULL, NULL);
209 rb->button_clear_queue();
211 while (!menu_quit) {
212 result=menu_show(m);
214 switch(result)
216 case 0:
217 rb->memcpy ( (void*)&settings.keymap[0] , (void*)items[0].desc , sizeof(items[0].desc));
218 menu_quit=1;
219 break;
220 case 1:
221 rb->memcpy ( (void*)&settings.keymap[0] , (void*)items[1].desc , sizeof(items[1].desc));
222 menu_quit=1;
223 break;
224 case 2:
225 rb->memcpy ( (void*)&settings.keymap[0] , (void*)items[2].desc , sizeof(items[2].desc));
226 menu_quit=1;
227 break;
228 default:
229 menu_quit=1;
230 break;
234 menu_exit(m);
237 /* options menu */
238 static void options_menu(void){
239 static const struct opt_items no_yes[2] = {
240 { "No", -1 },
241 { "Yes", -1 },
243 int m;
244 int result;
245 int menu_quit=0;
246 int new_setting;
247 static const struct menu_item items[] = {
248 { "Map Keys to kempston", NULL },
249 { "Display Speed", NULL },
250 { "Invert Colors", NULL },
251 { "Frameskip", NULL },
252 { "Sound", NULL },
253 { "Volume", NULL },
254 { "Predefined keymap", NULL },
255 { "Custom keymap", NULL },
257 static struct opt_items frameskip_items[] = {
258 { "0", -1 },
259 { "1", -1 },
260 { "2", -1 },
261 { "3", -1 },
262 { "4", -1 },
263 { "5", -1 },
264 { "6", -1 },
265 { "7", -1 },
266 { "8", -1 },
267 { "9", -1 },
271 m = menu_init(rb,items, sizeof(items) / sizeof(*items),
272 NULL, NULL, NULL, NULL);
274 rb->button_clear_queue();
276 while (!menu_quit) {
277 result=menu_show(m);
279 switch(result)
281 case 0:
282 new_setting=settings.kempston;
283 rb->set_option("Map Keys to kempston",&new_setting,INT,
284 no_yes, 2, NULL);
285 if (new_setting != settings.kempston )
286 settings.kempston=new_setting;
287 break;
288 case 1:
289 new_setting = settings.showfps;
290 rb->set_option("Display Speed",&new_setting,INT,
291 no_yes, 2, NULL);
292 if (new_setting != settings.showfps )
293 settings.showfps=new_setting;
294 break;
295 case 2:
296 new_setting = settings.invert_colors;
297 rb->set_option("Invert Colors",&new_setting,INT,
298 no_yes, 2, NULL);
299 if (new_setting != settings.invert_colors )
300 settings.invert_colors=new_setting;
301 rb->splash(HZ, "Restart to see effect");
302 break;
303 case 3:
304 new_setting = settings.frameskip;
305 rb->set_option("Frameskip",&new_setting,INT,
306 frameskip_items, 10, NULL);
307 if (new_setting != settings.frameskip )
308 settings.frameskip=new_setting;
309 break;
310 case 4:
311 new_setting = settings.sound;
312 rb->set_option("Sound",&new_setting,INT,
313 no_yes, 2, NULL);
314 if (new_setting != settings.sound )
315 settings.sound=new_setting;
316 #if CONFIG_CODEC == SWCODEC && !defined SIMULATOR
317 rb->pcm_play_stop();
318 #endif
319 break;
320 case 5:
321 new_setting = 9 - settings.volume;
322 rb->set_option("Volume",&new_setting,INT,
323 frameskip_items, 10, NULL);
324 new_setting = 9 - new_setting;
325 if (new_setting != settings.volume )
326 settings.volume=new_setting;
327 break;
328 case 6:
329 select_keymap();
330 break;
331 case 7:
332 set_keys();
333 break;
334 default:
335 menu_quit=1;
336 break;
340 menu_exit(m);
343 /* menu */
344 static bool zxbox_menu(void)
346 #if CONFIG_CODEC == SWCODEC && !defined SIMULATOR
347 rb->pcm_play_stop();
348 #endif
349 int m;
350 int result;
351 int menu_quit=0;
352 int exit=0;
353 char c;
354 static const struct menu_item items[] = {
355 { "VKeyboard", NULL },
356 { "Play/Pause Tape", NULL },
357 { "Save quick snapshot", NULL },
358 { "Load quick snapshot", NULL },
359 { "Save Snapshot", NULL },
360 { "Toggle \"fast\" mode", NULL },
361 { "Options", NULL },
362 { "Quit", NULL },
365 m = menu_init(rb,items, sizeof(items) / sizeof(*items),
366 NULL, NULL, NULL, NULL);
368 rb->button_clear_queue();
370 while (!menu_quit) {
371 result=menu_show(m);
373 switch(result)
375 case 0:
376 if (!zx_kbd_input((char*) &c))
378 press_key(c);
380 clear_kbd=1;
381 menu_quit=1;
382 break;
383 case 1:
384 pause_play();
385 menu_quit=1;
386 break;
387 case 2:
388 save_quick_snapshot();
389 menu_quit = 1;
390 break;
391 case 3:
392 load_quick_snapshot();
393 menu_quit = 1;
394 break;
395 case 4:
396 save_snapshot();
397 break;
398 case 5:
399 sp_nosync=!sp_nosync;
400 menu_quit=1;
401 break;
402 case 6:
403 options_menu();
404 break;
405 case 7:
406 menu_quit=1;
407 exit=1;
408 break;
409 default:
410 menu_quit=1;
411 break;
415 menu_exit(m);
416 #if defined(HAVE_ADJUSTABLE_CPU_FREQ)
417 rb->cpu_boost(true);
418 #endif
420 int i;
421 for ( i=0 ; i<5 ; i++){
422 if (settings.keymap[i] == 'E')
423 intkeys[i]=SK_KP_Enter;
424 else if ( settings.keymap[i] == 'S' )
425 intkeys[i]=SK_KP_Space;
426 else
427 intkeys[i] = (unsigned) settings.keymap[i];
429 #ifdef USE_GREY
430 grey_show(true);
431 #endif
432 return (exit);
436 /* */
437 extern unsigned char loadim[];
438 extern unsigned long loadim_size;
440 #define SHOW_OFFS 1
442 static void update(void)
444 update_screen();
445 sp_border_update >>= 1;
446 sp_imag_vert = sp_imag_horiz = 0;
449 static void run_singlemode(void)
451 int t = 0;
452 int evenframe, halfsec, updateframe;
454 sp_int_ctr = 0;
455 endofsingle = 0;
456 spti_reset();
458 while(!endofsingle) {
459 video_frames++;
460 if (clear_kbd){
461 clear_keystates();
462 clear_kbd=0;
464 if(exit_requested){
465 if (zxbox_menu()){
466 /* Save the user settings if they have changed */
467 if (rb->memcmp(&settings,&old_settings,sizeof(settings))!=0) {
468 #ifdef USE_GREY
469 grey_show(false);
470 #endif
471 rb->splash(0, "Saving settings...");
472 configfile_save(GLOBALCFG, config,sizeof(config)/sizeof(*config),SETTINGS_VERSION);
475 return;
477 exit_requested = 0;
478 video_frames=-1;
479 start_time = *rb->current_tick;
480 sound_on = settings.sound;
481 showframe = settings.frameskip+1;
482 spti_reset();
484 halfsec = !(sp_int_ctr % 25);
485 evenframe = !(sp_int_ctr & 1);
487 if(screen_visible) updateframe = sp_nosync ? halfsec :
488 !((sp_int_ctr+SHOW_OFFS) % showframe);
489 else updateframe = 0;
490 if(halfsec) {
491 sp_flash_state = ~sp_flash_state;
492 flash_change();
494 if(evenframe) {
495 play_tape();
496 sp_scline = 0;
498 spkb_process_events(evenframe);
499 sp_updating = updateframe;
500 t += CHKTICK;
501 t = sp_halfframe(t, evenframe ? EVENHF : ODDHF);
502 if(SPNM(load_trapped)) {
503 SPNM(load_trapped) = 0;
504 DANM(haltstate) = 0;
505 qload();
507 z80_interrupt(0xFF);
508 sp_int_ctr++;
509 if(!evenframe) rec_tape();
510 if(!sp_nosync) {
511 if(!sound_avail) spti_wait();
513 if(updateframe) update();
514 play_sound(evenframe);
516 else if(updateframe) update();
522 void check_params(const void* parameter)
524 spcf_read_conf_file(GLOBALCFG);
525 spcf_read_command_line(parameter);
528 static void init_load(const void *parameter)
530 if(load_immed) snsh_z80_load_intern(loadim, loadim_size);
532 check_params(parameter);
533 if(spcf_init_snapshot != NULL) {
534 #ifndef USE_GREY
535 rb->splashf(HZ, "Loading snapshot '%s'", spcf_init_snapshot);
536 #endif
538 load_snapshot_file_type(spcf_init_snapshot, spcf_init_snapshot_type);
539 free_string(spcf_init_snapshot);
542 if(spcf_init_tapefile != NULL) {
543 /*sprintf(msgbuf, "Loading tape '%s'", spcf_init_tapefile);
544 put_msg(msgbuf);*/
545 start_play_file_type(spcf_init_tapefile, 0, spcf_init_tapefile_type);
546 if(!load_immed) pause_play();
547 free_string(spcf_init_tapefile);
551 void start_spectemu(const void *parameter)
553 spti_init();
554 init_load(parameter);
555 init_spect_scr();
556 init_spect_sound();
557 init_spect_key();
559 run_singlemode();