bugfixes, new scaling, double ym upd at 940

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@83 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2007-03-31 13:57:45 +00:00
parent 3d48f1437f
commit 2433f40912
22 changed files with 360 additions and 171 deletions

View file

@ -79,10 +79,8 @@ zip_failed:
f = fopen(path, "rb");
if (f == NULL) return NULL;
#ifndef NO_IONBF
/* we use our own buffering */
setvbuf(f, NULL, _IONBF, 0);
#endif
file = malloc(sizeof(*file));
if (file == NULL) {

View file

@ -72,7 +72,7 @@ int PicoReset(int hard)
PicoMemReset();
SekReset();
// s68k doesn't have the TAS quirk, so we just globally set normal TAS handler in MCD mode (used by Batman games).
CycloneSetRealTAS(PicoMCD & 1);
SekSetRealTAS(PicoMCD & 1);
SekCycleCntT=0;
z80_reset();
@ -486,6 +486,12 @@ static int PicoFrameSimple(void)
int y=0,line=0,lines=0,lines_step=0,sects;
int cycles_68k_vblock,cycles_68k_block;
// we don't emulate DMA timing in this mode
if (Pico.m.dma_bytes) {
Pico.m.dma_bytes=0;
Pico.video.status&=~2;
}
if (Pico.m.pal) {
// M68k cycles/frame: 152009.78
if(pv->reg[1]&8) { // 240 lines

View file

@ -31,7 +31,7 @@ void mp3_update(int *buffer, int length, int stereo);
// enable_ym2612&dac, enable_sn76496, enable_z80, stereo_sound,
// alt_renderer, 6button_gamepad, accurate_timing, accurate_sprites,
// draw_no_32col_border, external_ym2612, enable_pcm, enable cdda
// enable_cdgfx, cd_perfect_sync
// enable_cdgfx, cd_perfect_sync, soft_32col_scaling
extern int PicoOpt;
extern int PicoVer;
extern int PicoSkipFrame; // skip rendering frame, but still do sound (if enabled) and emulation stuff

View file

@ -311,6 +311,7 @@ int SekInit(void);
int SekReset(void);
int SekInterrupt(int irq);
void SekState(unsigned char *data);
void SekSetRealTAS(int use_real);
// cd/Sek.c
int SekInitS68k(void);

View file

@ -186,3 +186,11 @@ void SekState(unsigned char *data)
memcpy(data+0x40,&PicoM68kCPU.pc, 0x04);
#endif
}
void SekSetRealTAS(int use_real)
{
#ifdef EMU_C68K
CycloneSetRealTAS(use_real);
#endif
}

View file

@ -30,10 +30,13 @@ typedef unsigned int u32;
#define rdprintf(...)
//#define wrdprintf dprintf
#define wrdprintf(...)
//#define plprintf dprintf
#define plprintf(...)
// -----------------------------------------------------------------
// poller detection
//#undef USE_POLL_DETECT
#define POLL_LIMIT 16
#define POLL_CYCLES 124
// int m68k_poll_addr, m68k_poll_cnt;
@ -143,7 +146,7 @@ void m68k_reg_write8(u32 a, u32 d)
#ifdef USE_POLL_DETECT
if ((s68k_poll_adclk&0xfe) == 2 && s68k_poll_cnt > POLL_LIMIT) {
SekSetStopS68k(0); s68k_poll_adclk = 0;
//printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);
plprintf("s68k poll release, a=%02x\n", a);
}
#endif
return;
@ -163,7 +166,7 @@ void m68k_reg_write8(u32 a, u32 d)
#ifdef USE_POLL_DETECT
if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) {
SekSetStopS68k(0); s68k_poll_adclk = 0;
//printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);
plprintf("s68k poll release, a=%02x\n", a);
}
#endif
return;
@ -174,7 +177,7 @@ void m68k_reg_write8(u32 a, u32 d)
#ifdef USE_POLL_DETECT
if ((a&0xfe) == (s68k_poll_adclk&0xfe) && s68k_poll_cnt > POLL_LIMIT) {
SekSetStopS68k(0); s68k_poll_adclk = 0;
//printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);
plprintf("s68k poll release, a=%02x\n", a);
}
#endif
return;
@ -183,6 +186,31 @@ void m68k_reg_write8(u32 a, u32 d)
dprintf("m68k FIXME: invalid write? [%02x] %02x", a, d);
}
#ifndef _ASM_CD_MEMORY_C
static
#endif
u32 s68k_poll_detect(u32 a, u32 d)
{
#ifdef USE_POLL_DETECT
// polling detection
if (a == (s68k_poll_adclk&0xff)) {
unsigned int clkdiff = SekCyclesDoneS68k() - (s68k_poll_adclk>>8);
if (clkdiff <= POLL_CYCLES) {
s68k_poll_cnt++;
//printf("-- diff: %u, cnt = %i\n", clkdiff, s68k_poll_cnt);
if (s68k_poll_cnt > POLL_LIMIT) {
SekSetStopS68k(1);
plprintf("s68k poll detected @ %06x, a=%02x\n", SekPcS68k, a);
}
s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;
return d;
}
}
s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;
s68k_poll_cnt = 0;
#endif
return d;
}
#define READ_FONT_DATA(basemask) \
{ \
@ -208,9 +236,9 @@ u32 s68k_reg_read16(u32 a)
case 0:
return ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state
case 2:
d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0x1f);
d = (Pico_mcd->s68k_regs[2]<<8) | (Pico_mcd->s68k_regs[3]&0x1f);
//printf("s68k_regs r3: %02x @%06x\n", (u8)d, SekPcS68k);
goto poll_detect;
return s68k_poll_detect(a, d);
case 6:
return CDC_Read_Reg();
case 8:
@ -240,31 +268,10 @@ u32 s68k_reg_read16(u32 a)
d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];
if (a >= 0x0e && a < 0x30) goto poll_detect;
if (a >= 0x0e && a < 0x30)
return s68k_poll_detect(a, d);
return d;
poll_detect:
#ifdef USE_POLL_DETECT
// polling detection
if (a == (s68k_poll_adclk&0xfe)) {
unsigned int clkdiff = SekCyclesDoneS68k() - (s68k_poll_adclk>>8);
if (clkdiff <= POLL_CYCLES) {
s68k_poll_cnt++;
//printf("-- diff: %u, cnt = %i\n", clkdiff, s68k_poll_cnt);
if (s68k_poll_cnt > POLL_LIMIT) {
SekSetStopS68k(1);
//printf("%05i:%03i: s68k poll detected @ %06x, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, SekPcS68k, a);
}
s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;
return d;
}
}
s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;
s68k_poll_cnt = 0;
#endif
return d;
}
#ifndef _ASM_CD_MEMORY_C
@ -407,6 +414,7 @@ static void OtherWrite8End(u32 a, u32 d, int realsize)
#include "cell_map.c"
#endif // !def _ASM_CD_MEMORY_C
// -----------------------------------------------------------------
// Read Rom and read Ram
@ -631,8 +639,11 @@ static void PicoWriteM68k8(u32 a,u8 d)
return;
}
if ((a&0xffffc0)==0xa12000)
if ((a&0xffffc0)==0xa12000) {
rdprintf("m68k_regs w8: [%02x] %02x @%06x", a&0x3f, d, SekPc);
m68k_reg_write8(a, d);
return;
}
OtherWrite8(a,d,8);
}
@ -688,7 +699,7 @@ static void PicoWriteM68k16(u32 a,u16 d)
#ifdef USE_POLL_DETECT
if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) {
SekSetStopS68k(0); s68k_poll_adclk = -1;
//printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);
plprintf("s68k poll release, a=%02x\n", a);
}
#endif
return;
@ -755,8 +766,10 @@ static void PicoWriteM68k32(u32 a,u32 d)
return;
}
if ((a&0xffffc0)==0xa12000)
if ((a&0xffffc0)==0xa12000) {
rdprintf("m68k_regs w32: [%02x] %08x @%06x", a&0x3f, d, SekPc);
if ((a&0x3e) == 0xe) dprintf("m68k FIXME: w32 [%02x]", a&0x3f);
}
OtherWrite16(a, (u16)(d>>16));
OtherWrite16(a+2,(u16)d);
@ -785,7 +798,13 @@ static u8 PicoReadS68k8(u32 a)
if ((a&0xfffe00) == 0xff8000) {
a &= 0x1ff;
rdprintf("s68k_regs r8: [%02x] @ %06x", a, SekPcS68k);
if (a >= 0x58 && a < 0x68)
if (a >= 0x0e && a < 0x30) {
d = Pico_mcd->s68k_regs[a];
s68k_poll_detect(a, d);
rdprintf("ret = %02x", (u8)d);
goto end;
}
else if (a >= 0x58 && a < 0x68)
d = gfx_cd_read(a&~1);
else d = s68k_reg_read16(a&~1);
if ((a&1)==0) d>>=8;
@ -1008,7 +1027,7 @@ static u32 PicoReadS68k32(u32 a)
// PCM
if ((a&0xff8000)==0xff0000) {
dprintf("FIXME: s68k_pcm r32: [%06x] @%06x", a, SekPcS68k);
dprintf("s68k_pcm r32: [%06x] @%06x", a, SekPcS68k);
a &= 0x7fff;
if (a >= 0x2000) {
a >>= 1;
@ -1293,6 +1312,7 @@ static void PicoWriteS68k32(u32 a,u32 d)
gfx_cd_write16(a, d>>16);
gfx_cd_write16(a+2, d&0xffff);
} else {
if ((a&0x1fe) == 0xe) dprintf("s68k FIXME: w32 [%02x]", a&0x3f);
s68k_reg_write8(a, d>>24);
s68k_reg_write8(a+1,(d>>16)&0xff);
s68k_reg_write8(a+2,(d>>8) &0xff);

View file

@ -135,6 +135,8 @@ m_s68k_decode_write_table:
.extern s68k_reg_write8
.extern s68k_poll_adclk
.extern PicoCpuS68k
.extern s68k_poll_detect
.extern SN76496Write
@ r0=reg3, r1-r3=temp
@ -993,6 +995,10 @@ m_m68k_write8_vdp:
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
@ -1123,7 +1129,11 @@ m_m68k_write16_vdp:
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:
@ -1291,6 +1301,10 @@ m_m68k_write32_vdp:
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
@ -1410,6 +1424,9 @@ m_s68k_read8_regs:
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
@ -1424,6 +1441,13 @@ m_s68k_read8_regs:
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
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

View file

@ -1702,7 +1702,9 @@ int YM2612Write_(unsigned int a, unsigned int v)
}
addr = ym2612.OPN.ST.address;
#ifndef EXTERNAL_YM2612
ym2612.REGS[addr] = v;
#endif
switch( addr & 0xf0 )
{
@ -1800,7 +1802,9 @@ int YM2612Write_(unsigned int a, unsigned int v)
}
addr = ym2612.OPN.ST.address | 0x100;
#ifndef EXTERNAL_YM2612
ym2612.REGS[addr] = v;
#endif
ret = OPNWriteReg(addr, v);
break;
@ -1869,7 +1873,10 @@ void YM2612PicoStateLoad_(void)
}
#ifndef EXTERNAL_YM2612
void *YM2612GetRegs(void)
{
return ym2612.REGS;
}
#endif

View file

@ -66,8 +66,10 @@ static int writebuff_ptr = 0;
/* OPN Mode Register Write */
static void set_timers( int v )
static int set_timers( int v )
{
int change;
/* b7 = CSM MODE */
/* b6 = 3 slot mode */
/* b5 = reset b */
@ -76,6 +78,7 @@ static void set_timers( int v )
/* b2 = timer enable a */
/* b1 = load b */
/* b0 = load a */
change = (ST_mode ^ v) & 0xc0;
ST_mode = v;
/* reset Timer b flag */
@ -85,6 +88,8 @@ static void set_timers( int v )
/* reset Timer a flag */
if( v & 0x10 )
ST_status &= ~1;
return change;
}
/* YM2612 write */
@ -93,11 +98,14 @@ static void set_timers( int v )
/* returns 1 if sample affecting state changed */
int YM2612Write_940(unsigned int a, unsigned int v)
{
int addr; //, ret=1;
int addr;
int upd = 1; /* the write affects sample generation */
v &= 0xff; /* adjust to 8 bit bus */
a &= 3;
//printf("%05i:%03i: ym w ([%i] %02x)\n", Pico.m.frame_count, Pico.m.scanline, a, v);
switch( a ) {
case 0: /* address port 0 */
if (!addr_A1 && ST_address == v)
@ -108,7 +116,7 @@ int YM2612Write_940(unsigned int a, unsigned int v)
(v == 0x24 || v == 0x25 || v == 0x26 || v == 0x2a))
return 0;
addr_A1 = 0;
//ret=0;
upd = 0;
break;
case 1: /* data port 0 */
@ -152,14 +160,16 @@ int YM2612Write_940(unsigned int a, unsigned int v)
}
return 0;
case 0x27: /* mode, timer control */
set_timers( v );
if (set_timers( v ))
break; // other side needs ST.mode for 3slot mode
return 0;
case 0x2a: /* DAC data (YM2612) */
dacout = ((int)v - 0x80) << 6; /* level unknown (notaz: 8 seems to be too much) */
return 0;
case 0x2b: /* DAC Sel (YM2612) */
/* b7 = dac enable */
dacen = v & 0x80;
upd = 0;
break; // other side has to know this
default:
break;
@ -173,7 +183,7 @@ int YM2612Write_940(unsigned int a, unsigned int v)
return 0;
ST_address = v;
addr_A1 = 1;
//ret=0;
upd = 0;
break;
case 3: /* data port 1 */
@ -186,14 +196,25 @@ int YM2612Write_940(unsigned int a, unsigned int v)
break;
}
//printf("ym pass\n");
if(currentConfig.EmuOpt & 4) {
/* queue this write for 940 */
if (writebuff_ptr < 2047) {
if (shared_ctl->writebuffsel == 1) {
shared_ctl->writebuff0[writebuff_ptr++] = (a<<8)|v;
} else {
shared_ctl->writebuff1[writebuff_ptr++] = (a<<8)|v;
UINT16 *writebuff = shared_ctl->writebuffsel ? shared_ctl->writebuff0 : shared_ctl->writebuff1;
/* detect rapid ym updates */
if (upd && !(writebuff_ptr & 0x80000000) && Pico.m.scanline < 224) {
int mid = Pico.m.pal ? 68 : 93;
if (Pico.m.scanline > mid) {
//printf("%05i:%03i: rapid ym\n", Pico.m.frame_count, Pico.m.scanline);
writebuff[writebuff_ptr++ & 0xffff] = 0xfffe;
writebuff_ptr |= 0x80000000;
//printf("%05i:%03i: ym w ([%02x] %02x, upd=%i)\n", Pico.m.frame_count, Pico.m.scanline, addr, v, upd);
}
}
/* queue this write for 940 */
if ((writebuff_ptr&0xffff) < 2047) {
writebuff[writebuff_ptr++ & 0xffff] = (a<<8)|v;
} else {
printf("warning: writebuff_ptr > 2047 ([%i] %02x)\n", a, v);
}
@ -301,7 +322,7 @@ void YM2612PicoStateLoad_940(void)
addr_A1 = old_A1;
add_job_940(JOB940_PICOSTATELOAD);
// add_job_940(JOB940_PICOSTATELOAD);
}
@ -465,9 +486,9 @@ int YM2612UpdateOne_940(int *buffer, int length, int stereo, int is_buf_empty)
else memset32(buffer, 0, length<<stereo);
if (shared_ctl->writebuffsel == 1) {
shared_ctl->writebuff0[writebuff_ptr] = 0xffff;
shared_ctl->writebuff0[writebuff_ptr & 0xffff] = 0xffff;
} else {
shared_ctl->writebuff1[writebuff_ptr] = 0xffff;
shared_ctl->writebuff1[writebuff_ptr & 0xffff] = 0xffff;
}
writebuff_ptr = 0;

View file

@ -84,7 +84,8 @@ OBJS += mp3.o
# CPU cores
ifeq "$(use_musashi)" "1"
DEFINC += -DEMU_M68K
OBJS += _build\m68kcpu.o _build\m68kopac.o _build\m68kopdm.o _build\m68kopnz.o _build\m68kops.o
OBJS += ../../cpu/musashi/m68kcpu.o ../../cpu/musashi/m68kopac.o ../../cpu/musashi/m68kopdm.o
OBJS += ../../cpu/musashi/m68kopnz.o ../../cpu/musashi/m68kops.o
else
DEFINC += -DEMU_C68K
OBJS += ../../cpu/Cyclone/proj/Cyclone.o

View file

@ -55,6 +55,56 @@ static void mp3_decode(void)
set_if_not_changed(&shared_ctl->mp3_offs, mp3_offs, readPtr - mp3_data);
}
static void ym_update(int *ym_buffer)
{
int i, dw;
int two_upds = 0;
UINT16 *wbuff;
if (shared_ctl->writebuffsel == 1) {
wbuff = shared_ctl->writebuff1;
} else {
wbuff = shared_ctl->writebuff0;
}
/* playback all writes */
for (i = 2048/2; i > 0; i--) {
UINT16 d;
dw = *(int *)wbuff;
d = dw;
wbuff++;
if (d == 0xffff) break;
if (d == 0xfffe) { two_upds=1; break; }
YM2612Write_(d >> 8, d);
d = (dw>>16);
wbuff++;
if (d == 0xffff) break;
if (d == 0xfffe) { two_upds=1; break; }
YM2612Write_(d >> 8, d);
}
if (two_upds) {
int len1 = shared_ctl->length / 2;
shared_ctl->ym_active_chs =
YM2612UpdateOne_(ym_buffer, len1, shared_ctl->stereo, 1);
for (i *= 2; i > 0; i--) {
UINT16 d = *wbuff++;
if (d == 0xffff) break;
YM2612Write_(d >> 8, d);
}
ym_buffer += shared_ctl->stereo ? len1*2 : len1;
len1 = shared_ctl->length - len1;
shared_ctl->ym_active_chs =
YM2612UpdateOne_(ym_buffer, len1, shared_ctl->stereo, 1);
} else {
shared_ctl->ym_active_chs =
YM2612UpdateOne_(ym_buffer, shared_ctl->length, shared_ctl->stereo, 1);
}
}
void Main940(void)
{
@ -92,30 +142,9 @@ void Main940(void)
YM2612PicoStateLoad_();
break;
case JOB940_YM2612UPDATEONE: {
int i, dw, *wbuff;
if (shared_ctl->writebuffsel == 1) {
wbuff = (int *) shared_ctl->writebuff1;
} else {
wbuff = (int *) shared_ctl->writebuff0;
}
/* playback all writes */
for (i = 2048/2; i > 0; i--) {
UINT16 d;
dw = *wbuff++;
d = dw;
if (d == 0xffff) break;
YM2612Write_(d >> 8, d);
d = (dw>>16);
if (d == 0xffff) break;
YM2612Write_(d >> 8, d);
}
shared_ctl->ym_active_chs =
YM2612UpdateOne_(ym_buffer, shared_ctl->length, shared_ctl->stereo, 1);
case JOB940_YM2612UPDATEONE:
ym_update(ym_buffer);
break;
}
case JOB940_MP3DECODE:
mp3_decode();

View file

@ -32,7 +32,7 @@ all: code940.bin
# stuff for 940 core
# init, emu_control, emu
OBJS940 += 940init.o 940.o 940ym2612.o memcpy.o mix.o
OBJS940 += 940init.o 940.o 940ym2612.o memcpy.o mix.o misc.o
# the asm code seems to be faster when run on 920, but not on 940 for some reason
# OBJS940 += ../../Pico/sound/ym2612_asm.o
@ -56,6 +56,9 @@ code940.gpe : $(OBJS940) ../helix/helix_mp3.a
mix.o : ../../../Pico/sound/mix.s
@echo $@
@$(GCC) $(COPT) $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@
misc.o : ../../../Pico/misc.s
@echo $@
@$(GCC) $(COPT) $(DEFINC) -DEXTERNAL_YM2612 -c $< -o $@
../helix/helix_mp3.a:
@make -C ../helix/

View file

@ -63,21 +63,7 @@ unsigned char *framebuff = 0; // temporary buffer for alt renderer
int state_slot = 0;
int reset_timing = 0;
/*
// tmp
static FILE *logf = NULL;
void pprintf(char *texto, ...)
{
va_list args;
va_start(args,texto);
vfprintf(logf,texto,args);
va_end(args);
fflush(logf);
sync();
}
*/
// utilities
static void strlwr(char* string)
{
@ -467,6 +453,18 @@ static void find_combos(void)
}
void scaling_update(void)
{
PicoOpt &= ~0x4100;
switch (currentConfig.scaling) {
default: break; // off
case 1: // hw hor
case 2: PicoOpt |= 0x0100; break; // hw hor+vert
case 3: PicoOpt |= 0x4000; break; // sw hor
}
}
int emu_ReadConfig(int game)
{
FILE *f;
@ -501,6 +499,7 @@ int emu_ReadConfig(int game)
currentConfig.KeyBinds[22] = 1<<30; // vol down
currentConfig.gamma = 100;
currentConfig.PicoCDBuffers = 64;
currentConfig.scaling = 0;
strncpy(cfg, PicoConfigFile, 511);
cfg[511] = 0;
} else {
@ -516,7 +515,7 @@ int emu_ReadConfig(int game)
bread = fread(&currentConfig, 1, sizeof(currentConfig), f);
fclose(f);
}
printf((bread == sizeof(currentConfig)) ? "(ok)\n" : "(failed)\n");
printf(bread > 0 ? "(ok)\n" : "(failed)\n");
PicoOpt = currentConfig.PicoOpt;
PsndRate = currentConfig.PsndRate;
@ -527,6 +526,7 @@ int emu_ReadConfig(int game)
actionNames[ 8] = "Z"; actionNames[ 9] = "Y";
actionNames[10] = "X"; actionNames[11] = "MODE";
}
scaling_update();
// some sanity checks
if (currentConfig.CPUclock < 1 || currentConfig.CPUclock > 4096) currentConfig.CPUclock = 200;
if (currentConfig.gamma < 10 || currentConfig.gamma > 300) currentConfig.gamma = 100;
@ -536,7 +536,7 @@ int emu_ReadConfig(int game)
currentConfig.KeyBinds[22] = 1<<30; // vol down
}
return (bread == sizeof(currentConfig));
return (bread > 0); // == sizeof(currentConfig));
}
@ -565,7 +565,9 @@ int emu_WriteConfig(int game)
bwrite = fwrite(&currentConfig, 1, sizeof(currentConfig), f);
fflush(f);
fclose(f);
#ifndef NO_SYNC
sync();
#endif
}
printf((bwrite == sizeof(currentConfig)) ? "(ok)\n" : "(failed)\n");
@ -581,8 +583,23 @@ void emu_Deinit(void)
SRam.changed = 0;
}
if (!(currentConfig.EmuOpt & 0x20))
emu_WriteConfig(0);
if (!(currentConfig.EmuOpt & 0x20)) {
FILE *f = fopen(PicoConfigFile, "r+b");
if (!f) emu_WriteConfig(0);
else {
// if we already have config, reload it, except last ROM
fseek(f, sizeof(currentConfig.lastRomFile), SEEK_SET);
fread(&currentConfig.EmuOpt, 1, sizeof(currentConfig) - sizeof(currentConfig.lastRomFile), f);
fseek(f, 0, SEEK_SET);
fwrite(&currentConfig, 1, sizeof(currentConfig), f);
fflush(f);
fclose(f);
#ifndef NO_SYNC
sync();
#endif
}
}
free(framebuff);
PicoExit();
@ -706,9 +723,13 @@ static void blit(const char *fps, const char *notice)
}
}
if (notice) osd_text(4, 232, notice);
if (notice || (emu_opt & 2)) {
int h = 232;
if (currentConfig.scaling == 2 && !(Pico.video.reg[1]&8)) h -= 8;
if (notice) osd_text(4, h, notice);
if (emu_opt & 2)
osd_text(osd_fps_x, 232, fps);
osd_text(osd_fps_x, h, fps);
}
if ((emu_opt & 0x400) && (PicoMCD & 1))
cd_leds();
@ -771,7 +792,9 @@ static void vidResetMode(void)
}
Pico.m.dirtyPal = 1;
// reset scaling
gp2x_video_RGB_setscaling((PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 240);
if (currentConfig.scaling == 2 && !(Pico.video.reg[1]&8))
gp2x_video_RGB_setscaling(8, (PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 224);
else gp2x_video_RGB_setscaling(0, (PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 240);
}
@ -1133,7 +1156,9 @@ void emu_Loop(void)
vidCpyM2 = vidCpyM2_32col;
}
}
gp2x_video_RGB_setscaling(scalex, 240);
if (currentConfig.scaling == 2 && !(modes&8)) // want vertical scaling and game is not in 240 line mode
gp2x_video_RGB_setscaling(8, scalex, 224);
else gp2x_video_RGB_setscaling(0, scalex, 240);
oldmodes = modes;
clearArea(1);
}
@ -1171,7 +1196,7 @@ void emu_Loop(void)
if (frames_shown > frames_done) frames_shown = frames_done;
}
}
#if 0
#if 1
sprintf(fpsbuff, "%05i", Pico.m.frame_count);
#endif
lim_time = (frames_done+1) * target_frametime;
@ -1446,7 +1471,9 @@ int emu_SaveLoadGame(int load, int sram)
ret = fwrite(sram_data, 1, sram_size, sramFile);
ret = (ret != sram_size) ? -1 : 0;
fclose(sramFile);
#ifndef NO_SYNC
sync();
#endif
}
}
return ret;
@ -1470,8 +1497,10 @@ int emu_SaveLoadGame(int load, int sram)
ret = PmovState(load ? 6 : 5, PmovFile);
areaClose(PmovFile);
PmovFile = 0;
if (!load) sync();
else Pico.m.dirtyPal=1;
if (load) Pico.m.dirtyPal=1;
#ifndef NO_SYNC
else sync();
#endif
}
else ret = -1;
if (!ret)

