1 #include <fs/filesys.h>
2 #include "sysconfig.h"
3 #include "sysdeps.h"
4
5 #include "uae.h"
6
7 #include <string.h>
8 #include <string.h>
9
10 #include "uae/memory.h"
11 #include "autoconf.h"
12 #include "options.h"
13 #include "blkdev.h"
14 #include "clipboard.h"
15 #include "custom.h"
16 #include "keyboard.h"
17 #include "inputdevice.h"
18 #include "disk.h"
19 #include "gui.h"
20 #include "events.h"
21 #include "luascript.h"
22
23 #include "uae/fs.h"
24 #include "uae/log.h"
25 #include "uae/glib.h"
26 #include "uae/time.h"
27
28 void keyboard_settrans (void);
29 libamiga_callbacks g_libamiga_callbacks = {};
30 log_function g_amiga_gui_message_function = NULL;
31 amiga_media_function g_amiga_media_function = NULL;
32
33 int g_uae_deterministic_mode = 0;
34 int g_amiga_paused = 0;
35 bool g_fs_uae_jit_compiler;
36 int g_amiga_savestate_docompress = 1;
37
38 #ifdef DEBUG_SYNC
39 FILE* g_fs_uae_sync_debug_file = NULL;
40 #endif
41
42 int g_amiga_video_format = AMIGA_VIDEO_FORMAT_RGBA;
43 int g_amiga_video_bpp = 4;
44
45 static char *g_floppy_sounds_dir;
46
47 int g_fs_uae_writable_disk_images = 0;
48
49 // This is called from the main UAE thread to inform the GUI that a floppy
50 // disk has been inserted or ejected.
51
gui_filename(int num,const char * name)52 void gui_filename (int num, const char *name) {
53 if (g_amiga_media_function) {
54 g_amiga_media_function(num, name);
55 }
56 }
57
58 uae_callback_function *uae_on_save_state_finished = NULL;
59 uae_callback_function *uae_on_restore_state_finished = NULL;
60 uae_callback_function *uae_on_update_leds = NULL;
61
62
63 extern "C" {
64
amiga_set_min_first_line(int line,int ntsc)65 int amiga_set_min_first_line(int line, int ntsc) {
66 if (line < 0 || line > 100) {
67 return 1;
68 }
69 if (ntsc) {
70 g_uae_min_first_line_ntsc = line;
71 }
72 else {
73 g_uae_min_first_line_pal = line;
74 }
75 return 0;
76 }
77
amiga_get_vsync_counter()78 int amiga_get_vsync_counter() {
79 return g_uae_vsync_counter;
80 }
81
amiga_set_vsync_counter(int vsync_counter)82 void amiga_set_vsync_counter(int vsync_counter) {
83 g_uae_vsync_counter = vsync_counter;
84 }
85
amiga_on_restore_state_finished(amiga_callback_function * function)86 void amiga_on_restore_state_finished(amiga_callback_function *function) {
87 uae_on_restore_state_finished = function;
88 }
89
amiga_on_save_state_finished(amiga_callback_function * function)90 void amiga_on_save_state_finished(amiga_callback_function *function) {
91 uae_on_save_state_finished = function;
92 }
93
amiga_set_save_state_compression(int compress)94 void amiga_set_save_state_compression(int compress) {
95 g_amiga_savestate_docompress = compress ? 1 : 0;
96 }
97
98 #ifdef WITH_LUA
99
amiga_init_lua(void (* lock)(void),void (* unlock)(void))100 void amiga_init_lua(void (*lock)(void), void (*unlock)(void)) {
101 //uae_lua_init(lock, unlock);
102 write_log("WARNING: not sending lock function to uae_lua_init\n");
103 uae_lua_init();
104 }
105
amiga_init_lua_state(lua_State * L)106 void amiga_init_lua_state(lua_State *L) {
107 uae_lua_init_state(L);
108 }
109
110 #endif
111
amiga_set_floppy_sounds_dir(const char * path)112 void amiga_set_floppy_sounds_dir(const char *path) {
113 int len = strlen(path);
114 if (path[len - 1] == '/') {
115 g_floppy_sounds_dir = g_strdup(path);
116 }
117 else {
118 // must have directory separator at the end
119 g_floppy_sounds_dir = g_strconcat(path, "/", NULL);
120 }
121 }
122
amiga_set_media_function(amiga_media_function function)123 void amiga_set_media_function(amiga_media_function function) {
124 g_amiga_media_function = function;
125 }
126
amiga_floppy_set_writable_images(int writable)127 void amiga_floppy_set_writable_images(int writable) {
128 g_fs_uae_writable_disk_images = writable;
129 }
130
amiga_init(void)131 int amiga_init(void)
132 {
133 printf("UAE: Initializing core derived from %s\n", UAE_BASE_VERSION);
134 write_log("UAE: Initializing core derived from %s\n", UAE_BASE_VERSION);
135
136 uae_register_main_thread();
137 uae_time_init();
138
139 /*
140 #ifdef DEBUG_SYNC
141 g_sync_debug_file = fopen("sync.log", "wb");
142 #endif
143 */
144
145 // clock sync base is 1000000 (microseconds)
146 syncbase = 1000000;
147
148 // clock sync base is 10000 (tenths of milliseconds)
149 //syncbase = 10000;
150
151 filesys_host_init();
152
153 romlist_init();
154 clipboard_init();
155 return 1;
156 }
157
amiga_init_jit_compiler(void)158 bool amiga_init_jit_compiler(void)
159 {
160 write_log("JIT: Enabling JIT compiler\n");
161 g_fs_uae_jit_compiler = true;
162 return true;
163 }
164
amiga_set_video_format(int format)165 void amiga_set_video_format(int format) {
166 g_amiga_video_format = format;
167 if (format == AMIGA_VIDEO_FORMAT_R5G6B5) {
168 g_amiga_video_bpp = 2;
169 }
170 else if (format == AMIGA_VIDEO_FORMAT_R5G5B5A1) {
171 g_amiga_video_bpp = 2;
172 }
173 else {
174 g_amiga_video_bpp = 4;
175 }
176 }
177
amiga_add_rtg_resolution(int width,int height)178 void amiga_add_rtg_resolution(int width, int height) {
179 write_log("adding rtg resolution %dx%d\n", width, height);
180 int *m = g_amiga_rtg_modes;
181 while (1) {
182 if (*m == -1) {
183 write_log("too many resolutions\n");
184 return;
185 }
186 if (*m == width && *(m + 1) == height) {
187 write_log("resolution already exists\n");
188 return;
189 }
190 if (*m == 0 && *(m + 1) ==0) {
191 *m = width;
192 *(m + 1) = height;
193 return;
194 }
195 m += 2;
196 }
197 }
198
amiga_map_cd_drives(int enable)199 void amiga_map_cd_drives(int enable) {
200 write_log("setting automount_cddrives to %d\n", enable != 0);
201 currprefs.win32_automount_cddrives = (enable != 0);
202 changed_prefs.win32_automount_cddrives = (enable != 0);
203 }
204
amiga_set_deterministic_mode()205 void amiga_set_deterministic_mode() {
206 write_log("libamiga enabling net play mode\n");
207 g_uae_deterministic_mode = 1;
208 }
209
amiga_write_uae_config(const char * path)210 void amiga_write_uae_config(const char *path) {
211 write_log("writing uae config to %s\n", path);
212 cfgfile_save(&currprefs, path, 0);
213 }
214
set_path(TCHAR * d1,TCHAR * d2,const TCHAR * s)215 static void set_path(TCHAR *d1, TCHAR *d2, const TCHAR *s)
216 {
217 /* Use PATH_MAX - 1 so we have space for any trailing slash */
218 uae_strlcpy(d1, s, PATH_MAX - 1);
219 int d1_len = strlen(d1);
220 if (d1[d1_len - 1] != '/') {
221 strcat(d1, "/");
222 }
223 uae_strlcpy(d2, d1, PATH_MAX);
224 }
225
amiga_set_paths(const char ** rom_paths,const char ** floppy_paths,const char ** cd_paths,const char ** hd_paths)226 void amiga_set_paths(const char **rom_paths, const char **floppy_paths,
227 const char **cd_paths, const char **hd_paths)
228 {
229 for (int i = 0; i < MAX_PATHS; i++) {
230 if (floppy_paths[i] == NULL || floppy_paths[i][0] == '\0') {
231 break;
232 }
233 set_path(currprefs.path_floppy.path[i],
234 changed_prefs.path_floppy.path[i], floppy_paths[i]);
235 }
236 for (int i = 0; i < MAX_PATHS; i++) {
237 if (cd_paths[i] == NULL || cd_paths[i][0] == '\0') {
238 break;
239 }
240 set_path(currprefs.path_cd.path[i],
241 changed_prefs.path_cd.path[i], cd_paths[i]);
242 }
243 for (int i = 0; i < MAX_PATHS; i++) {
244 if (hd_paths[i] == NULL || hd_paths[i][0] == '\0') {
245 break;
246 }
247 set_path(currprefs.path_hardfile.path[i],
248 changed_prefs.path_hardfile.path[i], hd_paths[i]);
249 }
250 for (int i = 0; i < MAX_PATHS; i++) {
251 if (rom_paths[i] == NULL || rom_paths[i][0] == '\0') {
252 break;
253 }
254 set_path(currprefs.path_rom.path[i],
255 changed_prefs.path_rom.path[i], rom_paths[i]);
256 }
257 }
258
amiga_set_synchronization_log_file(const char * path)259 int amiga_set_synchronization_log_file(const char *path) {
260 #ifdef DEBUG_SYNC
261 FILE *f = g_fopen(path, "wb");
262 if (f) {
263 write_log("sync debug log to %s\n", path);
264 g_fs_uae_sync_debug_file = f;
265 return 1;
266 }
267 else {
268 write_log("error opening synchronization log file\n");
269 return 0;
270 }
271 #endif
272 }
273
amiga_quickstart(int quickstart_model,int quickstart_config,int accuracy)274 int amiga_quickstart(int quickstart_model, int quickstart_config,
275 int accuracy) {
276 int quickstart_compa = 1 - accuracy;
277 int quickstart_romcheck = 0;
278 write_log("amiga_quickstart model=%d config=%d compa=%d (accuracy %d)\n",
279 quickstart_model, quickstart_config, quickstart_compa, accuracy);
280 return built_in_prefs(&currprefs, quickstart_model, quickstart_config,
281 quickstart_compa, quickstart_romcheck);
282 }
283
amiga_get_rand_checksum()284 int amiga_get_rand_checksum() {
285 return uaerand() & 0x00ffffff;
286 }
287
amiga_get_state_checksum(void)288 int amiga_get_state_checksum(void)
289 {
290 int checksum = uae_get_memory_checksum(NULL, 0);
291 #ifdef DEBUG_SYNC
292 write_sync_log("memcheck: %08x\n", checksum);
293 #endif
294 return checksum & 0x00ffffff;
295 }
296
amiga_get_state_checksum_and_dump(void * data,int size)297 int amiga_get_state_checksum_and_dump(void *data, int size)
298 {
299 int checksum = uae_get_memory_checksum(data, size);
300 return checksum & 0x00ffffff;
301 }
302
amiga_main(void)303 void amiga_main(void)
304 {
305 write_log("amiga_main\n");
306 uae_register_emulation_thread();
307
308 keyboard_settrans();
309
310 int argc = 1;
311 char *argv[4] = {
312 strdup("fs-uae"),
313 NULL,
314 };
315 real_main(argc, argv);
316 #ifdef FILESYS
317 write_log("real_main returned\n");
318 write_log("calling filesys_flush_cache\n");
319 filesys_flush_cache ();
320 #endif
321 write_log("flushing all file streams\n");
322 fflush(NULL);
323 }
324
amiga_write_config(const char * path)325 void amiga_write_config(const char *path) {
326 cfgfile_save(&currprefs, path, 0);
327 }
328
amiga_enable_serial_port(const char * serial_name)329 int amiga_enable_serial_port(const char *serial_name)
330 {
331 write_log("amiga_enable_serial_port\n");
332 if (serial_name != NULL && serial_name[0]) {
333 write_log("serial port device: %s\n", serial_name);
334 strcpy(changed_prefs.sername, serial_name);
335 strcpy(currprefs.sername, serial_name);
336 changed_prefs.use_serial = 1;
337 currprefs.use_serial = 1;
338 return 1;
339 }
340 return 0;
341 }
342
amiga_enable_parallel_port(const char * parallel_name)343 int amiga_enable_parallel_port(const char *parallel_name)
344 {
345 write_log("amiga_enable_parallel_port\n");
346 if (parallel_name != NULL && parallel_name[0]) {
347 write_log("Parallel port device: %s\n", parallel_name);
348 strcpy(changed_prefs.prtname, parallel_name);
349 strcpy(currprefs.prtname, parallel_name);
350 return 1;
351 }
352 return 0;
353 }
354
amiga_set_cpu_idle(int idle)355 void amiga_set_cpu_idle(int idle)
356 {
357 idle = CLAMP(idle, 0, 10);
358 if (idle != 0) {
359 idle = (12 - idle) * 15;
360 }
361 uae_log("setting cpu_idle = %d\n", idle);
362 changed_prefs.cpu_idle = idle;
363 currprefs.cpu_idle = idle;
364 }
365
amiga_pause(int pause)366 int amiga_pause(int pause) {
367 //pause_emulation = pause;
368 if (pause) {
369 write_log("calling pausemode (1)\n");
370 //pausemode(-1);
371 g_amiga_paused = 1;
372 pausemode(9);
373 }
374 else {
375 write_log("calling pausemode (0)\n");
376 g_amiga_paused = 0;
377 //pausemode(-1);
378 pausemode(0);
379 }
380 return 0;
381 }
382
amiga_reset(int hard)383 int amiga_reset(int hard) {
384 uae_reset(hard, 1);
385 return hard;
386 }
387
amiga_state_save(int slot)388 int amiga_state_save(int slot) {
389 if (slot < 0) {
390 return 0;
391 }
392 if (slot >= 9) {
393 return 0;
394 }
395 write_log("amiga_state_save %d\n", slot);
396 int code = AKS_STATESAVEQUICK1 + slot * 2;
397 inputdevice_add_inputcode(code, 1);
398 return 1;
399 }
400
amiga_state_load(int slot)401 int amiga_state_load(int slot) {
402 if (slot < 0) {
403 return 0;
404 }
405 if (slot >= 9) {
406 return 0;
407 }
408 write_log("amiga_state_load %d\n", slot);
409 int code = AKS_STATERESTOREQUICK1 + slot * 2;
410 inputdevice_add_inputcode(code, 1);
411 return 1;
412 }
413
amiga_floppy_get_file(int index)414 const char *amiga_floppy_get_file(int index) {
415 return currprefs.floppyslots[index].df;
416 }
417
amiga_floppy_get_list_entry(int index)418 const char *amiga_floppy_get_list_entry(int index) {
419 return currprefs.dfxlist[index];
420 }
421
amiga_floppy_get_drive_type(int index)422 int amiga_floppy_get_drive_type(int index) {
423 return currprefs.floppyslots[index].dfxtype + 1;
424 }
425
amiga_get_num_cdrom_drives()426 int amiga_get_num_cdrom_drives() {
427 // FIXME: a bit hackish, do some sanity check on this method
428 for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
429 if (currprefs.cdslots[i].inuse != 0) {
430 return i + 1;
431 }
432 }
433 return 0;
434 }
435
amiga_get_num_floppy_drives()436 int amiga_get_num_floppy_drives() {
437 for (int i = 0; i < 4; i++) {
438 if (currprefs.floppyslots[i].dfxtype < 0) {
439 return i;
440 }
441 }
442 return 4;
443 }
444
amiga_floppy_set_from_list(int drive,int index)445 int amiga_floppy_set_from_list(int drive, int index) {
446 write_log("insert floppy (%d) into drive (%d)\n", index, drive);
447 if (drive < 0 || drive > 3) {
448 // assert
449 return 0;
450 }
451 if (index < 0 || index >= AMIGA_FLOPPY_LIST_SIZE) {
452 // assert
453 return 0;
454 }
455 write_log("perform disk_swap drive %d floppy entry %d\n", drive, index);
456 strcpy(changed_prefs.floppyslots[drive].df, currprefs.dfxlist[index]);
457 //strcpy(currprefs.floppyslots[drive].df, currprefs.dfxlist[entry]);
458 disk_insert(drive, currprefs.floppyslots[drive].df);
459 /*
460 int i;
461 // eject disk from other drive (if inserted)
462 for (i = 0; i < 4; i++) {
463 if (strcmp (currprefs.floppyslots[i].df, currprefs.dfxlist[index]) == 0)
464 changed_prefs.floppyslots[i].df[0] = 0;
465 }
466 // insert disk
467 // FIXME: IMPORTANT: CHECK length of file (prevent buffer overrun)
468 strcpy(changed_prefs.floppyslots[drive].df, currprefs.dfxlist[index]);
469 config_changed = 1;
470 return 1;
471 */
472 return 1;
473 }
474
amiga_floppy_set_file(int drive,const char * file)475 int amiga_floppy_set_file(int drive, const char *file) {
476 write_log("insert floppy (%s) into drive (%d)\n", file, drive);
477 int i;
478 // eject disk from other drive (if inserted)
479 for (i = 0; i < 4; i++) {
480 if (strcmp (currprefs.floppyslots[i].df, file) == 0) {
481 changed_prefs.floppyslots[i].df[0] = 0;
482 }
483 }
484 // insert disk
485 // FIXME: IMPORTANT: CHECK length of file (prevent buffer overrun)
486 strcpy(changed_prefs.floppyslots[drive].df, file);
487 config_changed = 1;
488 return 1;
489 }
490
amiga_cdrom_get_file(int index)491 const char *amiga_cdrom_get_file(int index) {
492 return currprefs.cdslots[index].name;
493 }
494
amiga_cdrom_eject(int drive)495 void amiga_cdrom_eject(int drive)
496 {
497 write_log("CD-ROM: eject drive %d\n", drive);
498 #if 0
499 write_log(" (currprefs.cdslots[%d].name = %s)\n",
500 drive, currprefs.cdslots[drive].name);
501 #endif
502
503 // changed_prefs.cdslots[drive].inuse = false;
504 changed_prefs.cdslots[drive].name[0] = '\0';
505 changed_prefs.cdslots[drive].type = SCSI_UNIT_DEFAULT;
506 config_changed = 1;
507 }
508
amiga_cdrom_set_file(int drive,const char * file)509 int amiga_cdrom_set_file(int drive, const char *file)
510 {
511 write_log("CD-ROM: insert \"%s\" into drive %d\n", file, drive);
512 #if 0
513 write_log(" (currprefs.cdslots[%d].name = %s)\n",
514 drive, currprefs.cdslots[drive].name);
515 write_log(" (changed_prefs.cdslots[%d].name = %s)\n",
516 drive, changed_prefs.cdslots[drive].name);
517 #endif
518
519 /* Eject CD from current drive */
520 amiga_cdrom_eject(drive);
521
522 /* Insert new CD */
523 if (file[0] != '\0') {
524 uae_tcslcpy(changed_prefs.cdslots[drive].name, file, MAX_DPATH);
525 // changed_prefs.cdslots[drive].inuse = 1;
526
527 /* Ejecting CD from other drives if it is inserted there */
528 // FIXME: REPLACE 4 with constant
529 for (int i = 0; i < 4; i++) {
530 if (i != drive && strcmp (currprefs.cdslots[i].name, file) == 0) {
531 amiga_cdrom_eject(i);
532 }
533 }
534 }
535 config_changed = 1;
536
537 return 1;
538 }
539
amiga_floppy_get_speed()540 int amiga_floppy_get_speed() {
541 int speed = currprefs.floppy_speed;
542 write_log("speed is %d\n", speed);
543 return speed / 100;
544 }
545
amiga_floppy_set_speed(int speed)546 int amiga_floppy_set_speed(int speed) {
547 write_log("set floppy speed to %d\n", speed);
548 changed_prefs.floppy_speed = speed * 100;
549 config_changed = 1;
550 return 1;
551 }
552
amiga_cpu_get_speed()553 int amiga_cpu_get_speed() {
554 int speed = currprefs.m68k_speed;
555 write_log("cpu speed is %d\n", speed);
556 write_log("cpu freq is %d\n", currprefs.cpu_frequency);
557 write_log("cpu mult is %d\n", currprefs.cpu_clock_multiplier);
558 return speed;
559 }
560
amiga_cpu_set_speed(int speed)561 int amiga_cpu_set_speed(int speed) {
562 static int initialized = 0;
563 static int org_cpu_clock_multiplier;
564 static int org_cpu_cycle_exact;
565 if (!initialized) {
566 org_cpu_clock_multiplier = currprefs.cpu_clock_multiplier;
567 org_cpu_cycle_exact = currprefs.cpu_cycle_exact;
568 initialized = 1;
569 }
570 write_log("set cpu speed to %d\n", speed);
571 changed_prefs.m68k_speed = speed;
572 if (speed == 0) {
573 changed_prefs.cpu_clock_multiplier = org_cpu_clock_multiplier;
574 changed_prefs.cpu_cycle_exact = org_cpu_cycle_exact;
575 }
576 else {
577 changed_prefs.cpu_clock_multiplier = 32;
578 changed_prefs.cpu_cycle_exact = 0;
579 }
580 config_changed = 1;
581 return 1;
582 }
583
amiga_parse_option(const char * option,const char * value,int type)584 static int amiga_parse_option(const char *option, const char *value, int type) {
585 // some strings are modified during parsing
586 char *value2 = strdup(value);
587 int result = cfgfile_parse_option(&currprefs, (char*) option,
588 (char*) value2, type);
589 free(value2);
590 write_log("set option \"%s\" to \"%s\" (result: %d)\n", option,
591 value, result);
592 if (result != 1) {
593 gui_message("Option failed: %s = %s", option, value);
594 amiga_log_warning("failed to set option \"%s\" to \"%s\" "
595 "(result: %d)\n", option, value, result);
596 }
597 return result;
598 }
599
amiga_set_option(const char * option,const char * value)600 int amiga_set_option(const char *option, const char *value) {
601 return amiga_parse_option(option, value, 0);
602 }
603
amiga_set_option_and_free(const char * option,char * value,amiga_free_function free_function)604 int amiga_set_option_and_free(const char *option, char *value,
605 amiga_free_function free_function) {
606 int result = amiga_set_option(option, value);
607 free_function(value);
608 return result;
609 }
610
amiga_set_hardware_option(const char * option,const char * value)611 int amiga_set_hardware_option(const char *option, const char *value) {
612 return amiga_parse_option(option, value, CONFIG_TYPE_HARDWARE);
613 }
614
amiga_set_int_option(const char * option,int value)615 int amiga_set_int_option(const char *option, int value) {
616 char *str_value = g_strdup_printf("%d", value);
617 int result = amiga_set_option(option, str_value);
618 g_free(str_value);
619 return result;
620 }
621
amiga_quit()622 int amiga_quit()
623 {
624 printf("UAE: Calling uae_quit\n");
625 uae_quit();
626 return 1;
627 }
628
amiga_set_display_function(display_function event_handler)629 void amiga_set_display_function(display_function event_handler) {
630 g_libamiga_callbacks.display = event_handler;
631 }
632
amiga_set_event_function(event_function event_handler)633 void amiga_set_event_function(event_function event_handler) {
634 g_libamiga_callbacks.event = event_handler;
635 }
636
amiga_set_init_function(init_function function)637 void amiga_set_init_function(init_function function) {
638 g_libamiga_callbacks.init = function;
639 }
640
amiga_set_render_function(render_function function)641 void amiga_set_render_function(render_function function) {
642 g_libamiga_callbacks.render = function;
643 }
644
amiga_set_log_function(log_function function)645 void amiga_set_log_function(log_function function) {
646 g_libamiga_callbacks.log = function;
647 }
648
amiga_set_gui_message_function(log_function function)649 void amiga_set_gui_message_function(log_function function) {
650 g_amiga_gui_message_function = function;
651 }
652
653 } // extern "C"
654
655 int disk_setwriteprotect (int num, const TCHAR *name, bool writeprotected);
gui_disk_image_change(int unitnum,const TCHAR * name,bool writeprotected)656 void gui_disk_image_change (int unitnum, const TCHAR *name, bool writeprotected) {
657 if (name && strlen(name) > 0) {
658 write_log("gui_disk_image_change drive %d name %s write protected %d\n",
659 unitnum, name, writeprotected);
660 /*
661 if (writeprotected) {
662 write_log("calling disk_setwriteprotect 0\n");
663 disk_setwriteprotect(unitnum, name, 0);
664 }
665 */
666 }
667 else {
668 write_log("gui_disk_image_change drive %d <no disk>\n", unitnum);
669 }
670
671 }
672
get_plugin_path(TCHAR * out,int size,const TCHAR * path)673 bool get_plugin_path (TCHAR *out, int size, const TCHAR *path) {
674 // static char* plugin_path_none = NULL;
675
676 if (strcmp(path, "floppysounds") == 0) {
677 if (g_floppy_sounds_dir) {
678 strncpy(out, g_floppy_sounds_dir, size);
679 }
680 else {
681 strncpy(out, "floppy_sounds", size);
682 }
683 // make sure out is null-terminated in any case
684 out[size - 1] = '\0';
685 }
686 else {
687 write_log("\n-----------------> STUB: get_plugin_path, "
688 "size: %d, path: %s\n", size, path);
689 out[0] = '\0';
690 }
691 return TRUE;
692 }
693
694