Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
716 | lvd | 1 | #include "std.h" |
2 | |||
3 | #include "resource.h" |
||
4 | #include "emul.h" |
||
5 | #include "vars.h" |
||
6 | #include "config.h" |
||
7 | #include "draw.h" |
||
8 | #include "dx.h" |
||
9 | #include "debug.h" |
||
10 | #include "memory.h" |
||
11 | #include "sound.h" |
||
12 | #include "savesnd.h" |
||
13 | #include "tape.h" |
||
14 | #include "gui.h" |
||
15 | #include "leds.h" |
||
16 | #include "snapshot.h" |
||
17 | #include "wd93dat.h" |
||
18 | #include "init.h" |
||
19 | #include "z80.h" |
||
20 | #include "emulkeys.h" |
||
21 | #include "util.h" |
||
22 | |||
23 | void main_pause() |
||
24 | { |
||
25 | text_i(rbuf+temp.scx/2-8,"pause",0x0F); flip(); |
||
26 | |||
27 | pause = 1; |
||
28 | sound_stop(); |
||
29 | updatebitmap(); |
||
30 | active = 0; |
||
31 | adjust_mouse_cursor(); |
||
32 | |||
33 | while (!process_msgs()) Sleep(10); |
||
34 | eat(); |
||
35 | |||
36 | active = 1; adjust_mouse_cursor(); |
||
37 | sound_play(); |
||
38 | pause = 0; |
||
39 | } |
||
40 | |||
41 | void main_debug() |
||
42 | { |
||
43 | Z80 &cpu = CpuMgr.Cpu(); |
||
44 | |||
45 | cpu.dbgchk = 1; |
||
46 | cpu.dbgbreak = 1; |
||
47 | dbgbreak = 1; |
||
48 | } |
||
49 | |||
50 | enum { FIX_FRAME = 0, FIX_LINE, FIX_PAPER, FIX_NOPAPER, FIX_HWNC, FIX_LAST }; |
||
51 | const char *fix_titles[FIX_LAST] = { |
||
52 | "%d t-states / int", |
||
53 | "%d t-states / line", |
||
54 | "paper starts at %d", |
||
55 | "border only: %d", |
||
56 | "hardware mc: %d" |
||
57 | }; |
||
58 | |||
59 | |||
60 | unsigned char whatfix = 0, whatsnd = 0; |
||
61 | unsigned char fixmode = -1; |
||
62 | int mul0 = 100, mul1 = 1000; |
||
63 | |||
64 | void chfix(int dx) |
||
65 | { |
||
66 | if (!fixmode) { |
||
67 | int value; |
||
68 | switch (whatfix) { |
||
69 | case FIX_FRAME: value = (conf.frame += dx); break; |
||
70 | case FIX_LINE: value = (conf.t_line += dx); break; |
||
71 | case FIX_PAPER: value = (conf.paper += dx); break; |
||
72 | case FIX_NOPAPER: value = (conf.nopaper ^= dx?1:0); break; |
||
73 | case FIX_HWNC: value = (comp.pEFF7 ^= dx?EFF7_HWMC:0)? 1 : 0; break; |
||
74 | } |
||
75 | video_timing_tables(); |
||
76 | apply_sound(); // t/frame affects AY engine! |
||
77 | sprintf(statusline, fix_titles[whatfix], value); statcnt=50; |
||
78 | if (dx) conf.ula_preset = -1; |
||
79 | return; |
||
80 | } |
||
81 | if (fixmode != 1) return; |
||
82 | |||
83 | dx = (dx > 0) ? 1 : ((dx < 0) ? -1 : 0); |
||
84 | |||
85 | *statusline = 0; statcnt = 50; |
||
86 | switch (whatsnd) { |
||
87 | case 0: |
||
88 | conf.sound.ay_stereo = (conf.sound.ay_stereo+dx+num_aystereo) % num_aystereo; |
||
89 | sprintf(statusline, "Stereo preset: %s", aystereo[conf.sound.ay_stereo]); |
||
90 | break; |
||
91 | case 1: |
||
92 | if (dx) conf.sound.ay_samples ^= 1; |
||
93 | sprintf(statusline, "Digital Soundchip: %s", conf.sound.ay_samples? "yes" : "no"); |
||
94 | break; |
||
95 | case 2: |
||
96 | conf.sound.ay_vols = (conf.sound.ay_vols+num_ayvols+dx) % num_ayvols; |
||
97 | sprintf(statusline, "Chip Table: %s", ayvols[conf.sound.ay_vols]); |
||
98 | break; |
||
99 | case 3: |
||
100 | conf.pal = (conf.pal+dx); |
||
101 | if (conf.pal == conf.num_pals) conf.pal = 0; |
||
102 | if (conf.pal == -1) conf.pal = conf.num_pals-1; |
||
103 | sprintf(statusline, "Palette: %s", pals[conf.pal].name); |
||
104 | video_color_tables(); |
||
105 | return; |
||
106 | } |
||
107 | apply_sound(); |
||
108 | } |
||
109 | |||
110 | void main_selectfix() |
||
111 | { |
||
112 | if (!fixmode) whatfix = (whatfix+1) % FIX_LAST; |
||
113 | fixmode = 0; mul0 = 1, mul1 = 10; |
||
114 | if (whatfix == FIX_FRAME) mul0 = 100, mul1 = 1000; |
||
115 | chfix(0); |
||
116 | } |
||
117 | |||
118 | void main_selectsnd() |
||
119 | { |
||
120 | if (fixmode==1) whatsnd = (whatsnd+1) & 3; |
||
121 | fixmode = 1; |
||
122 | chfix(0); |
||
123 | } |
||
124 | |||
125 | void main_incfix() { chfix(mul0); } |
||
126 | void main_decfix() { chfix(-mul0); } |
||
127 | void main_incfix10() { chfix(mul1); } |
||
128 | void main_decfix10() { chfix(-mul1); } |
||
129 | |||
130 | void main_leds() |
||
131 | { |
||
132 | conf.led.enabled ^= 1; |
||
133 | sprintf(statusline, "leds %s", conf.led.enabled ? "on" : "off"); statcnt = 50; |
||
134 | } |
||
135 | |||
136 | void main_maxspeed() |
||
137 | { |
||
138 | conf.sound.enabled ^= 1; |
||
139 | temp.frameskip = conf.sound.enabled? conf.frameskip : conf.frameskipmax; |
||
140 | if (conf.sound.enabled) sound_play(); else sound_stop(); |
||
141 | sprintf(statusline, "Max speed: %s", conf.sound.enabled ? "NO" : "YES"); statcnt = 50; |
||
142 | } |
||
143 | |||
144 | // select filter / driver through gui dialog ---------------------------- |
||
145 | |||
146 | INT_PTR CALLBACK filterdlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp) |
||
147 | { |
||
148 | if (msg == WM_INITDIALOG) |
||
149 | { |
||
150 | HWND box = GetDlgItem(dlg, IDC_LISTBOX); int i; |
||
151 | |||
152 | if (lp) { |
||
153 | for (i = 0; drivers[i].name; i++) |
||
154 | SendMessage(box, LB_ADDSTRING, 0, (LPARAM)drivers[i].name); |
||
155 | SendMessage(box, LB_SETCURSEL, conf.driver, 0); |
||
156 | SetWindowText(dlg, "Select driver for rendering"); |
||
157 | } else { |
||
158 | for (i = 0; renders[i].name; i++) |
||
159 | SendMessage(box, LB_ADDSTRING, 0, (LPARAM)renders[i].name); |
||
160 | SendMessage(box, LB_SETCURSEL, conf.render, 0); |
||
161 | } |
||
162 | |||
163 | RECT rcw, cli; GetWindowRect(box, &rcw); GetClientRect(box, &cli); |
||
164 | RECT rcd; GetWindowRect(dlg, &rcd); |
||
165 | |||
166 | int nc_width = (rcw.right - rcw.left) - (cli.right - cli.left); |
||
167 | int nc_height = (rcw.bottom - rcw.top) - (cli.bottom - cli.top); |
||
168 | int dlg_w = (rcd.right - rcd.left) - (rcw.right - rcw.left); |
||
169 | int dlg_h = (rcd.bottom - rcd.top) - (rcw.bottom - rcw.top); |
||
170 | nc_width += 300; |
||
171 | nc_height += i*SendMessage(box, LB_GETITEMHEIGHT, 0, 0); |
||
172 | dlg_w += nc_width; dlg_h += nc_height; |
||
173 | SetWindowPos(box, 0, 0, 0, nc_width, nc_height, SWP_NOZORDER | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_SHOWWINDOW); |
||
174 | |||
175 | GetWindowRect(wnd, &rcw); |
||
176 | SetWindowPos(dlg, 0, |
||
177 | rcw.left + ((rcw.right-rcw.left)-dlg_w)/2, |
||
178 | rcw.top + ((rcw.bottom-rcw.top)-dlg_h)/2, |
||
179 | dlg_w, dlg_h, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_SHOWWINDOW); |
||
180 | |||
181 | SetFocus(box); |
||
182 | return FALSE; |
||
183 | } |
||
184 | |||
185 | if ((msg == WM_COMMAND && wp == IDCANCEL) || |
||
186 | (msg == WM_SYSCOMMAND && (wp & 0xFFF0) == SC_CLOSE)) |
||
187 | { |
||
188 | EndDialog(dlg, -1); |
||
189 | return TRUE; |
||
190 | } |
||
191 | |||
192 | if (msg == WM_COMMAND) |
||
193 | { |
||
194 | int control = LOWORD(wp); |
||
195 | if (control == IDOK || (control == IDC_LISTBOX && HIWORD(wp) == LBN_DBLCLK)) |
||
196 | { |
||
197 | EndDialog(dlg, SendDlgItemMessage(dlg, IDC_LISTBOX, LB_GETCURSEL, 0, 0)); |
||
198 | return TRUE; |
||
199 | } |
||
200 | } |
||
201 | return FALSE; |
||
202 | } |
||
203 | |||
204 | void main_selectfilter() |
||
205 | { |
||
206 | OnEnterGui(); |
||
207 | int index = DialogBoxParam(hIn, MAKEINTRESOURCE(IDD_FILTER_DIALOG), wnd, filterdlg, 0); |
||
208 | eat(); |
||
209 | if (index < 0) |
||
210 | { |
||
211 | OnExitGui(); |
||
212 | return; |
||
213 | } |
||
214 | OnExitGui(false); |
||
215 | conf.render = index; |
||
216 | sprintf(statusline, "Video: %s", renders[index].name); statcnt = 50; |
||
217 | apply_video(); eat(); |
||
218 | } |
||
219 | |||
220 | void main_selectdriver() |
||
221 | { |
||
222 | if (!(temp.rflags & RF_DRIVER)) { |
||
223 | strcpy(statusline, "Not available for this filter"); statcnt = 50; |
||
224 | return; |
||
225 | } |
||
226 | |||
227 | OnEnterGui(); |
||
228 | int index = DialogBoxParam(hIn, MAKEINTRESOURCE(IDD_FILTER_DIALOG), wnd, filterdlg, 1); |
||
229 | eat(); |
||
230 | |||
231 | if (index < 0) |
||
232 | { |
||
233 | OnExitGui(); |
||
234 | return; |
||
235 | } |
||
236 | OnExitGui(false); |
||
237 | conf.driver = index; |
||
238 | sprintf(statusline, "Render to: %s", drivers[index].name); statcnt = 50; |
||
239 | apply_video(); |
||
240 | eat(); |
||
241 | } |
||
242 | |||
243 | // ---------------------------------------------------------------------- |
||
244 | |||
245 | void main_poke() |
||
246 | { |
||
247 | OnEnterGui(); |
||
248 | DialogBox(hIn, MAKEINTRESOURCE(IDD_POKE), wnd, pokedlg); |
||
249 | eat(); |
||
250 | OnExitGui(); |
||
251 | } |
||
252 | |||
253 | void main_starttape() |
||
254 | { |
||
255 | //if (comp.tape.play_pointer) stop_tape(); else start_tape(); |
||
256 | (comp.tape.play_pointer) ? stop_tape() : start_tape(); |
||
257 | } |
||
258 | |||
259 | void main_tapebrowser() |
||
260 | { |
||
261 | #ifdef MOD_SETTINGS |
||
262 | lastpage = "TAPE", setup_dlg(); |
||
263 | #endif |
||
264 | } |
||
265 | |||
266 | #ifndef MOD_SETTINGS |
||
267 | void setup_dlg() {} |
||
268 | #endif |
||
269 | |||
270 | static const char *getrom(ROM_MODE page) |
||
271 | { |
||
272 | switch (page) { |
||
273 | case RM_128: return "Basic 128"; |
||
274 | case RM_SYS: return "Service ROM"; |
||
275 | case RM_DOS: return "TR-DOS"; |
||
276 | case RM_SOS: return "Basic 48"; |
||
277 | case RM_CACHE: return "Cache"; |
||
278 | } |
||
279 | return "???"; |
||
280 | } |
||
281 | |||
282 | void m_reset(ROM_MODE page) |
||
283 | { |
||
284 | sprintf(statusline, "Reset to %s", getrom(page)); statcnt = 50; |
||
285 | nmi_pending = 0; |
||
286 | cpu.nmi_in_progress = false; |
||
287 | reset(page); |
||
288 | } |
||
289 | void main_reset128() { m_reset(RM_128); } |
||
290 | void main_resetsys() { m_reset(RM_SYS); } |
||
291 | void main_reset48() { m_reset(RM_SOS); comp.p7FFD = 0x30; comp.pEFF7 |= EFF7_LOCKMEM; /*Alone Coder*/} |
||
292 | void main_resetbas() { m_reset(RM_SOS); } |
||
293 | void main_resetdos() { if (conf.trdos_present) m_reset(RM_DOS); } |
||
294 | void main_resetcache() { if (conf.cache) m_reset(RM_CACHE); } |
||
295 | void main_reset() { m_reset((ROM_MODE)conf.reset_rom); } |
||
296 | |||
297 | void m_nmi(ROM_MODE page) |
||
298 | { |
||
299 | set_mode(page); |
||
300 | sprintf(statusline, "NMI to %s", getrom(page)); statcnt = 50; |
||
301 | comp.p00 = 0; // quorum |
||
302 | cpu.sp -= 2; |
||
303 | if(cpu.DbgMemIf->rm(cpu.pc) == 0x76) // nmi on halt command |
||
304 | cpu.pc++; |
||
305 | cpu.DbgMemIf->wm(cpu.sp, cpu.pcl); |
||
306 | cpu.DbgMemIf->wm(cpu.sp+1, cpu.pch); |
||
307 | cpu.pc = 0x66; cpu.iff1 = cpu.halted = 0; |
||
308 | } |
||
309 | |||
310 | void main_nmi() |
||
311 | { |
||
312 | nmi_pending = 1; |
||
313 | if(conf.mem_model != MM_ATM3) |
||
314 | m_nmi(RM_NOCHANGE); |
||
315 | } |
||
316 | |||
317 | void main_nmidos() |
||
318 | { |
||
319 | if((conf.mem_model == MM_PROFSCORP || conf.mem_model == MM_SCORP) && |
||
320 | !(comp.flags & CF_TRDOS) && cpu.pc < 0x4000) |
||
321 | { |
||
322 | nmi_pending = conf.frame * 50; // 50 * 20ms |
||
323 | return; |
||
324 | } |
||
325 | m_nmi(RM_DOS); |
||
326 | } |
||
327 | |||
328 | void main_nmicache() { m_nmi(RM_CACHE); } |
||
329 | |||
330 | static void qsave(const char *fname) { |
||
331 | char xx[0x200]; addpath(xx, fname); |
||
332 | FILE *ff = fopen(xx, "wb"); |
||
333 | if (ff) { |
||
334 | if (writeSNA(ff)) sprintf(statusline, "Quick save to %s", fname), statcnt = 30; |
||
335 | fclose(ff); |
||
336 | } |
||
337 | } |
||
338 | void qsave1() { qsave("qsave1.sna"); } |
||
339 | void qsave2() { qsave("qsave2.sna"); } |
||
340 | void qsave3() { qsave("qsave3.sna"); } |
||
341 | |||
342 | static void qload(const char *fname) { |
||
343 | char xx[0x200]; addpath(xx, fname); |
||
344 | if (loadsnap(xx)) sprintf(statusline, "Quick load from %s", fname), statcnt = 30; |
||
345 | } |
||
346 | void qload1() { qload("qsave1.sna"); } |
||
347 | void qload2() { qload("qsave2.sna"); } |
||
348 | void qload3() { qload("qsave3.sna"); } |
||
349 | |||
350 | void main_keystick() |
||
351 | { |
||
352 | input.keymode = (input.keymode == K_INPUT::KM_KEYSTICK)? K_INPUT::KM_DEFAULT : K_INPUT::KM_KEYSTICK; |
||
353 | } |
||
354 | |||
355 | void main_autofire() |
||
356 | { |
||
357 | conf.input.fire ^= 1; |
||
358 | input.firedelay = 1; |
||
359 | sprintf(statusline, "autofire %s", conf.input.fire ? "on" : "off"), statcnt = 30; |
||
360 | } |
||
361 | |||
362 | void main_save() |
||
363 | { |
||
364 | sound_stop(); |
||
365 | if (conf.cmos) |
||
366 | save_nv(); |
||
367 | unsigned char optype = 0; |
||
368 | for (int i = 0; i < 4; i++) |
||
369 | { |
||
370 | if (!comp.wd.fdd[i].test()) |
||
371 | return; |
||
372 | optype |= comp.wd.fdd[i].optype; |
||
373 | } |
||
374 | |||
375 | if (!optype) |
||
376 | sprintf(statusline, "all saved"), statcnt = 30; |
||
377 | } |
||
378 | |||
379 | void main_fullscr() |
||
380 | { |
||
381 | if (!(temp.rflags & (RF_GDI|RF_OVR|RF_CLIP|RF_D3D))) |
||
382 | sprintf(statusline, "only for overlay/gdi/nonexclusive modes"), statcnt = 30; |
||
383 | else |
||
384 | { |
||
385 | conf.fullscr ^= 1; |
||
386 | apply_video(); |
||
387 | } |
||
388 | } |
||
389 | |||
390 | void main_mouse() |
||
391 | { |
||
392 | conf.lockmouse ^= 1; |
||
393 | adjust_mouse_cursor(); |
||
394 | sprintf(statusline, "mouse %slocked", conf.lockmouse? nil:"un"), statcnt = 30; |
||
395 | } |
||
396 | |||
397 | void main_help() { showhelp(); } |
||
398 | void mon_help() { showhelp("monitor_keys"); } |
||
399 | |||
400 | void main_atmkbd() |
||
401 | { |
||
402 | conf.atm.xt_kbd ^= 1; |
||
403 | if (conf.atm.xt_kbd) sprintf(statusline, "ATM mode on. emulator hotkeys disabled"); |
||
404 | else sprintf(statusline, "ATM mode off"); |
||
405 | statcnt = 50; |
||
406 | } |
||
407 | |||
408 | void main_pastetext() { input.paste(); } |
||
409 | |||
410 | void wnd_resize(int scale) |
||
411 | { |
||
412 | if (conf.fullscr) |
||
413 | { |
||
414 | sprintf(statusline, "impossible in fullscreen mode"); |
||
415 | statcnt = 50; |
||
416 | return; |
||
417 | } |
||
418 | |||
419 | if (!scale) |
||
420 | { |
||
421 | ShowWindow(wnd, SW_MAXIMIZE); |
||
422 | return; |
||
423 | } |
||
424 | |||
425 | ShowWindow(wnd, SW_RESTORE); |
||
426 | DWORD style = GetWindowLong(wnd, GWL_STYLE); |
||
427 | RECT rc = { 0, 0, LONG(temp.ox * scale), LONG(temp.oy * scale) }; |
||
428 | AdjustWindowRect(&rc, style, 0); |
||
429 | SetWindowPos(wnd, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); |
||
430 | if(temp.rflags & RF_2X) |
||
431 | scale *= 2; |
||
432 | else if(temp.rflags & RF_3X) |
||
433 | scale *= 3; |
||
434 | else if(temp.rflags & RF_4X) |
||
435 | scale *= 4; |
||
436 | sprintf(statusline, "scale: %dx", scale); |
||
437 | statcnt = 50; |
||
438 | } |
||
439 | |||
440 | void main_size1() { wnd_resize(1); } |
||
441 | void main_size2() { wnd_resize(2); } |
||
442 | void main_sizem() { wnd_resize(0); } |
||
443 | |||
444 | static void SetBorderSize(unsigned BorderSize) |
||
445 | { |
||
446 | // 0 - none |
||
447 | // 1 - small |
||
448 | // 2 - full |
||
449 | if(BorderSize > 2) |
||
450 | { |
||
451 | return; |
||
452 | } |
||
453 | conf.bordersize = BorderSize; |
||
454 | apply_video(); |
||
455 | } |
||
456 | |||
457 | void main_border_none() { SetBorderSize(0); } |
||
458 | void main_border_small() { SetBorderSize(1); } |
||
459 | void main_border_full() { SetBorderSize(2); } |
||
460 | |||
461 | |||
462 | void correct_exit() |
||
463 | { |
||
464 | sound_stop(); |
||
465 | if(!done_fdd(true)) |
||
466 | return; |
||
467 | |||
468 | nowait = 1; |
||
469 | normal_exit = true; |
||
470 | exit(); |
||
471 | } |
||
472 | |||
473 | void opensnap() |
||
474 | { |
||
475 | OnEnterGui(); |
||
476 | opensnap(0); |
||
477 | eat(); |
||
478 | OnExitGui(); |
||
479 | } |
||
480 | |||
481 | void savesnap() |
||
482 | { |
||
483 | OnEnterGui(); |
||
484 | savesnap(-1); |
||
485 | eat(); |
||
486 | OnExitGui(); |
||
487 | } |