f = fopen(path, "rb");\r
if (f == NULL) return NULL;\r
\r
-#ifndef NO_IONBF\r
/* we use our own buffering */\r
setvbuf(f, NULL, _IONBF, 0);\r
-#endif\r
\r
file = malloc(sizeof(*file));\r
if (file == NULL) {\r
PicoMemReset();\r
SekReset();\r
// s68k doesn't have the TAS quirk, so we just globally set normal TAS handler in MCD mode (used by Batman games).\r
- CycloneSetRealTAS(PicoMCD & 1);\r
+ SekSetRealTAS(PicoMCD & 1);\r
SekCycleCntT=0;\r
z80_reset();\r
\r
int y=0,line=0,lines=0,lines_step=0,sects;\r
int cycles_68k_vblock,cycles_68k_block;\r
\r
- if(Pico.m.pal) {\r
+ // we don't emulate DMA timing in this mode\r
+ if (Pico.m.dma_bytes) {\r
+ Pico.m.dma_bytes=0;\r
+ Pico.video.status&=~2;\r
+ }\r
+\r
+ if (Pico.m.pal) {\r
// M68k cycles/frame: 152009.78\r
if(pv->reg[1]&8) { // 240 lines\r
cycles_68k_block = (int) ((double) OSC_PAL / 7 / 50 / 312 * 15 + 0.4); // 16 sects, 16*15=240, 7308\r
// enable_ym2612&dac, enable_sn76496, enable_z80, stereo_sound,\r
// alt_renderer, 6button_gamepad, accurate_timing, accurate_sprites,\r
// draw_no_32col_border, external_ym2612, enable_pcm, enable cdda\r
-// enable_cdgfx, cd_perfect_sync\r
+// enable_cdgfx, cd_perfect_sync, soft_32col_scaling\r
extern int PicoOpt;\r
extern int PicoVer;\r
extern int PicoSkipFrame; // skip rendering frame, but still do sound (if enabled) and emulation stuff\r
int SekReset(void);\r
int SekInterrupt(int irq);\r
void SekState(unsigned char *data);\r
+void SekSetRealTAS(int use_real);\r
\r
// cd/Sek.c\r
int SekInitS68k(void);\r
memcpy(data+0x40,&PicoM68kCPU.pc, 0x04);\r
#endif\r
}\r
+\r
+void SekSetRealTAS(int use_real)\r
+{\r
+#ifdef EMU_C68K\r
+ CycloneSetRealTAS(use_real);\r
+#endif\r
+}\r
+\r
#define rdprintf(...)\r
//#define wrdprintf dprintf\r
#define wrdprintf(...)\r
+//#define plprintf dprintf\r
+#define plprintf(...)\r
\r
// -----------------------------------------------------------------\r
\r
// poller detection\r
+//#undef USE_POLL_DETECT\r
#define POLL_LIMIT 16\r
#define POLL_CYCLES 124\r
// int m68k_poll_addr, m68k_poll_cnt;\r
#ifdef USE_POLL_DETECT\r
if ((s68k_poll_adclk&0xfe) == 2 && s68k_poll_cnt > POLL_LIMIT) {\r
SekSetStopS68k(0); s68k_poll_adclk = 0;\r
- //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+ plprintf("s68k poll release, a=%02x\n", a);\r
}\r
#endif\r
return;\r
#ifdef USE_POLL_DETECT\r
if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) {\r
SekSetStopS68k(0); s68k_poll_adclk = 0;\r
- //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+ plprintf("s68k poll release, a=%02x\n", a);\r
}\r
#endif\r
return;\r
#ifdef USE_POLL_DETECT\r
if ((a&0xfe) == (s68k_poll_adclk&0xfe) && s68k_poll_cnt > POLL_LIMIT) {\r
SekSetStopS68k(0); s68k_poll_adclk = 0;\r
- //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+ plprintf("s68k poll release, a=%02x\n", a);\r
}\r
#endif\r
return;\r
dprintf("m68k FIXME: invalid write? [%02x] %02x", a, d);\r
}\r
\r
+#ifndef _ASM_CD_MEMORY_C\r
+static\r
+#endif\r
+u32 s68k_poll_detect(u32 a, u32 d)\r
+{\r
+#ifdef USE_POLL_DETECT\r
+ // polling detection\r
+ if (a == (s68k_poll_adclk&0xff)) {\r
+ unsigned int clkdiff = SekCyclesDoneS68k() - (s68k_poll_adclk>>8);\r
+ if (clkdiff <= POLL_CYCLES) {\r
+ s68k_poll_cnt++;\r
+ //printf("-- diff: %u, cnt = %i\n", clkdiff, s68k_poll_cnt);\r
+ if (s68k_poll_cnt > POLL_LIMIT) {\r
+ SekSetStopS68k(1);\r
+ plprintf("s68k poll detected @ %06x, a=%02x\n", SekPcS68k, a);\r
+ }\r
+ s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;\r
+ return d;\r
+ }\r
+ }\r
+ s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;\r
+ s68k_poll_cnt = 0;\r
+#endif\r
+ return d;\r
+}\r
\r
#define READ_FONT_DATA(basemask) \\r
{ \\r
case 0:\r
return ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
case 2:\r
- d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0x1f);\r
+ d = (Pico_mcd->s68k_regs[2]<<8) | (Pico_mcd->s68k_regs[3]&0x1f);\r
//printf("s68k_regs r3: %02x @%06x\n", (u8)d, SekPcS68k);\r
- goto poll_detect;\r
+ return s68k_poll_detect(a, d);\r
case 6:\r
return CDC_Read_Reg();\r
case 8:\r
\r
d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
\r
- if (a >= 0x0e && a < 0x30) goto poll_detect;\r
-\r
- return d;\r
-\r
-poll_detect:\r
-#ifdef USE_POLL_DETECT\r
- // polling detection\r
- if (a == (s68k_poll_adclk&0xfe)) {\r
- unsigned int clkdiff = SekCyclesDoneS68k() - (s68k_poll_adclk>>8);\r
- if (clkdiff <= POLL_CYCLES) {\r
- s68k_poll_cnt++;\r
- //printf("-- diff: %u, cnt = %i\n", clkdiff, s68k_poll_cnt);\r
- if (s68k_poll_cnt > POLL_LIMIT) {\r
- SekSetStopS68k(1);\r
- //printf("%05i:%03i: s68k poll detected @ %06x, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, SekPcS68k, a);\r
- }\r
- s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;\r
- return d;\r
- }\r
- }\r
- s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;\r
- s68k_poll_cnt = 0;\r
+ if (a >= 0x0e && a < 0x30)\r
+ return s68k_poll_detect(a, d);\r
\r
-#endif\r
return d;\r
}\r
\r
#include "cell_map.c"\r
#endif // !def _ASM_CD_MEMORY_C\r
\r
+\r
// -----------------------------------------------------------------\r
// Read Rom and read Ram\r
\r
return;\r
}\r
\r
- if ((a&0xffffc0)==0xa12000)\r
+ if ((a&0xffffc0)==0xa12000) {\r
rdprintf("m68k_regs w8: [%02x] %02x @%06x", a&0x3f, d, SekPc);\r
+ m68k_reg_write8(a, d);\r
+ return;\r
+ }\r
\r
OtherWrite8(a,d,8);\r
}\r
#ifdef USE_POLL_DETECT\r
if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) {\r
SekSetStopS68k(0); s68k_poll_adclk = -1;\r
- //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+ plprintf("s68k poll release, a=%02x\n", a);\r
}\r
#endif\r
return;\r
return;\r
}\r
\r
- if ((a&0xffffc0)==0xa12000)\r
+ if ((a&0xffffc0)==0xa12000) {\r
rdprintf("m68k_regs w32: [%02x] %08x @%06x", a&0x3f, d, SekPc);\r
+ if ((a&0x3e) == 0xe) dprintf("m68k FIXME: w32 [%02x]", a&0x3f);\r
+ }\r
\r
OtherWrite16(a, (u16)(d>>16));\r
OtherWrite16(a+2,(u16)d);\r
if ((a&0xfffe00) == 0xff8000) {\r
a &= 0x1ff;\r
rdprintf("s68k_regs r8: [%02x] @ %06x", a, SekPcS68k);\r
- if (a >= 0x58 && a < 0x68)\r
+ if (a >= 0x0e && a < 0x30) {\r
+ d = Pico_mcd->s68k_regs[a];\r
+ s68k_poll_detect(a, d);\r
+ rdprintf("ret = %02x", (u8)d);\r
+ goto end;\r
+ }\r
+ else if (a >= 0x58 && a < 0x68)\r
d = gfx_cd_read(a&~1);\r
else d = s68k_reg_read16(a&~1);\r
if ((a&1)==0) d>>=8;\r
\r
// PCM\r
if ((a&0xff8000)==0xff0000) {\r
- dprintf("FIXME: s68k_pcm r32: [%06x] @%06x", a, SekPcS68k);\r
+ dprintf("s68k_pcm r32: [%06x] @%06x", a, SekPcS68k);\r
a &= 0x7fff;\r
if (a >= 0x2000) {\r
a >>= 1;\r
gfx_cd_write16(a, d>>16);\r
gfx_cd_write16(a+2, d&0xffff);\r
} else {\r
+ if ((a&0x1fe) == 0xe) dprintf("s68k FIXME: w32 [%02x]", a&0x3f);\r
s68k_reg_write8(a, d>>24);\r
s68k_reg_write8(a+1,(d>>16)&0xff);\r
s68k_reg_write8(a+2,(d>>8) &0xff);\r
.extern s68k_reg_write8
.extern s68k_poll_adclk
.extern PicoCpuS68k
+.extern s68k_poll_detect
+.extern SN76496Write
@ r0=reg3, r1-r3=temp
tst r0, #0x70000
tsteq r0, #0x000e0
bxne lr @ invalid
+ and r2, r0, #0x19
+ cmp r2, #0x11
+ andeq r0, r1, #0xff
+ beq SN76496Write
and r1, r1, #0xff
orr r1, r1, r1, lsl #8 @ byte access gets mirrored
b PicoVideoWrite
tsteq r0, #0x000e0
bxne lr @ invalid
bic r0, r0, #1
- b PicoVideoWrite
+ and r2, r0, #0x18
+ cmp r2, #0x10
+ bne PicoVideoWrite
+ and r0, r1, #0xff
+ b SN76496Write @ lsb goes to 0x11
m_m68k_write16_ram:
tst r0, #0x70000
tsteq r0, #0x000e0
bxne lr @ invalid
+ and r2, r0, #0x18
+ cmp r2, #0x10
+ moveq r0, r1, lsr #16
+ beq SN76496Write @ which game is crazy enough to do that?
stmfd sp!,{r0,r1,lr}
mov r1, r1, lsr #16
bl PicoVideoWrite
tst r0, #0x7e00
movne r0, #0
bxne lr
+ sub r2, r0, #0x0e
+ cmp r2, #(0x30-0x0e)
+ blo m_s68k_read8_comm
sub r2, r0, #0x58
cmp r2, #0x10
ldrlo r2, =gfx_cd_read
and r0, r0, #0xff
bx lr
+m_s68k_read8_comm:
+ ldr r1, =(Pico+0x22200)
+ ldr r1, [r1]
+ add r1, r1, #0x110000
+ ldrb r1, [r1, r0]
+ b s68k_poll_detect
+
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
}\r
\r
addr = ym2612.OPN.ST.address;\r
+#ifndef EXTERNAL_YM2612\r
ym2612.REGS[addr] = v;\r
+#endif\r
\r
switch( addr & 0xf0 )\r
{\r
}\r
\r
addr = ym2612.OPN.ST.address | 0x100;\r
+#ifndef EXTERNAL_YM2612\r
ym2612.REGS[addr] = v;\r
+#endif\r
\r
ret = OPNWriteReg(addr, v);\r
break;\r
}\r
\r
\r
+#ifndef EXTERNAL_YM2612\r
void *YM2612GetRegs(void)\r
{\r
return ym2612.REGS;\r
}\r
+#endif\r
+\r
\r
\r
/* OPN Mode Register Write */\r
-static void set_timers( int v )\r
+static int set_timers( int v )\r
{\r
+ int change;\r
+\r
/* b7 = CSM MODE */\r
/* b6 = 3 slot mode */\r
/* b5 = reset b */\r
/* b2 = timer enable a */\r
/* b1 = load b */\r
/* b0 = load a */\r
+ change = (ST_mode ^ v) & 0xc0;\r
ST_mode = v;\r
\r
/* reset Timer b flag */\r
/* reset Timer a flag */\r
if( v & 0x10 )\r
ST_status &= ~1;\r
+\r
+ return change;\r
}\r
\r
/* YM2612 write */\r
/* returns 1 if sample affecting state changed */\r
int YM2612Write_940(unsigned int a, unsigned int v)\r
{\r
- int addr; //, ret=1;\r
+ int addr;\r
+ int upd = 1; /* the write affects sample generation */\r
\r
v &= 0xff; /* adjust to 8 bit bus */\r
a &= 3;\r
\r
+ //printf("%05i:%03i: ym w ([%i] %02x)\n", Pico.m.frame_count, Pico.m.scanline, a, v);\r
+\r
switch( a ) {\r
case 0: /* address port 0 */\r
if (!addr_A1 && ST_address == v)\r
(v == 0x24 || v == 0x25 || v == 0x26 || v == 0x2a))\r
return 0;\r
addr_A1 = 0;\r
- //ret=0;\r
+ upd = 0;\r
break;\r
\r
case 1: /* data port 0 */\r
}\r
return 0;\r
case 0x27: /* mode, timer control */\r
- set_timers( v );\r
- break; // other side needs ST.mode for 3slot mode\r
+ if (set_timers( v ))\r
+ break; // other side needs ST.mode for 3slot mode\r
+ return 0;\r
case 0x2a: /* DAC data (YM2612) */\r
dacout = ((int)v - 0x80) << 6; /* level unknown (notaz: 8 seems to be too much) */\r
return 0;\r
case 0x2b: /* DAC Sel (YM2612) */\r
/* b7 = dac enable */\r
dacen = v & 0x80;\r
+ upd = 0;\r
break; // other side has to know this\r
default:\r
break;\r
return 0;\r
ST_address = v;\r
addr_A1 = 1;\r
- //ret=0;\r
+ upd = 0;\r
break;\r
\r
case 3: /* data port 1 */\r
break;\r
}\r
\r
+ //printf("ym pass\n");\r
+\r
if(currentConfig.EmuOpt & 4) {\r
- /* queue this write for 940 */\r
- if (writebuff_ptr < 2047) {\r
- if (shared_ctl->writebuffsel == 1) {\r
- shared_ctl->writebuff0[writebuff_ptr++] = (a<<8)|v;\r
- } else {\r
- shared_ctl->writebuff1[writebuff_ptr++] = (a<<8)|v;\r
+ UINT16 *writebuff = shared_ctl->writebuffsel ? shared_ctl->writebuff0 : shared_ctl->writebuff1;\r
+\r
+ /* detect rapid ym updates */\r
+ if (upd && !(writebuff_ptr & 0x80000000) && Pico.m.scanline < 224) {\r
+ int mid = Pico.m.pal ? 68 : 93;\r
+ if (Pico.m.scanline > mid) {\r
+ //printf("%05i:%03i: rapid ym\n", Pico.m.frame_count, Pico.m.scanline);\r
+ writebuff[writebuff_ptr++ & 0xffff] = 0xfffe;\r
+ writebuff_ptr |= 0x80000000;\r
+ //printf("%05i:%03i: ym w ([%02x] %02x, upd=%i)\n", Pico.m.frame_count, Pico.m.scanline, addr, v, upd);\r
}\r
+ }\r
+\r
+ /* queue this write for 940 */\r
+ if ((writebuff_ptr&0xffff) < 2047) {\r
+ writebuff[writebuff_ptr++ & 0xffff] = (a<<8)|v;\r
} else {\r
printf("warning: writebuff_ptr > 2047 ([%i] %02x)\n", a, v);\r
}\r
\r
addr_A1 = old_A1;\r
\r
- add_job_940(JOB940_PICOSTATELOAD);\r
+// add_job_940(JOB940_PICOSTATELOAD);\r
}\r
\r
\r
else memset32(buffer, 0, length<<stereo);\r
\r
if (shared_ctl->writebuffsel == 1) {\r
- shared_ctl->writebuff0[writebuff_ptr] = 0xffff;\r
+ shared_ctl->writebuff0[writebuff_ptr & 0xffff] = 0xffff;\r
} else {\r
- shared_ctl->writebuff1[writebuff_ptr] = 0xffff;\r
+ shared_ctl->writebuff1[writebuff_ptr & 0xffff] = 0xffff;\r
}\r
writebuff_ptr = 0;\r
\r
# CPU cores\r
ifeq "$(use_musashi)" "1"\r
DEFINC += -DEMU_M68K\r
-OBJS += _build\m68kcpu.o _build\m68kopac.o _build\m68kopdm.o _build\m68kopnz.o _build\m68kops.o\r
+OBJS += ../../cpu/musashi/m68kcpu.o ../../cpu/musashi/m68kopac.o ../../cpu/musashi/m68kopdm.o\r
+OBJS += ../../cpu/musashi/m68kopnz.o ../../cpu/musashi/m68kops.o\r
else\r
DEFINC += -DEMU_C68K\r
OBJS += ../../cpu/Cyclone/proj/Cyclone.o\r
set_if_not_changed(&shared_ctl->mp3_offs, mp3_offs, readPtr - mp3_data);\r
}\r
\r
+static void ym_update(int *ym_buffer)\r
+{\r
+ int i, dw;\r
+ int two_upds = 0;\r
+ UINT16 *wbuff;\r
+\r
+ if (shared_ctl->writebuffsel == 1) {\r
+ wbuff = shared_ctl->writebuff1;\r
+ } else {\r
+ wbuff = shared_ctl->writebuff0;\r
+ }\r
+\r
+ /* playback all writes */\r
+ for (i = 2048/2; i > 0; i--) {\r
+ UINT16 d;\r
+ dw = *(int *)wbuff;\r
+ d = dw;\r
+ wbuff++;\r
+ if (d == 0xffff) break;\r
+ if (d == 0xfffe) { two_upds=1; break; }\r
+ YM2612Write_(d >> 8, d);\r
+ d = (dw>>16);\r
+ wbuff++;\r
+ if (d == 0xffff) break;\r
+ if (d == 0xfffe) { two_upds=1; break; }\r
+ YM2612Write_(d >> 8, d);\r
+ }\r
+\r
+ if (two_upds) {\r
+ int len1 = shared_ctl->length / 2;\r
+ shared_ctl->ym_active_chs =\r
+ YM2612UpdateOne_(ym_buffer, len1, shared_ctl->stereo, 1);\r
+\r
+ for (i *= 2; i > 0; i--) {\r
+ UINT16 d = *wbuff++;\r
+ if (d == 0xffff) break;\r
+ YM2612Write_(d >> 8, d);\r
+ }\r
+\r
+ ym_buffer += shared_ctl->stereo ? len1*2 : len1;\r
+ len1 = shared_ctl->length - len1;\r
+\r
+ shared_ctl->ym_active_chs =\r
+ YM2612UpdateOne_(ym_buffer, len1, shared_ctl->stereo, 1);\r
+ } else {\r
+ shared_ctl->ym_active_chs =\r
+ YM2612UpdateOne_(ym_buffer, shared_ctl->length, shared_ctl->stereo, 1);\r
+ }\r
+}\r
+\r
\r
void Main940(void)\r
{\r
YM2612PicoStateLoad_();\r
break;\r
\r
- case JOB940_YM2612UPDATEONE: {\r
- int i, dw, *wbuff;\r
- if (shared_ctl->writebuffsel == 1) {\r
- wbuff = (int *) shared_ctl->writebuff1;\r
- } else {\r
- wbuff = (int *) shared_ctl->writebuff0;\r
- }\r
-\r
- /* playback all writes */\r
- for (i = 2048/2; i > 0; i--) {\r
- UINT16 d;\r
- dw = *wbuff++;\r
- d = dw;\r
- if (d == 0xffff) break;\r
- YM2612Write_(d >> 8, d);\r
- d = (dw>>16);\r
- if (d == 0xffff) break;\r
- YM2612Write_(d >> 8, d);\r
- }\r
-\r
- shared_ctl->ym_active_chs =\r
- YM2612UpdateOne_(ym_buffer, shared_ctl->length, shared_ctl->stereo, 1);\r
+ case JOB940_YM2612UPDATEONE:\r
+ ym_update(ym_buffer);\r
break;\r
- }\r
\r
case JOB940_MP3DECODE:\r
mp3_decode();\r
# stuff for 940 core\r
\r
# init, emu_control, emu\r
-OBJS940 += 940init.o 940.o 940ym2612.o memcpy.o mix.o\r
+OBJS940 += 940init.o 940.o 940ym2612.o memcpy.o mix.o misc.o\r
# the asm code seems to be faster when run on 920, but not on 940 for some reason\r
# OBJS940 += ../../Pico/sound/ym2612_asm.o\r
\r
mix.o : ../../../Pico/sound/mix.s\r
@echo $@\r
@$(GCC) $(COPT) $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@\r
+misc.o : ../../../Pico/misc.s\r
+ @echo $@\r
+ @$(GCC) $(COPT) $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@\r
\r
../helix/helix_mp3.a:\r
@make -C ../helix/\r
int state_slot = 0;\r
int reset_timing = 0;\r
\r
-/*\r
-// tmp\r
-static FILE *logf = NULL;\r
\r
-void pprintf(char *texto, ...)\r
-{\r
- va_list args;\r
-\r
- va_start(args,texto);\r
- vfprintf(logf,texto,args);\r
- va_end(args);\r
- fflush(logf);\r
- sync();\r
-}\r
-*/\r
// utilities\r
static void strlwr(char* string)\r
{\r
}\r
\r
\r
+void scaling_update(void)\r
+{\r
+ PicoOpt &= ~0x4100;\r
+ switch (currentConfig.scaling) {\r
+ default: break; // off\r
+ case 1: // hw hor\r
+ case 2: PicoOpt |= 0x0100; break; // hw hor+vert\r
+ case 3: PicoOpt |= 0x4000; break; // sw hor\r
+ }\r
+}\r
+\r
+\r
int emu_ReadConfig(int game)\r
{\r
FILE *f;\r
currentConfig.KeyBinds[22] = 1<<30; // vol down\r
currentConfig.gamma = 100;\r
currentConfig.PicoCDBuffers = 64;\r
+ currentConfig.scaling = 0;\r
strncpy(cfg, PicoConfigFile, 511);\r
cfg[511] = 0;\r
} else {\r
bread = fread(¤tConfig, 1, sizeof(currentConfig), f);\r
fclose(f);\r
}\r
- printf((bread == sizeof(currentConfig)) ? "(ok)\n" : "(failed)\n");\r
+ printf(bread > 0 ? "(ok)\n" : "(failed)\n");\r
\r
PicoOpt = currentConfig.PicoOpt;\r
PsndRate = currentConfig.PsndRate;\r
actionNames[ 8] = "Z"; actionNames[ 9] = "Y";\r
actionNames[10] = "X"; actionNames[11] = "MODE";\r
}\r
+ scaling_update();\r
// some sanity checks\r
if (currentConfig.CPUclock < 1 || currentConfig.CPUclock > 4096) currentConfig.CPUclock = 200;\r
if (currentConfig.gamma < 10 || currentConfig.gamma > 300) currentConfig.gamma = 100;\r
currentConfig.KeyBinds[22] = 1<<30; // vol down\r
}\r
\r
- return (bread == sizeof(currentConfig));\r
+ return (bread > 0); // == sizeof(currentConfig));\r
}\r
\r
\r
bwrite = fwrite(¤tConfig, 1, sizeof(currentConfig), f);\r
fflush(f);\r
fclose(f);\r
+#ifndef NO_SYNC\r
sync();\r
+#endif\r
}\r
printf((bwrite == sizeof(currentConfig)) ? "(ok)\n" : "(failed)\n");\r
\r
SRam.changed = 0;\r
}\r
\r
- if (!(currentConfig.EmuOpt & 0x20))\r
- emu_WriteConfig(0);\r
+ if (!(currentConfig.EmuOpt & 0x20)) {\r
+ FILE *f = fopen(PicoConfigFile, "r+b");\r
+ if (!f) emu_WriteConfig(0);\r
+ else {\r
+ // if we already have config, reload it, except last ROM\r
+ fseek(f, sizeof(currentConfig.lastRomFile), SEEK_SET);\r
+ fread(¤tConfig.EmuOpt, 1, sizeof(currentConfig) - sizeof(currentConfig.lastRomFile), f);\r
+ fseek(f, 0, SEEK_SET);\r
+ fwrite(¤tConfig, 1, sizeof(currentConfig), f);\r
+ fflush(f);\r
+ fclose(f);\r
+#ifndef NO_SYNC\r
+ sync();\r
+#endif\r
+ }\r
+ }\r
+\r
free(framebuff);\r
\r
PicoExit();\r
}\r
}\r
\r
- if (notice) osd_text(4, 232, notice);\r
- if (emu_opt & 2)\r
- osd_text(osd_fps_x, 232, fps);\r
+ if (notice || (emu_opt & 2)) {\r
+ int h = 232;\r
+ if (currentConfig.scaling == 2 && !(Pico.video.reg[1]&8)) h -= 8;\r
+ if (notice) osd_text(4, h, notice);\r
+ if (emu_opt & 2)\r
+ osd_text(osd_fps_x, h, fps);\r
+ }\r
if ((emu_opt & 0x400) && (PicoMCD & 1))\r
cd_leds();\r
\r
}\r
Pico.m.dirtyPal = 1;\r
// reset scaling\r
- gp2x_video_RGB_setscaling((PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 240);\r
+ if (currentConfig.scaling == 2 && !(Pico.video.reg[1]&8))\r
+ gp2x_video_RGB_setscaling(8, (PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 224);\r
+ else gp2x_video_RGB_setscaling(0, (PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 240);\r
}\r
\r
\r
vidCpyM2 = vidCpyM2_32col;\r
}\r
}\r
- gp2x_video_RGB_setscaling(scalex, 240);\r
+ if (currentConfig.scaling == 2 && !(modes&8)) // want vertical scaling and game is not in 240 line mode\r
+ gp2x_video_RGB_setscaling(8, scalex, 224);\r
+ else gp2x_video_RGB_setscaling(0, scalex, 240);\r
oldmodes = modes;\r
clearArea(1);\r
}\r
if (frames_shown > frames_done) frames_shown = frames_done;\r
}\r
}\r
-#if 0\r
+#if 1\r
sprintf(fpsbuff, "%05i", Pico.m.frame_count);\r
#endif\r
lim_time = (frames_done+1) * target_frametime;\r
ret = fwrite(sram_data, 1, sram_size, sramFile);\r
ret = (ret != sram_size) ? -1 : 0;\r
fclose(sramFile);\r
+#ifndef NO_SYNC\r
sync();\r
+#endif\r
}\r
}\r
return ret;\r
ret = PmovState(load ? 6 : 5, PmovFile);\r
areaClose(PmovFile);\r
PmovFile = 0;\r
- if (!load) sync();\r
- else Pico.m.dirtyPal=1;\r
+ if (load) Pico.m.dirtyPal=1;\r
+#ifndef NO_SYNC\r
+ else sync();\r
+#endif\r
}\r
else ret = -1;\r
if (!ret)\r
typedef struct {\r
char lastRomFile[512];\r
int EmuOpt; // LSb->MSb: use_sram, show_fps, enable_sound, gzip_saves,\r
- // squidgehack, save_cfg_on_exit, <unused>, 16_bit_mode\r
+ // squidgehack, no_save_cfg_on_exit, <unused>, 16_bit_mode\r
// craigix_ram, confirm_save, show_cd_leds\r
//\r
int PicoOpt; // used for config saving only, see Pico.h\r
int JoyBinds[4][32];\r
int PicoAutoRgnOrder;\r
int PicoCDBuffers;\r
+ int scaling; // 0=center, 1=hscale, 2=hvscale, 3=hsoftscale\r
} currentConfig_t;\r
\r
extern char romFileName[];\r
void emu_set_save_cbs(int gz);\r
void emu_forced_frame(void);\r
int find_bios(int region, char **bios_file);\r
+void scaling_update(void);\r
\r
#define FRAMEBUFF_ADDR2 (FRAMEBUFF_ADDR1+0x30000)\r
#define FRAMEBUFF_ADDR3 (FRAMEBUFF_ADDR2+0x30000)\r
\r
-static const int gp2x_screenaddrs[] = { FRAMEBUFF_ADDR0, FRAMEBUFF_ADDR1, FRAMEBUFF_ADDR2, FRAMEBUFF_ADDR3 };\r
+static const int gp2x_screenaddrs[4] = { FRAMEBUFF_ADDR0, FRAMEBUFF_ADDR1, FRAMEBUFF_ADDR2, FRAMEBUFF_ADDR3 };\r
+static int gp2x_screenaddrs_use[4];\r
static unsigned short gp2x_screenaddr_old[4];\r
\r
\r
/* video stuff */\r
void gp2x_video_flip(void)\r
{\r
- unsigned short msw = (unsigned short)(gp2x_screenaddrs[screensel&3] >> 16);\r
+ unsigned short lsw = (unsigned short) gp2x_screenaddrs_use[screensel&3];\r
+ unsigned short msw = (unsigned short)(gp2x_screenaddrs_use[screensel&3] >> 16);\r
\r
gp2x_memregs[0x2910>>1] = msw;\r
gp2x_memregs[0x2914>>1] = msw;\r
- gp2x_memregs[0x290E>>1] = 0;\r
- gp2x_memregs[0x2912>>1] = 0;\r
+ gp2x_memregs[0x290E>>1] = lsw;\r
+ gp2x_memregs[0x2912>>1] = lsw;\r
\r
// jump to other buffer:\r
gp2x_screen = gp2x_screens[++screensel&3];\r
/* doulblebuffered flip */\r
void gp2x_video_flip2(void)\r
{\r
- unsigned short msw = (unsigned short)(gp2x_screenaddrs[screensel&1] >> 16);\r
+ unsigned short msw = (unsigned short)(gp2x_screenaddrs_use[screensel&1] >> 16);\r
\r
gp2x_memregs[0x2910>>1] = msw;\r
gp2x_memregs[0x2914>>1] = msw;\r
\r
\r
// TV Compatible function //\r
-void gp2x_video_RGB_setscaling(int W, int H)\r
+void gp2x_video_RGB_setscaling(int ln_offs, int W, int H)\r
{\r
float escalaw, escalah;\r
int bpp = (gp2x_memregs[0x28DA>>1]>>9)&0x3;\r
+ unsigned short scalw;\r
+\r
+ // set offset\r
+ gp2x_screenaddrs_use[0] = gp2x_screenaddrs[0] + ln_offs * 320 * bpp;\r
+ gp2x_screenaddrs_use[1] = gp2x_screenaddrs[1] + ln_offs * 320 * bpp;\r
+ gp2x_screenaddrs_use[2] = gp2x_screenaddrs[2] + ln_offs * 320 * bpp;\r
+ gp2x_screenaddrs_use[3] = gp2x_screenaddrs[3] + ln_offs * 320 * bpp;\r
\r
escalaw = 1024.0; // RGB Horiz LCD\r
escalah = 320.0; // RGB Vert LCD\r
}\r
\r
// scale horizontal\r
- gp2x_memregs[0x2906>>1]=(unsigned short)((float)escalaw *(W/320.0));\r
+ scalw = (unsigned short)((float)escalaw *(W/320.0));\r
+ /* if there is no horizontal scaling, vertical doesn't work. Here is a nasty wrokaround... */\r
+ if (H != 240 && W == 320) scalw--;\r
+ gp2x_memregs[0x2906>>1]=scalw;\r
// scale vertical\r
gp2x_memregl[0x2908>>2]=(unsigned long)((float)escalah *bpp *(H/240.0));\r
}\r
gp2x_screenaddr_old[2] = gp2x_memregs[0x2912>>1];\r
gp2x_screenaddr_old[3] = gp2x_memregs[0x2914>>1];\r
\r
+ memcpy(gp2x_screenaddrs_use, gp2x_screenaddrs, sizeof(gp2x_screenaddrs));\r
gp2x_memset_all_buffers(0, 0, 320*240*2);\r
\r
// snd\r
void gp2x_video_changemode(int bpp);\r
void gp2x_video_changemode2(int bpp);\r
void gp2x_video_setpalette(int *pal, int len);\r
-void gp2x_video_RGB_setscaling(int W, int H);\r
+void gp2x_video_RGB_setscaling(int ln_offs, int W, int H);\r
void gp2x_video_wait_vsync(void);\r
void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len);\r
void gp2x_memcpy_all_buffers(void *data, int offset, int len);\r
return alphasort(d1, d2);\r
}\r
\r
-static char *filter_exts[] = { ".mp3", ".MP3", ".srm", ".brm", "s.gz", ".mds", "bcfg", ".txt", ".htm", "html", ".jpg", ".gpe" };\r
+static char *filter_exts[] = {\r
+ ".mp3", ".MP3", ".srm", ".brm", "s.gz", ".mds", "bcfg", ".txt", ".htm", "html",\r
+ ".jpg", ".gpe", ".cue"\r
+};\r
\r
static int scandir_filter(const struct dirent *ent)\r
{\r
//memset(gp2x_screen, 0, 320*240);\r
gp2x_pd_clone_buffer2();\r
\r
- gp2x_text_out8(tl_x, y, "Scale 32 column mode %s", (currentConfig.PicoOpt&0x100)?"ON":"OFF"); // 0\r
- gp2x_text_out8(tl_x, (y+=10), "Gamma correction %i.%02i", currentConfig.gamma / 100, currentConfig.gamma%100); // 1\r
- gp2x_text_out8(tl_x, (y+=10), "Emulate Z80 %s", (currentConfig.PicoOpt&0x004)?"ON":"OFF"); // 2\r
- gp2x_text_out8(tl_x, (y+=10), "Emulate YM2612 (FM) %s", (currentConfig.PicoOpt&0x001)?"ON":"OFF"); // 3\r
- gp2x_text_out8(tl_x, (y+=10), "Emulate SN76496 (PSG) %s", (currentConfig.PicoOpt&0x002)?"ON":"OFF"); // 4\r
- gp2x_text_out8(tl_x, (y+=10), "gzip savestates %s", (currentConfig.EmuOpt &0x008)?"ON":"OFF"); // 5\r
- gp2x_text_out8(tl_x, (y+=10), "Don't save config on exit %s", (currentConfig.EmuOpt &0x020)?"ON":"OFF"); // 6\r
+ gp2x_text_out8(tl_x, y, "Gamma correction %i.%02i", currentConfig.gamma / 100, currentConfig.gamma%100); // 0\r
+ gp2x_text_out8(tl_x, (y+=10), "Emulate Z80 %s", (currentConfig.PicoOpt&0x004)?"ON":"OFF"); // 1\r
+ gp2x_text_out8(tl_x, (y+=10), "Emulate YM2612 (FM) %s", (currentConfig.PicoOpt&0x001)?"ON":"OFF"); // 2\r
+ gp2x_text_out8(tl_x, (y+=10), "Emulate SN76496 (PSG) %s", (currentConfig.PicoOpt&0x002)?"ON":"OFF"); // 3\r
+ gp2x_text_out8(tl_x, (y+=10), "gzip savestates %s", (currentConfig.EmuOpt &0x008)?"ON":"OFF"); // 4\r
+ gp2x_text_out8(tl_x, (y+=10), "Don't save config on exit %s", (currentConfig.EmuOpt &0x020)?"ON":"OFF"); // 5\r
gp2x_text_out8(tl_x, (y+=10), "needs restart:");\r
- gp2x_text_out8(tl_x, (y+=10), "craigix's RAM timings %s", (currentConfig.EmuOpt &0x100)?"ON":"OFF"); // 8\r
- gp2x_text_out8(tl_x, (y+=10), "squidgehack (now %s %s", mms, (currentConfig.EmuOpt &0x010)?"ON":"OFF"); // 9\r
+ gp2x_text_out8(tl_x, (y+=10), "craigix's RAM timings %s", (currentConfig.EmuOpt &0x100)?"ON":"OFF"); // 7\r
+ gp2x_text_out8(tl_x, (y+=10), "squidgehack (now %s %s", mms, (currentConfig.EmuOpt &0x010)?"ON":"OFF"); // 8\r
gp2x_text_out8(tl_x, (y+=10), "Done");\r
\r
// draw cursor\r
\r
static void amenu_loop_options(void)\r
{\r
- int menu_sel = 0, menu_sel_max = 10;\r
+ int menu_sel = 0, menu_sel_max = 9;\r
unsigned long inp = 0;\r
\r
for(;;)\r
if(inp & GP2X_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }\r
if((inp& GP2X_B)||(inp&GP2X_LEFT)||(inp&GP2X_RIGHT)) { // toggleable options\r
switch (menu_sel) {\r
- case 0: currentConfig.PicoOpt^=0x100; break;\r
- case 2: currentConfig.PicoOpt^=0x004; break;\r
- case 3: currentConfig.PicoOpt^=0x001; break;\r
- case 4: currentConfig.PicoOpt^=0x002; break;\r
- case 5: currentConfig.EmuOpt ^=0x008; break;\r
- case 6: currentConfig.EmuOpt ^=0x020; break;\r
- case 8: currentConfig.EmuOpt ^=0x100; break;\r
- case 9: currentConfig.EmuOpt ^=0x010; break;\r
- case 10: return;\r
+ case 1: currentConfig.PicoOpt^=0x004; break;\r
+ case 2: currentConfig.PicoOpt^=0x001; break;\r
+ case 3: currentConfig.PicoOpt^=0x002; break;\r
+ case 4: currentConfig.EmuOpt ^=0x008; break;\r
+ case 5: currentConfig.EmuOpt ^=0x020; break;\r
+ case 7: currentConfig.EmuOpt ^=0x100; break;\r
+ case 8: currentConfig.EmuOpt ^=0x010; break;\r
+ case 9: return;\r
}\r
}\r
if(inp & (GP2X_X|GP2X_A)) return;\r
if(inp & (GP2X_LEFT|GP2X_RIGHT)) { // multi choise\r
switch (menu_sel) {\r
- case 1:\r
+ case 0:\r
while ((inp = gp2x_joystick_read(1)) & (GP2X_LEFT|GP2X_RIGHT)) {\r
currentConfig.gamma += (inp & GP2X_LEFT) ? -1 : 1;\r
if (currentConfig.gamma < 1) currentConfig.gamma = 1;\r
\r
static void draw_menu_options(int menu_sel)\r
{\r
- int tl_x = 25, tl_y = 40, y;\r
- char monostereo[8], strframeskip[8], *strrend;\r
+ int tl_x = 25, tl_y = 32, y;\r
+ char monostereo[8], strframeskip[8], *strrend, *strscaling;\r
\r
strcpy(monostereo, (currentConfig.PicoOpt&0x08)?"stereo":"mono");\r
if (currentConfig.Frameskip < 0)\r
} else {\r
strrend = " 8bit accurate";\r
}\r
+ switch (currentConfig.scaling) {\r
+ default: strscaling = " OFF"; break;\r
+ case 1: strscaling = "hw horizontal"; break;\r
+ case 2: strscaling = "hw horiz. + vert."; break;\r
+ case 3: strscaling = "sw horizontal"; break;\r
+ }\r
\r
y = tl_y;\r
//memset(gp2x_screen, 0, 320*240);\r
gp2x_pd_clone_buffer2();\r
\r
gp2x_text_out8(tl_x, y, "Renderer: %s", strrend); // 0\r
- gp2x_text_out8(tl_x, (y+=10), "Accurate timing (slower) %s", (currentConfig.PicoOpt&0x040)?"ON":"OFF"); // 1\r
- gp2x_text_out8(tl_x, (y+=10), "Accurate sprites (slower) %s", (currentConfig.PicoOpt&0x080)?"ON":"OFF"); // 2\r
- gp2x_text_out8(tl_x, (y+=10), "Show FPS %s", (currentConfig.EmuOpt &0x002)?"ON":"OFF"); // 3\r
+ gp2x_text_out8(tl_x, (y+=10), "Scaling: %s", strscaling); // 1\r
+ gp2x_text_out8(tl_x, (y+=10), "Accurate timing (slower) %s", (currentConfig.PicoOpt&0x040)?"ON":"OFF"); // 2\r
+ gp2x_text_out8(tl_x, (y+=10), "Accurate sprites (slower) %s", (currentConfig.PicoOpt&0x080)?"ON":"OFF"); // 3\r
+ gp2x_text_out8(tl_x, (y+=10), "Show FPS %s", (currentConfig.EmuOpt &0x002)?"ON":"OFF"); // 4\r
gp2x_text_out8(tl_x, (y+=10), "Frameskip %s", strframeskip);\r
- gp2x_text_out8(tl_x, (y+=10), "Enable sound %s", (currentConfig.EmuOpt &0x004)?"ON":"OFF"); // 5\r
+ gp2x_text_out8(tl_x, (y+=10), "Enable sound %s", (currentConfig.EmuOpt &0x004)?"ON":"OFF"); // 6\r
gp2x_text_out8(tl_x, (y+=10), "Sound Quality: %5iHz %s", currentConfig.PsndRate, monostereo);\r
- gp2x_text_out8(tl_x, (y+=10), "Use ARM940 core for sound %s", (currentConfig.PicoOpt&0x200)?"ON":"OFF"); // 7\r
- gp2x_text_out8(tl_x, (y+=10), "6 button pad %s", (currentConfig.PicoOpt&0x020)?"ON":"OFF"); // 8\r
+ gp2x_text_out8(tl_x, (y+=10), "Use ARM940 core for sound %s", (currentConfig.PicoOpt&0x200)?"ON":"OFF"); // 8\r
+ gp2x_text_out8(tl_x, (y+=10), "6 button pad %s", (currentConfig.PicoOpt&0x020)?"ON":"OFF"); // 9\r
gp2x_text_out8(tl_x, (y+=10), "Genesis Region: %s", region_name(currentConfig.PicoRegion));\r
- gp2x_text_out8(tl_x, (y+=10), "Use SRAM/BRAM savestates %s", (currentConfig.EmuOpt &0x001)?"ON":"OFF"); // 10\r
- gp2x_text_out8(tl_x, (y+=10), "Confirm save overwrites %s", (currentConfig.EmuOpt &0x200)?"ON":"OFF"); // 11\r
- gp2x_text_out8(tl_x, (y+=10), "Save slot %i", state_slot); // 12\r
+ gp2x_text_out8(tl_x, (y+=10), "Use SRAM/BRAM savestates %s", (currentConfig.EmuOpt &0x001)?"ON":"OFF"); // 11\r
+ gp2x_text_out8(tl_x, (y+=10), "Confirm save overwrites %s", (currentConfig.EmuOpt &0x200)?"ON":"OFF"); // 12\r
+ gp2x_text_out8(tl_x, (y+=10), "Save slot %i", state_slot); // 13\r
gp2x_text_out8(tl_x, (y+=10), "GP2X CPU clocks %iMhz", currentConfig.CPUclock);\r
gp2x_text_out8(tl_x, (y+=10), "[Sega/Mega CD options]");\r
- gp2x_text_out8(tl_x, (y+=10), "[advanced options]"); // 15\r
+ gp2x_text_out8(tl_x, (y+=10), "[advanced options]"); // 16\r
gp2x_text_out8(tl_x, (y+=10), "Save cfg as default");\r
if (rom_data)\r
gp2x_text_out8(tl_x, (y+=10), "Save cfg for current game only");\r
} else {\r
actionNames[8] = actionNames[9] = actionNames[10] = actionNames[11] = 0;\r
}\r
+ scaling_update();\r
}\r
\r
static int menu_loop_options(void)\r
{\r
- int menu_sel = 0, menu_sel_max = 16;\r
+ int menu_sel = 0, menu_sel_max = 17;\r
unsigned long inp = 0;\r
\r
if (rom_data) menu_sel_max++;\r
if(inp & GP2X_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }\r
if((inp& GP2X_B)||(inp&GP2X_LEFT)||(inp&GP2X_RIGHT)) { // toggleable options\r
switch (menu_sel) {\r
- case 1: currentConfig.PicoOpt^=0x040; break;\r
- case 2: currentConfig.PicoOpt^=0x080; break;\r
- case 3: currentConfig.EmuOpt ^=0x002; break;\r
- case 5: currentConfig.EmuOpt ^=0x004; break;\r
- case 7: currentConfig.PicoOpt^=0x200; break;\r
- case 8: currentConfig.PicoOpt^=0x020; break;\r
- case 10: currentConfig.EmuOpt ^=0x001; break;\r
- case 11: currentConfig.EmuOpt ^=0x200; break;\r
- case 14: cd_menu_loop_options();\r
+ case 2: currentConfig.PicoOpt^=0x040; break;\r
+ case 3: currentConfig.PicoOpt^=0x080; break;\r
+ case 4: currentConfig.EmuOpt ^=0x002; break;\r
+ case 6: currentConfig.EmuOpt ^=0x004; break;\r
+ case 8: currentConfig.PicoOpt^=0x200; break;\r
+ case 9: currentConfig.PicoOpt^=0x020; break;\r
+ case 11: currentConfig.EmuOpt ^=0x001; break;\r
+ case 12: currentConfig.EmuOpt ^=0x200; break;\r
+ case 15: cd_menu_loop_options();\r
if (engineState == PGS_ReloadRom)\r
return 0; // test BIOS\r
break;\r
- case 15: amenu_loop_options(); break;\r
- case 16: // done (update and write)\r
+ case 16: amenu_loop_options(); break;\r
+ case 17: // done (update and write)\r
menu_options_save();\r
if (emu_WriteConfig(0)) strcpy(menuErrorMsg, "config saved");\r
else strcpy(menuErrorMsg, "failed to write config");\r
return 1;\r
- case 17: // done (update and write for current game)\r
+ case 18: // done (update and write for current game)\r
menu_options_save();\r
if (emu_WriteConfig(1)) strcpy(menuErrorMsg, "config saved");\r
else strcpy(menuErrorMsg, "failed to write config");\r
else if ( currentConfig.EmuOpt &0x80) currentConfig.EmuOpt &= ~0x80;\r
}\r
break;\r
- case 4:\r
+ case 1:\r
+ currentConfig.scaling += (inp & GP2X_LEFT) ? -1 : 1;\r
+ if (currentConfig.scaling < 0) currentConfig.scaling = 0;\r
+ if (currentConfig.scaling > 3) currentConfig.scaling = 3;\r
+ break;\r
+ case 5:\r
currentConfig.Frameskip += (inp & GP2X_LEFT) ? -1 : 1;\r
if (currentConfig.Frameskip < 0) currentConfig.Frameskip = -1;\r
if (currentConfig.Frameskip > 32) currentConfig.Frameskip = 32;\r
break;\r
- case 6:\r
+ case 7:\r
if ((inp & GP2X_RIGHT) && currentConfig.PsndRate == 44100 && !(currentConfig.PicoOpt&0x08)) {\r
currentConfig.PsndRate = 8000; currentConfig.PicoOpt|= 0x08;\r
} else if ((inp & GP2X_LEFT) && currentConfig.PsndRate == 8000 && (currentConfig.PicoOpt&0x08)) {\r
currentConfig.PsndRate = 44100; currentConfig.PicoOpt&=~0x08;\r
} else currentConfig.PsndRate = sndrate_prevnext(currentConfig.PsndRate, inp & GP2X_RIGHT);\r
break;\r
- case 9:\r
+ case 10:\r
region_prevnext(inp & GP2X_RIGHT);\r
break;\r
- case 12:\r
+ case 13:\r
if (inp & GP2X_RIGHT) {\r
state_slot++; if (state_slot > 9) state_slot = 0;\r
} else {state_slot--; if (state_slot < 0) state_slot = 9;\r
}\r
break;\r
- case 13:\r
+ case 14:\r
while ((inp = gp2x_joystick_read(1)) & (GP2X_LEFT|GP2X_RIGHT)) {\r
currentConfig.CPUclock += (inp & GP2X_LEFT) ? -1 : 1;\r
if (currentConfig.CPUclock < 1) currentConfig.CPUclock = 1;\r
if (rom_data) menu_sel = menu_sel_min = 0;\r
if (PicoPatches) menu_sel_max = 9;\r
\r
- for(;;)\r
+ /* make sure action buttons are not pressed on entering menu */\r
+ draw_menu_root(menu_sel);\r
+ while (gp2x_joystick_read(1) & (GP2X_B|GP2X_X|GP2X_SELECT)) usleep(50*1000);\r
+\r
+ for (;;)\r
{\r
draw_menu_root(menu_sel);\r
inp = wait_for_input(GP2X_UP|GP2X_DOWN|GP2X_B|GP2X_X|GP2X_SELECT);\r
\r
// switch to 8bpp\r
gp2x_video_changemode2(8);\r
- gp2x_video_RGB_setscaling(320, 240);\r
+ gp2x_video_RGB_setscaling(0, 320, 240);\r
gp2x_video_flip2();\r
}\r
\r
-#define VERSION "1.31"\r
+#define VERSION "1.32"\r
\r
../../Pico/sound/ym2612.o : ../../Pico/sound/ym2612.c
@echo $@
- @$(GCC) $(COPT_COMMON) $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@ # -mtune=arm940t
+ @$(GCC) $(COPT_COMMON) $(DEFINC) -c $< -o $@ # -mtune=arm940t -DEXTERNAL_YM2612
# faked asm
../../Pico/Draw.o : ../../Pico/Draw.c
memcpy(current_pal, pal, len*4);
}
-void gp2x_video_RGB_setscaling(int W, int H)
+void gp2x_video_RGB_setscaling(int v_offs, int W, int H)
{
}
#define PORT_CONFIG_H
#define CPU_CALL
-#define NO_IONBF
+#define NO_SYNC
// draw2.c
#define START_ROW 0 // which row of tiles to start rendering at?
\r
Changelog\r
---------\r
+1.32\r
+ + Added some new scaling options.\r
+ * Fixed DMA timing emulation (caused lock-ups for some genesis games).\r
+ * Idle loop detection was picking up wrong code and causing glitches, fixed.\r
+ * The ym2612 code on 940 now can handle multiple updates per frame\r
+ (fixes Thunger Force III "seiren" level drums for example).\r
+ * Memory handlers were ignoring some writes to PSG chip, fixed (missing sounds in\r
+ Popful Mail, Silpheed).\r
+\r
1.31\r
* Changed the way memory mode register is read (fixes Lunar 2, broken in 1.30).\r
* Fixed TAS opcode on sub-68k side (fixes Batman games).\r