From d4b05b5c4bbe34d59b09db9c56c75f13465ed820 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Fri, 27 Aug 2010 19:40:34 +0300 Subject: [PATCH] 2300b13 --- akiko.cpp | 43 +- blkdev.cpp | 2 +- blkdev_cdimage.cpp | 20 +- cdtv.cpp | 62 +-- cfgfile.cpp | 16 +- custom.cpp | 6 +- gencpu.cpp | 4 +- include/akiko.h | 2 - include/cdtv.h | 3 - include/gui.h | 3 + include/inputdevice.h | 19 + include/options.h | 10 +- inputdevice.cpp | 87 ++-- od-win32/blkdev_win32_ioctl.cpp | 39 +- od-win32/hardfile_win32.cpp | 25 +- od-win32/lib/prowizard.lib | Bin 1140766 -> 1140414 bytes od-win32/prowizard/prowizard.vcxproj | 4 +- od-win32/prowizard/prowizard.vcxproj.filters | 12 +- od-win32/win32.cpp | 232 +++++++--- od-win32/win32.h | 4 +- od-win32/win32gfx.cpp | 75 +++- od-win32/win32gfx.h | 3 +- od-win32/win32gui.cpp | 18 +- od-win32/winuaechangelog.txt | 25 ++ prowizard/rippers/GMC.c | 311 ++++++++++++++ prowizard/rippers/NP3.c | 418 +++++++++++++++++++ prowizard/rippers/ProPacker10.c | 12 +- prowizard/rippers/ProPacker21.c | 25 +- prowizard/rippers/ProPacker30.c | 24 +- zfile.cpp | 2 +- 30 files changed, 1238 insertions(+), 268 deletions(-) create mode 100644 prowizard/rippers/GMC.c create mode 100644 prowizard/rippers/NP3.c diff --git a/akiko.cpp b/akiko.cpp index 77d059c2..9c19c45e 100644 --- a/akiko.cpp +++ b/akiko.cpp @@ -554,29 +554,35 @@ static bool isaudiotrack (int startlsn) return true; } +static struct cd_toc *get_track (int startlsn) +{ + for (int i = cdrom_toc_cd_buffer.first_track_offset + 1; i <= cdrom_toc_cd_buffer.last_track_offset; i++) { + struct cd_toc *s = &cdrom_toc_cd_buffer.toc[i]; + uae_u32 addr = s->paddress; + if (startlsn < addr) + return s - 1; + } + return NULL; +} static int last_play_end; static int cd_play_audio (int startlsn, int endlsn, int scan) { struct cd_toc *s = NULL; - uae_u32 addr; - int i; if (!cdrom_toc_cd_buffer.points) return 0; - for (i = cdrom_toc_cd_buffer.first_track_offset; i <= cdrom_toc_cd_buffer.last_track_offset; i++) { - s = &cdrom_toc_cd_buffer.toc[i]; - addr = s->paddress; - if (s->track > 0 && s->track < 100 && addr >= startlsn) - break; - } + s = get_track (startlsn); if (s && (s->control & 0x0c) == 0x04) { - write_log (L"tried to play data track %d!\n", s->track); - s++; + s = get_track (startlsn + 150); + if (s && (s->control & 0x0c) == 0x04) { + write_log (L"tried to play data track %d!\n", s->track); + s++; + startlsn = s->paddress; + s++; + endlsn = s->paddress; + } startlsn = s->paddress; - s++; - endlsn = s->paddress; - return 0; } qcode_valid = 0; last_play_end = endlsn; @@ -1844,17 +1850,6 @@ void restore_akiko_finish (void) #endif -void akiko_entergui (void) -{ - if (cdrom_playing) - write_comm_pipe_u32 (&requests, 0x0102, 1); -} -void akiko_exitgui (void) -{ - if (cdrom_playing) - write_comm_pipe_u32 (&requests, 0x0103, 1); -} - void akiko_mute (int muted) { cdrom_muted = muted; diff --git a/blkdev.cpp b/blkdev.cpp index 585a3b70..38573421 100644 --- a/blkdev.cpp +++ b/blkdev.cpp @@ -304,7 +304,7 @@ static int getunitinfo (int unitnum, int drive, cd_standard_unit csu, int *isaud } uae_u8 buffer[2048]; if (sys_command_cd_read (unitnum, buffer, 16, 1)) { - if (!memcmp (buffer + 8, "CDTV", 4) || !memcmp (buffer + 8, "CD32", 4)) { + if (!memcmp (buffer + 8, "CDTV", 4) || !memcmp (buffer + 8, "CD32", 4) || !memcmp (buffer + 8, "COMM", 4)) { uae_u32 crc; write_log (L"CD32 or CDTV"); if (sys_command_cd_read (unitnum, buffer, 21, 1)) { diff --git a/blkdev_cdimage.cpp b/blkdev_cdimage.cpp index 9012df8f..588bf93f 100644 --- a/blkdev_cdimage.cpp +++ b/blkdev_cdimage.cpp @@ -638,7 +638,7 @@ end: static void cdda_stop (struct cdunit *cdu) { - if (cdu->cdda_play > 0) { + if (cdu->cdda_play != 0) { cdu->cdda_play = -1; while (cdu->cdda_play) { Sleep (10); @@ -792,7 +792,11 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int } else if (sectorsize == 2336 && t->size == 2352) { // 2352 -> 2336 while (size-- > 0) { - zfile_fseek (t->handle, t->offset + sector * t->size + 16, SEEK_SET); + uae_u8 b = 0; + zfile_fseek (t->handle, t->offset + sector * t->size + 15, SEEK_SET); + zfile_fread (&b, 1, 1, t->handle); + if (b != 2 && b != 0) // MODE0 or MODE2 only allowed + return 0; zfile_fread (data, sectorsize, 1, t->handle); sector++; data += sectorsize; @@ -806,8 +810,8 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int cdu->cd_last_pos = sector; ret = sectorsize * size; - } else { + uae_u8 sectortype = extra >> 16; uae_u8 cmd9 = extra >> 8; int sync = (cmd9 >> 7) & 1; @@ -1146,7 +1150,7 @@ static int parsemds (struct cdunit *cdu, struct zfile *zmds, const TCHAR *img) } if (tb->subchannel && t->handle) { - t->suboffset = t->offset + t->size; + t->suboffset = t->size; t->subcode = 1; // interleaved t->subhandle = zfile_dup (t->handle); t->skipsize = SUB_CHANNEL_SIZE; @@ -1291,6 +1295,8 @@ static int parseccd (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img) } } + zfile_fclose (zimg); + zfile_fclose (zsub); return cdu->tracks; } @@ -1662,7 +1668,7 @@ static void unload_image (struct cdunit *cdu) { int i; - for (i = 0; i < cdu->tracks; i++) { + for (i = 0; i < sizeof cdu->toc / sizeof (struct cdtoc); i++) { struct cdtoc *t = &cdu->toc[i]; zfile_fclose (t->handle); if (t->handle != t->subhandle) @@ -1706,8 +1712,6 @@ static void close_device (int unitnum) struct cdunit *cdu = &cdunits[unitnum]; if (cdu->open) { cdda_stop (cdu); - unload_image (cdu); - uae_sem_destroy (&cdu->sub_sem); cdu->open = false; if (cdimage_unpack_thread) { cdimage_unpack_thread = 0; @@ -1718,6 +1722,8 @@ static void close_device (int unitnum) cdimage_unpack_thread = 0; destroy_comm_pipe (&unpack_pipe); } + unload_image (cdu); + uae_sem_destroy (&cdu->sub_sem); } blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name); } diff --git a/cdtv.cpp b/cdtv.cpp index 268ba4fd..308e965f 100644 --- a/cdtv.cpp +++ b/cdtv.cpp @@ -198,6 +198,8 @@ static int pause_audio (int pause) static int read_sectors (int start, int length) { + if (cd_playing) + cdaudiostop (); #ifdef CDTV_DEBUG_CMD write_log (L"READ DATA sector %d, %d sectors (blocksize=%d)\n", start, length, cdtv_sectorsize); #endif @@ -207,8 +209,6 @@ static int read_sectors (int start, int length) cdrom_length = length * cdtv_sectorsize; cd_motor = 1; cd_audio_status = AUDIO_STATUS_NOT_SUPPORTED; - if (cd_playing) - cdaudiostop (); return 0; } @@ -472,7 +472,7 @@ static int read_toc (int track, int msflsn, uae_u8 *out) static int cdrom_modeset (uae_u8 *cmd) { cdtv_sectorsize = (cmd[2] << 8) | cmd[3]; - if (cdtv_sectorsize != 2048 && cdtv_sectorsize != 2336) { + if (cdtv_sectorsize != 2048 && cdtv_sectorsize != 2336 && cdtv_sectorsize != 2352 && cdtv_sectorsize != 2328) { write_log (L"CDTV: tried to set unknown sector size %d\n", cdtv_sectorsize); cdtv_sectorsize = 2048; } @@ -631,47 +631,6 @@ static void cdrom_command_thread (uae_u8 b) } } -static int read_raw (int sector, uae_u8 *dst, int blocksize) -{ - int osector = sector - 150; - static struct zfile *f; - static int track; - int trackcnt; - TCHAR fname[MAX_DPATH]; - uae_u32 prevlsn = 0; - struct cd_toc *t = &toc.toc[0]; - - trackcnt = 0; - for (;;) { - int lsn = t->paddress; - if (t->point >= 0xa0) { - t++; - continue; - } - if (sector < lsn - prevlsn) - break; - trackcnt++; - sector -= lsn - prevlsn; - prevlsn = lsn; - t++; - } - if (track != trackcnt) { - _stprintf (fname, L"track%d.bin", trackcnt); - zfile_fclose (f); - f = zfile_fopen (fname, L"rb", ZFD_NORMAL); - if (f) - write_log (L"opened '%s'\n", fname); - track = trackcnt; - } - if (f) { - write_log (L"CDTV fakeraw: %dx%d=%d\n", sector, blocksize, sector * blocksize); - zfile_fseek (f, sector * blocksize, SEEK_SET); - zfile_fread (dst, blocksize, 1, f); - return 1; - } - return sys_command_cd_rawread (unitnum, dst, osector, blocksize, 1); -} - static void dma_do_thread (void) { static int readsector; @@ -693,10 +652,8 @@ static void dma_do_thread (void) uae_u8 buffer[2352]; if (!didread || readsector != (cdrom_offset / cdtv_sectorsize)) { readsector = cdrom_offset / cdtv_sectorsize; - if (readsector > 3000) - write_log (L""); if (cdtv_sectorsize != 2048) - didread = read_raw (readsector, buffer, cdtv_sectorsize); + didread = sys_command_cd_rawread (unitnum, buffer, readsector, 1, cdtv_sectorsize); else didread = sys_command_cd_read (unitnum, buffer, readsector, 1); if (!didread) { @@ -1960,14 +1917,3 @@ void restore_cdtv_finish (void) } #endif - -void cdtv_entergui (void) -{ - if (cd_playing && !cd_paused) - write_comm_pipe_u32 (&requests, 0x102, 1); -} -void cdtv_exitgui (void) -{ - if (cd_playing && !cd_paused) - write_comm_pipe_u32 (&requests, 0x103, 1); -} diff --git a/cfgfile.cpp b/cfgfile.cpp index 3fcea0ab..cdd2d79f 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -1494,27 +1494,27 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) } if (_tcscmp (option, L"joyportfriendlyname0") == 0 || _tcscmp (option, L"joyportfriendlyname1") == 0) { - inputdevice_joyport_config (p, value, _tcscmp (option, L"joyportfriendlyname0") == 0 ? 0 : 1, 0, 2); + inputdevice_joyport_config (p, value, _tcscmp (option, L"joyportfriendlyname0") == 0 ? 0 : 1, -1, 2); return 1; } if (_tcscmp (option, L"joyportfriendlyname2") == 0 || _tcscmp (option, L"joyportfriendlyname3") == 0) { - inputdevice_joyport_config (p, value, _tcscmp (option, L"joyportfriendlyname2") == 0 ? 2 : 3, 0, 2); + inputdevice_joyport_config (p, value, _tcscmp (option, L"joyportfriendlyname2") == 0 ? 2 : 3, -1, 2); return 1; } if (_tcscmp (option, L"joyportname0") == 0 || _tcscmp (option, L"joyportname1") == 0) { - inputdevice_joyport_config (p, value, _tcscmp (option, L"joyportname0") == 0 ? 0 : 1, 0, 1); + inputdevice_joyport_config (p, value, _tcscmp (option, L"joyportname0") == 0 ? 0 : 1, -1, 1); return 1; } if (_tcscmp (option, L"joyportname2") == 0 || _tcscmp (option, L"joyportname3") == 0) { - inputdevice_joyport_config (p, value, _tcscmp (option, L"joyportname2") == 0 ? 2 : 3, 0, 1); + inputdevice_joyport_config (p, value, _tcscmp (option, L"joyportname2") == 0 ? 2 : 3, -1, 1); return 1; } if (_tcscmp (option, L"joyport0") == 0 || _tcscmp (option, L"joyport1") == 0) { - inputdevice_joyport_config (p, value, _tcscmp (option, L"joyport0") == 0 ? 0 : 1, 0, 0); + inputdevice_joyport_config (p, value, _tcscmp (option, L"joyport0") == 0 ? 0 : 1, -1, 0); return 1; } if (_tcscmp (option, L"joyport2") == 0 || _tcscmp (option, L"joyport3") == 0) { - inputdevice_joyport_config (p, value, _tcscmp (option, L"joyport2") == 0 ? 2 : 3, 0, 0); + inputdevice_joyport_config (p, value, _tcscmp (option, L"joyport2") == 0 ? 2 : 3, -1, 0); return 1; } if (cfgfile_strval (option, value, L"joyport0mode", &p->jports[0].mode, joyportmodes, 0)) @@ -3107,13 +3107,13 @@ static int cfgfile_handle_custom_event (TCHAR *custom, int mode) } #endif -int cmdlineparser (TCHAR *s, TCHAR *outp[], int max) +int cmdlineparser (const TCHAR *s, TCHAR *outp[], int max) { int j, cnt = 0; int slash = 0; int quote = 0; TCHAR tmp1[MAX_DPATH]; - TCHAR *prev; + const TCHAR *prev; int doout; doout = 0; diff --git a/custom.cpp b/custom.cpp index 4546f5df..62714acb 100644 --- a/custom.cpp +++ b/custom.cpp @@ -206,6 +206,7 @@ struct sprite { }; static struct sprite spr[MAX_SPRITES]; +static int plfstrt_sprite; uaecptr sprite_0; int sprite_0_width, sprite_0_height, sprite_0_doubled; @@ -1803,6 +1804,7 @@ static void start_bpl_dma (int hpos, int hstart) } } + plfstrt_sprite = plfstrt; fetch_start (hpos); fetch_cycle = 0; last_fetch_hpos = hstart; @@ -4752,7 +4754,7 @@ STATIC_INLINE void do_sprites_1 (int num, int cycle, int hpos) if (cycle && !s->dmacycle) return; /* Superfrog intro flashing bee fix */ - dma = hpos < plfstrt || diwstate != DIW_waiting_stop; + dma = hpos < plfstrt_sprite || diwstate != DIW_waiting_stop; if (vpos == s->vstop || vpos == sprite_vblank_endline) { s->dmastate = 0; posctl = 1; @@ -5603,10 +5605,12 @@ static void hsync_handler (void) bsdsock_fake_int_handler (); } + plfstrt_sprite = plfstrt; /* See if there's a chance of a copper wait ending this line. */ cop_state.hpos = 0; cop_state.last_write = 0; compute_spcflag_copper (maxhpos); + serial_hsynchandler (); #ifdef CUSTOM_SIMPLE do_sprites (0); diff --git a/gencpu.cpp b/gencpu.cpp index 3b5afb51..a15a5655 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -1632,7 +1632,7 @@ static void gen_opcode (unsigned long int opcode) genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); if (curi->smode == immi) { - c = curi->size == sz_long ? 2 : 4; + // SUBAQ.x is always 8 cycles c += 4; } else { c = curi->size == sz_long ? 2 : 4; @@ -1718,7 +1718,7 @@ static void gen_opcode (unsigned long int opcode) genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); if (curi->smode == immi) { - c = curi->size == sz_long ? 2 : 4; + // ADDAQ.x is always 8 cycles c += 4; } else { c = curi->size == sz_long ? 2 : 4; diff --git a/include/akiko.h b/include/akiko.h index 06ae5447..bada59ed 100644 --- a/include/akiko.h +++ b/include/akiko.h @@ -7,8 +7,6 @@ extern void akiko_reset (void); extern int akiko_init (void); extern void akiko_free (void); -extern void akiko_entergui (void); -extern void akiko_exitgui (void); extern void AKIKO_hsync_handler (void); extern void akiko_mute (int); diff --git a/include/cdtv.h b/include/cdtv.h index 5b9af323..635eae12 100644 --- a/include/cdtv.h +++ b/include/cdtv.h @@ -8,9 +8,6 @@ extern void cdtv_free (void); extern void CDTV_hsync_handler(void); extern void cdtv_check_banks (void); -extern void cdtv_entergui (void); -extern void cdtv_exitgui (void); - void cdtv_battram_write (int addr, int v); uae_u8 cdtv_battram_read (int addr); diff --git a/include/gui.h b/include/gui.h index e28e24e1..be9c9ed6 100644 --- a/include/gui.h +++ b/include/gui.h @@ -21,6 +21,9 @@ extern void gui_disk_image_change (int, const TCHAR *, bool writeprotected); extern unsigned int gui_ledstate; extern void gui_display (int shortcut); +extern void gui_gameport_button_change (int port, int button, int onoff); +extern void gui_gameport_axis_change (int port, int axis, int state, int max); + extern bool no_gui, quit_to_gui; #define LED_CD_ACTIVE 1 diff --git a/include/inputdevice.h b/include/inputdevice.h index 9bedd0ea..d5e375a1 100644 --- a/include/inputdevice.h +++ b/include/inputdevice.h @@ -7,6 +7,25 @@ * Copyright 2001-2002 Toni Wilen */ +#define DIR_LEFT_BIT 0 +#define DIR_RIGHT_BIT 1 +#define DIR_UP_BIT 2 +#define DIR_DOWN_BIT 3 +#define DIR_LEFT (1 << DIR_LEFT_BIT) +#define DIR_RIGHT (1 << DIR_RIGHT_BIT) +#define DIR_UP (1 << DIR_UP_BIT) +#define DIR_DOWN (1 << DIR_DOWN_BIT) + +#define JOYBUTTON_1 0 /* fire/left mousebutton */ +#define JOYBUTTON_2 1 /* 2nd/right mousebutton */ +#define JOYBUTTON_3 2 /* 3rd/middle mousebutton */ +#define JOYBUTTON_CD32_PLAY 3 +#define JOYBUTTON_CD32_RWD 4 +#define JOYBUTTON_CD32_FFW 5 +#define JOYBUTTON_CD32_GREEN 6 +#define JOYBUTTON_CD32_YELLOW 7 +#define JOYBUTTON_CD32_RED 8 +#define JOYBUTTON_CD32_BLUE 9 #define IDTYPE_JOYSTICK 0 #define IDTYPE_MOUSE 1 diff --git a/include/options.h b/include/options.h index 6ccfc75c..6585241e 100644 --- a/include/options.h +++ b/include/options.h @@ -444,7 +444,7 @@ extern struct uaedev_config_info *add_filesys_config (struct uae_prefs *p, int i extern void default_prefs (struct uae_prefs *, int); extern void discard_prefs (struct uae_prefs *, int); -int parse_cmdline_option (struct uae_prefs *, TCHAR, const TCHAR *); +int parse_cmdline_option (struct uae_prefs *, TCHAR, const TCHAR*); extern int cfgfile_yesno (const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location); extern int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, int scale); @@ -453,11 +453,11 @@ extern int cfgfile_string (const TCHAR *option, const TCHAR *value, const TCHAR extern TCHAR *cfgfile_subst_path (const TCHAR *path, const TCHAR *subst, const TCHAR *file); extern TCHAR *target_expand_environment (const TCHAR *path); -extern int target_parse_option (struct uae_prefs *, TCHAR *option, TCHAR *value); +extern int target_parse_option (struct uae_prefs *, const TCHAR *option, const TCHAR *value); extern void target_save_options (struct zfile*, struct uae_prefs *); extern void target_default_options (struct uae_prefs *, int type); extern void target_fixup_options (struct uae_prefs *); -extern int target_cfgfile_load (struct uae_prefs *, TCHAR *filename, int type, int isdefault); +extern int target_cfgfile_load (struct uae_prefs *, const TCHAR *filename, int type, int isdefault); extern void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type); extern int cfgfile_load (struct uae_prefs *p, const TCHAR *filename, int *type, int ignorelink, int userconfig); @@ -472,8 +472,8 @@ extern uae_u32 cfgfile_modify (uae_u32 index, TCHAR *parms, uae_u32 size, TCHAR extern void cfgfile_addcfgparam (TCHAR *); extern int built_in_prefs (struct uae_prefs *p, int model, int config, int compa, int romcheck); extern int built_in_chipset_prefs (struct uae_prefs *p); -extern int cmdlineparser (TCHAR *s, TCHAR *outp[], int max); -extern int cfgfile_configuration_change(int); +extern int cmdlineparser (const TCHAR *s, TCHAR *outp[], int max); +extern int cfgfile_configuration_change (int); extern void fixup_prefs_dimensions (struct uae_prefs *prefs); extern void fixup_prefs (struct uae_prefs *prefs); extern void fixup_cpu (struct uae_prefs *prefs); diff --git a/inputdevice.cpp b/inputdevice.cpp index 19c8f8cd..ea027d68 100644 --- a/inputdevice.cpp +++ b/inputdevice.cpp @@ -45,13 +45,11 @@ #include "zfile.h" #include "cia.h" #include "autoconf.h" -#include "rp.h" -#include "dongle.h" -#include "cdtv.h" #ifdef RETROPLATFORM #include "rp.h" -#include "cloanto/RetroPlatformIPC.h" #endif +#include "dongle.h" +#include "cdtv.h" extern int bootrom_header, bootrom_items; @@ -63,25 +61,9 @@ extern int bootrom_header, bootrom_items; int inputdevice_logging = 0; -#define DIR_LEFT 1 -#define DIR_RIGHT 2 -#define DIR_UP 4 -#define DIR_DOWN 8 - #define IE_INVERT 0x80 #define IE_CDTV 0x100 -#define JOYBUTTON_1 0 /* fire/left mousebutton */ -#define JOYBUTTON_2 1 /* 2nd/right mousebutton */ -#define JOYBUTTON_3 2 /* 3rd/middle mousebutton */ -#define JOYBUTTON_CD32_PLAY 3 -#define JOYBUTTON_CD32_RWD 4 -#define JOYBUTTON_CD32_FFW 5 -#define JOYBUTTON_CD32_GREEN 6 -#define JOYBUTTON_CD32_YELLOW 7 -#define JOYBUTTON_CD32_RED 8 -#define JOYBUTTON_CD32_BLUE 9 - #define INPUTEVENT_JOY1_CD32_FIRST INPUTEVENT_JOY1_CD32_PLAY #define INPUTEVENT_JOY2_CD32_FIRST INPUTEVENT_JOY2_CD32_PLAY #define INPUTEVENT_JOY1_CD32_LAST INPUTEVENT_JOY1_CD32_BLUE @@ -1844,8 +1826,11 @@ static int getvelocity (int num, int subnum, int pct) else if (val > 0) v = 1; } - if (!mouse_deltanoreset[num][subnum]) + if (!mouse_deltanoreset[num][subnum]) { mouse_delta[num][subnum] -= v; + gui_gameport_axis_change (num, subnum * 2 + 0, 0, -1); + gui_gameport_axis_change (num, subnum * 2 + 1, 0, -1); + } return v; } @@ -2848,14 +2833,10 @@ int handle_input_event (int nr, int state, int max, int autofire) if (state) { joybutton[joy] |= 1 << ie->data; -#ifdef RETROPLATFORM - rp_update_gameport (joy, RP_JOYSTICK_BUTTON1 << ie->data, 1); -#endif + gui_gameport_button_change (joy, ie->data, 1); } else { joybutton[joy] &= ~(1 << ie->data); -#ifdef RETROPLATFORM - rp_update_gameport (joy, RP_JOYSTICK_BUTTON1 << ie->data, 0); -#endif + gui_gameport_button_change (joy, ie->data, 0); } if (ie->data == 0 && old != (joybutton[joy] & (1 << ie->data)) && currprefs.cpu_cycle_exact) { @@ -2897,7 +2878,30 @@ int handle_input_event (int nr, int state, int max, int autofire) delta = -JOYMOUSE_CDTV; } - mouse_delta[joy][unit] += delta * ((ie->data & IE_INVERT) ? -1 : 1); + if (ie->data & IE_INVERT) + delta = -delta; + mouse_delta[joy][unit] += delta; + + max = 32; + if (unit) { + if (delta < 0) { + gui_gameport_axis_change (joy, DIR_UP_BIT, abs (delta), max); + gui_gameport_axis_change (joy, DIR_DOWN_BIT, 0, max); + } + if (delta > 0) { + gui_gameport_axis_change (joy, DIR_DOWN_BIT, abs (delta), max); + gui_gameport_axis_change (joy, DIR_UP_BIT, 0, max); + } + } else { + if (delta < 0) { + gui_gameport_axis_change (joy, DIR_LEFT_BIT, abs (delta), max); + gui_gameport_axis_change (joy, DIR_RIGHT_BIT, 0, max); + } + if (delta > 0) { + gui_gameport_axis_change (joy, DIR_RIGHT_BIT, abs (delta), max); + gui_gameport_axis_change (joy, DIR_LEFT_BIT, 0, max); + } + } } else if (ie->type & 32) { /* button mouse emulation vertical */ @@ -2941,6 +2945,19 @@ int handle_input_event (int nr, int state, int max, int autofire) } if (ie->data & IE_INVERT) state = -state; + + if (!unit) { + if (state <= 0) + gui_gameport_axis_change (joy, DIR_UP_BIT, abs (state), max); + if (state >= 0) + gui_gameport_axis_change (joy, DIR_DOWN_BIT, abs (state), max); + } else { + if (state <= 0) + gui_gameport_axis_change (joy, DIR_LEFT_BIT, abs (state), max); + if (state >= 0) + gui_gameport_axis_change (joy, DIR_RIGHT_BIT, abs (state), max); + } + state = state * currprefs.input_analog_joystick_mult / max; state += (128 * currprefs.input_analog_joystick_mult / 100) + currprefs.input_analog_joystick_offset; if (state < 0) @@ -2948,6 +2965,8 @@ int handle_input_event (int nr, int state, int max, int autofire) if (state > 255) state = 255; joydirpot[joy][unit] = state; + mouse_deltanoreset[joy][0] = 1; + mouse_deltanoreset[joy][1] = 1; } else { @@ -2979,6 +2998,8 @@ int handle_input_event (int nr, int state, int max, int autofire) if (ie->data & DIR_DOWN) bot = obot[joy] = pos; } + mouse_deltanoreset[joy][0] = 1; + mouse_deltanoreset[joy][1] = 1; joydir[joy] = 0; if (left) joydir[joy] |= DIR_LEFT; @@ -2988,12 +3009,10 @@ int handle_input_event (int nr, int state, int max, int autofire) joydir[joy] |= DIR_UP; if (bot) joydir[joy] |= DIR_DOWN; -#ifdef RETROPLATFORM - rp_update_gameport (joy, RP_JOYSTICK_LEFT, left); - rp_update_gameport (joy, RP_JOYSTICK_RIGHT, right); - rp_update_gameport (joy, RP_JOYSTICK_DOWN, bot); - rp_update_gameport (joy, RP_JOYSTICK_UP, top); -#endif + gui_gameport_axis_change (joy, DIR_LEFT_BIT, left, 0); + gui_gameport_axis_change (joy, DIR_RIGHT_BIT, right, 0); + gui_gameport_axis_change (joy, DIR_UP_BIT, top, 0); + gui_gameport_axis_change (joy, DIR_DOWN_BIT, bot, 0); } break; case 0: /* ->KEY */ diff --git a/od-win32/blkdev_win32_ioctl.cpp b/od-win32/blkdev_win32_ioctl.cpp index 85154bec..67013961 100644 --- a/od-win32/blkdev_win32_ioctl.cpp +++ b/od-win32/blkdev_win32_ioctl.cpp @@ -150,8 +150,7 @@ static int win32_error (struct dev_info_ioctl *ciw, int unitnum, const TCHAR *fo FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL); - if (log_scsi) - write_log (L"IOCTL: unit=%d,%s,%d: %s\n", unitnum, buf, err, (TCHAR*)lpMsgBuf); + write_log (L"IOCTL ERR: unit=%d,%s,%d: %s\n", unitnum, buf, err, (TCHAR*)lpMsgBuf); va_end (arglist); return err; } @@ -406,15 +405,9 @@ retry: int len = spti_read (ciw, unitnum, data, sector, sectorsize); if (len) { if (data) { - if (sectorsize >= 2352) { - memcpy (data, p, sectorsize); - data += sectorsize; - ret += sectorsize; - } else { - memcpy (data, p + 16, sectorsize); - data += sectorsize; - ret += sectorsize; - } + memcpy (data, p, sectorsize); + data += sectorsize; + ret += sectorsize; } got = true; } @@ -543,6 +536,7 @@ static void *cdda_play (void *v) if (oldplay != ciw->cdda_play) { idleframes = 0; + bool seensub = false; struct _timeb tb1, tb2; _ftime (&tb1); cdda_pos = ciw->cdda_start; @@ -570,11 +564,12 @@ static void *cdda_play (void *v) sub_deinterleave (dst + 2352, subbuf); if (seenindex) { for (int i = 2 * SUB_ENTRY_SIZE; i < SUB_CHANNEL_SIZE; i++) { - if (subbuf[i]) { // non-zero R-W subchannels + if (subbuf[i]) { // non-zero R-W subchannels? int diff = cdda_pos - sector + 2; write_log (L"-> CD+G start pos fudge -> %d (%d)\n", sector, -diff); idleframes -= diff; cdda_pos = sector; + seensub = true; break; } } @@ -591,6 +586,14 @@ static void *cdda_play (void *v) diff -= ciw->cdda_delay; if (idleframes >= 0 && diff < 0 && ciw->cdda_play > 0) Sleep (-diff); + if (diff > 0 && !seensub) { + int ch = diff / 7 + 25; + if (ch > idleframes) + ch = idleframes; + idleframes -= ch; + cdda_pos += ch; + } + setstate (ciw, AUDIO_STATUS_IN_PROGRESS); } @@ -717,7 +720,7 @@ end: static void cdda_stop (struct dev_info_ioctl *ciw) { - if (ciw->cdda_play > 0) { + if (ciw->cdda_play != 0) { ciw->cdda_play = -1; while (ciw->cdda_play) { Sleep (10); @@ -985,6 +988,11 @@ static int ioctl_command_readwrite (int unitnum, int sector, int size, int write if (!ciw) return 0; + if (ciw->usesptiread) + return ioctl_command_rawread (unitnum, data, sector, size, 2048, 0); + + cdda_stop (ciw); + DWORD dtotal; int cnt = 3; uae_u8 *p = ciw->tempbuffer; @@ -992,7 +1000,6 @@ static int ioctl_command_readwrite (int unitnum, int sector, int size, int write if (!open_createfile (ciw, 0)) return 0; - cdda_stop (ciw); ciw->cd_last_pos = sector; while (cnt-- > 0) { gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE); @@ -1033,9 +1040,10 @@ static int ioctl_command_readwrite (int unitnum, int sector, int size, int write return 0; } if (dtotal == 0) { + static int reported; /* ESS Mega (CDTV) "fake" data area returns zero bytes and no error.. */ spti_read (ciw, unitnum, data, sector, 2048); - if (log_scsi) + if (reported++ < 100) write_log (L"IOCTL unit %d, sector %d: ReadFile()==0. SPTI=%d\n", unitnum, sector, GetLastError ()); return 1; } @@ -1245,6 +1253,7 @@ static int sys_cddev_open (struct dev_info_ioctl *ciw, int unitnum) ioctl_command_stop (unitnum); update_device_info (unitnum); ciw->open = true; + //ciw->usesptiread = true; write_log (L"IOCTL: device '%s' (%s/%s/%s) opened succesfully (unit=%d,media=%d)\n", ciw->devname, ciw->di.vendorid, ciw->di.productid, ciw->di.revision, unitnum, ciw->di.media_inserted); diff --git a/od-win32/hardfile_win32.cpp b/od-win32/hardfile_win32.cpp index 495491b5..0e4f2fd0 100644 --- a/od-win32/hardfile_win32.cpp +++ b/od-win32/hardfile_win32.cpp @@ -88,10 +88,17 @@ static void rdbdump (HANDLE h, uae_u64 offset, uae_u8 *buf, int blocksize) int i, blocks; TCHAR name[100]; FILE *f; + bool needfree = false; - blocks = (buf[132] << 24) | (buf[133] << 16) | (buf[134] << 8) | (buf[135] << 0); - if (blocks < 0 || blocks > 100000) - return; + if (buf) { + blocks = (buf[132] << 24) | (buf[133] << 16) | (buf[134] << 8) | (buf[135] << 0); + if (blocks < 0 || blocks > 100000) + return; + } else { + blocks = 16383; + buf = (uae_u8*)VirtualAlloc (NULL, CACHE_SIZE, MEM_COMMIT, PAGE_READWRITE); + needfree = true; + } _stprintf (name, L"rdb_dump_%d.rdb", cnt); f = _tfopen (name, L"wb"); if (!f) @@ -107,6 +114,9 @@ static void rdbdump (HANDLE h, uae_u64 offset, uae_u8 *buf, int blocksize) offset += blocksize; } fclose (f); + if (needfree) + VirtualFree (buf, 0, MEM_RELEASE); + write_log (L"'%s' saved\n", name); cnt++; } @@ -219,6 +229,7 @@ static int ismounted (const TCHAR *name, HANDLE hd) #define CA "Commodore\0Amiga\0" static int safetycheck (HANDLE h, const TCHAR *name, uae_u64 offset, uae_u8 *buf, int blocksize) { + uae_u64 origoffset = offset; int i, j, blocks = 63, empty = 1; DWORD outlen; LONG high; @@ -252,6 +263,8 @@ static int safetycheck (HANDLE h, const TCHAR *name, uae_u64 offset, uae_u8 *buf } if (!memcmp (buf + 2, "CIS@", 4) && !memcmp (buf + 16, CA, strlen (CA))) { + if (do_rdbdump) + rdbdump (h, offset, NULL, blocksize); write_log (L"hd accepted (PCMCIA RAM)\n"); return -2; } @@ -284,12 +297,16 @@ static int safetycheck (HANDLE h, const TCHAR *name, uae_u64 offset, uae_u8 *buf regclosetree (fkey); } if (match) { + if (do_rdbdump > 1) + rdbdump (h, origoffset, NULL, blocksize); write_log (L"hd accepted, enabled in registry!\n"); return -7; } } mounted = ismounted (name, h); if (!mounted) { + if (do_rdbdump > 1) + rdbdump (h, origoffset, NULL, blocksize); write_log (L"hd accepted, not empty and not mounted in Windows\n"); return -8; } @@ -303,6 +320,8 @@ static int safetycheck (HANDLE h, const TCHAR *name, uae_u64 offset, uae_u8 *buf //write_log (L"hd ignored, not empty and no RDB detected or Windows mounted\n"); //return 0; } + if (do_rdbdump > 1) + rdbdump (h, origoffset, NULL, blocksize); write_log (L"hd accepted (empty)\n"); return -9; } diff --git a/od-win32/lib/prowizard.lib b/od-win32/lib/prowizard.lib index 0ae8ca6501bbc5f9d44e90792c5e933162b5ec1a..c2ddc8693fadfd04f4a1029ae67870788dce028f 100644 GIT binary patch delta 25323 zcmeHvd017|_xC<`zUL0-Dky^rC^#E(K?THFF-&oua!Spz%qaskr+XC#;EGvj+sqtF zv#cyLIjNO^rIk5gWme`;j%kUdg+uXv);afH5H8=}?|I(m`~LO%xbA12efC~^-fQo* z_F?_8)K3nluB@+5cD74MdcI+Emwb$||3v2|GggI!ptYbJ0(ADhXv8A6=i# zGyzDPQkw;&`E8iCD(#xXv{mU!7pA@9qMyK|i|)bhqkc!2t}@LoX1c2M+GM8l(VhcL z=cD7zn9fI6IxwA=^e$ly)B7mwZKn58+~Z8|qX)+`y^qFBVtOBC&R}{UEuYHtKHB^S z(^sW~$fqh@*D;qKKb6T4x}Nzdb~`iFM1xu|gO4U}WQPBVUU`EVs?xzbE@n7*=YG0A zlo_g!F{qIFsr3nFtV%;iF=JJl6U&TM>E#cY@jh}P;LGglRJNEItB@&r468;%mormU zav7MZDi!?2OjQYk+T^02N@Q+6lliI3DQ5Q3!xx#^N7Krf*+)z3GILdW;|McXrNd{L zxhmZq%UovsR3@?c9#)M8&0%6yTG)e$RcZTBCRU|05lpN?7VS#rC6|w3mgb*Sr@jN3 z#Yc~4FiTDJQXgjV(auiHQkjmEn}8SWEEW7m{ssn_+V!Bk@GaOR;BT=%<7}L z1DVxFYqFWOD(yx3s&uI~vsNLS%Q~Lf0#T>Q%;uw^W0|cgxpSGVD!qA{*?d&kli7T9 z;smo*rSi?p26EAlkL-`zZeyvsb1!3z)qsebbEDee^5h ztK{-AOtRKiDY6NZe3Z1ENj@5|hDlXv?mQ;_Z>XRflYI1*l}SE2??R^My>uJGs*of6 zS5}R>G-3{-{saH-$@QOvyt{%q{>$Y0Z)fm7$anqMYxtiF;QH@3@qaA9(Em>V@~*qI z4R*dM?ug2toEe)xbwSho){=>zep|HUm$quRb41HnA^-BU*!;KWH}k!b@^7|sYgp1S z4QrO6VQH^vSZIlc&AzT-wNtdL&3rAJvrEgmT+y-~(K>ddpNDYliI@avC zj&-=AV`~IGdpk_e9*@(r@ek_Rq%nFnBUA5UQnXzzTzm>_lrL8#UC(V&@py2QM30_LoMsxXj4LM4Q<1p(bW< znb=#(v3xr#c+<|BeFOeiJF9J#Sd&PJZBLTengJ4YsRLsG&Y=d$-gn8tI#<=VdQB1K0mUK&}HY= zk&Oj?XVw)jOGX{`a<7fPt#UgzjcM4|cYX=gCML)2{Q2#^hMm23YBf8b+_ghvP|h}S z`B5J>G1o7g)u&A~W8HbzXLX%-uJ~|GqgoSw=h3VFc`W^<7iy3FYN@BYfp;CCd1>dd zA1~_Fq)tBlm=GG0nA9$c{*4v;2zJ&0l7d<=Hd2+;;^$e-Ymg-OwhAv9y`o-RV-2a( z)+?!!sH^q(%BALR^6+4xU%dc=oau&Fm?XeV505+F5I zh+m&;i;=$_Eqw12fffnjhaMFqEyTz_Jt}NYsv)i1@)co+zY4pB5Po~JH<@LN@R1`> zvbxr_@{9r@+uQ!m7k3Ly^i;*EAO@O`#Be=DIi4jq956J!(kxPaEwczRZ+i_H2q)&C8RbJ=wm7 zRJK{#r+umT$}8GXzHYwOt`zZ|`PwPYz{$3L`mWZOit-9ga3;5@G*fBLf8C0)-pWjs zlM1wntpZDu!+yEH0P2GAlasNbyw(<>p8UfV?PE0*L%vc^x5Yb0;?$0LJ6flf{^Mxf zSB(Sb$$uDt!8+_AU6Hp_X`u?`?fUEN%4+ppBgVQane)@px=-a+19UGp{7<4*Kck!F z6UF1+vWM}O&+2S?YK3-u;a+QZ+5N0;ZFCJHvOhP+$d_Ny9r2043=Iu(CMoTytXC#R zqVDo@ar*AO{}#a^x8JPm7Zg~YobaLUC*SZPQ9O39w@o_l)xA|iD!%QaE=K&z$-lZ< zTCe(0WbtxAuNI+}M*nzC$r^^}zx5ZPu*en~)V5mtJx1;Kl>9=tepBthx$_l=g&0|g z)xYbLh4u^KhvU2@I1{JuUqd7C(wQVTcu+4XJN9Kdi6nFREooOeX!yr7dW~dRX`xZqawHUu}Wb$xj#Qy$exdGEK)9KiAup z1hqcbpN*=XK-n?KFJIB`RHu!SDx6QfuD2@5=3m!0imoYHuOPz)UoxeO^-x;(hG!C@c~{UdnXB3p!<*4l8g zLG|P^_7&aL#WOLPnm07KZDQrwLNbEt@~EShZt~?phFNv0%TOzCo@6-ZD*`W_Y-pln zKdBi%`=}5hx1VD8qiGFE^N;-)Bi~tVC{q_twZ*w(y+LjAhU*RIYizrBiw&!NZATpy z6z5bYyShoE(%0iRT5G!VPfpsJ$!9+|46CX8_?WxcAL)NJyj)3OUH;K^gG1@Vqt^|W z1GJ!8`*C*To4#bET-DkahVs(p*wifuHpYb3PEq))F z4$Vm|%SkQW#PE*~h<7yRoz5G(2{-w|^Tw9Ovb^9KIYY{LQGs#3P|BSbj1zS?b23Z$ zx(mkfLK!c=V9aS=c2(;cT_zRu(YmFAHd@d3MZcJ|r#+bn`oQ3ZT;DU_anV?RFoN3{ za^fq!&zYg~WZuhp=w8kUQ_7K*~wewaP@1Ak#)GM6 z9SEuCv61w=U`Z-i9)1T|LvZ+AV9_~w=N{t|LY-&-EieC&QVXd!h17fH>6fJ?gLvFW z#;{tYp82P`WPR$uKuAd~la_xYkNC*w(6|hU9)}dc%nFY3F|ZEcIw)Z;fvcs2$$svD zpF82_F8H}yey+COm$spwbNaciDhKZa8{iL|;pZ0mx##`dCO@~s&mH%3=lt9aKPO=H ztHtjIPOauRaIKZfO$0YUWnsebMtsd5@jY;{O5JyXYpEpJ3l2wMv{n(g<_dQJTr(x! zA#jcP^F1tK!uR~dZ^lTWnEyqvgV+5Xu$i~}-IyTKLJ))m-x_#HzOfEpQfO=<+~e>5 zZtMZL5oU_!A=izKFhSd2Hzr|DPA@V>xG2?1q#6u*8=X%7b~ENS13v;1=~10DiS1%3r|0}lg9<`2M)z!Kng;Mc$pfZqU*0>5R<<^BoG2?SgPeh0h_ zJP9;n_IwYl10+E*kOX}OBtb`jBAZ2tN7zGqDcVd7JU<+VfU@Kr8&=m`&3z#@ye_%XtwDD%0z^=e=fZc$<0J{UPVW!Y?Igp+sFvdtuJg_Hl6fh0=n1RK!USOU=z#!l@ z;1J+$;4t7m;Beq)z!AW2fus0ym-P+#BYzm1@~lsd;Q_V-FnWA!rS6QtSQ38tdk+GpBh5>x`55%tOY{#a|)iN+?ERB%l0>v5`S;#8_feQoF*FyrD}9=I?IN1PRj=K401sBrH;c zpPPx`rE2gadxA78nvxopp@s(-9p}HuDYisu4{kHmTe#Zx$U;T?a%kVn^5GN4WE-j8 z{mA+MtKR>X>g|kC^Z!isn*FMmZ`xz5CvU%OoGx^JB7nB-hA`|HpxOIR5|mwmx+n0Y zR#m|J<`MF*yM+$g^ zKX9&}^Z2=Se(oJV_lci7UD|KoENm z_yKSSkQDIyJ_WoJ0i=NOQc=LWfTVy6fKWAxAX302h!ijhA_Yu>NC88TqJT*bDPWRA z3Yg@O0wy`6fT=*FfN5tz3b@#(fDa&mR_sGSQoyu@AO(B`NDBBEkQ8tUkQDH7ASvLl zfuw-H0g?iyod79d+6j;X{tieAnBGofPn0ASvK`KvKZ;o)qxEKvKZvKvKYz5h-BO^rV1Ep_2lJt4&eBXjN4Khk@yW z7xjRofExfw0n;-nVA9~EfExoz0XGMd0&WTX3`m-scFYd|F9J!S-^HAvX9;7Ao?8P+ zPIsUaI0cvhoJk6}4VZZdAk9u2(JsI*fuzBY0ZD_O06qx32<+uoz+J2BUKzUgd5x6@ zH7VIT4-aUqC|MawcD8B)RP7Q$IA&K-u*I@;n@+U#Q2OQ2ty_8TJH|+nR;}+M(Q+}0 zdQIidkFC+Xu#TV;dK2GN7^4O`>LO@7Ux*;hq?n4+?I$?h9=&VqV00|~`<$!$t@-DM z*8h0Zf~ZMfs;Ap?TGLlHQ)y1>d1>(t9baL0wBjAl8;z0IE~5%eS#CXLDo=&+oSejl z<&3_}#oDGQu?$6Hc`xIKJ8PTj8_(xiAI?cX&j;5wEyOwZ1md`qGhxERtFha4w?6tIyIgE%V-01CDh#&*DIApaZeNe;`KCeFtLYnPK872jrY}OHSb^>KTpT z`r4dug;}R{Lw3#xooBSGlupPqOeu$O=>0xtbg3sDF>yk^@7a4o_JyVViO8oB*>|+e zDt4q4Ny|r_Jr5lD`({BRq@qPVuKN z86!p|(h<50fzc~*f~I2A3Hn}n>dl%@&~)g;!L{N9jjZM^@@Ai$dM`s;o{m%hHGb}r zF|2tV6oDoDwXm4ZvUD^Zaw;eDY%-d4#X7WD-sTvJ;6eYb4mL%0RL|`xN9YW#p3ouu za$av7pmWm8aE3mG&N-NR6CF=G1C1yBRMA;eULTXmlUl}a1e^YySfX+TBVF?hIlqZYH_+Ny=9AZ?Zu-S`3pbyou9kl=l=9_0$M~(VfSHgJuVHbFGT*Y>bD^tAHC@E?9N)*GiIR>T|czZ}$?F^Z~+zY4bU`xDB0lky%u zGKOmp_q|V4l3JDbH}D(7yK*5&S?g%e5W;Is(beTk!c0wg;b^;^du|F=9{PzPSRcwP zwMzMoLSr-^K2>YyU5bo4-Xz=<%-bY6LV00{sN+M!P0gduV!G9atS6ZUt@#JI+30QG zzj}J!>L+Wsi&Qf0DfR-X{+|H50QUj=0gHg6fW^Qkfct@SfS&?40>1#h1td+4?SOLV zN0_3qp=}k7eF2F5h5Jw7F`$5vSOSy;=zCJ#P;!duhB8uAcM6bH_d`HBq~kEC9MZ=F zf5CG;5Oc)+C6F}r*TAd5bHLw#zXM5Q{|USf{1;dX)S>~<+V0vwG>AJy<5Cav^$>6q z0Z~B8AQ@N=901fp(LD;(0iOZVSvu1jz7U9wk$WkS&g?6JR^UrOJ8&HkwRFGkeg8g? z&hUGHbcX-f1%@&@3Z%pQk3iZBoCekh-UgDYE(g+~JqqKh2`~=W4A=!ohxk6;=ixw7 z^|Yy>v-?V5B5*x03HUZJ8Ay8Qf{i-AZ9Jiv~?_kolV?I}6~KLOGffDZR`NWTW` z4ZI6X2MU-NeSt<`e;^$P1}a+u%cp4d7<9RXea>4qFtw|`Jy6ZtQiQ2Yu+n5pLhQwz zN6%9a;6W-bx-zGuXDX2fr_@sEch@xyG;G>Rf6R*6W zgSw;`>yt76(o|0`yfra$c#P?lmI2DLa20M=jPGxn;rHA0KWPht=ff{gHU4*R#N94a zH#u#XX>0Y13p%wd2FU;EE2fX-cXpVb_ohoyUG<}6 zqzi{rZHjFAGk}kLz*cdsEdFXLsGKYe*9lBECE4}srqv16U5QGv*ckIlUoypue5$$G zu198lZYzFhIlhH?bO2|lk~q1O`Ks4MlEld)TqmJTvf3%s_$EejHq=pFHEX(>wRLJJ zMd~o~6`vr*QP+EfSyD=|UvbpQaMYCtaAu+uFLSu)TFM)ym^b;XHHw7M)6J?Ua@utB z>;S%4U(#rKSC;ure^PQ{&RyzFnzz)vx_?&<4Z)l1YSzEa)Qfl>;4 zlj0?sD8K)vxm84USxP(NYQRRHEcJdv&m(5L;vH()ly`bo*G*n`#Qa>7>dD7FXn9#a zam)OPK78O~lOG%R%wwba_D_hNHhvOjiEmmcB14km+Ep3G_nOiLh^~XAe*CWtO{i$c zitr0G>Wv^iwnT_9pT~+b3!A5re8+G0NDddD&X9*~_`y&t0d{>#z(v)fFiT5wm^_IJTAZ7`2+(_{eO_1x%Y@U}t=(EvNfB5S4 zkN<`8JI6~Kz`6g^0?pg7i;s;H&uFG6$WFKZ0f9%oX`Ieib~G6HPcsBt!8oz5#&rsf zK>F9h&U!hK-35o9L|D0(6In1;KeQFXLcN^G9sox>C<}9XIgzD-qYWso4thC}jRc3H zA?y(^C$g#FB%HnxI74Nb$QFX5jg5uTfsZ(mtpZ281`Au`9I0>%d&|p-jJ8bV z$ie+ZFDJ6Y;DVK~5-%q*veDA2YhjnbB@-($4f?E}5@_&pBC8M1u7pK-Igxb)N4ruB z22%eC;($mQV`j-;(&Bf4xqXs^+!FWClKYNTTJj1)2JufOi1l3$E%`B{XWrn`Chd1A z)HZBZQoL;qQ0x+$g%J)0QR;?qr_TpsV^O<Y|2xV z!b{5>c%>GgE#F=!hG@rXPxGY5#dg9jeydPyHRE?&ZGSOIj9zbh)F9Lhd1V_j8i_wkR#OBFKH)mT7U%GioMC%kJUW zg=9O&3LcO7V=>`TU7u2i|eDxQM4bAs!e0 z;BouK290U;zyR|9Gort#;1ouvr}z9ufj-0#jmL8uel1%QZkPyum4;h$G!cBo3SF?W z3Q>Gf%dhSi>+|bRiY>w}Qzv`>QAR7lw+Ef#ICMt}A8^weaUx*)8nGq6FiG4jyuovy z5?l9Lgq_t^lw>Ke7?=k<4txXn8}J=qDbS7o_kcTrw9_Jc6`7aN9c~f$0UwZMXvm}H z3BmmAN}ZnDF4>LxC^|>vH!O?f5&dkYL5}@YOq!+!X2dVe76Z*{g$&BnYp8@_(NtCx z1B(PlgTkPkJ?euCR!%E4`wXlNZ@5O=K+~S_8_PA}JoI;4sF~_b|B`vbdX^xba!?fc zlqncu?fKIPXucaoruTb*v?$Pip3XXjz<6L0Fd10P&rT5^3(1*(K4<l7=Wl&z~ z^8PvVOLOMmYgB*hj>=Sx3Wae~u zOK~$hEmA4S&5AU&veTj}o+7f-8df|-W~Vi(c&eYB7G3ewAUiF_m31I0tFS{k?k_C) z1yk0Odd-u5Hg`xlCT8A?XdBPxSmRoLo~P^QD^?#gU0REZCu4S6OOLYZpr8p@X+|X& zX&F4E{Q^cQUp#8cR=$TmPBh*F^faDYzmF5G7hCZXt=GEZ39T1b@r2fMW*uOR;rg7Xb$He( z&pA(Ud8w~sB4PkUM%@5&yg$$n6) z-y(0b;deGnODm3NVrlk!T*JhecZlX=RMUYa%Krmkxa@U~7`uE9IckdxJn zRavQJ4$u6{Xz23vYtoY47>T}0p7Ip6q}3XBHQh@si(^X4w1p#6iZX<*p3IYe;}vXH z+9K8P1tGkj)li2|vKp*Be}-6ZBrQrELBXsCemf}~*@|f^gf$MeUffD}g=U@y#1Pc4d&ox4as$p<`dpQ`v zy<8tZ2hX!N>{GC#K(oJ$o*YER{wVy-!rT9YS44ciA!ZTf@$uyvSe>Ra+7s42?9#VKh;^gHd8 zp}D}R@tok)c%8ttR^E1x1WOjMU`D>cmI~Jw9GT(_Y>=L>=wYevqGLmb2|?a}w121t z9{FKI3X?*W_X|->qw-db_fVDhNAR98RUi&Jj0}R6<+mom%1&Cb2x-_9ej`H+GE+Gy z-%C^#THJAz(A`HjvgF zGHQJZ3AQ|K&UCh%F{9N=8w0^mHL8#o`h2)F=9Csa2u z7q|$x9EhdR{XB3fFdw*#Za1w4lLMsVYcB9*;Bw$QKx!&FxUK;113m{V22zufPxE;o zS@H9MwD*1y*Z|0Z5x})Tx_Yn<_#kjSFdeuNI0`7d%FnzmHncb}E@;+RSTMJ26(e}a z95J-Id4;SqLR@~ykI_~-b?3d5CE4PP)^StD9b2N`zuWQER?g@6D_lEeYm3HT5 zP!CO)y}Xta-({>!7whu44Z7+4;5;$bN|T%PRGVSBaf+2wn9fVK+Um%y=ZiD6eAQiZ zu<~Jq_qO(dyRgU6jpOy)bzR?Gu7A(03Gj)DVw3tRQe1bx9cgJ}(Qc;H8K`YP^)sDQ zjm47zKABN0QDgdu-}sH6^a)f*o5Z9lW}}@D)s;8wXrIWB3=$pu^}!;(lW z`>RWqA^CAbh%;W1qyAJfPT@v-7{Bz6Xj97hWDB2gdBS#aOY?wz@`?Q2N%0Lmm){X< zRkT%I{`P56z2Cj>w0N*Vz@%&CxPQbVeMq~u0ZXG?6OYhZR54Di#T{8qjEuG(Z3u0b zq&7^|3MnG`H1~>lq`Bpf>Lrn3w;N~(i3==2F{Oq&@BcK2I+0GJQR>GvNqsF70(_OB zbYjm(EzfB}eAY;%e3jZ;`QkFUty+IF)7DmOF0 zwf>+9O-f1*STwTS2eoUbzN;|3H|0AHOWo!6;Z{!|6F$kE7Hd6*vEofywdH86@TpEL ze$;X!2w06R12soC#HT`&;Rc-vEsUSH$wwa$qNTrhrhs~966JZpVhAJR51pfF`o z*?7_FP{yAzQuRNTU9>(G$frPMvl(nKwYBrMR-ldzN%Ur>I?8BZPsZvyppv63&1ySV zy~nvy`Qmmq(HI(6!-!PYFn+hAO&#HDln=_}ft_skY8r`U18oO1d`yPMRQtj7?)SSe zl2CtqCZ3=!6jWZj;#*o9jr+rjRue;Et{~s6N8+U!nh5a?@P`}-3*!CT!I`lN&)0EC z$>JM^+M*4+LU2V$TD2L-jKpx}Jm>lM0j;a~GZ zswV>#tmMhSlj_O%X^sY-jFY2ngET?EefQRhfhUvBl+WpXF0#%dZ09R`GS=|I_L|e0 ziBsf;FPLKkcrw}w{MH$vx4uo(15smm$vhmmH*_>~;M3nR7%Kup`O?}JhvM^~^PB4P zAg*Sg2c0=op9gWO&!d|XMm`VXYW8{1xkdGP5U2V)&_yN$(r(ki=lpGLfL)T=;UbR) zdK7QSqd}bN(IAtm>d_!h^=OcR)xyZ5L7eK*prfqn(IBp7hXx(!EG!CpGUEIW4IKg% zk4D|bMrlzl#?B_ZX8MnCu<@GXpUXh#(5!>E6aLES$Rj7(>W&-ayGnEbrg_?)D(15! z7?TDk>3!Y@stc@Y{c*c!xJ|Je!V;&LEmenrd$zHQwCpZ2T6kM^N?fN*OQdC&1peYg zTl4-@2-T#QyEx@fNb3L#{#FDoE|eB;045wisANt#siLo%eMKwJTR!NfQUYCao^=pD z@kxI130t^JT7u&YQ~ek-4Qf%k`MePmW_+-TgsDz|tTNabGE+KCq(w3#;d?tKVF0bZp5oiE@~Y1#7>pwEnu3X~{n3w2MqJ8Q0otV`Y|>tM(< zt1>jtjPGFdJ!m!04B;K0w1xHcR(jzbMm1cNhQsrrwW|z=VpRa zi@Hd|2aMO%Z%nHz=9~W?8EdFzD2#9ey;q$*Wbb)Wb@m9o_<$Y8AReBhi7}H1in^H} zeahB33@0@IKYFziPfpM(-gL5UgR2V;mkvbf4r~eR0qh3s1*CyX??(Z911AFe0Ve?m z0;dCEJ9N(m4g=yeiob_~%S*r!z#YKRz%#(9z*1laP(U%}0HZaq`MANvAz&%6BhUlv z16&Rq3M4^fy&%DE;B!DS!@<Nq z79O|HtmE3LwynH;xyH&(Pnbe^`95Ta1VR&t{so;+Ctc%FWh6IiuBkuj({{0XMIEOW3q& z3@Kk7_DR%brTOM??m!oVpq2ze6S0a8PP8e0UHFz3BwB!y>)W-kV zzGS9mr_ka{Jc-%q<#?fKQIeZpuKD5E)niw(hvP%jYvcz~8U#Lztip)$^ipZb11?N$ zwfwn@C0brR^RH!Rk%4Dn5jEF=EX9ox|6`s^cc>1gUZZ(cX@&JwODCdmqJYbx+TxcM z{!Eq~ZE;bVnBB8n^>p|m_7F7`Q>(^wRgP+?8k3ZXs1G1hs2UT#p24CqKuk^5m?ny8 z_Qh;msi0alYSsaLR*|R}{~J>4q?Re4s)nX33%XRWAA@4y0n$rL3TH3ql9THDP}S=u zI0!FD%LBWaP8l)YUJZ`V4vy>DE3-7OpJp#DwtUPpwieBLXMRocy|-mm0jlRAbE#L{ z{4!7aP452Q+Jo=uqzmWv4BH6TU~~f6Rf5^$_{BN_ZZdvpm>O8FpTh+7hJEbk4*9vC z{M;=+*9B!$rNE-+T|{5-hwW84GV-7I2hzf;CQ0&hbVHElWiVR~j>e3Ey#r1yDmkas z6j#BiE{)n4F=~n^aI_i*GrFbgmF$0;3T|4QBJd%w4=54IqS;E}hJvG2IGBwDhb=xb zCUY~Hvw|7j6Qpi5una#p8(bSDY#z7-g>!?8SGdK*@pI>eFc)o+sV2UEqz7m%LPsk& zs>*vZ+WRyIW#6sJ`>&Mus?oj~-gl|;zBvh2bdh4Tk5EkKam+#cN&i186cr+yFBI|F zYpYo{6TJ4q!$KJEJIgl6QidVi2|8|CW(LpOr*FU?>TL+4SzjK7R1+9omQ{`NwBY;x zkyKJj-9a(la2ZQ1#oY&N2rLGY*J?iynn?M`1PVdc@f!_hY1zrc90Mb(QJrH(tb{bd@cm~)2cn%l|{2AB+cmdc7co|3=jjKS~ zTtJrlVPGk68t?{iCh!)0cC!*p83J|!?*L^WEdTD^-tbf2@U!0VpS|H^<)`=}km6f` zB!^m$!pYcA;pE4n@DbkdG2Za8!0Yf#xE}}e7mz-{r8~E@?=}Hf0?ojUz;e7NJxN}K z9Y8Da7?8XPCxH_1I~(1>i$^ylkj{7sX;0{kr~ zrGoftCU3&(;|$nN%HQ^AE7&E)P_w1JVo8#h3;2^$fk%McIl?|rAJQhEJz6oJ;YNS7 zUA4fKMBCr2$$S>m-i}(vCk8YiC6WP!iya{+43@ll9qp?F^k2#I_O+@pYQZ@B>-y06 z(Cwsc2?KMSEB^*>ad{@%OJ*+dmFqw^a%l`G)&Xxq)+Q;wQWi!fi(OEtVM-SA37gc>QGK*4(m#%n4hf-c0^4{KIeZ6A zl%{~oO!>=5_J-2b03%+J)g)26im?>9DM(ZZ@7!LJlo3Cmz0{%xIUIk*Dn{g;JTNK(7$-DuVP>K-HoS_PG|b(|$_(ucOKX&5Qr1K8(F>U4~pFI`Ni zp~2qWA>D$Y{%cP|co)l0qDMOyy?s^Lu zc~|ONuZETk330U3hj>3St)kzkhwJh=^&JjnwB*%yY!6^qr@GQ#bK>}GPEoSCgJT{P zU5z6K^CZsa+M-IU^8|n5l?AEuvNb6XG_*N?&pGJiyCI)U(r7LC*8eT6yjM516_wTD`pPr=?638Tk>};}S0|H@(2qHm{?GZ&?j zr@H5>gBkA~$(SFhPfkfmPI@c0zH^&_vHuj#tzxWF5JHZyDxv9OCR7g3EoH+05S&Va zHT#(04cjg;!5fbBWkTgpUd)6_LDOVCs}lN+Wg2goG>B;`ht<=VX7w~D{izy`c4r!I zxVeF8`~+=!7v?u)k7U})Ve2NQtsJgSX4t=MBdOF`YMDoyc^apmz#~nBE)0&ojL@BraomZ|J;)>Ahjl3a0mltdE%98|JQI zdT&^BhUqJZy|_;0aI+hY&yFgT7gUub-R83Kh~LzuxEMxS7Y|0yg#!wi+fzC`Qz!+?>k{m4Y$kFXju0R%Wam`o7JKmBWD*i$u>9$>~w!4&^C zs}lMaGE?Q?Y{^WOgZvmXRSq}TBOU#z5X|*IX1>rqh?%{ie*`mo!}x~G>pW#-CZ zorak!heM&vTsi!+kU7oxQ!$9Od$TH`R}>Q~2iGblRt}$TVPfTQW-1da1&ihe^8}|? zV3zukRYT?`X7PsSk1B@UCGuAem&P+|rC@Vf3YpDcXnla$yrIum%vL!}zs78p z!zXQ+%^Qk7U^Z_!*^JpL1-qbQ6r5f`Vf;L1_l8y{nZ0rt5y$M_Fzs1p_l8A@%w92k zQiItmhkwsuc5f&~dNnw`0+VbL)e!Rrlf0p&ok`yCbSaZ6hpDHT^uH72RZQ}RgQJ<` z4Huob=tWPs2W6E)P-ItDCA6Qxf++O-{Qo>S|C5qUH(1brIXM5@7x*9aJOAr7{Lck& z{`Z^sKNg_xf9L-4p&`avo7ah-#qjG-iwT<}8;Zh$(OHcbjGb0@!NvwpEVweR@q+c) z^&p2VaJ{47ys*)n$JB??1+o9C>oja*Y}Gl&j)VwoaZ`aUeNJHe)(GsG6 z(AdC+^fIs$qYdoLasx};XJB)08rWYUMrKVkvbXyh+3+bwcI{mw+jGFk4wND;-oy&~ znpjIr^pD9Vw*IDxeO%v+0c>Uw{mrc5cr)wzhM8&BnOW!|Gh6tNnf0#i6j@X+k*#ux zY|E!2n|elMH#8O&S>M7oWm?#==Pm5xB^I{qa|=6l$in(ww=k1nWuJ#zS*s)~n>*CX zHchdzOB}~vTG{wZR#s@Su>-Ab?5jRDc5S+iwfV%xJ}9!WW+!b-C)nA%cso1U%Fg0O z*x9og)9fs9k)74}#LnjY8*;IoO|(hujTnj9TS~0-X^EYlDzR0v#6};K*u;xCz9+G+ zkwI(*o)|vw8N_aES|IlSSZKFkYyT#;cC0?D$HuZQ>|db*NZw;s} zwB7vSfZBq-J!^-PN1r|Dkya19t4fwK{N7Wc%zU)tx+G;S7tb{f1&j+6_I1@E1+Yms&H z#&bLBS53b_`1u{Vx>b0`=*^V)hB=IX7a~ZMOa3K9SXeVawwj5;GkR|}Tr13x)I2${ zQi*5P^_Ez^(p0!wCxEWk2MYHe(Zv@%CrD~RV5!9Z(h#-U0)L;r`{75S8TF6N^8yXsoC0H^HU%VGBj-UWkzSKqo<}`!rSgM zbd(=7(Uiqhy*Bj~e*Xzwg1oP%W~MJUs#Al%*iRFrsCb_d1 zmAg*R+^*Of4&Hx~M(L&Us7ad1ehRI0Q}=Ss(TZ0M@nuTuwkd>zIz)It7HyzZ0Q0ZN44chT1c zXpUUmL#K9};2t_xoc~OR?7-h!?J32^)w(qyRkN+!D!j+HOw`B7vDhzO9IBX@$leQ~_ysDcRTD9=XmEV1!3)Xt)dL`R_K`$v+-pPA@FLjh-H2PRSxl#46WGPJlnXlYK z3T+O4CS0%Hx0?_G6bt1b2+zZI?@#Ulpm>+zDK8lBvIvc9RXVADpE z>`c~A3HDzNnv5IDhdb#%tfJLohWij^yq389K;`YxVbPRxSO?iMplo@gn_6&p=33o>=&Sy=X|v-dwdLG5hrI z#stXy{8jztM{_s3>B;>XFRw3ll;_^m|Kev%E7uMQF}&~1y|_P0e#Bw0YjJ7$oWn56 zPh(Lo-gb<+p&ZxHu)@>mseJrRgM*)K?8$qpvEgp50OehnY53TCMUFOh@Mn8@vW@9w z*ik(|wjW+HoO^h+4PtnW77yp0U_70V={B;S?+HgY#&ElC08J|v86r*U81yvvspSUs zZlxzIeoVy8de88_pIJ+3u-A4O7Ws-#Qzvh@&r|%?`wY7S+$H|tt}Q`6eAV!-FE3iG zj?zWiMkyCPbJMUoP@6Td8`t?VDh~=JA;usjccDYIy(yYSM9@SxQJ!(51^qsLDAHK}E zPdtZBjUU1p+Y-a4?l(l4T{^~=;A!8%k7jA&g|2-1a${Y7CrgvS+fCN!gy;BCLt;W$p34f-**uYqpA38C&PZ@U?7_)^t+$7|_fJK?nY3rzS%}(Va52Wb$2@nNF|s$JQw_Pv z70%~Q)VZ@tbGw%1_BW*;nyh!<%FQZuXCk3hc=UL#K>B=f>1UAm4~!rVTkvwofy>n?AxaMsED z<>gsoUM8Qu-565;TzN*BJL8U2z$s5VG)VfcsdGIlT4a<>(w1kIxic^H3>E#pH4)r=Fj~0U@07;DPYzAz3Js!w@PUcQYo3K^wBMoD?*6=~L!+`d5LsFrcZoqf7p z&h8+pTt=BR_mCX9!x*G-ib$V`ETJq25?#Z<+CXZh#I1saH51~#_DP3)(ixxhyHC3B zlOpuqy!Cxj3!n6aDq%N+J>!d<;*)ZH(mOtBoln~ClTP`ht3K(jPcoy6tHtjMNv-Bf zkeVo!8waVoDo*kx{KS`#_81#0b>9i8fs*ALNRKJfen?nrq1_Ha!VHdz{9xcKF6bkL zbA0~q#%SRH-$dBXj}X@LlHZLfW*X=rNc{^>Dm1p@L!PyZ{FOpux=_kD+%SgoBjF~I zpC~lOA>wYKF%2WI(M@9%boMMVhB#%$TxMkd0x`@*b&?VJ`L^zhl2aTvETvF z1%3z42Ty`4z{B7M@F=(iJO(0;{Q&*~9tW?3{|4_e=42-z7zM_D1gnFjNCrvKw;(Ax z1d^f)ASwD2Bt-@c6H*iblAZ=2>1hR$o=gxIbqxo91IK}vLAc6TF?d$vWb6intBAM> z{tey&br@N;-#+2f@DJFW|qpU>0I|)NW&Y z{}!E_zcn`0trVBM#D&M;<>>jXag$)BA<-3m?C9tnclcYAjSe33r*VgTZm;o6jp{?= zLsx6ULz^e54jt7W_Bzbyjk;blS|Z+tma7iNevW=Y)rBz4;<~)u2>Wa~`=GJ6F(~YXvlqAQ)*Zc4u(-Q( zR$ZAa>Sa6G(C?`B|KEoG->{(_F_!-y*-#la)Gbth$&dML$$!6U3=ghsJ$K4s*Q#1i z)zmy{J?-e&s`XT*!x)IFbk--8_#`;@J!hkRQWKxl&L{O$C9}MSQ44iwVuZz zsn+upB-MKU3Q4t|7d+PUwrV|pR;}j&)q3t!ttSm~vYt1{dWP|iH;lFa_f6<+)r7u{ z37<^pB9KhzauD+bTM2dqSAkE1Yr&!52jE!nL(m0&1d<8e3a$XxgBw5u#e{AIVGY?P zkWA=jAeqq5LB)h_hCn71_Es^Wq=-x?DIya}ipYeLA~K<*h)gIcA`?oA$b^y}GNGi0 zOepCg6H3npWI_u;GNHRcGNJS=pqS9_Adm_D9wZZb2qY7VQY$9(2uLRMC`cys7)U1c z2arrC*>WJ9` zP>LrLdJ`lQN{Y#Z-U7*l-Ui8p-UG>mJ^;yt>R^b-gc?9Hp(02o)C!UbwS$TYr3f;i zWV6YH)&N(45g?gRvdsszr6EDq^M3V1 z#}(@-!+O5zan_}Ba&?AOa5>l&m%~QIVZg0-jU{3k>NOXJb51R8onebwFn+tvuq_%I z6ZjB86DK6|p7*fSOe4heO}!*NUr7;9QG{ph*-yT8&v@J@-8I^FjBT{}%Acox{In|{ z&*u*@?v>xwn!dLg@8o7&k!Bv_V}nhpac9v3Fx{6bE2iA+66Ns4Rw#-4PZFfQ%wGv1f*f^nfX+v z^j$9-v4*2%?uhp3-%Y)WtGDP=HYthLxMj$eaNUsqE@i+X8~?L1kE6r{vi zaV0h5L`Z5nmrt7Kliu}7>wJ>Tdp5L%IDha(obyRHd{UWDqUF4L0f$ejl{gw#OEO!K8`|%Yz+sR^XZ*UA!eGH$l90k6%)nkd|Nx=i}f>1hS&^ZxiebJu;BRwSe2f+Taeb9k>&G3j7)z z1Qvp$z#=dk+y$-x_kzw(Ado4BnOBzOkdF!!hSg*TasCgGEVF>Vbr{5YlN|wJ zlN8GgTcTLzbdW4_SCCfGSe+@W=waYF9M1xh5@angFv#xF(6su zhMwazu&xskJs{AsdOV0`bdfVJ8Jr7}Wqt=F%RB&mp)NQIY!1E+(uEd*Ex`A{mf#w& zE%+hW0i;I!JE+BdJ%(zdkQV87?Q*SwmR!zXIwy@K@EYj4h>dHCzs$nUg zKgFh#&(<>C5v)#b0phmm0D?#?(VwQ*4ryoSLF|o7F!_$!W>TOC@*| zpq<}0<4uy{1Ya3%I^V$m#pFgkOfP#jj8l2Z30pY-y06KmWINo~R2&;1+w-rPyl)kx za%@zq`vlvQ)UBj>PE##ETf<82PFyu5$gh27dduTEPvJo_vJb`@ziYCZeVT0A;3xZA z8!by^WH0dLRCdTezG<>+kzM}srfE@1)$&p{9&}I8$q(YqbA5T|*EiSE(^c=P`>7A= zn+N*Yo>VTXZ)3jh*_}wC4WTe@Yj2j6i$=FMck#0!q+|>3XTIvqhMg<*a^LXQ|5)pCG&fS-*=MFV!R4th0kdew#3AMd$v`grrJem1|9+9F$mJUs{RIjfsU zDYWIMwsCPJKN})+kl%a5+#}L|W64Wao4fkjN!d>+|HyOI;C1GAqWov$*ey?xU)^V( z>dUL{i8M`1Q#z>X%%LW4P?wLLr0F2Pc*y)_9sk)xr_Ok<~G~10#am6Er;Ggso)%&%xmsl&%C1*|%k9)>KiZX;8NlhPlo~E+buB*Jg zlWrfu?@Ski_=SE(hxrbsrM=Y|`;xbBCPa($kp4TKvzv$WAsfXw{n~Imqw=@P%<-Bp zBX~)u5GRhq$UYjuSi5NcV7eG(o`lC0O)O)RdHc241^S2w=ZJNM4TN}gAE<~ArKoQy z%JVFKkbjmVF5q!L;D#1Htt-{=`CCMbkiyS~3s1-ww}?4{JWMMN)&yN|)in6z@ef|G zpTFO$LFAz~c>8;rJ$(6g@tT}+T4*fr==+-Se27`J^NkY)Jzw#;K9#$kH=23SaGOaU zYZi|Re8x6&6FK`U(IN0rBWz|q*D9tv&!Orm$I@?0Gk=7X*DX!xmG_hDH_7#nHEXz3 z5Sf8I+y5;0b`Z?2oY576Z+ zDVe%=QgmLY-Nnb*#J;IBrr#?shi#cX8P5jO@gzy|NXXg~`Rz67N2J*UaWLzzNw%EU zq<~2?yYag=v9?f$N881S+7_IypgQF*6uK!TR7*IkaMBR%DL%+9HnVPm`t&`MP41H1 zrhJ86tkt0;zgvn)O(+#iYH5%PI<+(wT{3Brf^_6OXe+%j4B7JWn#taD^a(0nPee!s zx|UMGvn_eKT?}{rCC!|PQ`!UCySdqAd6CAMKfgNK_0JR1>}p7x*V`!M9dMnKTz5rj zCPR$tt}V;rnrhUvlV+D-nIIK>mvc^#3hou1(-qy+Sv+?@n*9S#&ipwmV&<`|8t&|} zwBANdR#1N5`&cl{kZ}%sf!Sp_)NG!1wqwCP4o`FU3l?$}Bcs>`O)ek_-0p4S`n8IV1h;`7f zCwykCA6`m#+w+g?{Cvpt%w5d$mWa_Wt;b^o1{RgZMYa=qU422sxt;^j0bS37SZ^v% zY%$C4=9A@!(N#JzrlQ$xfi&#XY~hp5F2 za07^SgKIyS5B>zAEnI(rlr9W~UJFKmF8r?p;!)96AEeSZ2GPA;sdUVXF2T_r{e>o! z^QEFqh>;KPp%K`iy4Z|={fj=dJ{lKVRA-SDEWmLCa2u%r=@Iq`@C%-}3_H8&oIOG1nWfS!S_!)|@9gPVOUSt!Jt=lu zbUl=?K@rNBKRiJxVU$`zWI~Rt-$_@-{gFZs9vh_zi_FWokNTzT-;+_!W)@EBblu{a zg^-Bkj`QbBi5hHnO9ee1NCo4|i_V+0C!~VJ+@9E6 z?;+5{g2VCJTxT$jHJ;Ps^|?KDIMyl0xjjueg{GV$rDC!>3wz@k<@weOx=XKNP=k4N=5#lh7dmzt_5FPzacE*Kr%G*hE<8V9Evr4AHTT|lB zJexD7Sl2!mysMMumSQq=_c`tLFL>^1Mrn|8XYWX}wo-!Z)1I1TmhhVqVz@oyg4(BX zTY6}Z@>{#ijd(^)(P2(R@ySkv^1@p}Pv-;@5e$s_IA#nSt-;?minI}bF`FQ6tMZr9 zUG~NO?u#q)#bJ%*(T6QVPhPBMJaM!fRQ0u2<7ktB)`V*0Y@f8;CvEge#~`Uijl#5~ z=D)m?TT^X})rTF@&#= z5^dFC>dIqqru(pogL{m7nUQbdBtH}-*2gY=X_S~8YC{bAijwNNB!=(v;G$>}Ew<({ zYcN0G;VssPvCiAjk%-cH|4~uMUOk79;E5*>fr#THAQkf{NX>T&q^9@@E&*;ybt0e!yt5#7Zkx23ermcF;E9$ zjjQ<9`-4UtzW`GHmq1#uj{$AqM9;Acqy_r|5V~9|K?ivNHbaO(#1W8I>UTg|sow?3 zXI|zxZ$$5+{csVa1$!Jw3-lC_7UXTfx*)k6XhA*@qy_nC5Cg&WI!N2$?|_t^JPU2e z1MmR^TB(y&ZUYvAoxq<#TDg<+t}}QIq?LOKNDKErz$Zc4Ht7bIf!#q9Zrf9!4eSX9 zff#fy2T0rF(p5u|=5FC#Nhk|3l zVc-OCIQTk<+u@=&6h?s4!56_C5Vyzm1~>|IYw;2X?vv|HM2rRB0>^<1!13T>5ckhT z&d5pNa&R)Z3Van@1HJ}+08RsoKx&~wAnvz|JeAYI6CkzZH82OXpp#RJ+jZ%T&4NH1 zHgmwnU@q7MoC|ga=Yf4e_^w>ff^UQ5gjvX^e<;RUI-%9;po>~q7yjvoViZq|7yZ0M zs4RQ)KN9Pi>LGEb6V;C?uN`RaXn1f_Z5Y|ZnO&29IEfqJT;P}u3OGOz=#hZR!byrraDE9aIu$1NxHO5p>Ievp!N742Y<^qp4 z!$xs!egErb4sGzS{3L#)4{H{nl**g1J%05pq=)`0?)CGEq*AnF_r)T8Sc^n|MN{6W z4RbV4N>$IQ%X@m|@yBQ?DSf-d;bsVu>**{FqWu?Fz8`P-Mh_(^fiJ;t*0)HCM@o3i zayw8_mv^yjLn{W*LrxnPBHtqE)D zsi~sGcZ(Enn}dJwg2k@9wE8|QQaAMj2Ye?{*N@{(Y1(yfTRt#^rTM)@sj8DH`yEfc z-+ae%yQ-5(hMtXDM_OVFe{H99#u|L=W=oLbsG7dnVypU{jz;<3ChdDmXKh%D-|Bhv ztUv70^YvlN`apWBU$tD)gf(mCzdWk{s@Nha&c1Hd=&j%=`PpL2@v81Gx!nWH7;S)_ z=kdY)ELc^a&hLWtVrZ4^Q?+VS!>p$?juzfd`sl5Lql7-{cq77US6qR0)ejs_M_Aoe zKk`!b1vjxCK~G5XUqv{)96Tu5s=BCRldZd|eu<~*$$!?mMjw{ux4U}kH+Yz*eiMdS zU#=dYe)C?neya&jPD~8Y=qOQ*8qHIaJhKZ8QWK-e>3F#MR`#jat!d!_l&FrOZAMy%6CI?TT44U)sEd^osv*h z4<9<%zEghboOQiEta(%a_ko<2)l)s6FnPYJq)Hp3RS)yh%hpj*RaGm4VWYuTfH}|a zz*Gi<1D922L~2b*Y0c4?oO`N+evj35C(vCV-rOb{F%Jb8X^Lxkc^jMBtv9x@wXZrM z74)(V(MB{$PD=R?jp)GEfO^LtI$htb&Di7Wtc>q7>jiIxW&I-vFS*dOCjQk~@Yc34 z^BTk^U{c)2+xN4@8}5bSsR~`X#1O?xN;En>y*}_Fe+%a{OT!gcX7CW$%PsJ5hDNE1 zT9KmQNW_kgf!$9~W2FVtx7QS+cu|6`E^IO2@oP5c!L<>UPEj7eW=B4>wyrC;?XtD0 z^6@MmnkKZD3y0`SHBzMyYx%i#ny&JPQ#9oE9AxXI32N|to@-)Z@Pma@zK9KPoA3f} zJ3_xlSj$(m6V6B@@LBE{`YiW3<+EHl=^umY2%XHoep58bi3U?kf#*M=?ZitC;Nf7y zuY$xWkBkn#63Y0AGE?A9{(~# zdfd0LS3Hu)-hhN#g19`Axap=?i|3T&l;r}96ezr9qD)A z5#8g9d~-Tt`{sOeH{~zYlk4$)Hl>8B+>dV>VXOY611^T%4!!mpxNEcrygtt!cu(L} z8#x|+)b96qauo-S>s2FslNX?6`d!s2dlGW`QEB!O#)Dq8)pxGNvAZ??u)LYke*mq9 zOS5S$HM3BfIR{KRR?#(_Keyig;I~rG2Cs|6slB^Q!-ZgTaGR3YAvcMrsCd%ShV>=Y5FO zB@DFO^LUaIA(3m-KubN3gcXJ-U8XM%%OQ_{FJS|++GANt)JZiM9x|s?=7yFF2 z8f|OK+d3^)8^zH8NmMAp0|m4~M-Xqwu})wU5Z6;&19TpXV|sPM zg+(yS1hJ-Ny};+d-rxkV510*NA?U)=kS?dZr9knEaoi6q0Q-X%1guvFL%5BI5ug_3 z8v{~od=>mGKwyG|jlw9Xnvpjojh>=+e&~>Lfp}$7>Gn?%s@2 zn#7ei#OO>Fzj*H?o!5W85(()&w?vv}6ZQD0sUK$Ak%IO>zO~Cpp%>m+yFy8Pj!QVj zjc{M8k<@=#UTNy4bvqF{BP@WAZ!3WQnfVV_BANPsdn+n#WTaMRlzA2%5Zp{Vy@a?8%vqnhIah zFjW!`9~q^#0X)9loms{1rqmQl6X5*xJ!Dz5d%W6|%k+ADkJhQQ+arGOoZSucpA>M< zXilMx0&mmll5tCt1+q1}-kE-$yp!5pMWy1L_T}Crosu<_#;L8ENO+irZf&x@YLfO9 z($KC*ve8c(%|ksVN@Mnu#;MII(&y|Em2Hr=n72`1bt6KlE}Dq8H1b~-w#T53?()3H z%YFM82A}k}@KDrv#hg95C$bJx`#rLcp)|DeM1kEEsfV&N6oie2Ik~t1zQ-$hq>0_% zU`L@rM(I}!lcmzc_)e}mQew|QoD*tl-#r)GG1u_E;a6mP+~xeYiMGd5yJ!7C6`@QO z_HFQn;p?cP$F;AF0E`-KW+~G4=*gR$vNq?n$B8xhf|qUmotVj#S8qbuFi4mOVLC7w zF&gQiY_?CzheU(cz?S*qsFG^jZeQF1U))c=xLSZPXPKPI|B)r4sUOh_Q!1UGhpKo@H3lO% ztUNv_rdz|#@s+dnAtIH7t~*4>gD2Y}VNq^9DTMPL9dr_Z>`gc{d*~21UMIxx6*@u3 zw{W2v|DciJa0X#tq7=QJwmJH}`257@ner;6`ZDAaRLA>|E&-#+dLYd8#DB_^Z$FgJ z4Pp^bJIb`vz8!?+S6+(j2kyl23*c9v3;Y&@!NsSE*Z^1oVLu{12fqjRfrr6gz+)h` zE0mWS{{~OsSdU(cXMg1-NDLKMZ5;m$)(206jX~sf(K8_ikgF+p7Hkdv2DSq)fbi9` zi}aZAEQHG-JqTU}UjcDZ*HjSW&IQ-D@-ienpWMK)8@vU+1>OeV0bvzfw2O8J{0RIL z+zz79%7+{nwXUN$#

_B3KSy2c4Lfl;;>7SPji;0uw$8nzH+MZ+jFoVw1#uBBcmmugk9VC6U;ZO~1Pa6Qy5S~Uv0yr2%b1FLuH9>ku zxh_aM3H3m7^rM-T4>cNqdvT2BcI^l8^ym5xOa%{uXm;hpjppD{9H)V_A%NT9`Vk~O zzi9E?*AW736LtpggLqnZ)j(%^8mtZW1{;8Vz$CCA*dBaF*#O|}U$YIj%tTYFy8v_e zrq^uE{JU;Aep@QRN>891?v!~rat_9*<(Ev@4hBd$B#|5 zm2{=j)6g`qgl^qwhG6tziZ4caPM{X>#nAl3sEvFv%_v(JootM17f?P*_LDmvvR~FaQvG+gWa_#2Wu)VtDvmmCcT}yST9igt z>>r@1n)z=k>S(x%=XTRQuqrh**TQp#;@0K(u_{#dx_ykFw`P@_G0r5d)jFE`-;F`d z;fN1UP4jjsx`t7?##TIFgsZOO$yTX#P}PkxMg729(szQRX^Q7=RPK`K+jaERup%GV z3%~5PAzB(+b<0R?i#<)H>w&gu@Cr7)-~4NuBq^QyR+{u!06qM~O8ns6)$Y>gny?mr zozb3=a-gSVH&EF&!sSapH5Bu-F0<{6sd9jV@?csMomcv#A%7o;tLN?H1s^aiy1-&szkcf!N? zr*}QY{Q9oc-Omr*D1A?^9@Grm$pK2Kydhq*W{}!p8r2Ni;O7l-(xd$1j*MU2S%#gj z03AjhCW&bkhN3!5rsDZGL>(q?vo65r1Y+8yIaOZGo!Dg&K=wJ|7289zri1{F91C`w8U&Tsa=0OsAY A8vp - + @@ -210,9 +210,9 @@ - + diff --git a/od-win32/prowizard/prowizard.vcxproj.filters b/od-win32/prowizard/prowizard.vcxproj.filters index 2ae6d6ec..ec062f2b 100644 --- a/od-win32/prowizard/prowizard.vcxproj.filters +++ b/od-win32/prowizard/prowizard.vcxproj.filters @@ -96,9 +96,6 @@ Source Files\Rippers - - Source Files\Rippers - Source Files\Rippers @@ -162,9 +159,6 @@ Source Files\Rippers - - Source Files\Rippers - Source Files\Rippers @@ -357,5 +351,11 @@ Source Files\Rippers + + Source Files\Rippers + + + Source Files\Rippers + \ No newline at end of file diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 6b572367..6a1df589 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -87,6 +87,7 @@ #include "blkdev.h" #ifdef RETROPLATFORM #include "rp.h" +#include "cloanto/RetroPlatformIPC.h" #endif extern int harddrive_dangerous, do_rdbdump, aspi_allow_all, no_rawinput; @@ -170,6 +171,10 @@ int quickstart = 1, configurationcache = 1, relativepaths = 0; static int multi_display = 1; static TCHAR *inipath = NULL; +static int guijoybutton[MAX_JPORTS]; +static int guijoyaxis[MAX_JPORTS][4]; +static bool guijoychange; + static int timeend (void) { if (!timeon) @@ -410,12 +415,6 @@ void resumepaused (int priority) if (pause_emulation > priority) return; resumesoundpaused (); -#ifdef CD32 - akiko_exitgui (); -#endif -#ifdef CDTV - cdtv_exitgui (); -#endif blkdev_exitgui (); if (pausemouseactive) setmouseactive (-1); @@ -432,12 +431,6 @@ void setpaused (int priority) return; pause_emulation = priority; setsoundpaused (); -#ifdef CD32 - akiko_entergui (); -#endif -#ifdef CDTV - cdtv_entergui (); -#endif blkdev_entergui (); pausemouseactive = 1; if (isfullscreen () <= 0) { @@ -740,6 +733,64 @@ void disablecapture (void) setmouseactive (0); } +void gui_gameport_button_change (int port, int button, int onoff) +{ + //write_log (L"%d %d %d\n", port, button, onoff); +#ifdef RETROPLATFORM + int mask = 0; + if (button == JOYBUTTON_CD32_PLAY) + mask = RP_JOYSTICK_BUTTON5; + if (button == JOYBUTTON_CD32_RWD) + mask = RP_JOYSTICK_BUTTON6; + if (button == JOYBUTTON_CD32_FFW) + mask = RP_JOYSTICK_BUTTON7; + if (button == JOYBUTTON_CD32_GREEN) + mask = RP_JOYSTICK_BUTTON4; + if (button == JOYBUTTON_3 || button == JOYBUTTON_CD32_YELLOW) + mask = RP_JOYSTICK_BUTTON3; + if (button == JOYBUTTON_1 || button == JOYBUTTON_CD32_RED) + mask = RP_JOYSTICK_BUTTON1; + if (button == JOYBUTTON_2 || button == JOYBUTTON_CD32_BLUE) + mask = RP_JOYSTICK_BUTTON2; + rp_update_gameport (port, mask, onoff); +#endif + if (onoff) + guijoybutton[port] |= 1 << button; + else + guijoybutton[port] &= ~(1 << button); + guijoychange = true; +} +void gui_gameport_axis_change (int port, int axis, int state, int max) +{ + int onoff = state ? 100 : 0; + if (axis < 0 || axis > 3) + return; + if (max < 0) { + if (guijoyaxis[port][axis] == 0) + return; + if (guijoyaxis[port][axis] > 0) + guijoyaxis[port][axis]--; + } else { + if (state > max) + state = max; + if (state < 0) + state = 0; + guijoyaxis[port][axis] = max ? state * 127 / max : onoff; +#ifdef RETROPLATFORM + if (axis == DIR_LEFT_BIT) + rp_update_gameport (port, RP_JOYSTICK_LEFT, onoff); + if (axis == DIR_RIGHT_BIT) + rp_update_gameport (port, DIR_RIGHT_BIT, onoff); + if (axis == DIR_UP_BIT) + rp_update_gameport (port, DIR_UP_BIT, onoff); + if (axis == DIR_DOWN_BIT) + rp_update_gameport (port, DIR_DOWN_BIT, onoff); +#endif + } + guijoychange = true; +} + + void setmouseactivexy (int x, int y, int dir) { int diff = 8; @@ -1317,6 +1368,32 @@ static int canstretch (void) return 0; } +static void plot (LPDRAWITEMSTRUCT lpDIS, int x, int y, int dx, int dy, int idx) +{ + COLORREF rgb; + + x += dx; + y += dy; + if (idx == 0) + rgb = RGB(0x00,0x00,0xff); + else if (idx == 1) + rgb = RGB(0xff,0x00,0x00); + else if (idx == 2) + rgb = RGB(0xff,0xff,0x00); + else if (idx == 3) + rgb = RGB(0x00,0xff,0x00); + else + rgb = RGB(0x00,0x00,0x00); + + SetPixel (lpDIS->hDC, x, y, rgb); + + SetPixel (lpDIS->hDC, x + 1, y, rgb); + SetPixel (lpDIS->hDC, x - 1, y, rgb); + + SetPixel (lpDIS->hDC, x, y + 1, rgb); + SetPixel (lpDIS->hDC, x, y - 1, rgb); +} + static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static RECT myrect; @@ -1463,32 +1540,85 @@ static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, { LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam; if (lpDIS->hwndItem == hStatusWnd) { - DWORD flags, tflags; - COLORREF oc; - TCHAR *txt = (TCHAR*)lpDIS->itemData; - tflags = txt[_tcslen (txt) + 1]; - SetBkMode (lpDIS->hDC, TRANSPARENT); - if ((tflags & 2) == 0) - tflags &= ~(4 | 8 | 16); - if (tflags & 4) { - oc = SetTextColor (lpDIS->hDC, RGB(0xcc, 0x00, 0x00)); // writing - } else if (tflags & 8) { - oc = SetTextColor (lpDIS->hDC, RGB(0x00, 0xcc, 0x00)); // playing - } else { - oc = SetTextColor (lpDIS->hDC, GetSysColor ((tflags & 2) ? COLOR_BTNTEXT : COLOR_GRAYTEXT)); - } - flags = DT_VCENTER | DT_SINGLELINE; - if (tflags & 1) { - flags |= DT_CENTER; - lpDIS->rcItem.left++; - lpDIS->rcItem.right -= 3; + if (lpDIS->itemID > 0 && lpDIS->itemID <= window_led_joy_start) { + int port = lpDIS->itemID - 1; + int x = (lpDIS->rcItem.right - lpDIS->rcItem.left + 1) / 2 + lpDIS->rcItem.left - 1; + int y = (lpDIS->rcItem.bottom - lpDIS->rcItem.top + 1) / 2 + lpDIS->rcItem.top - 1; + FillRect (lpDIS->hDC, &lpDIS->rcItem, (HBRUSH)(COLOR_3DFACE + 1)); + for (int i = 0; i < 2; i++) { + int buttons = guijoybutton[port + i * 2]; + int m = i == 0 ? 1 : 2; + bool got = false; + if (buttons & (1 << JOYBUTTON_CD32_BLUE)) { + plot (lpDIS, x - 1, y, 0, 0, 0); + got = true; + } + if (buttons & (1 << JOYBUTTON_CD32_RED)) { + plot (lpDIS, x + 1, y, 0, 0, 1); + got = true; + } + if (buttons & (1 << JOYBUTTON_CD32_YELLOW)) { + plot (lpDIS, x, y - 1, 0, 0, 2); + got = true; + } + if (buttons & (1 << JOYBUTTON_CD32_GREEN)) { + plot (lpDIS, x, y + 1, 0, 0, 3); + got = true; + } + if (!got) { + if (buttons & 1) + plot (lpDIS, x, y, 0, 0, 1); + if (buttons & 2) + plot (lpDIS, x, y, 0, 0, 0); + if (buttons & ~(1 | 2)) + plot (lpDIS, x, y, 0, 0, -1); + } + for (int j = 0; j < 4; j++) { + int dx = 0, dy = 0; + int axis = guijoyaxis[port + i * 2][j]; + if (j == DIR_LEFT_BIT) + dx = -1; + if (j == DIR_RIGHT_BIT) + dx = +1; + if (j == DIR_UP_BIT) + dy = -1; + if (j == DIR_DOWN_BIT) + dy = +1; + if (axis && (dx || dy)) { + dx *= axis * 8 / 127; + dy *= axis * 8 / 127; + plot (lpDIS, x, y, dx, dy, -1); + } + } + } } else { - flags |= DT_LEFT; - lpDIS->rcItem.right--; - lpDIS->rcItem.left += 2; + DWORD flags, tflags; + COLORREF oc; + TCHAR *txt = (TCHAR*)lpDIS->itemData; + tflags = txt[_tcslen (txt) + 1]; + SetBkMode (lpDIS->hDC, TRANSPARENT); + if ((tflags & 2) == 0) + tflags &= ~(4 | 8 | 16); + if (tflags & 4) { + oc = SetTextColor (lpDIS->hDC, RGB(0xcc, 0x00, 0x00)); // writing + } else if (tflags & 8) { + oc = SetTextColor (lpDIS->hDC, RGB(0x00, 0xcc, 0x00)); // playing + } else { + oc = SetTextColor (lpDIS->hDC, GetSysColor ((tflags & 2) ? COLOR_BTNTEXT : COLOR_GRAYTEXT)); + } + flags = DT_VCENTER | DT_SINGLELINE; + if (tflags & 1) { + flags |= DT_CENTER; + lpDIS->rcItem.left++; + lpDIS->rcItem.right -= 3; + } else { + flags |= DT_LEFT; + lpDIS->rcItem.right--; + lpDIS->rcItem.left += 2; + } + DrawText (lpDIS->hDC, txt, _tcslen (txt), &lpDIS->rcItem, flags); + SetTextColor (lpDIS->hDC, oc); } - DrawText (lpDIS->hDC, txt, _tcslen (txt), &lpDIS->rcItem, flags); - SetTextColor (lpDIS->hDC, oc); } break; } @@ -1599,6 +1729,12 @@ void handle_events (void) int was_paused = 0; static int cnt; + if (guijoychange && window_led_joy_start > 0) { + guijoychange = false; + for (int i = 0; i < window_led_joy_start; i++) + PostMessage (hStatusWnd, SB_SETTEXT, (WPARAM)((i + 1) | SBT_OWNERDRAW), (LPARAM)L""); + } + while (pause_emulation) { if (pause_emulation && was_paused == 0) { setpaused (pause_emulation); @@ -2665,15 +2801,14 @@ static const TCHAR *obsolete[] = { L"killwinkeys", L"sound_force_primary", L"iconified_highpriority", L"sound_sync", L"sound_tweak", L"directx6", L"sound_style", L"file_path", L"iconified_nospeed", L"activepriority", L"magic_mouse", - L"filesystem_codepage", + L"filesystem_codepage", L"aspi", 0 }; -int target_parse_option (struct uae_prefs *p, TCHAR *option, TCHAR *value) +int target_parse_option (struct uae_prefs *p, const TCHAR *option, const TCHAR *value) { TCHAR tmpbuf[CONFIG_BLEN]; int i, v; - bool vb; int result = (cfgfile_yesno (option, value, L"middle_mouse", &p->win32_middle_mouse) || cfgfile_yesno (option, value, L"map_drives", &p->win32_automount_drives) @@ -2764,15 +2899,6 @@ int target_parse_option (struct uae_prefs *p, TCHAR *option, TCHAR *value) return 1; } - if (cfgfile_yesno (option, value, L"aspi", &vb)) { - p->win32_uaescsimode = 0; - if (vb) - p->win32_uaescsimode = get_aspi (0); - if (p->win32_uaescsimode < UAESCSI_ASPI_FIRST) - p->win32_uaescsimode = UAESCSI_ADAPTECASPI; - return 1; - } - if (cfgfile_string (option, value, L"rtg_vblank", tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) { if (!_tcscmp (tmpbuf, L"real")) { p->win32_rtgvblankrate = -1; @@ -2810,8 +2936,9 @@ int target_parse_option (struct uae_prefs *p, TCHAR *option, TCHAR *value) } if (cfgfile_strval (option, value, L"uaescsimode", &p->win32_uaescsimode, scsimode, 0)) { - // do not forget me! - p->win32_uaescsimode = UAESCSI_CDEMU; + // force SCSIEMU if pre 2.3 configuration + if (p->config_version < ((2 << 16) | (3 << 8))) + p->win32_uaescsimode = UAESCSI_CDEMU; return 1; } @@ -4241,6 +4368,10 @@ static int parseargs (const TCHAR *argx, const TCHAR *np, const TCHAR *np2) do_rdbdump = 1; return 1; } + if (!_tcscmp (arg, L"hddump")) { + do_rdbdump = 2; + return 1; + } if (!_tcscmp (arg, L"disableharddrivesafetycheck")) { //harddrive_dangerous = 0x1234dead; return 1; @@ -5302,6 +5433,7 @@ int PASCAL wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdL } #endif #endif + SetDllDirectory (L""); /* Make sure we do an InitCommonControls() to get some advanced controls */ InitCommonControls (); diff --git a/od-win32/win32.h b/od-win32/win32.h index 28e7a8f4..24ed8879 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -18,8 +18,8 @@ #define WINUAEPUBLICBETA 1 #define LANG_DLL 1 -#define WINUAEBETA L"12" -#define WINUAEDATE MAKEBD(2010, 8, 21) +#define WINUAEBETA L"13" +#define WINUAEDATE MAKEBD(2010, 8, 27) #define WINUAEEXTRA L"" #define WINUAEREV L"" diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index a72e1731..9aefbd8b 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -99,6 +99,7 @@ static int screen_is_initialized; int display_change_requested, normal_display_change_starting; int window_led_drives, window_led_drives_end; int window_led_hd, window_led_hd_end; +int window_led_joys, window_led_joys_end, window_led_joy_start; extern int console_logging; int window_extra_width, window_extra_height; @@ -1957,8 +1958,9 @@ static void createstatuswindow (void) RECT rc; HLOCAL hloc; LPINT lpParts; - int drive_width, hd_width, cd_width, power_width, fps_width, idle_width, snd_width; - int num_parts = 11; + int drive_width, hd_width, cd_width, power_width, fps_width, idle_width, snd_width, joy_width; + int joys = 0; + int num_parts = 11 + joys; double scaleX, scaleY; WINDOWINFO wi; int extra; @@ -1987,28 +1989,61 @@ static void createstatuswindow (void) fps_width = (int)(64 * scaleX); idle_width = (int)(64 * scaleX); snd_width = (int)(72 * scaleX); + joy_width = (int)(24 * scaleX); GetClientRect (hMainWnd, &rc); /* Allocate an array for holding the right edge coordinates. */ - hloc = LocalAlloc (LHND, sizeof (int) * num_parts); + hloc = LocalAlloc (LHND, sizeof (int) * (num_parts + 1)); if (hloc) { + int i = 0, i1, j; lpParts = (LPINT)LocalLock (hloc); - /* Calculate the right edge coordinate for each part, and copy the coords - * to the array. */ - lpParts[0] = rc.right - (drive_width * 4) - power_width - idle_width - fps_width - cd_width - hd_width - snd_width - extra; - lpParts[1] = lpParts[0] + snd_width; - lpParts[2] = lpParts[1] + idle_width; - lpParts[3] = lpParts[2] + fps_width; - lpParts[4] = lpParts[3] + power_width; - lpParts[5] = lpParts[4] + hd_width; - lpParts[6] = lpParts[5] + cd_width; - lpParts[7] = lpParts[6] + drive_width; - lpParts[8] = lpParts[7] + drive_width; - lpParts[9] = lpParts[8] + drive_width; - lpParts[10] = lpParts[9] + drive_width; - window_led_drives = lpParts[6]; - window_led_drives_end = lpParts[10]; - window_led_hd = lpParts[4]; - window_led_hd_end = lpParts[5]; + /* Calculate the right edge coordinate for each part, and copy the coords to the array. */ + int startx = rc.right - (drive_width * 4) - power_width - idle_width - fps_width - cd_width - hd_width - snd_width - joys * joy_width - extra; + for (j = 0; j < joys; j++) { + lpParts[i] = startx; + i++; + startx += joy_width; + } + window_led_joy_start = i; + // snd + lpParts[i] = startx; + i++; + // cpu + lpParts[i] = lpParts[i - 1] + snd_width; + i++; + // fps + lpParts[i] = lpParts[i - 1] + idle_width; + i++; + // power + lpParts[i] = lpParts[i - 1] + fps_width; + i++; + i1 = i; + // hd + lpParts[i] = lpParts[i - 1] + power_width; + i++; + // cd + lpParts[i] = lpParts[i - 1] + hd_width; + i++; + // df0 + lpParts[i] = lpParts[i - 1] + cd_width; + i++; + // df1 + lpParts[i] = lpParts[i - 1] + drive_width; + i++; + // df2 + lpParts[i] = lpParts[i - 1] + drive_width; + i++; + // df3 + lpParts[i] = lpParts[i - 1] + drive_width; + i++; + // edge + lpParts[i] = lpParts[i - 1] + drive_width; + + window_led_joys = lpParts[0]; + window_led_joys_end = lpParts[1]; + window_led_hd = lpParts[i1]; + window_led_hd_end = lpParts[i1 + 1]; + window_led_drives = lpParts[i1 + 2]; + window_led_drives_end = lpParts[i1 + 6]; /* Create the parts */ SendMessage (hStatusWnd, SB_SETPARTS, (WPARAM)num_parts, (LPARAM)lpParts); diff --git a/od-win32/win32gfx.h b/od-win32/win32gfx.h index 1cad516d..9fe40afa 100644 --- a/od-win32/win32gfx.h +++ b/od-win32/win32gfx.h @@ -24,8 +24,9 @@ extern HCURSOR normalcursor; extern HWND hStatusWnd; extern int default_freq; extern int normal_display_change_starting; -extern int window_led_drives, window_led_drives_end; +extern int window_led_drives, window_led_drives_end, window_led_joy_start; extern int window_led_hd, window_led_hd_end; +extern int window_led_joys, window_led_joys_end; extern HDC gethdc (void); extern void releasehdc (HDC hdc); diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 3efe556d..b85ac956 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -86,6 +86,9 @@ #include "statusline.h" #include "zarchive.h" #include "win32_uaenet.h" +#ifdef RETROPLATFORM +#include "rp.h" +#endif #define ARCHIVE_STRING L"*.zip;*.7z;*.rar;*.lha;*.lzh;*.lzx" @@ -1682,7 +1685,7 @@ static struct ConfigStruct *getconfigstorefrompath (TCHAR *path, TCHAR *out, int return 0; } -int target_cfgfile_load (struct uae_prefs *p, TCHAR *filename, int type, int isdefault) +int target_cfgfile_load (struct uae_prefs *p, const TCHAR *filename, int type, int isdefault) { int v, i, type2; int ct, ct2, size; @@ -2378,7 +2381,7 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs inprec_open (full_path, 1); break; } - if (!nosavepath) { + if (!nosavepath || 1) { if (flag == 0 || flag == 1) { amiga_path = _tcsstr (openFileName.lpstrFile, openFileName.lpstrFileTitle); if (amiga_path && amiga_path != openFileName.lpstrFile) { @@ -9394,6 +9397,8 @@ static void floppytooltip (HWND hDlg, int num, uae_u32 crc32) id = floppybuttonsq[num][0]; else id = floppybuttons[num][0]; + if (id < 0) + return; ti.cbSize = sizeof (TOOLINFO); ti.uFlags = TTF_SUBCLASS | TTF_IDISHWND; ti.hwnd = hDlg; @@ -9487,7 +9492,8 @@ static void addfloppyhistory (HWND hDlg) f_text = floppybuttons[n][0]; else f_text = IDC_DISKTEXT; - addfloppyhistory_2 (hDlg, n, f_text, iscd (n) ? HISTORY_CD : HISTORY_FLOPPY); + if (f_text >= 0) + addfloppyhistory_2 (hDlg, n, f_text, iscd (n) ? HISTORY_CD : HISTORY_FLOPPY); } } @@ -9601,11 +9607,12 @@ static void addfloppytype (HWND hDlg, int n) } chk = !showcd && disk_getwriteprotect (text) && state == TRUE ? BST_CHECKED : 0; if (f_wp >= 0) - CheckDlgButton(hDlg, f_wp, chk); + CheckDlgButton (hDlg, f_wp, chk); chk = !showcd && state && DISK_validate_filename (text, 0, NULL, NULL, NULL) ? TRUE : FALSE; if (f_wp >= 0) { ew (hDlg, f_wp, chk); - ew (hDlg, f_wptext, chk); + if (f_wptext >= 0) + ew (hDlg, f_wptext, chk); } } @@ -14387,6 +14394,7 @@ void gui_led (int led, int on) ptr[_tcslen (ptr) + 1] |= 8; if (active2) ptr[_tcslen (ptr) + 1] |= 16; + pos += window_led_joy_start; PostMessage (hStatusWnd, SB_SETTEXT, (WPARAM)((pos + 1) | type), (LPARAM)ptr); if (tt != NULL) PostMessage (hStatusWnd, SB_SETTIPTEXT, (WPARAM)(pos + 1), (LPARAM)tt); diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 6ed957fc..2dbcf6d0 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,29 @@ +Beta 13: + +- addaq.x #x,Ax and subaq.x #x,Ax had too long cycle count (this was really stupid bug) +- joystick type (default,mouse,joystick,analog joystick,etc..) was reset to default when + configuration was loaded +- do not decide bitplane dma overriding sprite dma too early, DDFSTRT might get moved few + cycles before bitplane dma was originally supposed to start (Heimdall 2 AGA mouse cursor) +- floppy panel DF0: "write-protected" text was getting disabled +- SCSI emulation is only forced if version stored in configuration file is older than 2.3 +- CDTV MODE2FORM0 2336 byte sectors didn't work in image mode +- Sherlock Holmes - Consulting Detective separate video tracks hack removed, working full image is available. +- mds subchannel data wrong positioning fixed +- fixed some rare thread syncronization issues when CDA was stopped +- read also standard 2048 byte sectors using SPTI if CDA required SPTI mode, mixing IOCTL + and SPTI does not seem to be reliable +- Brian the Lion CD32 starts CDA play at the very end of data track, obviously this must not + be an error, only return error if both current start and start + 2s is located inside data track +- files inside archives didn't load if path was relative +- paused CD32/CDTV was resumed after exiting GUI ("old-style" GUI pause/resume was not removed..) +- directories selected via "favorite menu" also sets default path +- prowizard updates + +- added ugly joystick/mouse direction status bar pointers (design stolen from Vice and + future AF player skin) Not sure if this was good idea.. + Beta 12: - : without '\' in harddrive paths was detected as a relative path, diff --git a/prowizard/rippers/GMC.c b/prowizard/rippers/GMC.c new file mode 100644 index 00000000..86229dcc --- /dev/null +++ b/prowizard/rippers/GMC.c @@ -0,0 +1,311 @@ +/* testGMC() */ +/* Rip_GMC() */ +/* Depack_GMC() */ + +#include "globals.h" +#include "extern.h" + + +short testGMC ( void ) +{ + /* test #1 */ + if ( (PW_i<7) || ((PW_Start_Address+444)>PW_in_size) ) + { +/*printf ( "#1\n" );*/ + return BAD; + } + PW_Start_Address = PW_i-7; + + /* samples descriptions */ + PW_WholeSampleSize=0; + PW_j=0; + for ( PW_k = 0 ; PW_k < 15 ; PW_k ++ ) + { + PW_o = (in_data[PW_Start_Address+16*PW_k+4]*256)+in_data[PW_Start_Address+16*PW_k+5]; + PW_n = (in_data[PW_Start_Address+16*PW_k+12]*256)+in_data[PW_Start_Address+16*PW_k+13]; + PW_o *= 2; + /* volumes */ + if ( in_data[PW_Start_Address + 7 + (16*PW_k)] > 0x40 ) + { +/*printf ( "#2\n" );*/ + return BAD; + } + /* size */ + if ( PW_o > 0xFFFF ) + { +/*printf ( "#2,1 Start:%ld\n" , PW_Start_Address );*/ + return BAD; + } + if ( PW_n > PW_o ) + { +/*printf ( "#2,2 Start:%ld\n" , PW_Start_Address );*/ + return BAD; + } + PW_WholeSampleSize += PW_o; + if ( PW_o != 0 ) + PW_j = PW_k+1; + } + if ( PW_WholeSampleSize <= 4 ) + { +/*printf ( "#2,3 Start:%ld\n" , PW_Start_Address );*/ + return BAD; + } + /* PW_j is the highest not null sample */ + + /* pattern table size */ + if ( ( in_data[PW_Start_Address+243] > 0x64 ) || + ( in_data[PW_Start_Address+243] == 0x00 ) ) + { + return BAD; + } + + /* pattern order table */ + PW_l=0; + for ( PW_n=0 ; PW_n<100 ; PW_n++ ) + { + PW_k = ((in_data[PW_Start_Address+244+PW_n*2]*256)+ + in_data[PW_Start_Address+245+PW_n*2]); + if ( ((PW_k/1024)*1024) != PW_k ) + { +/*printf ( "#4 Start:%ld (PW_k:%ld)\n" , PW_Start_Address , PW_k);*/ + return BAD; + } + PW_l = ((PW_k/1024)>PW_l) ? PW_k/1024 : PW_l; + } + PW_l += 1; + /* PW_l is the number of pattern */ + /* 20100822 - was wrong when there was only one pattern */ + /*if ( (PW_l == 1) || (PW_l >0x64) )*/ + if ( PW_l >0x64 ) + { +/*printf ("#4.5 Start:%ld\n",PW_Start_Address);*/ + return BAD; + } + + /* test pattern data */ + PW_o = in_data[PW_Start_Address+243]; + PW_m = 0; + for ( PW_k=0 ; PW_k 0x03 ) || + ( (in_data[PW_Start_Address+444+PW_k*1024+PW_n*4+2]&0x0f) >= 0x90 )) + { +/*printf ( "#5,0 Start:%ld (PW_k:%ld)\n" , PW_Start_Address , PW_k);*/ + return BAD; + } + /* 20100822 - following test is removed as there seem to exist GMC with + sample number higher than the actual number of sample saved ... + seen in Jumping Jack Son game*/ +/* if ( ((in_data[PW_Start_Address+444+PW_k*1024+PW_n*4+2]&0xf0)>>4) > PW_j ) + { +printf ( "#5,1 Start:%ld (PW_j:%ld) (where:%ld) (value:%x)\n" + , PW_Start_Address , PW_j , PW_Start_Address+444+PW_k*1024+PW_n*4+2 + , ((in_data[PW_Start_Address+444+PW_k*1024+PW_n*4+2]&0xf0)>>4) ); + return BAD; + }*/ + /* test volume effect if value is > 64 */ + if ( ((in_data[PW_Start_Address+444+PW_k*1024+PW_n*4+2]&0x0f) == 3) && + (in_data[PW_Start_Address+444+PW_k*1024+PW_n*4+3] > 0x64) ) + { +/*printf ( "#5,2 Start:%ld (PW_j:%ld)\n" , PW_Start_Address , PW_j);*/ + return BAD; + } + if ( ((in_data[PW_Start_Address+444+PW_k*1024+PW_n*4+2]&0x0f) == 4) && + (in_data[PW_Start_Address+444+PW_k*1024+PW_n*4+3] > 0x63) ) + { +/*printf ( "#5,3 Start:%ld (PW_j:%ld)\n" , PW_Start_Address , PW_j);*/ + return BAD; + } + if ( ((in_data[PW_Start_Address+444+PW_k*1024+PW_n*4+2]&0x0f) == 5) && + (in_data[PW_Start_Address+444+PW_k*1024+PW_n*4+3] > PW_o+1) ) + { +/*printf ( "#5,4 Start:%ld (effect:5)(PW_o:%ld)(4th note byte:%x)\n" , PW_Start_Address , PW_j , in_data[PW_Start_Address+444+PW_k*1024+PW_n*4+3]);*/ + return BAD; + } + if ( ((in_data[PW_Start_Address+444+PW_k*1024+PW_n*4+2]&0x0f) == 6) && + (in_data[PW_Start_Address+444+PW_k*1024+PW_n*4+3] >= 0x02) ) + { +/*printf ( "#5,5 Start:%ld (at:%ld)\n" , PW_Start_Address , PW_Start_Address+444+PW_k*1024+PW_n*4+3 );*/ + return BAD; + } + if ( ((in_data[PW_Start_Address+444+PW_k*1024+PW_n*4+2]&0x0f) == 7) && + (in_data[PW_Start_Address+444+PW_k*1024+PW_n*4+3] >= 0x02) ) + { +/*printf ( "#5,6 Start:%ld (at:%ld)\n" , PW_Start_Address , PW_Start_Address+444+PW_k*1024+PW_n*4+3 );*/ + return BAD; + } + if ( ((in_data[PW_Start_Address+444+PW_k*1024+PW_n*4]&0x0f) > 0x00) || (in_data[PW_Start_Address+445+PW_k*1024+PW_n*4] > 0x00) ) + PW_m = 1; + } + } + if ( PW_m == 0 ) + { + /* only empty notes */ + return BAD; + } + /* PW_WholeSampleSize is the whole sample size */ + + return GOOD; +} + + +void Rip_GMC ( void ) +{ + /* PW_l is still the number of pattern to play */ + /* PW_WholeSampleSize is already the whole sample size */ + + OutputSize = PW_WholeSampleSize + (PW_l*1024) + 444; + + CONVERT = GOOD; + Save_Rip ( "Game Music Creator module", GMC ); + + if ( Save_Status == GOOD ) + PW_i += 444; /* after header */ +} + +/* + * Game_Music_Creator.c 1997 (c) Sylvain "Asle" Chipaux + * + * Depacks musics in the Game Music Creator format and saves in ptk. + * + * update: 30/11/99 + * - removed open() (and other fread()s and the like) + * - general Speed & Size Optmizings + * + * update: 23/08/10 + * - clean up +*/ + + +void Depack_GMC ( void ) +{ + Uchar *Whatever; + Uchar Max=0x00; + long WholeSampleSize=0; + long i=0,j=0; + long Where = PW_Start_Address; + FILE *out; + + if ( Save_Status == BAD ) + return; + + sprintf ( Depacked_OutName , "%ld.mod" , Cpt_Filename-1 ); + out = PW_fopen ( Depacked_OutName , "w+b" ); + + /* title */ + Whatever = (Uchar *) malloc ( 1084 ); + BZERO ( Whatever , 1084 ); + + /* read and write whole header */ + /*printf ( "Converting sample headers ... " );*/ + for ( i=0 ; i<15 ; i++ ) + { + Whatever[(i*30)+42] = in_data[Where+4]; + Whatever[(i*30)+43] = in_data[Where+5]; + WholeSampleSize += (((in_data[Where+4]*256)+in_data[Where+5])*2); + Whatever[(i*30)+44] = in_data[Where+6]; + Whatever[(i*30)+45] = in_data[Where+7]; + Whatever[(i*30)+48] = in_data[Where+12]; + Whatever[(i*30)+49] = in_data[Where+13]; + + if ( (Whatever[(i*30)+48] == 0x00) && (Whatever[(i*30)+49] == 0x02) ) + Whatever[(i*30)+49] = 0x01; + + /* loop start stuff - must check if there's a loop */ + if ( ((in_data[Where+12]*256)+in_data[Where+13]) > 2 ) + { + /* ok, there's a loop size. use addresses to get the loop start */ + /* I know, that could be done some other way ... */ + unsigned char c=0x00,d; + if ( in_data[Where+3] > in_data[Where+11] ) + {d = in_data[Where+11]+256 - in_data[Where+3]; c += 1;} + else + d = in_data[Where+11] - in_data[Where+3]; + if ( in_data[Where+2] > in_data[Where+10] ) + c += (in_data[Where+10]+256 - in_data[Where+2]); + else + c += in_data[Where+10] - in_data[Where+2]; + /* other bytes _must_ be 0 */ + Whatever[(i*30)+46] = c/2; + Whatever[(i*30)+47] = d/2; + } + + Where += 16; + } + + /* pattern list size */ + Where = PW_Start_Address + 0xF3; + Whatever[950] = in_data[Where++]; + Whatever[951] = 0x7F; + + /* read and write size of pattern list */ + /*printf ( "Creating the pattern table ... " );*/ + Max = 0x00; + for ( i=0 ; i<100 ; i++ ) + { + Whatever[952+i] = ((in_data[Where]*256)+in_data[Where+1])/1024; + Where += 2; + if ( Whatever[952+i] > Max ) + Max = Whatever[952+i]; + } + + /* write ID */ + Whatever[1080] = 'M'; + Whatever[1081] = '.'; + Whatever[1082] = 'K'; + Whatever[1083] = '.'; + fwrite ( Whatever , 1084 , 1 , out ); + + + /* pattern data */ + /*printf ( "Converting pattern datas " );*/ + Where = PW_Start_Address + 444; + for ( i=0 ; i<=Max ; i++ ) + { + BZERO ( Whatever , 1024 ); + for ( j=0 ; j<1024 ; j++ ) Whatever[j] = in_data[Where++]; + for ( j=0 ; j<256 ; j++ ) + { + switch ( Whatever[(j*4)+2]&0x0f ) + { + case 3: /* replace by C */ + Whatever[(j*4)+2] += 0x09; + break; + case 4: /* replace by D */ + Whatever[(j*4)+2] += 0x09; + break; + case 5: /* replace by B */ + Whatever[(j*4)+2] += 0x06; + break; + case 6: /* replace by E0 */ + Whatever[(j*4)+2] += 0x08; + break; + case 7: /* replace by E0 */ + Whatever[(j*4)+2] += 0x07; + break; + case 8: /* replace by F */ + Whatever[(j*4)+2] += 0x07; + break; + default: + break; + } + } + fwrite ( Whatever , 1024 , 1 , out ); + } + free ( Whatever ); + + /* sample data */ + /*printf ( "Saving sample data ... " );*/ + fwrite ( &in_data[Where] , WholeSampleSize , 1 , out ); + + /* crap */ + Crap ( "Game Music Creator" , BAD , BAD , out ); + + fflush ( out ); + fclose ( out ); + + printf ( "done\n" ); + return; /* useless ... but */ +} diff --git a/prowizard/rippers/NP3.c b/prowizard/rippers/NP3.c new file mode 100644 index 00000000..d58d5728 --- /dev/null +++ b/prowizard/rippers/NP3.c @@ -0,0 +1,418 @@ +/* testNoisepacker3() */ +/* Rip_Noisepacker3() */ +/* Depack_Noisepacker3() */ + +#include "globals.h" +#include "extern.h" + +short testNoisepacker3 ( void ) +{ + if ( PW_i < 9 ) + { + return BAD; + } + PW_Start_Address = PW_i-9; + + /* size of the pattern table */ + PW_j = (in_data[PW_Start_Address+2]*256)+in_data[PW_Start_Address+3]; + if ( (((PW_j/2)*2) != PW_j) || (PW_j == 0) ) + { +/*printf ( "#2 Start:%ld\n" , PW_Start_Address );*/ + return BAD; + } + /* PW_j is the size of the pattern list (*2) */ + + /* test nbr of samples */ + if ( (in_data[PW_Start_Address+1]&0x0f) != 0x0C ) + { +/*printf ( "#3,0 Start:%ld (nbr sample : %d)\n" , PW_Start_Address, in_data[PW_Start_Address+1]&0x0f);*/ + return BAD; + } + PW_l = ((in_data[PW_Start_Address]<<4)&0xf0)|((in_data[PW_Start_Address+1]>>4)&0x0f); + if ( (PW_l > 0x1F) || (PW_l == 0) || ((PW_Start_Address+8+PW_j+PW_l*8)>PW_in_size)) + { +/*printf ( "#3 Start:%ld\n" , PW_Start_Address );*/ + return BAD; + } + /* PW_l is the number of samples */ + + /* test volumes */ + for ( PW_k=0 ; PW_k 0x40 ) + { + return BAD; + } + } + + /* test sample sizes */ + PW_WholeSampleSize=0; + for ( PW_k=0 ; PW_k 0xFFFF) || + (PW_m > 0xFFFF) || + (PW_n > 0xFFFF) ) + { +/*printf ( "#5 Start:%ld\n" , PW_Start_Address );*/ + return BAD; + } + if ( (PW_m + PW_n) > (PW_o+2) ) + { +/*printf ( "#5,1 Start:%ld\n" , PW_Start_Address );*/ + return BAD; + } + if ( (PW_n != 0) && (PW_m == 0) ) + { +/*printf ( "#5,2 Start:%ld\n" , PW_Start_Address );*/ + return BAD; + } + PW_WholeSampleSize += PW_o; + } + if ( PW_WholeSampleSize <= 4 ) + { +/*printf ( "#5,3 Start:%ld\n" , PW_Start_Address );*/ + return BAD; + } + + + /* small shit to gain some vars */ + PW_l *= 16; + PW_l += 8; + PW_l += 4; + /* PW_l is now the size of the header 'til the end of sample descriptions */ + if ( (PW_l+PW_Start_Address) > PW_in_size ) + { +/*printf ( "NP3 Header bigger than file size (%ld > %ld)\n", PW_l, PW_in_size);*/ + return BAD; + } + + + /* test pattern table */ + PW_n=0; + for ( PW_k=0 ; PW_k PW_n ) + PW_n = PW_m; + } + PW_l += PW_j; + PW_l += PW_n; + PW_l += 8; /*paske on a que l'address du dernier pattern .. */ + /* PW_l is now the size of the header 'til the end of the track list */ + /* PW_j is now available for use :) */ + /* PW_n is the highest pattern number (*8) */ + + /* test track data size */ + PW_k = (in_data[PW_Start_Address+6]*256)+in_data[PW_Start_Address+7]; + if ( (PW_k <= 63) || ((PW_k+PW_l+PW_Start_Address)>PW_in_size)) + { +/*printf ( "#7 Start:%ld\n" , PW_Start_Address );*/ + return BAD; + } + + /* test notes */ + /* re-calculate the number of sample */ + /* PW_k is the track data size */ + PW_j = ((in_data[PW_Start_Address]<<4)&0xf0)|((in_data[PW_Start_Address+1]>>4)&0x0f); + for ( PW_m=0 ; PW_m < PW_k ; PW_m++ ) + { + if ( (in_data[PW_Start_Address+PW_l+PW_m]&0x80) == 0x80 ) + continue; + /* si note trop grande et si effet = A */ + if ( (in_data[PW_Start_Address+PW_l+PW_m] > 0x49)|| + ((in_data[PW_Start_Address+PW_l+PW_m+1]&0x0f) == 0x0A) ) + { +/*printf ( "#8,1 Start:%ld (at %x)(PW_k:%x)(PW_l:%x)(PW_m:%x)\n" , PW_Start_Address,PW_Start_Address+PW_l+PW_m,PW_k,PW_l,PW_m );*/ + return BAD; + } + /* si effet D et arg > 0x64 */ + if ( ((in_data[PW_Start_Address+PW_l+PW_m+1]&0x0f) == 0x0D )&& + (in_data[PW_Start_Address+PW_l+PW_m+2] > 0x64 ) ) + { +/*printf ( "#8,2 Start:%ld (at %ld)(effet:%x)(arg:%x)\n" + , PW_Start_Address + , PW_Start_Address+PW_l+PW_m + , in_data[PW_Start_Address+PW_l+PW_m+1]&0x0f + , in_data[PW_Start_Address+PW_l+PW_m+2] );*/ + return BAD; + } + /* sample nbr > ce qui est defini au debut ? */ +/* if ( (((in_data[PW_Start_Address+PW_l+PW_m]<<4)&0x10)| + ((in_data[PW_Start_Address+PW_l+PW_m+1]>>4)&0x0f)) > PW_j ) + { +printf ( "#8,1 Start:%ld (at %x)(PW_k:%x)(PW_l:%x)(PW_m:%x)(PW_j:%ld),(smp nbr given:%d)\n" +, PW_Start_Address +,PW_Start_Address+PW_l+PW_m +,PW_k +,PW_l +,PW_m +,PW_j, +(((in_data[PW_Start_Address+PW_l+PW_m]<<4)&0x10)| ((in_data[PW_Start_Address+PW_l+PW_m+1]>>4)&0x0f))); + + return BAD; + }*/ + /* all is empty ?!? ... cannot be ! */ + if ( (in_data[PW_Start_Address+PW_l+PW_m] == 0) && + (in_data[PW_Start_Address+PW_l+PW_m+1] == 0) && + (in_data[PW_Start_Address+PW_l+PW_m+2] == 0) && (PW_m<(PW_k-3)) ) + { +/*printf ( "#8,3 Start:%ld (at %x)(PW_k:%x)(PW_l:%x)(PW_m:%x)(PW_j:%ld)\n" , PW_Start_Address,PW_Start_Address+PW_l+PW_m,PW_k,PW_l,PW_m,PW_j );*/ + return BAD; + } + PW_m += 2; + } + + /* PW_WholeSampleSize is the size of the sample data */ + /* PW_l is the size of the header 'til the track datas */ + /* PW_k is the size of the track datas */ + return GOOD; +} + + + +void Rip_Noisepacker3 ( void ) +{ + OutputSize = PW_k + PW_WholeSampleSize + PW_l; + /* printf ( "\b\b\b\b\b\b\b\bNoisePacker v3 module found at %ld !. its size is : %ld\n" , PW_Start_Address , OutputSize );*/ + + CONVERT = GOOD; + Save_Rip ( "NoisePacker v3 module", Noisepacker3 ); + + if ( Save_Status == GOOD ) + PW_i += 16; /* 15 should do but call it "just to be sure" :) */ +} + + + +/* + * NoisePacker_v3.c 1998 (c) Asle / ReDoX + * + * Converts NoisePacked MODs back to ptk + * Last revision : 26/11/1999 by Sylvain "Asle" Chipaux + * reduced to only one FREAD. + * Speed-up and Binary smaller. + * update : 01/12/99 + * - removed fopen() and attached funcs. + * update : 23/08/10 + * - Whatever wasn't cleaned up when writing patternlist (showed only if one pattern) + * - cleaned up a bit +*/ +void Depack_Noisepacker3 ( void ) +{ + Uchar *Whatever; + Uchar c1=0x00,c2=0x00,c3=0x00,c4=0x00; + Uchar Nbr_Pos; + Uchar Nbr_Smp; + Uchar poss[36][2]; + Uchar Pat_Max=0x00; + long Where=PW_Start_Address; + long WholeSampleSize=0; + long TrackDataSize; + long Track_Addresses[128][4]; + long Unknown1; + long i=0,j=0,k; + long Track_Data_Start_Address; + long SampleDataAddress=0; + FILE *out; + + if ( Save_Status == BAD ) + return; + + fillPTKtable(poss); + + BZERO ( Track_Addresses , 128*4*4 ); + + sprintf ( Depacked_OutName , "%ld.mod" , Cpt_Filename-1 ); + out = PW_fopen ( Depacked_OutName , "w+b" ); + + /* read number of sample */ + Nbr_Smp = ((in_data[Where]<<4)&0xf0) | ((in_data[Where+1]>>4)&0x0f); + /*printf ( "\nNumber of sample : %d (%x)\n" , Nbr_Smp , Nbr_Smp );*/ + + /* write title */ + Whatever = (Uchar *) malloc ( 1084 ); + BZERO ( Whatever , 1084 ); + /*fwrite ( Whatever , 20 , 1 , out );*/ + + /* read size of pattern list */ + Nbr_Pos = in_data[Where+3]/2; + /*printf ( "Size of pattern list : %d\n" , Nbr_Pos );*/ + + /* read 2 unknown bytes which size seem to be of some use ... */ + Unknown1 = (in_data[Where+4]*256)+in_data[Where+5]; + + /* read track data size */ + TrackDataSize = (in_data[Where+6]*256)+in_data[Where+7]; + /*printf ( "TrackDataSize : %ld\n" , TrackDataSize );*/ + + /* read sample descriptions */ + Where += 8; + for ( i=0 ; i Pat_Max ) + Pat_Max = Whatever[i+952]; + } + Where += Nbr_Pos*2; + Pat_Max += 1; + /*printf ( "Number of pattern : %d\n" , Pat_Max );*/ + + /* write pattern table */ + /*fwrite ( Whatever , 128 , 1 , out );*/ + + /* write ptk's ID */ + Whatever[1080] = 'M'; + Whatever[1081] = '.'; + Whatever[1082] = 'K'; + Whatever[1083] = '.'; + /*fwrite ( Whatever , 4 , 1 , out );*/ + fwrite ( Whatever , 1084 , 1 , out ); + + /* read tracks addresses per pattern */ + /*printf ( "\nWhere : %ld\n" , Where );*/ + for ( i=0 ; i= 0x80 ) + { + k += ((0x100-c1)-1); + continue; + } + c2 = in_data[Where]; + Where += 1; + c3 = in_data[Where]; + Where += 1; + + Whatever[k*16+j*4] = (c1<<4)&0x10; + c4 = (c1 & 0xFE)/2; + Whatever[k*16+j*4] |= poss[c4][0]; + Whatever[k*16+j*4+1] = poss[c4][1]; + if ( (c2&0x0f) == 0x08 ) + c2 &= 0xf0; + if ( (c2&0x0f) == 0x07 ) + { + c2 = (c2&0xf0)+0x0A; + if ( c3 > 0x80 ) + c3 = 0x100-c3; + else + c3 = (c3<<4)&0xf0; + } + if ( (c2&0x0f) == 0x06 ) + { + if ( c3 > 0x80 ) + c3 = 0x100-c3; + else + c3 = (c3<<4)&0xf0; + } + if ( (c2&0x0f) == 0x05 ) + { + if ( c3 > 0x80 ) + c3 = 0x100-c3; + else + c3 = (c3<<4)&0xf0; + } + if ( (c2&0x0f) == 0x0E ) + { + c3 = 0x01; + } + if ( (c2&0x0f) == 0x0B ) + { + c3 += 0x04; + c3 /= 2; + } + Whatever[k*16+j*4+2] = c2; + Whatever[k*16+j*4+3] = c3; + if ( (c2&0x0f) == 0x0D ) + k = 100; /* to leave the loop */ + } + if ( Where > SampleDataAddress ) + SampleDataAddress = Where; + } + fwrite ( Whatever , 1024 , 1 , out ); + } + free ( Whatever ); + + /* sample data */ + if ( (((SampleDataAddress-PW_Start_Address)/2)*2) != SampleDataAddress ) + SampleDataAddress += 1; + Where = SampleDataAddress; + /*printf ( "Starting address of sample data : %x\n" , ftell ( in ) );*/ + fwrite ( &in_data[SampleDataAddress] , WholeSampleSize , 1 , out ); + + Crap ( " NoisePacker v3 " , BAD , BAD , out ); + + fclose ( out ); + + printf ( "done\n" ); + return; /* useless ... but */ +} diff --git a/prowizard/rippers/ProPacker10.c b/prowizard/rippers/ProPacker10.c index 22386296..6d2bfc77 100644 --- a/prowizard/rippers/ProPacker10.c +++ b/prowizard/rippers/ProPacker10.c @@ -168,8 +168,10 @@ void Rip_PP10 ( void ) * - overall speed and size optimizings. * Update: 19/04/00 (all pointed out by Thomas Neumann) * - replen bug correction - * Update: 15/05/10 + * Update: 15/08/10 * - rewrote depacker for patternlist generation + * update : 23 aug 2010 + * - fixed yet another patternlist bug */ void Depack_PP10 ( void ) @@ -221,7 +223,7 @@ void Depack_PP10 ( void ) Header[951] = in_data[Where]; Where += 1; - // now, where = 0xFA + /* now, where = 0xFA*/ for (i=0;ik)) + { m = ReadPat[i]; + /*fprintf (info,"(i:%ld)(min:%ld)(k:%ld)",i,m,k);*/ + } /* if k == m then an already existing ref was found */ if (k==m) + { + /*fprintf (info," <- pattern known (k:%ld - m:%ld)\n",k,m);*/ continue; + } +/* else + fprintf (info,"\n");*/ /* m is the next minimum */ k = m; for (i=0; i pos %ld gets %ld\n",i,l);*/ + Header[952+i] = (unsigned char)l; + j++; + } + j--; l++; } - if ( l != Header[950] ) - l -= 1; + /*fprintf (info,"\nnumber of pattern stored : %ld",l);*/ /*fprintf (info,"number of pattern stored : %ld\n\n",l);*/ - //fflush (info); + /*fprintf (info," (%ld)\n",l);*/ /* write ptk's ID */ Header[1080] = 'M'; @@ -262,7 +277,7 @@ void Depack_PP21 ( void ) for (i=0;i 40 at : %ld)\n" , PW_Start_Address+PW_k+766+PW_j*4+2 );*/ return BAD; } - /* break > 40 ? */ + /* break > 64 ? */ if ( ((in_data[PW_Start_Address+PW_k+766+PW_j*4+2]&0x0f)==0x0d) && - (in_data[PW_Start_Address+PW_k+766+PW_j*4+3] > 0x40 ) ) + (in_data[PW_Start_Address+PW_k+766+PW_j*4+3] > 0x64 ) ) { -/*printf ( "#6,1\n" );*/ +/*printf ( "#6,1 Start:%ld\n",PW_Start_Address );*/ return BAD; } /* jump > 128 */ if ( ((in_data[PW_Start_Address+PW_k+766+PW_j*4+2]&0x0f)==0x0b) && (in_data[PW_Start_Address+PW_k+766+PW_j*4+3] > 0x7f ) ) { -/*printf ( "#6,2\n" );*/ +/*printf ( "#6,2 Start:%ld\n",PW_Start_Address );*/ return BAD; } /* smp > 1f ? */ if ((in_data[PW_Start_Address+PW_k+766+PW_j*4]&0xf0)>0x10) { -/*printf ( "#6,3\n" );*/ +/*printf ( "#6,3 Start:%ld\n",PW_Start_Address );*/ return BAD; } } @@ -177,6 +177,8 @@ void Rip_PP30 ( void ) * - no more fopen () * update : 16 aug 2010 * - rewrotte depacker for patternlist generation + * update : 23 aug 2010 + * - fixed yet another patternlist bug */ void Depack_PP30 ( void ) @@ -227,7 +229,7 @@ void Depack_PP30 ( void ) Header[951] = in_data[Where]; Where += 1; - // now, where = 0xFA + /* now, where = 0xFA */ for (i=0;ivolume = zv; root->type = ZNODE_DIR; i = 0; - if (name[0] != '/' && name[0] != '\\') { + if (name[0] != '/' && name[0] != '\\' && _tcsncmp (name, L".\\", 2) != 0) { if (_tcschr (name, ':') == 0) { for (i = _tcslen (name) - 1; i > 0; i--) { if (name[i] == FSDB_DIR_SEPARATOR) { -- 2.47.3