From: notaz Date: Sun, 27 May 2007 13:08:10 +0000 (+0000) Subject: merged ppu code, added input+zapper, FDS/VS insert in menu X-Git-Tag: r1~44 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e328100eecae3adfce1c3b57364bee5d166217ef;p=fceu.git merged ppu code, added input+zapper, FDS/VS insert in menu git-svn-id: file:///home/notaz/opt/svn/fceu@138 be3aeb3a-fb24-0410-a615-afba39da0efa --- diff --git a/Makefile.gp2x b/Makefile.gp2x index 0b17061..65970a6 100644 --- a/Makefile.gp2x +++ b/Makefile.gp2x @@ -29,7 +29,7 @@ gpfce.gpe: fceu include zlib/Makefile OBJDRIVER = ${B}minimal.o ${B}cpuctrl.o ${B}squidgehack.o ${B}asmutils.o ${B}gp2x.o ${B}main.o ${B}throttle.o \ - ${B}unix-netplay.o ${B}gp2x-sound.o ${B}gp2x-video.o ${B}lnx-joystick.o ${B}usbjoy.o ${B}menu.o ${B}fonts.o \ + ${B}unix-netplay.o ${B}gp2x-sound.o ${B}gp2x-video.o ${B}usbjoy.o ${B}menu.o ${B}fonts.o \ drivers/common/cheat.o drivers/common/config.o drivers/common/args.o drivers/common/vidblit.o ${UNZIPOBJS} ppu.o movie.o LDRIVER += -L /mnt/sd/lib -L/mnt/sd/gp2x/usr/lib -lm -lz -static -Wl,-Map=fceu.map diff --git a/drivers/gp2x/asmutils.h b/drivers/gp2x/asmutils.h index 52f9ab8..0ad81b1 100644 --- a/drivers/gp2x/asmutils.h +++ b/drivers/gp2x/asmutils.h @@ -1,5 +1,6 @@ void flushcache(unsigned int beginning_addr, unsigned int end_addr, unsigned int flags); void block_or(void *src, size_t n, int pat); +void block_and(void *src, size_t n, int pat); void block_andor(void *src, size_t n, int andpat, int orpat); void spend_cycles(int c); // utility void soft_scale(void *dst, unsigned short *pal, int offs, int lines); diff --git a/drivers/gp2x/asmutils.s b/drivers/gp2x/asmutils.s index 4a2e1a3..62e0661 100644 --- a/drivers/gp2x/asmutils.s +++ b/drivers/gp2x/asmutils.s @@ -28,6 +28,26 @@ block_loop_or: bx lr +.global block_and @ void *src, size_t n, int andpat + +block_and: + stmfd sp!, {r4-r5} + orr r2, r2, r2, lsl #8 + orr r2, r2, r2, lsl #16 + mov r1, r1, lsr #4 +block_loop_and: + ldmia r0, {r3-r5,r12} + subs r1, r1, #1 + and r3, r3, r2 + and r4, r4, r2 + and r5, r5, r2 + and r12,r12,r2 + stmia r0!, {r3-r5,r12} + bne block_loop_and + ldmfd sp!, {r4-r5} + bx lr + + .global block_andor @ void *src, size_t n, int andpat, int orpat block_andor: diff --git a/drivers/gp2x/dface.h b/drivers/gp2x/dface.h index 486b4d4..efbdab1 100644 --- a/drivers/gp2x/dface.h +++ b/drivers/gp2x/dface.h @@ -12,10 +12,6 @@ void KillSound(void); void SilenceSound(int s); /* DOS and SDL */ -int InitJoysticks(void); -void KillJoysticks(void); -uint32 *GetJSOr(void); - int InitVideo(void); void KillVideo(void); void BlitScreen(uint8 *buf); diff --git a/drivers/gp2x/input.c b/drivers/gp2x/input.c index 1506f4e..cc8132b 100644 --- a/drivers/gp2x/input.c +++ b/drivers/gp2x/input.c @@ -17,6 +17,7 @@ #include "../../state.h" #include "../../general.h" +#include "../../input.h" /* UsrInputType[] is user-specified. InputType[] is current (game loading can override user settings) @@ -80,13 +81,14 @@ static void do_emu_acts(uint32 acts) FCEUI_SaveState(); } } - else if (acts & (1 << 29)) + else if (acts & (3 << 28)) // state slot next/prev { FILE *st; char *fname; - CurrentState++; + CurrentState += (acts & (1 << 29)) ? 1 : -1; if (CurrentState > 9) CurrentState = 0; + if (CurrentState < 0) CurrentState = 9; fname = FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0); st=fopen(fname,"rb"); @@ -94,6 +96,57 @@ static void do_emu_acts(uint32 acts) FCEU_DispMessage("[%s] State Slot %i", st ? "USED" : "FREE", CurrentState); if (st) fclose(st); } + else if (acts & (1 << 27)) // FDS insert/eject + { + FCEU_DoSimpleCommand(FCEUNPCMD_FDSINSERT); + } + else if (acts & (1 << 26)) // FDS select + { + FCEU_DoSimpleCommand(FCEUNPCMD_FDSSELECT); + } + else if (acts & (1 << 25)) // VS Unisystem insert coin + { + FCEU_DoSimpleCommand(FCEUNPCMD_VSUNICOIN); + } +} + + +#define down(b) (keys & GP2X_##b) +static void do_fake_mouse(unsigned long keys) +{ + static int x=0, y=0; + int speed = 3; + + if (down(A)) speed = 1; + if (down(Y)) speed = 5; + + if (down(LEFT)) + { + x -= speed; + if (x < 0) x = 0; + } + else if (down(RIGHT)) + { + x += speed; + if (x > 255) x = 255; + } + + if (down(UP)) + { + y -= speed; + if (y < 0) y = 0; + } + else if (down(DOWN)) + { + y += speed; + if (y > 239) y = 239; + } + + MouseData[0] = x; + MouseData[1] = y; + MouseData[2] = 0; + if (down(B)) MouseData[2] |= 1; + if (down(X)) MouseData[2] |= 2; } @@ -105,7 +158,6 @@ void FCEUD_UpdateInput(void) uint32 all_acts = 0; int i; - #define down(b) (keys & GP2X_##b) if ((down(VOL_DOWN) && down(VOL_UP)) || (keys & (GP2X_L|GP2X_L|GP2X_START)) == (GP2X_L|GP2X_L|GP2X_START)) { Exit = 1; @@ -135,9 +187,14 @@ void FCEUD_UpdateInput(void) volpushed_frames = 0; } - JSreturn = 0; // RLDU SEBA + if (InputType[1] != SI_GAMEPAD) + { + /* try to feed fake mouse there */ + do_fake_mouse(keys); + } + for (i = 0; i < 32; i++) { if (keys & (1 << i)) @@ -174,30 +231,6 @@ void FCEUD_UpdateInput(void) } do_emu_acts(all_acts); - - - //JSreturn=(JS&0xFF000000)|(JS&0xFF)|((JS&0xFF0000)>>8)|((JS&0xFF00)<<8); - - // JSreturn=(JSreturn&0xFF000000)|(JSreturn&0xFF)|((JSreturn&0xFF0000)>>8)|((JSreturn&0xFF00)<<8); - // TODO: make these bindable, use new interface - /* - if(gametype==GIT_FDS) - { - if ((pad & GP2X_PUSH) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_L)) && (!(pad & GP2X_R)) && (!(lastpad2 & GP2X_PUSH))) - { - DriverInterface(DES_FDSSELECT,0); - } - else if ((pad & GP2X_L) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_PUSH)) && (!(pad & GP2X_R))&& (!(lastpad2 & GP2X_L))) - { - DriverInterface(DES_FDSINSERT,0); - } - else if ((pad & GP2X_R) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_L)) && (!(pad & GP2X_PUSH)) && (!(lastpad2 & GP2X_R))) - { - DriverInterface(DES_FDSEJECT,0); - } - } - return; - */ } @@ -210,6 +243,9 @@ static void InitOtherInput(void) int x; int attrib; + printf("InitOtherInput: InputType[0]: %i, InputType[1]: %i, InputTypeFC: %i\n", + InputType[0], InputType[1], InputTypeFC); + for(t=0,x=0;x<2;x++) { attrib=0; diff --git a/drivers/gp2x/lnx-joystick.c b/drivers/gp2x/lnx-joystick.c deleted file mode 100644 index 4c2ae6a..0000000 --- a/drivers/gp2x/lnx-joystick.c +++ /dev/null @@ -1,201 +0,0 @@ -/* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2002 Ben Parnell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include "main.h" -#include "lnx-joystick.h" - -int joy[4]={0,0,0,0}; -int joyBMap[4][4]; - -static int32 joybuttons[4]={0,0,0,0}; -static int32 joyx[4]={0,0,0,0}; -static int32 joyy[4]={0,0,0,0}; - -static void ConfigJoystick(int z); -static int fd[4]; - -#define JOY_A 1 -#define JOY_B 2 -#define JOY_SELECT 4 -#define JOY_START 8 -#define JOY_UP 0x10 -#define JOY_DOWN 0x20 -#define JOY_LEFT 0x40 -#define JOY_RIGHT 0x80 - -static void UpdateJoyData(int x) -{ - struct js_event e; - - while(read(fd[x],&e,sizeof(struct js_event))==sizeof(struct js_event)) - { - e.type&=~JS_EVENT_INIT; - if(e.type==JS_EVENT_BUTTON) - { - if(e.value) - joybuttons[x]|=(1<=16383) ret|=JOY_RIGHT<<(x<<3); - if(joyy[x]<=-16383) ret|=JOY_UP<<(x<<3); - else if(joyy[x]>=16383) ret|=JOY_DOWN<<(x<<3); - } - return ret; -} - -void KillJoysticks(void) -{ - int x; - for(x=0;x<4;x++) - if(joy[x]) - close(fd[x]); -} - -int InitJoysticks(void) -{ - char dbuf[64]; - int version; - int z; - - for(z=0;z<4;z++) - { - if(!joy[z]) continue; - sprintf(dbuf,"/dev/js%d",joy[z]-1); - if((fd[z]=open(dbuf,O_RDONLY|O_NONBLOCK))<0) - { - printf("Could not open %s.\n",dbuf); - joy[z]=0; - continue; - } - - if(ioctl(fd[z], JSIOCGVERSION, &version)==-1) - { - printf("Error using ioctl JSIOCGVERSION on %s.\n",dbuf); - joy[z]=0; - close(fd[z]); - continue; - } - - if(!(joyBMap[z][0]|joyBMap[z][1]|joyBMap[z][2]|joyBMap[z][3])) - ConfigJoystick(z); - } - - return(joy[0]|joy[1]|joy[2]|joy[3]); -} - -#define WNOINPUT(); for(;;){uint8 t; if(read(fileno(stdin),&t,1)==-1) \ - {break;}} - -static void BConfig(int z,int b) -{ - WNOINPUT(); - for(;;) - { - uint8 t; - if(read(fileno(stdin),&t,1)==-1) - { - if(errno!=EAGAIN) break; - } - else - break; - - { - struct js_event e; - - while(read(fd[z],&e,sizeof(struct js_event))==sizeof(struct js_event)) - { - if(e.type==JS_EVENT_BUTTON) - { - if(!e.value) - { - joyBMap[z][b]=1<= 240) return; + + if (tofix || sphitx != 0x100) { lastpixel = (timestamp*48-linestartts)>>4; if (PAL) lastpixel += lastpixel>>4; - //printf("lastpixel: %i\n", lastpixel); + } + + if (tofix && lastpixel>=TOFIXNUM) + { + Fixit1(); + tofix=0; + } - if(lastpixel>=TOFIXNUM) + // CheckSpriteHit() + if(sphitx!=0x100) + { + int l=lastpixel-16; + int x; + + for(x=sphitx;x<(sphitx+8) && x>(x-sphitx))) && !(Plinef[x]&64)) + { + PPU_status|=0x40; + sphitx=0x100; + break; + } } } } @@ -355,7 +386,7 @@ static DECLFR(A2002) /* merged */ uint8 ret; - TryFixit1(); + FakedLineUpdate(); ret = PPU_status; ret|=PPUGenLatch&0x1F; vtoggle=0; @@ -368,7 +399,7 @@ static DECLFR(A2002) static DECLFR(A200x) { /* merged */ - TryFixit1(); + FakedLineUpdate(); return PPUGenLatch; } @@ -378,7 +409,7 @@ static DECLFR(A2007) uint8 ret; uint32 tmp=RefreshAddr&0x3FFF; - TryFixit1(); + FakedLineUpdate(); ret=VRAMBuffer; @@ -403,7 +434,7 @@ static DECLFR(A2007) static DECLFW(B2000) { /* NMI2? */ - TryFixit1(); + FakedLineUpdate(); PPUGenLatch=V; PPU[0]=V; TempAddr&=0xF3FF; @@ -413,7 +444,7 @@ static DECLFW(B2000) static DECLFW(B2001) { /* merged */ - TryFixit1(); + FakedLineUpdate(); PPUGenLatch=V; PPU[1]=V; if(V&0xE0) @@ -458,7 +489,7 @@ static DECLFW(B2005) { /* merged */ uint32 tmp=TempAddr; - TryFixit1(); + FakedLineUpdate(); PPUGenLatch=V; if (!vtoggle) { @@ -480,7 +511,7 @@ static DECLFW(B2005) static DECLFW(B2006) { /* merged */ - TryFixit1(); + FakedLineUpdate(); PPUGenLatch=V; if(!vtoggle) @@ -570,24 +601,19 @@ void FCEUI_FrameSkip(int x) #endif /* This is called at the beginning of each visible scanline */ -static void Loop6502(void) +static void LineUpdate(uint8 *target) { uint32 tem; - int x; - uint8 *target=XBuf+scanline*320+32; - if(ScreenON || SpriteON) - { - /* PRefreshLine() will not get called on skipped frames. This - could cause a problem, but the solution would be rather complex, - due to the current sprite 0 hit code. - */ - #ifdef FRAMESKIP - if(!FSkip) + if(FSkip) + { + if(PPU_hook) + PRefreshLine(); + } + else + { + if(ScreenON) { - #endif - if(ScreenON) - { if(scanline>=FSettings.FirstSLine && scanline<=FSettings.LastSLine) BGRender(target); else @@ -595,56 +621,62 @@ static void Loop6502(void) if(PPU_hook) PRefreshLine(); } - } - else - { - tem=Pal[0]|(Pal[0]<<8)|(Pal[0]<<16)|(Pal[0]<<24); - tem|=0x40404040; - FCEU_dwmemset(target,tem,264); - } - #ifdef FRAMESKIP } - #endif - if (SpriteON && scanline) - RefreshSprite(target); - #ifdef FRAMESKIP - if(!FSkip) + else { - #endif - if(PPU[1]&0x01) - { - for(x=63;x>=0;x--) - ((uint32 *)target)[x]=((uint32*)target)[x]&0xF0F0F0F0; - } -#ifdef GP2X - if((PPU[1]>>5)==0x7) block_or(target, 256, 0xc0); - else if(PPU[1]&0xE0) block_andor(target, 256, 0x3f, 0x40); - else block_andor(target, 256, 0x3f, 0x80); -#else - if((PPU[1]>>5)==0x7) - for(x=63;x>=0;x--) - ((uint32 *)target)[x]=(((uint32*)target)[x])|0xc0c0c0c0; - else if(PPU[1]&0xE0) - for(x=63;x>=0;x--) - ((uint32 *)target)[x]=(((uint32*)target)[x]&0x3f3f3f3f)|0x40404040; - else - for(x=63;x>=0;x--) - ((uint32 *)target)[x]=(((uint32*)target)[x]&0x3f3f3f3f)|0x80808080; -#endif - // black borders - ((uint32 *)target)[-2]=((uint32 *)target)[-1]=0; - ((uint32 *)target)[64]=((uint32 *)target)[65]=0; - #ifdef FRAMESKIP + tem=Pal[0]|0x40; + tem|=tem << 8; + tem|=tem << 16; + FCEU_dwmemset(target,tem,256); } - #endif - } - else - { - tem=Pal[0]|(Pal[0]<<8)|(Pal[0]<<16)|(Pal[0]<<24); - FCEU_dwmemset(target,tem,256); } + if(InputScanlineHook) - InputScanlineHook(target, scanline); + InputScanlineHook(target,spork?sprlinebuf:0,linestartts,256); +} + + +static void LineUpdateEnd(uint8 *target) +{ +#ifdef GP2X + if(ScreenON || SpriteON) // Yes, very el-cheapo. + { + if(PPU[1]&0x01) + block_and(target, 256, 0x30); + } + if((PPU[1]>>5)==0x7) + block_or(target, 256, 0xc0); + else if(PPU[1]&0xE0) + block_or(target, 256, 0x40); + else + block_andor(target, 256, 0x3f, 0x80); +#else + int x; + + if(ScreenON || SpriteON) // Yes, very el-cheapo. + { + if(PPU[1]&0x01) + { + for(x=63;x>=0;x--) + *(uint32 *)&target[x<<2]=(*(uint32*)&target[x<<2])&0x30303030; + } + } + if((PPU[1]>>5)==0x7) + { + for(x=63;x>=0;x--) + *(uint32 *)&target[x<<2]=((*(uint32*)&target[x<<2])&0x3f3f3f3f)|0xc0c0c0c0; + } + else if(PPU[1]&0xE0) + for(x=63;x>=0;x--) + *(uint32 *)&target[x<<2]=(*(uint32*)&target[x<<2])|0x40404040; + else + for(x=63;x>=0;x--) + *(uint32 *)&target[x<<2]=((*(uint32*)&target[x<<2])&0x3f3f3f3f)|0x80808080; +#endif + + // black borders + ((uint32 *)target)[-2]=((uint32 *)target)[-1]=0; + ((uint32 *)target)[64]=((uint32 *)target)[65]=0; } #define PAL(c) ((c)+cc) @@ -968,36 +1000,6 @@ void Fixit1(void) } -/* This is called at the beginning of all h-blanks on visible lines. */ -static void DoHBlank(void) -{ - if(ScreenON || SpriteON) - FetchSpriteData(); - if(GameHBIRQHook && (ScreenON || SpriteON) && ((PPU[0]&0x38)!=0x18)) - { - X6502_Run(6); - Fixit2(); - X6502_Run(4+3); // original value was 4, but adding 3 fixes glitch in smb3 (and breaks something?) - GameHBIRQHook(); - X6502_Run(85-10-16-3); - } - else - { - X6502_Run(6); // Tried 65, caused problems with Slalom(maybe others) - Fixit2(); - X6502_Run(85-6-16); - } - if(GameHBIRQHook2 && (ScreenON || SpriteON)) - GameHBIRQHook2(); - //PPU_hook(0,-1); - //fprintf(stderr,"%3d: $%04x\n",scanline,RefreshAddr); - scanline++; - if (scanline<240) - ResetRL(); - X6502_Run(16); -} - - // ============================// // end of new code // ===========================// @@ -1215,32 +1217,62 @@ int FCEUI_Initialize(void) } void MMC5_hb(int); /* Ugh ugh ugh. */ -static INLINE void Thingo(void) +static void DoLine(void) { - Loop6502(); + uint8 *target=XBuf+scanline*320+32; + + LineUpdate(target); if(MMC5Hack && (ScreenON || SpriteON)) MMC5_hb(scanline); + X6502_Run(256); + // check: Battletoads & Double Dragon, Addams Family // sky glitches in SMB1 if done wrong - if(tosprite>=256) + FakedLineUpdate(); + +#ifdef FRAMESKIP + if(!FSkip) +#endif + if(SpriteON && spork) + CopySprites(target); + +#ifdef FRAMESKIP + if(!FSkip) +#endif + LineUpdateEnd(target); + sphitx=0x100; + + if(ScreenON || SpriteON) + FetchSpriteData(); + + // DoHBlank(); + if(GameHBIRQHook && (ScreenON || SpriteON) && ((PPU[0]&0x38)!=0x18)) { - X6502_Run(256); + X6502_Run(6); + Fixit2(); + X6502_Run(4); + GameHBIRQHook(); + X6502_Run(85-10-16); } else { - // a dirty hack for Addams Family and inaccurate sprite hit emulation - if(tosprite<8) tosprite-=tosprite*3>>2; - - X6502_Run(tosprite); - PPU[2]|=0x40; - X6502_Run(256-tosprite); - tosprite = 256; + X6502_Run(6); // Tried 65, caused problems with Slalom(maybe others) + Fixit2(); + X6502_Run(85-6-16); } - TryFixit1(); - DoHBlank(); + + if(SpriteON) + RefreshSprites(); + if(GameHBIRQHook2 && (ScreenON || SpriteON)) + GameHBIRQHook2(); + scanline++; + if (scanline<240) + ResetRL(XBuf+scanline*320+32); + X6502_Run(16); } + void EmLoop(void) { for(;;) @@ -1305,7 +1337,8 @@ void EmLoop(void) RefreshAddr=TempAddr; if(PPU_hook) PPU_hook(RefreshAddr&0x3fff); } - ResetRL(); + spork=0; + ResetRL(XBuf+32); X6502_Run(16-kook); kook ^= 1; @@ -1326,7 +1359,7 @@ void EmLoop(void) for(scanline=0;scanline<240;) // scanline is incremented in DoLine. Evil. :/ { deempcnt[deemp]++; - Thingo(); + DoLine(); } if(MMC5Hack && (ScreenON || SpriteON)) MMC5_hb(scanline); for(x=1,max=0,maxref=0;x<7;x++) diff --git a/input.c b/input.c index b540f55..ba07072 100644 --- a/input.c +++ b/input.c @@ -36,7 +36,7 @@ #include "dprintf.h" extern INPUTC *FCEU_InitZapper(int w); -extern INPUTC *FCEU_InitPowerpad(int w); +extern INPUTC *FCEU_InitPowerpadA(int w); extern INPUTC *FCEU_InitArkanoid(int w); extern INPUTCFC *FCEU_InitArkanoidFC(void); @@ -57,7 +57,7 @@ static int JPAttribFC=0; static int JPTypeFC=0; static void *InputDataPtrFC; -void (*InputScanlineHook)(uint8 *buf, int line); +void (*InputScanlineHook)(uint8 *bg, uint8 *spr, uint32 linets, int final); static INPUTC DummyJPort={0,0,0,0,0}; static INPUTC *JPorts[2]={&DummyJPort,&DummyJPort}; @@ -232,16 +232,16 @@ static DECLFR(VSUNIRead1) return ret; } -static void SLHLHook(uint8 *buf, int line) +static void SLHLHook(uint8 *bg, uint8 *spr, uint32 linets, int final) { int x; for(x=0;x<2;x++) if(JPorts[x]->SLHook) - JPorts[x]->SLHook(x,buf,line); + JPorts[x]->SLHook(x,bg,spr,linets,final); if(FCExp) if(FCExp->SLHook) - FCExp->SLHook(buf,line); + FCExp->SLHook(bg,spr,linets,final); } static void CheckSLHook(void) @@ -266,7 +266,7 @@ static void FASTAPASS(1) SetInputStuff(int x) break; case SI_ARKANOID:JPorts[x]=FCEU_InitArkanoid(x);break; case SI_ZAPPER:JPorts[x]=FCEU_InitZapper(x);break; - case SI_POWERPADA:JPorts[x]=FCEU_InitPowerpad(x);break; + case SI_POWERPADA:JPorts[x]=FCEU_InitPowerpadA(x);break; case SI_NONE:JPorts[x]=&DummyJPort;break; } diff --git a/input.h b/input.h index daaa304..7c0da59 100644 --- a/input.h +++ b/input.h @@ -3,7 +3,7 @@ typedef struct { void FP_FASTAPASS(1) (*Write)(uint8 v); void FP_FASTAPASS(1) (*Strobe)(int w); void FP_FASTAPASS(3) (*Update)(int w, void *data, int arg); - void FP_FASTAPASS(3) (*SLHook)(int w, uint8 *buf, int line); + void FP_FASTAPASS(3) (*SLHook)(int w, uint8 *bg, uint8 *spr, uint32 linets, int final); void FP_FASTAPASS(3) (*Draw)(int w, uint8 *buf, int arg); } INPUTC; @@ -12,7 +12,7 @@ typedef struct { void FP_FASTAPASS(1) (*Write)(uint8 v); void (*Strobe)(void); void FP_FASTAPASS(2) (*Update)(void *data, int arg); - void FP_FASTAPASS(2) (*SLHook)(uint8 *buf, int line); + void FP_FASTAPASS(3) (*SLHook)(uint8 *bg, uint8 *spr, uint32 linets, int final); void FP_FASTAPASS(2) (*Draw)(uint8 *buf, int arg); } INPUTCFC; @@ -20,7 +20,7 @@ void DrawInput(uint8 *buf); void UpdateInput(void); void InitializeInput(void); extern void (*PStrobe[2])(void); -extern void (*InputScanlineHook)(uint8 *buf, int line); +extern void (*InputScanlineHook)(uint8 *bg, uint8 *spr, uint32 linets, int final); #define FCEUNPCMD_RESET 0x01 #define FCEUNPCMD_POWER 0x02 diff --git a/input/Makefile b/input/Makefile index 0327a9f..5358840 100644 --- a/input/Makefile +++ b/input/Makefile @@ -1,8 +1,4 @@ -INPOBJS = input/cursor.o input/powerpad.o input/zapper.o input/arkanoid.o input/shadow.o input/fkb.o +INP_C += input/cursor.c input/zapper.c input/powerpad.c input/arkanoid.c input/shadow.c input/fkb.c input/hypershot.c input/mahjong.c input/oekakids.c input/ftrainer.c input/quiz.c input/toprider.c input/bworld.c input/suborkb.c + +INPOBJS = $(patsubst %.c,%.o,$(INP_C)) -input/cursor.o: input/cursor.c -input/zapper.o: input/zapper.c -input/powerpad.o: input/powerpad.c -input/arkanoid.o: input/arkanoid.c -input/shadow.o: input/shadow.c -input/fkb.o: input/fkb.c input/fkb.h diff --git a/input/arkanoid.c b/input/arkanoid.c index b53fd3a..e1f337c 100644 --- a/input/arkanoid.c +++ b/input/arkanoid.c @@ -1,7 +1,7 @@ /* FCE Ultra - NES/Famicom Emulator * * Copyright notice for this file: - * Copyright (C) 2002 Ben Parnell + * Copyright (C) 2002 Xodnizel * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +19,8 @@ */ #include -#include -#include "share.h" +#include +#include "share.h" typedef struct { uint32 mzx,mzb; @@ -47,7 +47,8 @@ static uint8 FP_FASTAPASS(2) ReadARKFC(int w,uint8 ret) else { ret|=((FCArk.mzx>>(7-FCArk.readbit))&1)<<1; - FCArk.readbit++; + if(!fceuindbg) + FCArk.readbit++; } } else @@ -65,7 +66,7 @@ static uint32 FixX(uint32 x) static void FP_FASTAPASS(2) UpdateARKFC(void *data, int arg) { - uint32 *ptr=data; + uint32 *ptr=(uint32 *)data; FCArk.mzx=FixX(ptr[0]); FCArk.mzb=ptr[2]?1:0; } @@ -88,7 +89,8 @@ static uint8 FP_FASTAPASS(1) ReadARK(int w) else { ret|=((NESArk[w].mzx>>(7-NESArk[w].readbit))&1)<<4; - NESArk[w].readbit++; + if(!fceuindbg) + NESArk[w].readbit++; } ret|=(NESArk[w].mzb&1)<<3; return(ret); @@ -102,7 +104,7 @@ static void FP_FASTAPASS(1) StrobeARK(int w) static void FP_FASTAPASS(3) UpdateARK(int w, void *data, int arg) { - uint32 *ptr=data; + uint32 *ptr=(uint32*)data; NESArk[w].mzx=FixX(ptr[0]); NESArk[w].mzb=ptr[2]?1:0; } diff --git a/input/bworld.c b/input/bworld.c new file mode 100644 index 0000000..beb6527 --- /dev/null +++ b/input/bworld.c @@ -0,0 +1,74 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2003 Xodnizel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include "share.h" + +static int seq,ptr,bit,cnt,have; +static uint8 bdata[20]; + + +static uint8 FP_FASTAPASS(2) Read(int w, uint8 ret) +{ + if(w && have) + { + switch(seq) + { + case 0: seq++; ptr=0; ret|=0x4; break; + case 1: seq++; bit=bdata[ptr]; cnt=0; ret|=0x4; break; + case 2: ret|=((bit&0x01)^0x01)<<2; bit>>=1; if(++cnt > 7) seq++; + break; + case 3: if(++ptr > 19) + { + seq=-1; + have=0; + } + else + seq=1; + default: break; + } + } + return(ret); +} + +static void FP_FASTAPASS(1) Write(uint8 V) +{ + //printf("%02x\n",V); +} + +static void FP_FASTAPASS(2) Update(void *data, int arg) +{ + if(*(uint8 *)data) + { + *(uint8 *)data=0; + seq=ptr=0; + have=1; + strcpy((char *)bdata,(char *)data+1); + strcpy((char *)&bdata[13],"SUNSOFT"); + } +} + +static INPUTCFC BarcodeWorld={Read,Write,0,Update,0,0}; + +INPUTCFC *FCEU_InitBarcodeWorld(void) +{ + return(&BarcodeWorld); +} + diff --git a/input/cursor.c b/input/cursor.c index cb78d73..c57b9d1 100644 --- a/input/cursor.c +++ b/input/cursor.c @@ -1,5 +1,20 @@ #include "share.h" +static uint8 GunSight[]={ + 0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,0,0,0, + 1,2,1,2,0,3,3,3,0,2,1,2,1, + 0,0,0,0,0,0,3,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,0,0,0, +}; static uint8 FCEUcursor[11*19]= { 1,0,0,0,0,0,0,0,0,0,0, @@ -23,6 +38,32 @@ static uint8 FCEUcursor[11*19]= 0,0,0,0,0,0,0,1,1,0,0, }; +void FCEU_DrawGunSight(uint8 *buf, int xc, int yc) +{ + int x,y; + int c,d; + + for(y=0;y<13;y++) + for(x=0;x<13;x++) + { + uint8 a; + a=GunSight[y*13+x]; + if(a) + { + c=(yc+y-7); + d=(xc+x-7); + if(c>=0 && d>=0 && d<256 && c<240) + { + if(a==3) + buf[c*SCREEN_WIDTH+d+SCREEN_OFFS]=0xBF-(buf[c*SCREEN_WIDTH+d+SCREEN_OFFS]&0x3F); + else + buf[c*SCREEN_WIDTH+d+SCREEN_OFFS]=a-1; + } + } + } +} + + void FCEU_DrawCursor(uint8 *buf, int xc, int yc) { int x,y; @@ -39,7 +80,7 @@ void FCEU_DrawCursor(uint8 *buf, int xc, int yc) c=(yc+y); d=(xc+x); if(d<256 && c<240) - buf[c*272+d]=a+127; + buf[c*SCREEN_WIDTH+d+SCREEN_OFFS]=a+127; } } } diff --git a/input/fkb.c b/input/fkb.c index c70e73f..6d7ee3a 100644 --- a/input/fkb.c +++ b/input/fkb.c @@ -1,7 +1,7 @@ /* FCE Ultra - NES/Famicom Emulator * * Copyright notice for this file: - * Copyright (C) 2002 Ben Parnell + * Copyright (C) 2002 Xodnizel * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,8 +21,8 @@ #include #include "share.h" #include "fkb.h" -#define AK2(x,y) ( (FKB_##x) | (FKB_##y <<8) ) -#define AK(x) FKB_##x +#define AK2(x,y) ( (FKB_##x) | (FKB_##y <<8) ) +#define AK(x) FKB_##x static uint8 bufit[0x49]; static uint8 ksmode; diff --git a/input/fkb.h b/input/fkb.h index ca27b34..72e3dca 100644 --- a/input/fkb.h +++ b/input/fkb.h @@ -1,27 +1,27 @@ -#define FKB_F1 0x01 -#define FKB_F2 0x02 -#define FKB_F3 0x03 -#define FKB_F4 0x04 -#define FKB_F5 0x05 -#define FKB_F6 0x06 -#define FKB_F7 0x07 -#define FKB_F8 0x08 -#define FKB_1 0x09 -#define FKB_2 0x0A -#define FKB_3 0x0B -#define FKB_4 0x0C -#define FKB_5 0x0D -#define FKB_6 0x0E -#define FKB_7 0x0F -#define FKB_8 0x10 -#define FKB_9 0x11 -#define FKB_0 0x12 -#define FKB_MINUS 0x13 -#define FKB_CARET 0x14 -#define FKB_BACKSLASH 0x15 -#define FKB_STOP 0x16 -#define FKB_ESCAPE 0x17 -#define FKB_Q 0x18 +#define FKB_F1 0x01 +#define FKB_F2 0x02 +#define FKB_F3 0x03 +#define FKB_F4 0x04 +#define FKB_F5 0x05 +#define FKB_F6 0x06 +#define FKB_F7 0x07 +#define FKB_F8 0x08 +#define FKB_1 0x09 +#define FKB_2 0x0A +#define FKB_3 0x0B +#define FKB_4 0x0C +#define FKB_5 0x0D +#define FKB_6 0x0E +#define FKB_7 0x0F +#define FKB_8 0x10 +#define FKB_9 0x11 +#define FKB_0 0x12 +#define FKB_MINUS 0x13 +#define FKB_CARET 0x14 +#define FKB_BACKSLASH 0x15 +#define FKB_STOP 0x16 +#define FKB_ESCAPE 0x17 +#define FKB_Q 0x18 #define FKB_W 0x19 #define FKB_E 0x1A #define FKB_R 0x1B diff --git a/input/ftrainer.c b/input/ftrainer.c new file mode 100644 index 0000000..5669310 --- /dev/null +++ b/input/ftrainer.c @@ -0,0 +1,74 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2003 Xodnizel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include "share.h" + +static uint32 FTVal,FTValR; +static char side; + +static uint8 FP_FASTAPASS(2) FT_Read(int w, uint8 ret) +{ + if(w) + { + ret|=FTValR; + } + return(ret); +} + +static void FP_FASTAPASS(1) FT_Write(uint8 V) +{ + FTValR=0; + + //printf("%08x\n",FTVal); + if(!(V&0x1)) + FTValR=(FTVal>>8); + else if(!(V&0x2)) + FTValR=(FTVal>>4); + else if(!(V&0x4)) + FTValR=FTVal; + + FTValR=(~FTValR)&0xF; + if(side=='B') + FTValR=((FTValR&0x8)>>3) | ((FTValR&0x4)>>1) | ((FTValR&0x2)<<1) | ((FTValR&0x1)<<3); + FTValR<<=1; +} + +static void FP_FASTAPASS(2) FT_Update(void *data, int arg) +{ + FTVal=*(uint32 *)data; +} + +static INPUTCFC FamilyTrainer={FT_Read,FT_Write,0,FT_Update,0,0}; + +INPUTCFC *FCEU_InitFamilyTrainerA(void) +{ + side='A'; + FTVal=FTValR=0; + return(&FamilyTrainer); +} + +INPUTCFC *FCEU_InitFamilyTrainerB(void) +{ + side='B'; + FTVal=FTValR=0; + return(&FamilyTrainer); +} + diff --git a/input/hypershot.c b/input/hypershot.c new file mode 100644 index 0000000..6e69c7a --- /dev/null +++ b/input/hypershot.c @@ -0,0 +1,50 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2003 Xodnizel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include "share.h" + +static uint8 HSVal,HSValR; + + +static uint8 FP_FASTAPASS(2) HS_Read(int w, uint8 ret) +{ + if(w) ret|=HSValR; + + return(ret); +} + +static void HS_Strobe(void) +{ + HSValR=HSVal<<1; +} + +static void FP_FASTAPASS(2) HS_Update(void *data, int arg) +{ + HSVal=*(uint8*)data; +} + +static INPUTCFC HyperShot={HS_Read,0,HS_Strobe,HS_Update,0,0}; + +INPUTCFC *FCEU_InitHS(void) +{ + HSVal=HSValR=0; + return(&HyperShot); +} diff --git a/input/mahjong.c b/input/mahjong.c new file mode 100644 index 0000000..97105ab --- /dev/null +++ b/input/mahjong.c @@ -0,0 +1,79 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2003 Xodnizel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include "share.h" + +static uint32 MReal,MRet; + +static uint8 FP_FASTAPASS(2) MJ_Read(int w, uint8 ret) +{ + if(w) + { +// ret|=(MRet&1)<<1; + ret|=((MRet&0x80)>>6)&2; +// MRet>>=1; + if(!fceuindbg) + MRet<<=1; + } + return(ret); +} + +static void FP_FASTAPASS(1) MJ_Write(uint8 v) +{ + /* 1: I-D7, J-D6, K-D5, L-D4, M-D3, Big Red-D2 + 2: A-D7, B-D6, C-D5, D-D4, E-D3, F-D2, G-D1, H-D0 + 3: Sel-D6, Start-D7, D5, D4, D3, D2, D1 + */ + MRet=0; + + v>>=1; + v&=3; + + if(v==3) + { + MRet=(MReal>>14)&0x7F; + //MRet=((MRet&0x1F) |((MRet&0x40)>>1)|((MRet&0x20)<<1)) <<1; //(MReal>>13)&0x7F; + } + else if(v==2) + { + MRet=MReal&0xFF; + } + else if(v==1) + { + MRet=(MReal>>8)&0x3F; + } +// HSValR=HSVal<<1; +} + +static void FP_FASTAPASS(2) MJ_Update(void *data, int arg) +{ + MReal=*(uint32*)data; + //printf("%08x\n",MReal>>13); + //HSVal=*(uint8*)data; +} + +static INPUTCFC Mahjong={MJ_Read,MJ_Write,0,MJ_Update,0,0}; + +INPUTCFC *FCEU_InitMahjong(void) +{ + MReal=MRet=0; + return(&Mahjong); +} diff --git a/input/oekakids.c b/input/oekakids.c new file mode 100644 index 0000000..ab25896 --- /dev/null +++ b/input/oekakids.c @@ -0,0 +1,95 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2003 Xodnizel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include "share.h" + +static uint8 OKValR,LastWR; +static uint32 OKData; +static uint32 OKX,OKY,OKB; + +static uint8 FP_FASTAPASS(2) OK_Read(int w, uint8 ret) +{ + if(w) + { + ret|=OKValR; + } + return(ret); +} + +static void FP_FASTAPASS(1) OK_Write(uint8 V) +{ + if(!(V&0x1)) + { + int32 vx,vy; + + //puts("Redo"); + OKValR=OKData=0; + + if(OKB) OKData|=1; + + if(OKY >= 48) + OKData|=2; + else if(OKB) OKData|=3; + + vx=OKX*240/256+8; + vy=OKY*256/240-12; + if(vy<0) vy=0; + if(vy>255) vy=255; + if(vx<0) vx=0; + if(vx>255) vx=255; + OKData |= (vx<<10) | (vy<<2); + } + else + { + if((~LastWR)&V&0x02) + OKData<<=1; + + if(!(V&0x2)) OKValR=0x4; + else + { + if(OKData&0x40000) OKValR=0; + else OKValR=0x8; + } + } + LastWR=V; +} + +static void FP_FASTAPASS(2) OK_Update(void *data, int arg) +{ + //puts("Sync"); + OKX=((uint32*)data)[0]; + OKY=((uint32*)data)[1]; + OKB=((uint32*)data)[2]; +} + +static void FP_FASTAPASS(2) DrawOeka(uint8 *buf, int arg) +{ + if(arg && OKY<44) + FCEU_DrawCursor(buf, OKX, OKY); +} + +static INPUTCFC OekaKids={OK_Read,OK_Write,0,OK_Update,0,DrawOeka}; + +INPUTCFC *FCEU_InitOekaKids(void) +{ + OKValR=0; + return(&OekaKids); +} diff --git a/input/powerpad.c b/input/powerpad.c index 3c613f9..ca58ee7 100644 --- a/input/powerpad.c +++ b/input/powerpad.c @@ -1,7 +1,7 @@ /* FCE Ultra - NES/Famicom Emulator * * Copyright notice for this file: - * Copyright (C) 2002 Ben Parnell + * Copyright (C) 2002 Xodnizel * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,10 +19,11 @@ */ #include -#include -#include "share.h" +#include +#include "share.h" +static char side; static uint32 pprsb[2]; static uint32 pprdata[2]; @@ -37,7 +38,8 @@ static uint8 FP_FASTAPASS(1) ReadPP(int w) if(pprsb[w]>=8) ret|=0x08; } - pprsb[w]++; + if(!fceuindbg) + pprsb[w]++; return ret; } @@ -48,13 +50,36 @@ static void FP_FASTAPASS(1) StrobePP(int w) void FP_FASTAPASS(3) UpdatePP(int w, void *data, int arg) { - pprdata[w]=*(uint32 *)data; + static const char shifttableA[12]={8,9,0,1,11,7,4,2,10,6,5,3}; + static const char shifttableB[12]={1,0,9,8,2,4,7,11,3,5,6,10}; + int x; + + pprdata[w]=0; + + if(side=='A') + for(x=0;x<12;x++) + pprdata[w]|=(((*(uint32 *)data)>>x)&1)<>x)&1)< +#include "share.h" + +static uint8 QZVal,QZValR; +static uint8 FunkyMode; + +static uint8 FP_FASTAPASS(2) QZ_Read(int w, uint8 ret) +{ + if(w) + { + //if(X.PC==0xdc7d) return(0xFF); + //printf("Blah: %04x\n",X.PC); + //FCEUI_DumpMem("dmp2",0xc000,0xffff); + + ret|=(QZValR&0x7)<<2; + QZValR=QZValR>>3; + + if(FunkyMode) + { + //ret=0x14; + //puts("Funky"); + QZValR|=0x28; + } + else + { + QZValR|=0x38; + } + } + return(ret); +} + +static void QZ_Strobe(void) +{ + QZValR=QZVal; + //puts("Strobe"); +} + +static void FP_FASTAPASS(1) QZ_Write(uint8 V) +{ + //printf("Wr: %02x\n",V); + FunkyMode=V&4; +} + +static void FP_FASTAPASS(2) QZ_Update(void *data, int arg) +{ + QZVal=*(uint8 *)data; +} + +static INPUTCFC QuizKing={QZ_Read,QZ_Write,QZ_Strobe,QZ_Update,0,0}; + +INPUTCFC *FCEU_InitQuizKing(void) +{ + QZVal=QZValR=0; + return(&QuizKing); +} diff --git a/input/shadow.c b/input/shadow.c index 499e640..2a5fd8d 100644 --- a/input/shadow.c +++ b/input/shadow.c @@ -1,7 +1,7 @@ /* FCE Ultra - NES/Famicom Emulator * * Copyright notice for this file: - * Copyright (C) 2002 Ben Parnell + * Copyright (C) 2002 Xodnizel * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ */ #include -#include +#include #include "share.h" @@ -27,46 +27,73 @@ typedef struct { uint32 mzx,mzy,mzb; int zap_readbit; int bogo; - uint32 colok; - uint32 coloklast; + int zappo; + uint64 zaphit; } ZAPPER; static ZAPPER ZD; -static void FP_FASTAPASS(2) ZapperThingy(uint8 *buf, int line) +static void FP_FASTAPASS(3) ZapperFrapper(uint8 *bg, uint8 *spr, uint32 linets, int final) { - int mzx=ZD.mzx; - - if(line==0) ZD.colok=1<<16; /* Disable it. */ - ZD.coloklast=ZD.colok; - - if((line>=ZD.mzy-3 && line<=ZD.mzy+3) && mzx<256) - { - int a,sum,x; - - for(x=-4;x<4;x++) - { - if((mzx+x)<0 || (mzx+x)>255) continue; - a=buf[mzx+x]&63; - sum=palo[a].r+palo[a].g+palo[a].b; - - if(sum>=100*3) - { - ZD.colok=timestamp+mzx/3; - break; - } - } - } + int xs,xe; + int zx,zy; + + if(!bg) // New line, so reset stuff. + { + ZD.zappo=0; + return; + } + xs=ZD.zappo; + xe=final; + + zx=ZD.mzx; + zy=ZD.mzy; + + if(xe>256) xe=256; + + if(scanline>=(zy-4) && scanline<=(zy+4)) + { + while(xs=(zx-4)) + { + a1=bg[xs]; + if(spr) + { + a2=spr[xs]; + + if(!(a2&0x80)) + if(!(a2&0x40) || (a1&64)) + a1=a2; + } + a1&=63; + + sum=palo[a1].r+palo[a1].g+palo[a1].b; + if(sum>=100*3) + { + ZD.zaphit=((uint64)linets+(xs+16)*(PAL?15:16))/48+timestampbase; + goto endo; + } + } + xs++; + } + } + endo: + ZD.zappo=final; } static INLINE int CheckColor(void) { - if( (timestamp>=ZD.coloklast && timestamp<=(ZD.coloklast+10)) || - (timestamp>=ZD.colok && timestamp<=(ZD.colok+10)) ) - return 0; - return 1; + //FCEUPPU_LineUpdate(); + + if((ZD.zaphit+10)>=(timestampbase+timestamp)) return(0); + + return(1); } + static uint8 FP_FASTAPASS(2) ReadZapper(int w, uint8 ret) { if(w) @@ -96,7 +123,7 @@ static void FP_FASTAPASS(2) DrawZapper(uint8 *buf, int arg) static void FP_FASTAPASS(2) UpdateZapper(void *data, int arg) { - uint32 *ptr=data; + uint32 *ptr=(uint32*)data; if(ZD.bogo) ZD.bogo--; @@ -106,9 +133,6 @@ static void FP_FASTAPASS(2) UpdateZapper(void *data, int arg) ZD.mzx=ptr[0]; ZD.mzy=ptr[1]; ZD.mzb=ptr[2]; - - if(ZD.mzx>=256 || ZD.mzy>=240) - ZD.colok=0; } static void StrobeShadow(void) @@ -116,7 +140,7 @@ static void StrobeShadow(void) ZD.zap_readbit=0; } -static INPUTCFC SHADOWC={ReadZapper,0,StrobeShadow,UpdateZapper,ZapperThingy,DrawZapper}; +static INPUTCFC SHADOWC={ReadZapper,0,StrobeShadow,UpdateZapper,ZapperFrapper,DrawZapper}; INPUTCFC *FCEU_InitSpaceShadow(void) { diff --git a/input/share.h b/input/share.h index bddf953..adfeca9 100644 --- a/input/share.h +++ b/input/share.h @@ -1,8 +1,13 @@ #include "../types.h" #include "../input.h" #include "../fce.h" -#include "../svga.h" -#include "../palette.h" +#include "../ppu.h" #include "../x6502.h" +#include "../palette.h" void FCEU_DrawCursor(uint8 *buf, int xc, int yc); +void FCEU_DrawGunSight(uint8 *buf, int xc, int yc); + +#define SCREEN_WIDTH 320 +#define SCREEN_OFFS 32 + diff --git a/input/suborkb.c b/input/suborkb.c new file mode 100644 index 0000000..5bd7082 --- /dev/null +++ b/input/suborkb.c @@ -0,0 +1,94 @@ +#include +#include "share.h" +#include "suborkb.h" +#define AK2(x,y) ( (FKB_##x) | (FKB_##y <<8) ) +#define AK(x) FKB_##x + +static uint8 bufit[0x61]; +static uint8 ksmode; +static uint8 ksindex; + + +static uint16 matrix[13][2][4]= +{ +{{AK(4),AK(G),AK(F),AK(C)}, + {AK(F2),AK(E),AK(5),AK(V)}}, +{{AK(2),AK(D),AK(S),AK(END)}, + {AK(F1),AK(W),AK(3),AK(X)}}, +{{AK(INSERT),AK(BACK),AK(NEXT),AK(RIGHT)}, + {AK(F8),AK(PRIOR),AK(DELETE),AK(HOME)}}, +{{AK(9),AK(I),AK(L),AK(COMMA)}, + {AK(F5),AK(O),AK(0),AK(PERIOD)}}, +{{AK(RBRACKET),AK(RETURN),AK(UP),AK(LEFT)}, + {AK(F7),AK(LBRACKET),AK(BACKSLASH),AK(DOWN)}}, +{{AK(Q),AK(CAPITAL),AK(Z),AK(TAB)}, + {AK(ESCAPE),AK(A),AK(1),AK(LCONTROL)}}, +{{AK(7),AK(Y),AK(K),AK(M)}, + {AK(F4),AK(U),AK(8),AK(J)}}, +{{AK(MINUS),AK(SEMICOLON),AK(APOSTROPHE),AK(SLASH)}, + {AK(F6),AK(P),AK(EQUALS),AK(LSHIFT)}}, +{{AK(T),AK(H),AK(N),AK(SPACE)}, + {AK(F3),AK(R),AK(6),AK(B)}}, +{{0,0,0,0}, + {0,0,0,0}}, +{{AK(LMENU),AK(NUMPAD4),AK(NUMPAD7),AK(F11)}, + {AK(F12),AK(NUMPAD1),AK(NUMPAD2),AK(NUMPAD8)}}, +{{AK(SUBTRACT),AK(ADD),AK(MULTIPLY),AK(NUMPAD9)}, + {AK(F10),AK(NUMPAD5),AK(DIVIDE),AK(NUMLOCK)}}, +{{AK(GRAVE),AK(NUMPAD6),AK(PAUSE),AK(SPACE)}, + {AK(F9),AK(NUMPAD3),AK(DECIMAL),AK(NUMPAD0)}}, +}; + +static void FP_FASTAPASS(1) SuborKB_Write(uint8 v) +{ + v>>=1; + if(v&2) + { + if((ksmode&1) && !(v&1)) + ksindex=(ksindex+1)%13; + } + ksmode=v; +} + +static uint8 FP_FASTAPASS(2) SuborKB_Read(int w, uint8 ret) +{ + if(w) + { + int x; + + ret&=~0x1E; +// if(ksindex==9) +// { +// if(ksmode&1) +// ret|=2; +// } +// else +// { + for(x=0;x<4;x++) + if(bufit[matrix[ksindex][ksmode&1][x]&0xFF]||bufit[matrix[ksindex][ksmode&1][x]>>8]) + ret|=1<<(x+1); +// } + ret^=0x1E; + } + return(ret); +} + +static void SuborKB_Strobe(void) +{ + ksmode=0; + ksindex=0; +} + +static void FP_FASTAPASS(2) SuborKB_Update(void *data, int arg) +{ + memcpy(bufit+1,data,0x60); +} + +static INPUTCFC SuborKB={SuborKB_Read,SuborKB_Write,SuborKB_Strobe,SuborKB_Update,0,0}; + +INPUTCFC *FCEU_InitSuborKB(void) +{ + memset(bufit,0,sizeof(bufit)); + ksmode=ksindex=0; + return(&SuborKB); +} diff --git a/input/suborkb.h b/input/suborkb.h new file mode 100644 index 0000000..735f820 --- /dev/null +++ b/input/suborkb.h @@ -0,0 +1,96 @@ +#define FKB_ESCAPE 0x01 +#define FKB_F1 0x02 +#define FKB_F2 0x03 +#define FKB_F3 0x04 +#define FKB_F4 0x05 +#define FKB_F5 0x06 +#define FKB_F6 0x07 +#define FKB_F7 0x08 +#define FKB_F8 0x09 +#define FKB_F9 0x0A +#define FKB_F10 0x0B +#define FKB_F11 0x0C +#define FKB_F12 0x0D +#define FKB_PAUSE 0x0E +#define FKB_GRAVE 0x0F +#define FKB_1 0x10 +#define FKB_2 0x11 +#define FKB_3 0x12 +#define FKB_4 0x13 +#define FKB_5 0x14 +#define FKB_6 0x15 +#define FKB_7 0x16 +#define FKB_8 0x17 +#define FKB_9 0x18 +#define FKB_0 0x19 +#define FKB_MINUS 0x1A +#define FKB_EQUALS 0x1B +#define FKB_BACK 0x1C +#define FKB_INSERT 0x1D +#define FKB_HOME 0x1E +#define FKB_PRIOR 0x1F +#define FKB_NUMLOCK 0x20 +#define FKB_DIVIDE 0x21 +#define FKB_MULTIPLY 0x22 +#define FKB_SUBTRACT 0x23 +#define FKB_TAB 0x24 +#define FKB_Q 0x25 +#define FKB_W 0x26 +#define FKB_E 0x27 +#define FKB_R 0x28 +#define FKB_T 0x29 +#define FKB_Y 0x2A +#define FKB_U 0x2B +#define FKB_I 0x2C +#define FKB_O 0x2D +#define FKB_P 0x2E +#define FKB_LBRACKET 0x2F +#define FKB_RBRACKET 0x30 +#define FKB_RETURN 0x31 +#define FKB_DELETE 0x32 +#define FKB_END 0x33 +#define FKB_NEXT 0x34 +#define FKB_NUMPAD7 0x35 +#define FKB_NUMPAD8 0x36 +#define FKB_NUMPAD9 0x37 +#define FKB_ADD 0x38 +#define FKB_CAPITAL 0x39 +#define FKB_A 0x3A +#define FKB_S 0x3B +#define FKB_D 0x3C +#define FKB_F 0x3D +#define FKB_G 0x3E +#define FKB_H 0x3F +#define FKB_J 0x40 +#define FKB_K 0x41 +#define FKB_L 0x42 +#define FKB_SEMICOLON 0x43 +#define FKB_APOSTROPHE 0x44 +#define FKB_NUMPAD4 0x45 +#define FKB_NUMPAD5 0x46 +#define FKB_NUMPAD6 0x47 +#define FKB_LSHIFT 0x48 +#define FKB_Z 0x49 +#define FKB_X 0x4A +#define FKB_C 0x4B +#define FKB_V 0x4C +#define FKB_B 0x4D +#define FKB_N 0x4E +#define FKB_M 0x4F +#define FKB_COMMA 0x50 +#define FKB_PERIOD 0x51 +#define FKB_SLASH 0x52 +#define FKB_BACKSLASH 0x53 +#define FKB_UP 0x54 +#define FKB_NUMPAD1 0x55 +#define FKB_NUMPAD2 0x56 +#define FKB_NUMPAD3 0x57 +#define FKB_LCONTROL 0x58 +#define FKB_LMENU 0x59 +#define FKB_SPACE 0x5A +#define FKB_LEFT 0x5B +#define FKB_DOWN 0x5C +#define FKB_RIGHT 0x5D +#define FKB_NUMPAD0 0x5E +#define FKB_DECIMAL 0x5F + diff --git a/input/toprider.c b/input/toprider.c new file mode 100644 index 0000000..aa3bda5 --- /dev/null +++ b/input/toprider.c @@ -0,0 +1,62 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2003 Xodnizel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include "share.h" + +static uint32 bs,bss; +static uint32 boop; + +static uint8 FP_FASTAPASS(2) Read(int w, uint8 ret) +{ + if(w) + { + ret|=(bs&1)<<3; + ret|=(boop&1)<<4; + bs>>=1; + boop>>=1; +// puts("Read"); + } + return(ret); +} + +static void FP_FASTAPASS(1) Write(uint8 V) +{ + // if(V&0x2) + bs=bss; + //printf("Write: %02x\n",V); +// boop=0xC0; +} + +static void FP_FASTAPASS(2) Update(void *data, int arg) +{ + bss=*(uint8*)data; + bss|=bss<<8; + bss|=bss<<8; +} + +static INPUTCFC TopRider={Read,Write,0,Update,0,0}; + +INPUTCFC *FCEU_InitTopRider(void) +{ + + return(&TopRider); +} + diff --git a/input/zapper.c b/input/zapper.c index 16f9e15..1caaff0 100644 --- a/input/zapper.c +++ b/input/zapper.c @@ -1,7 +1,7 @@ /* FCE Ultra - NES/Famicom Emulator * * Copyright notice for this file: - * Copyright (C) 2002 Ben Parnell + * Copyright (C) 2002 Xodnizel * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ */ #include -#include +#include #include "share.h" @@ -27,47 +27,71 @@ typedef struct { uint32 mzx,mzy,mzb; int zap_readbit; int bogo; - uint32 colok; - uint32 coloklast; + int zappo; + uint64 zaphit; } ZAPPER; static ZAPPER ZD[2]; -static void FP_FASTAPASS(3) ZapperThingy(int w, uint8 *buf, int line) +static void FP_FASTAPASS(3) ZapperFrapper(int w, uint8 *bg, uint8 *spr, uint32 linets, int final) { - int mzx=ZD[w].mzx; - - if(line==0) ZD[w].colok=1<<16; /* Disable it. */ - - ZD[w].coloklast=ZD[w].colok; - - if(ZD[w].mzb&2) return; - if((line>=ZD[w].mzy-3 && line<=ZD[w].mzy+3) && mzx<256) - { - int a,sum,x; - - for(x=-4;x<4;x++) - { - if((mzx+x)<0 || (mzx+x)>255) continue; - a=buf[mzx+x]&63; - sum=palo[a].r+palo[a].g+palo[a].b; - - if(sum>=100*3) - { - ZD[w].colok=timestamp+mzx/3; - break; - } - } - } - + int xs,xe; + int zx,zy; + + if(!bg) // New line, so reset stuff. + { + ZD[w].zappo=0; + return; + } + xs=ZD[w].zappo; + xe=final; + + zx=ZD[w].mzx; + zy=ZD[w].mzy; + + if(xe>256) xe=256; + + if(scanline>=(zy-4) && scanline<=(zy+4)) + { + while(xs=(zx-4)) + { + a1=bg[xs]; + if(spr) + { + a2=spr[xs]; + + if(!(a2&0x80)) + if(!(a2&0x40) || (a1&64)) + a1=a2; + } + a1&=63; + + sum=palo[a1].r+palo[a1].g+palo[a1].b; + if(sum>=100*3) + { + ZD[w].zaphit=((uint64)linets+(xs+16)*(PAL?15:16))/48+timestampbase; + goto endo; + } + } + xs++; + } + } + endo: + ZD[w].zappo=final; } static INLINE int CheckColor(int w) { - if( (timestamp>=ZD[w].coloklast && timestamp<=(ZD[w].coloklast+100)) || - (timestamp>=ZD[w].colok && timestamp<=(ZD[w].colok+100)) ) - return 0; - return 1; + //FCEUPPU_LineUpdate(); + + if((ZD[w].zaphit+100)>=(timestampbase+timestamp) + && !(ZD[w].mzb&2)) return(0); + + return(1); } static uint8 FP_FASTAPASS(1) ReadZapperVS(int w) @@ -86,12 +110,13 @@ static uint8 FP_FASTAPASS(1) ReadZapperVS(int w) if(!CheckColor(w)) ret|=0x1; } - ZD[w].zap_readbit++; + if(!fceuindbg) + ZD[w].zap_readbit++; return ret; } static void FP_FASTAPASS(1) StrobeZapperVS(int w) -{ +{ ZD[w].zap_readbit=0; } @@ -108,13 +133,14 @@ static uint8 FP_FASTAPASS(1) ReadZapper(int w) static void FASTAPASS(3) DrawZapper(int w, uint8 *buf, int arg) { if(arg) - FCEU_DrawCursor(buf, ZD[w].mzx,ZD[w].mzy); + FCEU_DrawGunSight(buf, ZD[w].mzx,ZD[w].mzy); } static void FP_FASTAPASS(3) UpdateZapper(int w, void *data, int arg) { - uint32 *ptr=data; + uint32 *ptr=(uint32 *)data; + //FCEU_DispMessage("%3d:%3d",ZD[w].mzx,ZD[w].mzy); if(ZD[w].bogo) ZD[w].bogo--; if(ptr[2]&3 && (!(ZD[w].mzb&3))) @@ -123,18 +149,15 @@ static void FP_FASTAPASS(3) UpdateZapper(int w, void *data, int arg) ZD[w].mzx=ptr[0]; ZD[w].mzy=ptr[1]; ZD[w].mzb=ptr[2]; - - if(ZD[w].mzb&2 || ZD[w].mzx>=256 || ZD[w].mzy>=240) - ZD[w].colok=0; } -static INPUTC ZAPC={ReadZapper,0,0,UpdateZapper,ZapperThingy,DrawZapper}; -static INPUTC ZAPVSC={ReadZapperVS,0,StrobeZapperVS,UpdateZapper,ZapperThingy,DrawZapper}; +static INPUTC ZAPC={ReadZapper,0,0,UpdateZapper,ZapperFrapper,DrawZapper}; +static INPUTC ZAPVSC={ReadZapperVS,0,StrobeZapperVS,UpdateZapper,ZapperFrapper,DrawZapper}; INPUTC *FCEU_InitZapper(int w) { memset(&ZD[w],0,sizeof(ZAPPER)); - if(FCEUGameInfo.type==GIT_VSUNI) + if(FCEUGameInfo.type == GIT_VSUNI) return(&ZAPVSC); else return(&ZAPC); diff --git a/ppu.c b/ppu.c index 1616f60..0fedcac 100644 --- a/ppu.c +++ b/ppu.c @@ -36,12 +36,21 @@ uint8 SPRAM[0x100]; static uint8 SPRBUF[0x100]; -static uint8 sprlinebuf[256+8]; +uint8 sprlinebuf[256+8]; + +int32 sphitx; +uint8 sphitdata; +int spork=0; /* spork the world. Any sprites on this line? + Then this will be set to 1. Needed for zapper + emulation and *gasp* sprite emulation. + */ + + extern void BGRender(uint8 *target); -extern int tosprite; static int maxsprites=8; +static int sprlinebuf_empty=0; void FCEUI_DisableSpriteLimitation(int a) @@ -215,11 +224,12 @@ void FetchSpriteData(void) extern int FSkip; #endif -void RefreshSprite(uint8 *target) +void RefreshSprites(void) { - int n, minx=256; + int n; SPRB *spr; + spork=0; if(!nosprites) return; #ifdef FRAMESKIP if(FSkip) @@ -237,6 +247,12 @@ void RefreshSprite(uint8 *target) nosprites--; spr = (SPRB*)SPRBUF+nosprites; + if (!sprlinebuf_empty) + { + FCEU_dwmemset(sprlinebuf,0x80808080,256); + sprlinebuf_empty = 1; + } + for(n=nosprites;n>=0;n--,spr--) { register uint32 J; @@ -251,47 +267,22 @@ void RefreshSprite(uint8 *target) int x=spr->x; atr=spr->atr; - if (x < minx) - { - if (minx == 256) FCEU_dwmemset(sprlinebuf,0x80808080,256); // only clear sprite buff when we encounter first sprite - minx = x; - } - if(n==0 && SpriteBlurp && !(PPU_status&0x40)) + if(n==0 && SpriteBlurp && !(PPU_status&0x40)) { - int z,ze=x+8; - if(ze>256) {ze=256;} - if(ScreenON && (scanlineFSettings.LastSLine - #ifdef FRAMESKIP - || FSkip - #endif - )) - BGRender(target); - - if(!(atr&H_FLIP)) - { - for(z=x;z>(z-x))) - { - if(!(target[z]&64)) - tosprite=z; - } - } - } - else - { - for(z=x;z>1)&0x08) | + ((J>>3)&0x04) | + ((J>>5)&0x02) | + ((J>>7)&0x01); } + c1=((spr->ca[0]>>1)&0x55)|(spr->ca[1]&0xAA); c2=(spr->ca[0]&0x55)|((spr->ca[1]<<1)&0xAA); @@ -328,18 +319,19 @@ void RefreshSprite(uint8 *target) if (J&0x40) C[1]=VB[c2]|(J>>8); } } + sprlinebuf_empty = 0; } } nosprites=0; - #ifdef FRAMESKIP - if(FSkip) return; - #endif - if (minx == 256) return; // no visible sprites + spork=1; +} + - { +void CopySprites(uint8 *target) +{ uint8 n=((PPU[1]&4)^4)<<1; - if ((int)n < minx) n = minx & 0xfc; + //if ((int)n < minx) n = minx & 0xfc; loopskie: { uint32 t=*(uint32 *)(sprlinebuf+n); @@ -364,419 +356,12 @@ void RefreshSprite(uint8 *target) } *(uint32 *)(target+n)=tb; #else - if(!(t&0x80000000)) - { - if(!(t&0x40)) // Normal sprite - P[n]=sprlinebuf[n]; - else if(P[n]&64) // behind bg sprite - P[n]=sprlinebuf[n]; - } - - if(!(t&0x800000)) - { - if(!(t&0x4000)) // Normal sprite - P[n+1]=(sprlinebuf+1)[n]; - else if(P[n+1]&64) // behind bg sprite - P[n+1]=(sprlinebuf+1)[n]; - } - - if(!(t&0x8000)) - { - if(!(t&0x400000)) // Normal sprite - P[n+2]=(sprlinebuf+2)[n]; - else if(P[n+2]&64) // behind bg sprite - P[n+2]=(sprlinebuf+2)[n]; - } - - if(!(t&0x80)) - { - if(!(t&0x40000000)) // Normal sprite - P[n+3]=(sprlinebuf+3)[n]; - else if(P[n+3]&64) // behind bg sprite - P[n+3]=(sprlinebuf+3)[n]; - } + #error not implemented #endif } } n+=4; if(n) goto loopskie; - } -} - - - - - -/* -void FetchSpriteData(void) -{ - uint8 ns,sb; - SPR *spr; - uint8 H; - int n; - int vofs; - uint8 P0=PPU[0]; - - - spr=(SPR *)SPRAM; - H=8; - - ns=sb=0; - - vofs=(unsigned int)(P0&0x8&(((P0&0x20)^0x20)>>2))<<9; - H+=(P0&0x20)>>2; - - if(!PPU_hook) - for(n=63;n>=0;n--,spr++) - { - if((unsigned int)(scanline-spr->y)>=H) continue; - //printf("%d, %u\n",scanline,(unsigned int)(scanline-spr->y)); - if(nsy); - - if (Sprite16) - vadr = ((spr->no&1)<<12) + ((spr->no&0xFE)<<4); - else - vadr = (spr->no<<4)+vofs; - - if (spr->atr&V_FLIP) - { - vadr+=7; - vadr-=t; - vadr+=(P0&0x20)>>1; - vadr-=t&8; - } - else - { - vadr+=t; - vadr+=t&8; - } - - // Fix this geniestage hack - if(MMC5Hack && geniestage!=1) C = MMC5SPRVRAMADR(vadr); - else C = VRAMADR(vadr); - - - dst.ca[0]=C[0]; - dst.ca[1]=C[8]; - dst.x=spr->x; - dst.atr=spr->atr; - - *(uint32 *)&SPRBUF[ns<<2]=*(uint32 *)&dst; - } - - ns++; - } - else - { - PPU_status|=0x20; - break; - } - } - else - for(n=63;n>=0;n--,spr++) - { - if((unsigned int)(scanline-spr->y)>=H) continue; - - if(nsy); - - if (Sprite16) - vadr = ((spr->no&1)<<12) + ((spr->no&0xFE)<<4); - else - vadr = (spr->no<<4)+vofs; - - if (spr->atr&V_FLIP) - { - vadr+=7; - vadr-=t; - vadr+=(P0&0x20)>>1; - vadr-=t&8; - } - else - { - vadr+=t; - vadr+=t&8; - } - - if(MMC5Hack) C = MMC5SPRVRAMADR(vadr); - else C = VRAMADR(vadr); - dst.ca[0]=C[0]; - if(ns<8) - { - PPU_hook(0x2000); - PPU_hook(vadr); - } - dst.ca[1]=C[8]; - dst.x=spr->x; - dst.atr=spr->atr; - - - *(uint32 *)&SPRBUF[ns<<2]=*(uint32 *)&dst; - } - - ns++; - } - else - { - PPU_status|=0x20; - break; - } - } - //if(ns>=7) - //printf("%d %d\n",scanline,ns); - if(ns>8) PPU_status|=0x20; // Handle case when >8 sprites per -// scanline option is enabled. - else if(PPU_hook) - { - for(n=0;n<(8-ns);n++) - { - PPU_hook(0x2000); - PPU_hook(vofs); - } - } - numsprites=ns; - SpriteBlurp=sb; -} - - - -void RefreshSprite(uint8 *target) -{ - - int n,sprindex; - SPRB *spr; - uint8 *P=target; - - //if (printed) { printf("SPRB: %d SPR: %d\n", sizeof(SPRB), sizeof(SPR)); printed=0; } - if(!numsprites) return; - - FCEU_dwmemset(sprlinebuf,0x80808080,256); - - numsprites--; - sprindex=numsprites; - spr = (SPRB*)SPRBUF; - - // for(n=nosprites;n>=0;n--,spr--) - for(n=numsprites;n>=0;n--,sprindex--) - { - uint8 J,atr,c1,c2; - int x=spr[sprindex].x; - uint8 *C; - uint8 *VB; - - P+=x; - - c1=((spr[sprindex].ca[0]>>1)&0x55)|(spr[sprindex].ca[1]&0xAA); - c2=(spr[sprindex].ca[0]&0x55)|((spr[sprindex].ca[1]<<1)&0xAA); - - J=spr[sprindex].ca[0]|spr[sprindex].ca[1]; - atr=spr[sprindex].atr; - - if(J) - { - if(n==0 && SpriteBlurp && !(PPU_status&0x40)) - { - int z,ze=x+8; - if(ze>256) {ze=256;} - if(ScreenON && (scanlineFSettings.LastSLine - #ifdef FRAMESKIP - || FSkip - #endif - )) - // nothing wrong with this - BGRender(target); - - if(!(atr&H_FLIP)) - { - for(z=x;z>(z-x))) - { - if(!(target[z]&64)) - tosprite=z; - } - } - } - else - { - for(z=x;z>=2;c2>>=2; - if (J&0x08) C[3]=VB[c1&3]|0x40; - if (J&0x04) C[2]=VB[c2&3]|0x40; - c1>>=2;c2>>=2; - if (J&0x20) C[5]=VB[c1&3]|0x40; - if (J&0x10) C[4]=VB[c2&3]|0x40; - c1>>=2;c2>>=2; - if (J&0x80) C[7]=VB[c1]|0x40; - if (J&0x40) C[6]=VB[c2]|0x40; - } else { - if (J&0x02) C[6]=VB[c1&3]|0x40; - if (J&0x01) C[7]=VB[c2&3]|0x40; - c1>>=2;c2>>=2; - if (J&0x08) C[4]=VB[c1&3]|0x40; - if (J&0x04) C[5]=VB[c2&3]|0x40; - c1>>=2;c2>>=2; - if (J&0x20) C[2]=VB[c1&3]|0x40; - if (J&0x10) C[3]=VB[c2&3]|0x40; - c1>>=2;c2>>=2; - if (J&0x80) *C=VB[c1]|0x40; - if (J&0x40) C[1]=VB[c2]|0x40; - } - } else { - if (atr&H_FLIP) - { - if (J&0x02) C[1]=VB[(c1&3)]; - if (J&0x01) *C=VB[(c2&3)]; - c1>>=2;c2>>=2; - if (J&0x08) C[3]=VB[(c1&3)]; - if (J&0x04) C[2]=VB[(c2&3)]; - c1>>=2;c2>>=2; - if (J&0x20) C[5]=VB[(c1&3)]; - if (J&0x10) C[4]=VB[(c2&3)]; - c1>>=2;c2>>=2; - if (J&0x80) C[7]=VB[c1]; - if (J&0x40) C[6]=VB[c2]; - }else{ - if (J&0x02) C[6]=VB[(c1&3)]; - if (J&0x01) C[7]=VB[(c2&3)]; - c1>>=2;c2>>=2; - if (J&0x08) C[4]=VB[(c1&3)]; - if (J&0x04) C[5]=VB[(c2&3)]; - c1>>=2;c2>>=2; - if (J&0x20) C[2]=VB[(c1&3)]; - if (J&0x10) C[3]=VB[(c2&3)]; - c1>>=2;c2>>=2; - if (J&0x80) *C=VB[c1]; - if (J&0x40) C[1]=VB[c2]; - } - } - } - P-=x; - } - - numsprites=0; - #ifdef FRAMESKIP - if(FSkip) return; - #endif - - { - uint8 n=((PPU[1]&4)^4)<<1; - loopskie: - { - uint32 t=*((uint32 *)(&(sprlinebuf[n]))); - if(t!=0x80808080) - { - #ifdef LSB_FIRST - if(!(t&0x80)) - { - if(!(t&0x40)) // Normal sprite - P[n]=sprlinebuf[n]; - else if(P[n]&64) // behind bg sprite - P[n]=sprlinebuf[n]; - } - - if(!(t&0x8000)) - { - if(!(t&0x4000)) // Normal sprite - P[n+1]=(sprlinebuf+1)[n]; - else if(P[n+1]&64) // behind bg sprite - P[n+1]=(sprlinebuf+1)[n]; - } - - if(!(t&0x800000)) - { - if(!(t&0x400000)) // Normal sprite - P[n+2]=(sprlinebuf+2)[n]; - else if(P[n+2]&64) // behind bg sprite - P[n+2]=(sprlinebuf+2)[n]; - } - - if(!(t&0x80000000)) - { - if(!(t&0x40000000)) // Normal sprite - P[n+3]=(sprlinebuf+3)[n]; - else if(P[n+3]&64) // behind bg sprite - P[n+3]=(sprlinebuf+3)[n]; - } - #else - if(!(t&0x80000000)) - { - if(!(t&0x40)) // Normal sprite - P[n]=sprlinebuf[n]; - else if(P[n]&64) // behind bg sprite - P[n]=sprlinebuf[n]; - } - - if(!(t&0x800000)) - { - if(!(t&0x4000)) // Normal sprite - P[n+1]=(sprlinebuf+1)[n]; - else if(P[n+1]&64) // behind bg sprite - P[n+1]=(sprlinebuf+1)[n]; - } - - if(!(t&0x8000)) - { - if(!(t&0x400000)) // Normal sprite - P[n+2]=(sprlinebuf+2)[n]; - else if(P[n+2]&64) // behind bg sprite - P[n+2]=(sprlinebuf+2)[n]; - } - - if(!(t&0x80)) - { - if(!(t&0x40000000)) // Normal sprite - P[n+3]=(sprlinebuf+3)[n]; - else if(P[n+3]&64) // behind bg sprite - P[n+3]=(sprlinebuf+3)[n]; - } - #endif - } - } - n+=4; - if(n) goto loopskie; - } } -*/ diff --git a/ppu.h b/ppu.h index b1b30ba..c519de3 100644 --- a/ppu.h +++ b/ppu.h @@ -2,4 +2,6 @@ extern uint8 SPRAM[0x100]; //extern uint8 SPRBUF[0x100]; extern void FetchSpriteData(void); -extern void RefreshSprite(uint8 *target); +extern void RefreshSprites(void); +extern void CopySprites(uint8 *target); + diff --git a/vsuni.c b/vsuni.c index 3fb3bcd..df73fbc 100644 --- a/vsuni.c +++ b/vsuni.c @@ -376,6 +376,9 @@ void FCEU_VSUniCheck(uint64 md5partial, int *MapperNo, uint8 *Mirroring) } } +#define SCREEN_WIDTH 320 +#define SCREEN_OFFS 32 + void FCEU_VSUniDraw(uint8 *XBuf) { uint32 *dest; @@ -383,29 +386,29 @@ void FCEU_VSUniDraw(uint8 *XBuf) if(!DIPS) return; - dest=(uint32 *)(XBuf+256*12+164); - for(y=24;y;y--,dest+=(256-72)>>2) + dest=(uint32 *)(XBuf+SCREEN_WIDTH*12+164+SCREEN_OFFS); + for(y=24;y;y--,dest+=(SCREEN_WIDTH-72)>>2) { for(x=72>>2;x;x--,dest++) *dest=0; } - dest=(uint32 *)(XBuf+256*(12+4)+164+6 ); - for(y=16;y;y--,dest+=(256>>2)-16) + dest=(uint32 *)(XBuf+SCREEN_WIDTH*(12+4)+164+6+SCREEN_OFFS ); + for(y=16;y;y--,dest+=(SCREEN_WIDTH>>2)-16) for(x=8;x;x--) { *dest=0x01010101; dest+=2; } - dest=(uint32 *)(XBuf+256*(12+4)+164+6 ); + dest=(uint32 *)(XBuf+SCREEN_WIDTH*(12+4)+164+6+SCREEN_OFFS ); for(x=0;x<8;x++,dest+=2) { - uint32 *da=dest+(256>>2); + uint32 *da=dest+(SCREEN_WIDTH>>2); if(!((vsdip>>x)&1)) - da+=(256>>2)*10; - for(y=4;y;y--,da+=256>>2) + da+=(SCREEN_WIDTH>>2)*10; + for(y=4;y;y--,da+=SCREEN_WIDTH>>2) *da=0; } }