Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
ui.c
Go to the documentation of this file.
1 /* Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
2  Copyright (C)2016-2022 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17 
18 
19 #include "xemu/emutools.h"
20 #include "ui.h"
21 #include "xemu/emutools_gui.h"
22 #include "xemu/emutools_files.h"
23 #include "xemu/d81access.h"
24 #include "xemu/emutools_hid.h"
25 #include "commodore_65.h"
26 #include "inject.h"
27 #include "vic3.h"
28 #include "dma65.h"
29 #include "xemu/basic_text.h"
30 #include "configdb.h"
31 
32 
33 static int attach_d81 ( int drive, const char *fn )
34 {
35  if (fn && *fn)
37  return -1;
38 }
39 
40 static void ui_attach_d81_by_browsing ( int drive )
41 {
42  char fnbuf[PATH_MAX + 1];
43  static char dir[PATH_MAX + 1] = "";
46  "Select D81 to attach",
47  dir,
48  fnbuf,
49  sizeof fnbuf
50  ))
51  attach_d81(drive, fnbuf);
52  else
53  DEBUGPRINT("UI: file selection for D81 mount was cancelled." NL);
54 }
55 
56 static void ui_attach_d81_by_browsing_8 ( void ) { ui_attach_d81_by_browsing(0); }
57 static void ui_attach_d81_by_browsing_9 ( void ) { ui_attach_d81_by_browsing(1); }
58 
59 static void ui_cb_detach_d81 ( const struct menu_st *m, int *query )
60 {
63 }
64 
65 static void ui_run_prg_by_browsing ( void )
66 {
67  char fnbuf[PATH_MAX + 1];
68  static char dir[PATH_MAX + 1] = "";
71  "Select PRG to directly load&run",
72  dir,
73  fnbuf,
74  sizeof fnbuf
75  )) {
76  c65_reset();
77  inject_register_prg(fnbuf, 0);
78  } else
79  DEBUGPRINT("UI: file selection for PRG injection was cancelled." NL);
80 }
81 
82 static void ui_dump_memory ( void )
83 {
84  char fnbuf[PATH_MAX + 1];
85  static char dir[PATH_MAX + 1] = "";
88  "Dump memory content into file",
89  dir,
90  fnbuf,
91  sizeof fnbuf
92  )) {
93  dump_memory(fnbuf);
94  }
95 }
96 
97 static void reset_into_c64_mode ( void )
98 {
99  if (c65_reset_asked()) {
100  // we need this, because autoboot disk image would bypass the "go to C64 mode" on 'Commodore key' feature
101  // this call will deny disk access, and re-enable on the READY. state.
104  KBD_PRESS_KEY(0x75); // C= key is pressed for C64 mode
105  }
106 }
107 
108 static void reset_into_c65_mode ( void )
109 {
110  if (c65_reset_asked()) {
111  KBD_RELEASE_KEY(0x75);
112  }
113 }
114 
115 static void reset_into_c65_mode_noboot ( void )
116 {
117  if (c65_reset_asked()) {
119  KBD_RELEASE_KEY(0x75);
120  }
121 }
122 
123 static void ui_cb_show_drive_led ( const struct menu_st *m, int *query )
124 {
127 }
128 
129 static void ui_emu_info ( void )
130 {
131  char td_stat_str[XEMU_CPU_STAT_INFO_BUFFER_SIZE];
132  xemu_get_timing_stat_string(td_stat_str, sizeof td_stat_str);
133  INFO_WINDOW(
134  "DMA chip current revision: %d (F018 rev-%s)\n"
135  "ROM version detected: %d%s\n"
136  "Current ROM: %s\n"
137  //"C64 'CPU' I/O port (low 3 bits): DDR=%d OUT=%d\n"
138  "Current VIC I/O mode: %s\n"
139  "\n"
140  "Xemu host CPU usage so far: %s\n"
141  "Xemu's host OS: %s"
142  ,
143  dma_chip_revision, dma_chip_revision ? "B, new" : "A, old",
144  rom_date, rom_date > 0 ? "" : " (unknown or bad ROM signature)",
146  //memory_get_cpu_io_port(0) & 7, memory_get_cpu_io_port(1) & 7,
147  vic_new_mode ? "VIC-III" : "VIC-II",
148  td_stat_str,
150  );
151 }
152 
153 // TODO: maybe we want to move these functions to somewhere else from this UI specific file ui.c
154 // It may can help to make ui.c xemucfg independent, btw.
155 static void load_and_use_rom ( const char *fn )
156 {
157  if (c65_reset_asked()) {
158  KBD_RELEASE_KEY(0x75);
160  } else
161  ERROR_WINDOW("Reset has been disallowed, thus you've rejected to load and use the selected ROM");
162 }
163 static void ui_load_rom_default ( void )
164 {
165  load_and_use_rom(DEFAULT_ROM_FILE);
166 }
167 static void ui_load_rom_specified ( void )
168 {
169  load_and_use_rom(configdb.rom);
170 }
171 
172 #ifdef CONFIG_DROPFILE_CALLBACK
173 void emu_dropfile_callback ( const char *fn )
174 {
175  DEBUGGUI("UI: file drop event, file: %s" NL, fn);
176  switch (QUESTION_WINDOW("Cancel|D81 to drv-8|D81 to drv-9|Run as PRG|Use as ROM", "What to do with the dropped file?")) {
177  case 1:
178  attach_d81(0, fn);
179  break;
180  case 2:
181  attach_d81(1, fn);
182  break;
183  case 3:
184  c65_reset();
186  break;
187  case 4:
188  load_and_use_rom(fn);
189  break;
190  }
191 }
192 #endif
193 
194 static void ui_load_rom_by_browsing ( void )
195 {
196  char fnbuf[PATH_MAX + 1];
197  static char dir[PATH_MAX + 1] = "";
200  "Select ROM to attach",
201  dir,
202  fnbuf,
203  sizeof fnbuf
204  ))
205  DEBUGPRINT("UI: file selection for loading ROM was cancelled." NL);
206  else
207  load_and_use_rom(fnbuf);
208 }
209 
210 
211 static void ui_put_screen_text_into_paste_buffer ( void )
212 {
213  char text[8192];
214  char *result = xemu_cbm_screen_to_text(
215  text,
216  sizeof text,
217  memory + ((vic3_registers[0x31] & 0x80) ? (vic3_registers[0x18] & 0xE0) << 6 : (vic3_registers[0x18] & 0xF0) << 6), // pointer to screen RAM, try to audo-tected: FIXME: works only in bank0!
218  (vic3_registers[0x31] & 0x80) ? 80 : 40, // number of columns, try to auto-detect it
219  25, // number of rows
220  (vic3_registers[0x18] & 2) // lowercase font? try to auto-detect by checking selected address chargen addr, LSB
221  );
222  if (result == NULL)
223  return;
224  if (*result) {
225  if (SDL_SetClipboardText(result))
226  ERROR_WINDOW("Cannot insert text into the OS paste buffer: %s", SDL_GetError());
227  else
228  OSD(-1, -1, "Copied to OS paste buffer.");
229  } else
230  INFO_WINDOW("Screen is empty, nothing to capture.");
231 }
232 
233 
234 static void ui_put_paste_buffer_into_screen_text ( void )
235 {
236  char *t = SDL_GetClipboardText();
237  if (t == NULL)
238  goto no_clipboard;
239  char *t2 = t;
240  while (*t2 && (*t2 == '\t' || *t2 == '\r' || *t2 == '\n' || *t2 == ' '))
241  t2++;
242  if (!*t2)
243  goto no_clipboard;
245  memory + ((vic3_registers[0x31] & 0x80) ? (vic3_registers[0x18] & 0xE0) << 6 : (vic3_registers[0x18] & 0xF0) << 6), // pointer to screen RAM, try to audo-tected: FIXME: works only in bank0!
246  (vic3_registers[0x31] & 0x80) ? 80 : 40, // number of columns, try to auto-detect it
247  25, // number of rows
248  t2, // text buffer as input
249  (vic3_registers[0x18] & 2) // lowercase font? try to auto-detect by checking selected address chargen addr, LSB
250  );
251  SDL_free(t);
252  return;
253 no_clipboard:
254  if (t)
255  SDL_free(t);
256  ERROR_WINDOW("Clipboard query error, or clipboard was empty");
257 }
258 
259 
260 /**** MENU SYSTEM ****/
261 
262 
263 static const struct menu_st menu_display[] = {
264  { "Fullscreen", XEMUGUI_MENUID_CALLABLE, xemugui_cb_windowsize, (void*)0 },
265  { "Window - 100%", XEMUGUI_MENUID_CALLABLE, xemugui_cb_windowsize, (void*)1 },
266  { "Window - 200%", XEMUGUI_MENUID_CALLABLE |
268  { "Enable mouse grab + emu", XEMUGUI_MENUID_CALLABLE |
270  { "Show drive LED", XEMUGUI_MENUID_CALLABLE |
271  XEMUGUI_MENUFLAG_QUERYBACK, ui_cb_show_drive_led, NULL },
272 #ifdef XEMU_FILES_SCREENSHOT_SUPPORT
274 #endif
275  { "Screen to OS paste buffer", XEMUGUI_MENUID_CALLABLE, xemugui_cb_call_user_data, ui_put_screen_text_into_paste_buffer },
276  { "OS paste buffer to screen", XEMUGUI_MENUID_CALLABLE, xemugui_cb_call_user_data, ui_put_paste_buffer_into_screen_text },
277  { NULL }
278 };
279 static const struct menu_st menu_debug[] = {
280  { "OSD key debugger", XEMUGUI_MENUID_CALLABLE |
282  { "Dump memory info file", XEMUGUI_MENUID_CALLABLE, xemugui_cb_call_user_data, ui_dump_memory },
283  { "Browse system folder", XEMUGUI_MENUID_CALLABLE, xemugui_cb_native_os_prefdir_browser, NULL },
284  { NULL }
285 };
286 static const struct menu_st menu_reset[] = {
287  { "Reset C65", XEMUGUI_MENUID_CALLABLE, xemugui_cb_call_user_data, reset_into_c65_mode },
288  { "Reset C65 without autoboot", XEMUGUI_MENUID_CALLABLE, xemugui_cb_call_user_data, reset_into_c65_mode_noboot },
289  { "Reset into C64 mode", XEMUGUI_MENUID_CALLABLE, xemugui_cb_call_user_data, reset_into_c64_mode },
290  { NULL }
291 };
292 static const struct menu_st menu_rom[] = {
293  { "Load custom ROM", XEMUGUI_MENUID_CALLABLE, xemugui_cb_call_user_data, ui_load_rom_by_browsing },
294  { "Load CLI specified ROM", XEMUGUI_MENUID_CALLABLE, xemugui_cb_call_user_data, ui_load_rom_specified },
295  { "Load Xemu default ROM", XEMUGUI_MENUID_CALLABLE, xemugui_cb_call_user_data, ui_load_rom_default },
296  { NULL }
297 };
298 static const struct menu_st menu_drives[] = {
299  { "Attach D81 to drive 8", XEMUGUI_MENUID_CALLABLE, xemugui_cb_call_user_data, ui_attach_d81_by_browsing_8 },
300  { "Detach D81 from drive 8", XEMUGUI_MENUID_CALLABLE, ui_cb_detach_d81, (void*)0 },
301  { "Attach D81 to drive 9", XEMUGUI_MENUID_CALLABLE, xemugui_cb_call_user_data, ui_attach_d81_by_browsing_9 },
302  { "Detach D81 from drive 9", XEMUGUI_MENUID_CALLABLE, ui_cb_detach_d81, (void*)1 },
303  { NULL }
304 };
305 static const struct menu_st menu_main[] = {
306  { "Display", XEMUGUI_MENUID_SUBMENU, NULL, menu_display },
307  { "Reset", XEMUGUI_MENUID_SUBMENU, NULL, menu_reset },
308  { "Debug", XEMUGUI_MENUID_SUBMENU, NULL, menu_debug },
309  { "ROM", XEMUGUI_MENUID_SUBMENU, NULL, menu_rom },
310  { "Drives / D81 images", XEMUGUI_MENUID_SUBMENU, NULL, menu_drives },
311  { "Run PRG directly", XEMUGUI_MENUID_CALLABLE, xemugui_cb_call_user_data, ui_run_prg_by_browsing },
312 #ifdef XEMU_ARCH_WIN
313  { "System console", XEMUGUI_MENUID_CALLABLE |
314  XEMUGUI_MENUFLAG_QUERYBACK, xemugui_cb_sysconsole, NULL },
315 #endif
316  { "Emulation state info", XEMUGUI_MENUID_CALLABLE, xemugui_cb_call_user_data, ui_emu_info },
318 #ifdef HAVE_XEMU_EXEC_API
319  { "Help (on-line)", XEMUGUI_MENUID_CALLABLE, xemugui_cb_web_help_main, NULL },
320 #endif
322  { NULL }
323 };
324 
325 
326 void ui_enter ( void )
327 {
328  DEBUGGUI("UI: handler has been called." NL);
329  if (xemugui_popup(menu_main)) {
330  DEBUGPRINT("UI: oops, POPUP does not worked :(" NL);
331  }
332 }
show_drive_led
int show_drive_led
Definition: vic3.c:60
basic_text.h
menu_st
Definition: emutools_gui.h:65
D81ACCESS_AUTOCLOSE
#define D81ACCESS_AUTOCLOSE
Definition: d81access.h:38
text
const char * text
Definition: basic_text.c:391
rom_date
int rom_date
Definition: dma65.c:55
emutools.h
ui.h
vic3.h
menu_st::user_data
const void * user_data
Definition: emutools_gui.h:69
current_rom_filepath
char current_rom_filepath[PATH_MAX]
Definition: commodore_65.c:51
xemugui_file_selector
int xemugui_file_selector(int dialog_mode, const char *dialog_title, char *default_dir, char *selected, int path_max_size)
Definition: emutools_gui.c:126
xemugui_popup
int xemugui_popup(const struct menu_st desc[])
Definition: emutools_gui.c:135
register_screenshot_request
int register_screenshot_request
Definition: enterprise128.c:54
c65_reset
void c65_reset(void)
Definition: commodore_65.c:792
xemugui_cb_osd_key_debugger
void xemugui_cb_osd_key_debugger(const struct menu_st *m, int *query)
Definition: popular_user_funcs.c:169
configdb_st::rom
char * rom
Definition: configdb.h:32
c65_reset_asked
int c65_reset_asked(void)
Definition: commodore_65.c:783
INFO_WINDOW
#define INFO_WINDOW(...)
Definition: xep128.h:114
fn
const char * fn
Definition: roms.c:42
XEMUGUI_MENUID_CALLABLE
#define XEMUGUI_MENUID_CALLABLE
Definition: emutools_gui.h:30
inject_register_allow_disk_access
void inject_register_allow_disk_access(void)
Definition: inject.c:132
emutools_gui.h
xemugui_cb_set_mouse_grab
void xemugui_cb_set_mouse_grab(const struct menu_st *m, int *query)
Definition: popular_user_funcs.c:176
xemu_cbm_text_to_screen
int xemu_cbm_text_to_screen(Uint8 *v, const int cols, const int rows, const char *buffer, const int lowercase)
Definition: basic_text.c:475
xemu_get_uname_string
const char * xemu_get_uname_string(void)
Definition: emutools.c:468
XEMUGUI_FSEL_FLAG_STORE_DIR
#define XEMUGUI_FSEL_FLAG_STORE_DIR
Definition: emutools_gui.h:28
d81access_attach_fsobj
int d81access_attach_fsobj(int which, const char *fn, int mode)
Definition: d81access.c:173
dma_chip_revision
int dma_chip_revision
Definition: dma65.c:53
XEMUGUI_MENUFLAG_QUERYBACK
#define XEMUGUI_MENUFLAG_QUERYBACK
Definition: emutools_gui.h:40
drive
char * drive
Definition: commodore_geos.c:151
XEMUGUI_FSEL_SAVE
#define XEMUGUI_FSEL_SAVE
Definition: emutools_gui.h:27
emutools_files.h
DEBUGPRINT
#define DEBUGPRINT(...)
Definition: emutools_basicdefs.h:171
VOIDPTR_TO_INT
#define VOIDPTR_TO_INT(x)
Definition: emutools_basicdefs.h:270
d81access_close
void d81access_close(int which)
Definition: d81access.c:78
vic3_registers
Uint8 vic3_registers[0x80]
Definition: vic3.c:61
configdb.h
dump_memory
int dump_memory(const char *fn)
Definition: commodore_65.c:754
dir
DIR * dir
Definition: cpmfs.c:46
ERROR_WINDOW
#define ERROR_WINDOW(...)
Definition: xep128.h:116
vic_new_mode
int vic_new_mode
Definition: vic3.c:62
D81ACCESS_PRG
#define D81ACCESS_PRG
Definition: d81access.h:34
NL
#define NL
Definition: fat32.c:37
xemugui_cb_set_integer_to_one
void xemugui_cb_set_integer_to_one(const struct menu_st *m, int *query)
Definition: popular_user_funcs.c:187
configdb
struct configdb_st configdb
Definition: configdb.c:34
XEMUGUI_FSEL_OPEN
#define XEMUGUI_FSEL_OPEN
Definition: emutools_gui.h:26
commodore_65.h
memory
Uint8 memory[0x100000]
Definition: commodore_65.c:43
D81ACCESS_FAKE64
#define D81ACCESS_FAKE64
Definition: d81access.h:39
xemu_get_timing_stat_string
void xemu_get_timing_stat_string(char *buf, unsigned int size)
Definition: emutools.c:538
hid_set_autoreleased_key
void hid_set_autoreleased_key(int key)
Definition: emutools_hid.c:66
emu_dropfile_callback
void emu_dropfile_callback(const char *fn)
Definition: primo.c:675
KBD_RELEASE_KEY
#define KBD_RELEASE_KEY(a)
Definition: emutools_hid.h:47
inject.h
OSD
#define OSD(...)
Definition: xep128.h:100
inject_register_prg
int inject_register_prg(const char *prg_fn, int prg_mode)
Definition: inject.c:140
XEMUGUI_MENUID_SUBMENU
#define XEMUGUI_MENUID_SUBMENU
Definition: emutools_gui.h:31
XEMUGUI_RETURN_CHECKED_ON_QUERY
#define XEMUGUI_RETURN_CHECKED_ON_QUERY(query, status)
Definition: emutools_gui.h:55
xemugui_cb_call_quit_if_sure
void xemugui_cb_call_quit_if_sure(const struct menu_st *m, int *query)
Definition: popular_user_funcs.c:79
xemugui_cb_call_user_data
void xemugui_cb_call_user_data(const struct menu_st *m, int *query)
Definition: popular_user_funcs.c:29
emutools_hid.h
xemu_cbm_screen_to_text
char * xemu_cbm_screen_to_text(char *buffer, const int buffer_size, const Uint8 *v, const int cols, const int rows, const int lowercase)
Definition: basic_text.c:419
XEMU_CPU_STAT_INFO_BUFFER_SIZE
#define XEMU_CPU_STAT_INFO_BUFFER_SIZE
Definition: emutools.h:65
c65_load_rom
int c65_load_rom(const char *fn, unsigned int dma_rev)
Definition: commodore_65.c:304
xemugui_cb_windowsize
void xemugui_cb_windowsize(const struct menu_st *m, int *query)
Definition: popular_user_funcs.c:97
configdb_st::dmarev
int dmarev
Definition: configdb.h:35
D81ACCESS_DIR
#define D81ACCESS_DIR
Definition: d81access.h:35
QUESTION_WINDOW
#define QUESTION_WINDOW(items, msg)
Definition: xep128.h:124
D81ACCESS_IMG
#define D81ACCESS_IMG
Definition: d81access.h:33
DEFAULT_ROM_FILE
#define DEFAULT_ROM_FILE
Definition: commodore_65.h:35
xemugui_cb_about_window
void xemugui_cb_about_window(const struct menu_st *m, int *query)
Definition: popular_user_funcs.c:53
dma65.h
ui_enter
void ui_enter(void)
Definition: ui.c:326
KBD_PRESS_KEY
#define KBD_PRESS_KEY(a)
Definition: emutools_hid.h:46
DEBUGGUI
#define DEBUGGUI
Definition: emutools_gui.h:22
XEMUGUI_MENUFLAG_SEPARATOR
#define XEMUGUI_MENUFLAG_SEPARATOR
Definition: emutools_gui.h:38
d81access.h