View file

@ -18,7 +18,7 @@ enum TPicoGameState {
typedef struct {
char lastRomFile[512];
int EmuOpt; // LSb->MSb: use_sram, show_fps, enable_sound, gzip_saves,
// squidgehack, save_cfg_on_exit, <unused>, 16_bit_mode
// squidgehack, no_save_cfg_on_exit, <unused>, 16_bit_mode
// craigix_ram, confirm_save, show_cd_leds
//
int PicoOpt; // used for config saving only, see Pico.h
@ -32,6 +32,7 @@ typedef struct {
int JoyBinds[4][32];
int PicoAutoRgnOrder;
int PicoCDBuffers;
int scaling; // 0=center, 1=hscale, 2=hvscale, 3=hsoftscale
} currentConfig_t;
extern char romFileName[];
@ -52,4 +53,5 @@ int emu_check_save_file(int slot);
void emu_set_save_cbs(int gz);
void emu_forced_frame(void);
int find_bios(int region, char **bios_file);
void scaling_update(void);

View file

@ -52,19 +52,21 @@ void *gp2x_screen;
#define FRAMEBUFF_ADDR2 (FRAMEBUFF_ADDR1+0x30000)
#define FRAMEBUFF_ADDR3 (FRAMEBUFF_ADDR2+0x30000)
static const int gp2x_screenaddrs[] = { FRAMEBUFF_ADDR0, FRAMEBUFF_ADDR1, FRAMEBUFF_ADDR2, FRAMEBUFF_ADDR3 };
static const int gp2x_screenaddrs[4] = { FRAMEBUFF_ADDR0, FRAMEBUFF_ADDR1, FRAMEBUFF_ADDR2, FRAMEBUFF_ADDR3 };
static int gp2x_screenaddrs_use[4];
static unsigned short gp2x_screenaddr_old[4];
/* video stuff */
void gp2x_video_flip(void)
{
unsigned short msw = (unsigned short)(gp2x_screenaddrs[screensel&3] >> 16);
unsigned short lsw = (unsigned short) gp2x_screenaddrs_use[screensel&3];
unsigned short msw = (unsigned short)(gp2x_screenaddrs_use[screensel&3] >> 16);
gp2x_memregs[0x2910>>1] = msw;
gp2x_memregs[0x2914>>1] = msw;
gp2x_memregs[0x290E>>1] = 0;
gp2x_memregs[0x2912>>1] = 0;
gp2x_memregs[0x290E>>1] = lsw;
gp2x_memregs[0x2912>>1] = lsw;
// jump to other buffer:
gp2x_screen = gp2x_screens[++screensel&3];
@ -73,7 +75,7 @@ void gp2x_video_flip(void)
/* doulblebuffered flip */
void gp2x_video_flip2(void)
{
unsigned short msw = (unsigned short)(gp2x_screenaddrs[screensel&1] >> 16);
unsigned short msw = (unsigned short)(gp2x_screenaddrs_use[screensel&1] >> 16);
gp2x_memregs[0x2910>>1] = msw;
gp2x_memregs[0x2914>>1] = msw;
@ -113,10 +115,17 @@ void gp2x_video_setpalette(int *pal, int len)
// TV Compatible function //
void gp2x_video_RGB_setscaling(int W, int H)
void gp2x_video_RGB_setscaling(int ln_offs, int W, int H)
{
float escalaw, escalah;
int bpp = (gp2x_memregs[0x28DA>>1]>>9)&0x3;
unsigned short scalw;
// set offset
gp2x_screenaddrs_use[0] = gp2x_screenaddrs[0] + ln_offs * 320 * bpp;
gp2x_screenaddrs_use[1] = gp2x_screenaddrs[1] + ln_offs * 320 * bpp;
gp2x_screenaddrs_use[2] = gp2x_screenaddrs[2] + ln_offs * 320 * bpp;
gp2x_screenaddrs_use[3] = gp2x_screenaddrs[3] + ln_offs * 320 * bpp;
escalaw = 1024.0; // RGB Horiz LCD
escalah = 320.0; // RGB Vert LCD
@ -131,7 +140,10 @@ void gp2x_video_RGB_setscaling(int W, int H)
}
// scale horizontal
gp2x_memregs[0x2906>>1]=(unsigned short)((float)escalaw *(W/320.0));
scalw = (unsigned short)((float)escalaw *(W/320.0));
/* if there is no horizontal scaling, vertical doesn't work. Here is a nasty wrokaround... */
if (H != 240 && W == 320) scalw--;
gp2x_memregs[0x2906>>1]=scalw;
// scale vertical
gp2x_memregl[0x2908>>2]=(unsigned long)((float)escalah *bpp *(H/240.0));
}
@ -304,6 +316,7 @@ void gp2x_init(void)
gp2x_screenaddr_old[2] = gp2x_memregs[0x2912>>1];
gp2x_screenaddr_old[3] = gp2x_memregs[0x2914>>1];
memcpy(gp2x_screenaddrs_use, gp2x_screenaddrs, sizeof(gp2x_screenaddrs));
gp2x_memset_all_buffers(0, 0, 320*240*2);
// snd

View file

@ -12,7 +12,7 @@ void gp2x_video_flip2(void);
void gp2x_video_changemode(int bpp);
void gp2x_video_changemode2(int bpp);
void gp2x_video_setpalette(int *pal, int len);
void gp2x_video_RGB_setscaling(int W, int H);
void gp2x_video_RGB_setscaling(int ln_offs, int W, int H);
void gp2x_video_wait_vsync(void);
void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len);
void gp2x_memcpy_all_buffers(void *data, int offset, int len);

View file

@ -286,7 +286,10 @@ static int scandir_cmp(const void *p1, const void *p2)
return alphasort(d1, d2);
}
static char *filter_exts[] = { ".mp3", ".MP3", ".srm", ".brm", "s.gz", ".mds", "bcfg", ".txt", ".htm", "html", ".jpg", ".gpe" };
static char *filter_exts[] = {
".mp3", ".MP3", ".srm", ".brm", "s.gz", ".mds", "bcfg", ".txt", ".htm", "html",
".jpg", ".gpe", ".cue"
};
static int scandir_filter(const struct dirent *ent)
{
@ -864,16 +867,15 @@ static void draw_amenu_options(int menu_sel)
//memset(gp2x_screen, 0, 320*240);
gp2x_pd_clone_buffer2();
gp2x_text_out8(tl_x, y, "Scale 32 column mode %s", (currentConfig.PicoOpt&0x100)?"ON":"OFF"); // 0
gp2x_text_out8(tl_x, (y+=10), "Gamma correction %i.%02i", currentConfig.gamma / 100, currentConfig.gamma%100); // 1
gp2x_text_out8(tl_x, (y+=10), "Emulate Z80 %s", (currentConfig.PicoOpt&0x004)?"ON":"OFF"); // 2
gp2x_text_out8(tl_x, (y+=10), "Emulate YM2612 (FM) %s", (currentConfig.PicoOpt&0x001)?"ON":"OFF"); // 3
gp2x_text_out8(tl_x, (y+=10), "Emulate SN76496 (PSG) %s", (currentConfig.PicoOpt&0x002)?"ON":"OFF"); // 4
gp2x_text_out8(tl_x, (y+=10), "gzip savestates %s", (currentConfig.EmuOpt &0x008)?"ON":"OFF"); // 5
gp2x_text_out8(tl_x, (y+=10), "Don't save config on exit %s", (currentConfig.EmuOpt &0x020)?"ON":"OFF"); // 6
gp2x_text_out8(tl_x, y, "Gamma correction %i.%02i", currentConfig.gamma / 100, currentConfig.gamma%100); // 0
gp2x_text_out8(tl_x, (y+=10), "Emulate Z80 %s", (currentConfig.PicoOpt&0x004)?"ON":"OFF"); // 1
gp2x_text_out8(tl_x, (y+=10), "Emulate YM2612 (FM) %s", (currentConfig.PicoOpt&0x001)?"ON":"OFF"); // 2
gp2x_text_out8(tl_x, (y+=10), "Emulate SN76496 (PSG) %s", (currentConfig.PicoOpt&0x002)?"ON":"OFF"); // 3
gp2x_text_out8(tl_x, (y+=10), "gzip savestates %s", (currentConfig.EmuOpt &0x008)?"ON":"OFF"); // 4
gp2x_text_out8(tl_x, (y+=10), "Don't save config on exit %s", (currentConfig.EmuOpt &0x020)?"ON":"OFF"); // 5
gp2x_text_out8(tl_x, (y+=10), "needs restart:");
gp2x_text_out8(tl_x, (y+=10), "craigix's RAM timings %s", (currentConfig.EmuOpt &0x100)?"ON":"OFF"); // 8
gp2x_text_out8(tl_x, (y+=10), "squidgehack (now %s %s", mms, (currentConfig.EmuOpt &0x010)?"ON":"OFF"); // 9
gp2x_text_out8(tl_x, (y+=10), "craigix's RAM timings %s", (currentConfig.EmuOpt &0x100)?"ON":"OFF"); // 7
gp2x_text_out8(tl_x, (y+=10), "squidgehack (now %s %s", mms, (currentConfig.EmuOpt &0x010)?"ON":"OFF"); // 8
gp2x_text_out8(tl_x, (y+=10), "Done");
// draw cursor
@ -884,7 +886,7 @@ static void draw_amenu_options(int menu_sel)
static void amenu_loop_options(void)
{
int menu_sel = 0, menu_sel_max = 10;
int menu_sel = 0, menu_sel_max = 9;
unsigned long inp = 0;
for(;;)
@ -895,21 +897,20 @@ static void amenu_loop_options(void)
if(inp & GP2X_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
if((inp& GP2X_B)||(inp&GP2X_LEFT)||(inp&GP2X_RIGHT)) { // toggleable options
switch (menu_sel) {
case 0: currentConfig.PicoOpt^=0x100; break;
case 2: currentConfig.PicoOpt^=0x004; break;
case 3: currentConfig.PicoOpt^=0x001; break;
case 4: currentConfig.PicoOpt^=0x002; break;
case 5: currentConfig.EmuOpt ^=0x008; break;
case 6: currentConfig.EmuOpt ^=0x020; break;
case 8: currentConfig.EmuOpt ^=0x100; break;
case 9: currentConfig.EmuOpt ^=0x010; break;
case 10: return;
case 1: currentConfig.PicoOpt^=0x004; break;
case 2: currentConfig.PicoOpt^=0x001; break;
case 3: currentConfig.PicoOpt^=0x002; break;
case 4: currentConfig.EmuOpt ^=0x008; break;
case 5: currentConfig.EmuOpt ^=0x020; break;
case 7: currentConfig.EmuOpt ^=0x100; break;
case 8: currentConfig.EmuOpt ^=0x010; break;
case 9: return;
}
}
if(inp & (GP2X_X|GP2X_A)) return;
if(inp & (GP2X_LEFT|GP2X_RIGHT)) { // multi choise
switch (menu_sel) {
case 1:
case 0:
while ((inp = gp2x_joystick_read(1)) & (GP2X_LEFT|GP2X_RIGHT)) {
currentConfig.gamma += (inp & GP2X_LEFT) ? -1 : 1;
if (currentConfig.gamma < 1) currentConfig.gamma = 1;
@ -949,8 +950,8 @@ static const char *region_name(unsigned int code)
static void draw_menu_options(int menu_sel)
{
int tl_x = 25, tl_y = 40, y;
char monostereo[8], strframeskip[8], *strrend;
int tl_x = 25, tl_y = 32, y;
char monostereo[8], strframeskip[8], *strrend, *strscaling;
strcpy(monostereo, (currentConfig.PicoOpt&0x08)?"stereo":"mono");
if (currentConfig.Frameskip < 0)
@ -963,27 +964,34 @@ static void draw_menu_options(int menu_sel)
} else {
strrend = " 8bit accurate";
}
switch (currentConfig.scaling) {
default: strscaling = " OFF"; break;
case 1: strscaling = "hw horizontal"; break;
case 2: strscaling = "hw horiz. + vert."; break;
case 3: strscaling = "sw horizontal"; break;
}
y = tl_y;
//memset(gp2x_screen, 0, 320*240);
gp2x_pd_clone_buffer2();
gp2x_text_out8(tl_x, y, "Renderer: %s", strrend); // 0
gp2x_text_out8(tl_x, (y+=10), "Accurate timing (slower) %s", (currentConfig.PicoOpt&0x040)?"ON":"OFF"); // 1
gp2x_text_out8(tl_x, (y+=10), "Accurate sprites (slower) %s", (currentConfig.PicoOpt&0x080)?"ON":"OFF"); // 2
gp2x_text_out8(tl_x, (y+=10), "Show FPS %s", (currentConfig.EmuOpt &0x002)?"ON":"OFF"); // 3
gp2x_text_out8(tl_x, (y+=10), "Scaling: %s", strscaling); // 1
gp2x_text_out8(tl_x, (y+=10), "Accurate timing (slower) %s", (currentConfig.PicoOpt&0x040)?"ON":"OFF"); // 2
gp2x_text_out8(tl_x, (y+=10), "Accurate sprites (slower) %s", (currentConfig.PicoOpt&0x080)?"ON":"OFF"); // 3
gp2x_text_out8(tl_x, (y+=10), "Show FPS %s", (currentConfig.EmuOpt &0x002)?"ON":"OFF"); // 4
gp2x_text_out8(tl_x, (y+=10), "Frameskip %s", strframeskip);
gp2x_text_out8(tl_x, (y+=10), "Enable sound %s", (currentConfig.EmuOpt &0x004)?"ON":"OFF"); // 5
gp2x_text_out8(tl_x, (y+=10), "Enable sound %s", (currentConfig.EmuOpt &0x004)?"ON":"OFF"); // 6
gp2x_text_out8(tl_x, (y+=10), "Sound Quality: %5iHz %s", currentConfig.PsndRate, monostereo);
gp2x_text_out8(tl_x, (y+=10), "Use ARM940 core for sound %s", (currentConfig.PicoOpt&0x200)?"ON":"OFF"); // 7
gp2x_text_out8(tl_x, (y+=10), "6 button pad %s", (currentConfig.PicoOpt&0x020)?"ON":"OFF"); // 8
gp2x_text_out8(tl_x, (y+=10), "Use ARM940 core for sound %s", (currentConfig.PicoOpt&0x200)?"ON":"OFF"); // 8
gp2x_text_out8(tl_x, (y+=10), "6 button pad %s", (currentConfig.PicoOpt&0x020)?"ON":"OFF"); // 9
gp2x_text_out8(tl_x, (y+=10), "Genesis Region: %s", region_name(currentConfig.PicoRegion));
gp2x_text_out8(tl_x, (y+=10), "Use SRAM/BRAM savestates %s", (currentConfig.EmuOpt &0x001)?"ON":"OFF"); // 10
gp2x_text_out8(tl_x, (y+=10), "Confirm save overwrites %s", (currentConfig.EmuOpt &0x200)?"ON":"OFF"); // 11
gp2x_text_out8(tl_x, (y+=10), "Save slot %i", state_slot); // 12
gp2x_text_out8(tl_x, (y+=10), "Use SRAM/BRAM savestates %s", (currentConfig.EmuOpt &0x001)?"ON":"OFF"); // 11
gp2x_text_out8(tl_x, (y+=10), "Confirm save overwrites %s", (currentConfig.EmuOpt &0x200)?"ON":"OFF"); // 12
gp2x_text_out8(tl_x, (y+=10), "Save slot %i", state_slot); // 13
gp2x_text_out8(tl_x, (y+=10), "GP2X CPU clocks %iMhz", currentConfig.CPUclock);
gp2x_text_out8(tl_x, (y+=10), "[Sega/Mega CD options]");
gp2x_text_out8(tl_x, (y+=10), "[advanced options]"); // 15
gp2x_text_out8(tl_x, (y+=10), "[advanced options]"); // 16
gp2x_text_out8(tl_x, (y+=10), "Save cfg as default");
if (rom_data)
gp2x_text_out8(tl_x, (y+=10), "Save cfg for current game only");
@ -1042,11 +1050,12 @@ static void menu_options_save(void)
} else {
actionNames[8] = actionNames[9] = actionNames[10] = actionNames[11] = 0;
}
scaling_update();
}
static int menu_loop_options(void)
{
int menu_sel = 0, menu_sel_max = 16;
int menu_sel = 0, menu_sel_max = 17;
unsigned long inp = 0;
if (rom_data) menu_sel_max++;
@ -1062,25 +1071,25 @@ static int menu_loop_options(void)
if(inp & GP2X_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
if((inp& GP2X_B)||(inp&GP2X_LEFT)||(inp&GP2X_RIGHT)) { // toggleable options
switch (menu_sel) {
case 1: currentConfig.PicoOpt^=0x040; break;
case 2: currentConfig.PicoOpt^=0x080; break;
case 3: currentConfig.EmuOpt ^=0x002; break;
case 5: currentConfig.EmuOpt ^=0x004; break;
case 7: currentConfig.PicoOpt^=0x200; break;
case 8: currentConfig.PicoOpt^=0x020; break;
case 10: currentConfig.EmuOpt ^=0x001; break;
case 11: currentConfig.EmuOpt ^=0x200; break;
case 14: cd_menu_loop_options();
case 2: currentConfig.PicoOpt^=0x040; break;
case 3: currentConfig.PicoOpt^=0x080; break;
case 4: currentConfig.EmuOpt ^=0x002; break;
case 6: currentConfig.EmuOpt ^=0x004; break;
case 8: currentConfig.PicoOpt^=0x200; break;
case 9: currentConfig.PicoOpt^=0x020; break;
case 11: currentConfig.EmuOpt ^=0x001; break;
case 12: currentConfig.EmuOpt ^=0x200; break;
case 15: cd_menu_loop_options();
if (engineState == PGS_ReloadRom)
return 0; // test BIOS
break;
case 15: amenu_loop_options(); break;
case 16: // done (update and write)
case 16: amenu_loop_options(); break;
case 17: // done (update and write)
menu_options_save();
if (emu_WriteConfig(0)) strcpy(menuErrorMsg, "config saved");
else strcpy(menuErrorMsg, "failed to write config");
return 1;
case 17: // done (update and write for current game)
case 18: // done (update and write for current game)
menu_options_save();
if (emu_WriteConfig(1)) strcpy(menuErrorMsg, "config saved");
else strcpy(menuErrorMsg, "failed to write config");
@ -1104,28 +1113,33 @@ static int menu_loop_options(void)
else if ( currentConfig.EmuOpt &0x80) currentConfig.EmuOpt &= ~0x80;
}
break;
case 4:
case 1:
currentConfig.scaling += (inp & GP2X_LEFT) ? -1 : 1;
if (currentConfig.scaling < 0) currentConfig.scaling = 0;
if (currentConfig.scaling > 3) currentConfig.scaling = 3;
break;
case 5:
currentConfig.Frameskip += (inp & GP2X_LEFT) ? -1 : 1;
if (currentConfig.Frameskip < 0) currentConfig.Frameskip = -1;
if (currentConfig.Frameskip > 32) currentConfig.Frameskip = 32;
break;
case 6:
case 7:
if ((inp & GP2X_RIGHT) && currentConfig.PsndRate == 44100 && !(currentConfig.PicoOpt&0x08)) {
currentConfig.PsndRate = 8000; currentConfig.PicoOpt|= 0x08;
} else if ((inp & GP2X_LEFT) && currentConfig.PsndRate == 8000 && (currentConfig.PicoOpt&0x08)) {
currentConfig.PsndRate = 44100; currentConfig.PicoOpt&=~0x08;
} else currentConfig.PsndRate = sndrate_prevnext(currentConfig.PsndRate, inp & GP2X_RIGHT);
break;
case 9:
case 10:
region_prevnext(inp & GP2X_RIGHT);
break;
case 12:
case 13:
if (inp & GP2X_RIGHT) {
state_slot++; if (state_slot > 9) state_slot = 0;
} else {state_slot--; if (state_slot < 0) state_slot = 9;
}
break;
case 13:
case 14:
while ((inp = gp2x_joystick_read(1)) & (GP2X_LEFT|GP2X_RIGHT)) {
currentConfig.CPUclock += (inp & GP2X_LEFT) ? -1 : 1;
if (currentConfig.CPUclock < 1) currentConfig.CPUclock = 1;
@ -1222,6 +1236,10 @@ static void menu_loop_root(void)
if (rom_data) menu_sel = menu_sel_min = 0;
if (PicoPatches) menu_sel_max = 9;
/* make sure action buttons are not pressed on entering menu */
draw_menu_root(menu_sel);
while (gp2x_joystick_read(1) & (GP2X_B|GP2X_X|GP2X_SELECT)) usleep(50*1000);
for (;;)
{
draw_menu_root(menu_sel);
@ -1324,7 +1342,7 @@ static void menu_gfx_prepare(void)
// switch to 8bpp
gp2x_video_changemode2(8);
gp2x_video_RGB_setscaling(320, 240);
gp2x_video_RGB_setscaling(0, 320, 240);
gp2x_video_flip2();
}

View file

@ -1,2 +1,2 @@
#define VERSION "1.31"
#define VERSION "1.32"

View file

@ -90,7 +90,7 @@ PicoDrive : $(OBJS) ../gp2x/helix/helix_mp3_x86.a
../../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

View file

@ -257,7 +257,7 @@ void gp2x_video_setpalette(int *pal, int len)
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)
{
}

View file

@ -4,7 +4,7 @@
#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?

View file

@ -214,6 +214,15 @@ Symbian:
Changelog
---------
1.32
+ Added some new scaling options.
* Fixed DMA timing emulation (caused lock-ups for some genesis games).
* Idle loop detection was picking up wrong code and causing glitches, fixed.
* The ym2612 code on 940 now can handle multiple updates per frame
(fixes Thunger Force III "seiren" level drums for example).
* Memory handlers were ignoring some writes to PSG chip, fixed (missing sounds in
Popful Mail, Silpheed).
1.31
* Changed the way memory mode register is read (fixes Lunar 2, broken in 1.30).
* Fixed TAS opcode on sub-68k side (fixes Batman games).