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
void flushcache(unsigned int beginning_addr, unsigned int end_addr, unsigned int flags);\r
void block_or(void *src, size_t n, int pat);\r
+void block_and(void *src, size_t n, int pat);\r
void block_andor(void *src, size_t n, int andpat, int orpat);\r
void spend_cycles(int c); // utility\r
void soft_scale(void *dst, unsigned short *pal, int offs, int lines);\r
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:
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);
#include "../../state.h"
#include "../../general.h"
+#include "../../input.h"
/* UsrInputType[] is user-specified. InputType[] is current
(game loading can override user settings)
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");
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;
}
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;
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))
}
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;
- */
}
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;
+++ /dev/null
-/* 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 <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <linux/joystick.h>
-#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<<e.number);
- else
- joybuttons[x]&=~(1<<e.number);
- }
- else if(e.type==JS_EVENT_AXIS)
- {
- if(e.number==0)
- joyx[x]=e.value;
- else if(e.number==1)
- joyy[x]=e.value;
- }
- }
-}
-
-uint32 GetJSOr(void)
-{
- int x,y;
- unsigned long ret;
- ret=0;
-
- for(x=0;x<4;x++)
- {
- int *joym=joyBMap[x];
-
- if(!joy[x]) continue;
- UpdateJoyData(x);
- for(y=0;y<4;y++)
- if(joybuttons[x]&joym[y]) ret|=(1<<y)<<(x<<3);
- if(joyx[x]<=-16383) ret|=JOY_LEFT<<(x<<3);
- else if(joyx[x]>=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<<e.number;
- goto endsa;
- }
- }
- }
- }
-
- }
- endsa:
- WNOINPUT();
-}
-
-void ConfigJoystick(int z)
-{
- int sa;
- static char *genb="** Press button for ";
-
- printf("\n\n Joystick button configuration:\n\n");
- printf(" Push the button to map to the virtual joystick.\n");
- printf(" If you do not wish to assign a button, press Enter to skip\n");
- printf(" that button.\n\n");
- printf(" Press enter to continue...\n");
- getchar();
- printf("**** Configuring joystick %d ****\n\n",z+1);
-
- sa=fcntl(fileno(stdin),F_GETFL);
- fcntl(fileno(stdin),F_SETFL,O_NONBLOCK);
-
- printf("%s\"Select\".\n",genb);
- BConfig(z,2);
-
- printf("%s\"Start\".\n",genb);
- BConfig(z,3);
-
- printf("%s\"B\".\n",genb);
- BConfig(z,1);
-
- printf("%s\"A\".\n",genb);
- BConfig(z,0);
-
- fcntl(fileno(stdin),F_SETFL,sa);
-}
-
+++ /dev/null
-extern int joy[4];
-extern int joyBMap[4][4];
-
{
SetSignals((void *)CloseStuff);
- if(InitJoysticks())
- inited|=2;
if(!InitVideo()) return 0;
inited|=4;
return 1;
// SaveConfig(NULL); // done explicitly in menu now
SetSignals(SIG_IGN);
- if(inited&2)
- KillJoysticks();
if(inited&4)
KillVideo();
if(inited&1)
\r
static bind_action_t emuctrl_actions[] =\r
{\r
- { "Save State ", 1<<31 },\r
- { "Load State ", 1<<30 },\r
- { "Next State Slot", 1<<29 },\r
+ { "Save State ", 1<<31 },\r
+ { "Load State ", 1<<30 },\r
+ { "Next State Slot ", 1<<29 },\r
+ { "Prev State Slot ", 1<<28 },\r
+ { "FDS Insert/Eject ", 1<<27 },\r
+ { "FDS Select Disk ", 1<<26 },\r
+ { "VSUni Insert Coin", 1<<25 },\r
};\r
\r
static void kc_sel_loop(void)\r
static uint8 deemp=0;
static int deempcnt[8];
-int tosprite=256;
-
FCEUGI FCEUGameInfo;
void (*GameInterface)(int h);
static int linestartts;
static int tofix=0;
-static void ResetRL(void)
+static uint8 *Plinef;
+
+extern uint8 sprlinebuf[256+8];
+extern int32 sphitx;
+extern uint8 sphitdata;
+
+extern int spork; /* spork the world. Any sprites on this line?
+ Then this will be set to 1. Needed for zapper
+ emulation and *gasp* sprite emulation.
+ */
+
+static void ResetRL(uint8 *target)
{
+ if(InputScanlineHook)
+ InputScanlineHook(0,0,0,0);
+ Plinef=target;
linestartts=timestamp*48+X6502_GetCycleCount();
tofix=1;
}
static INLINE void Fixit1(void);
-static void TryFixit1(void)
+/* faking FCEUPPU_LineUpdate() from later versions of the emu */
+static void FakedLineUpdate(void)
{
#define TOFIXNUM (272-0x4)
int lastpixel;
- if (scanline < 240 && tofix)
+ if (scanline >= 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<l;x++)
{
- Fixit1();
- tofix=0;
+ if((sphitdata&(0x80>>(x-sphitx))) && !(Plinef[x]&64))
+ {
+ PPU_status|=0x40;
+ sphitx=0x100;
+ break;
+ }
}
}
}
/* merged */
uint8 ret;
- TryFixit1();
+ FakedLineUpdate();
ret = PPU_status;
ret|=PPUGenLatch&0x1F;
vtoggle=0;
static DECLFR(A200x)
{
/* merged */
- TryFixit1();
+ FakedLineUpdate();
return PPUGenLatch;
}
uint8 ret;
uint32 tmp=RefreshAddr&0x3FFF;
- TryFixit1();
+ FakedLineUpdate();
ret=VRAMBuffer;
static DECLFW(B2000)
{
/* NMI2? */
- TryFixit1();
+ FakedLineUpdate();
PPUGenLatch=V;
PPU[0]=V;
TempAddr&=0xF3FF;
static DECLFW(B2001)
{
/* merged */
- TryFixit1();
+ FakedLineUpdate();
PPUGenLatch=V;
PPU[1]=V;
if(V&0xE0)
{
/* merged */
uint32 tmp=TempAddr;
- TryFixit1();
+ FakedLineUpdate();
PPUGenLatch=V;
if (!vtoggle)
{
static DECLFW(B2006)
{
/* merged */
- TryFixit1();
+ FakedLineUpdate();
PPUGenLatch=V;
if(!vtoggle)
#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
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)
}
-/* 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
// ===========================//
}
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(;;)
RefreshAddr=TempAddr;
if(PPU_hook) PPU_hook(RefreshAddr&0x3fff);
}
- ResetRL();
+ spork=0;
+ ResetRL(XBuf+32);
X6502_Run(16-kook);
kook ^= 1;
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++)
#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);
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};
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)
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;
}
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;
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;
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
-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
/* 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
*/
#include <string.h>
-#include <stdlib.h>
-#include "share.h"
+#include <stdlib.h>
+#include "share.h"
typedef struct {
uint32 mzx,mzb;
else
{
ret|=((FCArk.mzx>>(7-FCArk.readbit))&1)<<1;
- FCArk.readbit++;
+ if(!fceuindbg)
+ FCArk.readbit++;
}
}
else
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;
}
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);
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;
}
--- /dev/null
+/* 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 <string.h>
+#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);
+}
+
#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,
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;
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;
}
}
}
/* 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
#include <string.h>
#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;
-#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
--- /dev/null
+/* 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 <string.h>
+#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);
+}
+
--- /dev/null
+/* 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 <string.h>
+#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);
+}
--- /dev/null
+/* 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 <string.h>
+#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);
+}
--- /dev/null
+/* 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 <string.h>
+#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);
+}
/* 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
*/
#include <string.h>
-#include <stdlib.h>
-#include "share.h"
+#include <stdlib.h>
+#include "share.h"
+static char side;
static uint32 pprsb[2];
static uint32 pprdata[2];
if(pprsb[w]>=8)
ret|=0x08;
}
- pprsb[w]++;
+ if(!fceuindbg)
+ pprsb[w]++;
return ret;
}
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)<<shifttableA[x];
+ else
+ for(x=0;x<12;x++)
+ pprdata[w]|=(((*(uint32 *)data)>>x)&1)<<shifttableB[x];
}
-static INPUTC PPC={ReadPP,0,StrobePP,UpdatePP,0,0};
+static INPUTC PwrPadCtrl={ReadPP,0,StrobePP,UpdatePP,0,0};
-INPUTC *FCEU_InitPowerpad(int w)
+static INPUTC *FCEU_InitPowerpad(int w)
{
pprsb[w]=pprdata[w]=0;
- return(&PPC);
+ return(&PwrPadCtrl);
+}
+
+INPUTC *FCEU_InitPowerpadA(int w)
+{
+ side='A';
+ return(FCEU_InitPowerpad(w));
+}
+
+INPUTC *FCEU_InitPowerpadB(int w)
+{
+ side='B';
+ return(FCEU_InitPowerpad(w));
}
--- /dev/null
+/* 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 <string.h>
+#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);
+}
/* 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
*/
#include <string.h>
-#include <stdlib.h>
+#include <stdlib.h>
#include "share.h"
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<xe)
+ {
+ uint8 a1,a2;
+ uint32 sum;
+ if(xs<=(zx+4) && 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)
static void FP_FASTAPASS(2) UpdateZapper(void *data, int arg)
{
- uint32 *ptr=data;
+ uint32 *ptr=(uint32*)data;
if(ZD.bogo)
ZD.bogo--;
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)
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)
{
#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
+
--- /dev/null
+#include <string.h>
+#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);
+}
--- /dev/null
+#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
+
--- /dev/null
+/* 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 <string.h>
+#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);
+}
+
/* 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
*/
#include <string.h>
-#include <stdlib.h>
+#include <stdlib.h>
#include "share.h"
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<xe)
+ {
+ uint8 a1,a2;
+ uint32 sum;
+ if(xs<=(zx+4) && 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)
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;
}
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)))
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);
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)
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)
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;
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 && (scanline<FSettings.FirstSLine || scanline>FSettings.LastSLine
- #ifdef FRAMESKIP
- || FSkip
- #endif
- ))
- BGRender(target);
-
- if(!(atr&H_FLIP))
- {
- for(z=x;z<ze;z++)
- {
- if(J&(0x80>>(z-x)))
- {
- if(!(target[z]&64))
- tosprite=z;
- }
- }
- }
- else
- {
- for(z=x;z<ze;z++)
- {
- if(J&(1<<(z-x)))
- {
- if(!(target[z]&64))
- tosprite=z;
- }
- }
- }
- //FCEU_DispMessage("%d, %d:%d",scanline,x,tosprite);
+ sphitx=x;
+ sphitdata=J;
+ if(atr&H_FLIP)
+ sphitdata= ((J<<7)&0x80) |
+ ((J<<5)&0x40) |
+ ((J<<3)&0x20) |
+ ((J<<1)&0x10) |
+ ((J>>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);
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);
}
*(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(ns<maxsprites)
- {
- if(n==63) sb=1;
-
- {
- SPRB dst;
- uint8 *C;
- int t;
- unsigned int vadr;
-
- t = (int)scanline-(spr->y);
-
- 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(ns<maxsprites)
- {
- if(n==63) sb=1;
-
- {
- SPRB dst;
- uint8 *C;
- int t;
- unsigned int vadr;
-
- t = (int)scanline-(spr->y);
-
- 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 && (scanline<FSettings.FirstSLine || scanline>FSettings.LastSLine
- #ifdef FRAMESKIP
- || FSkip
- #endif
- ))
- // nothing wrong with this
- BGRender(target);
-
- if(!(atr&H_FLIP))
- {
- for(z=x;z<ze;z++)
- {
- if(J&(0x80>>(z-x)))
- {
- if(!(target[z]&64))
- tosprite=z;
- }
- }
- }
- else
- {
- for(z=x;z<ze;z++)
- {
- if(J&(1<<(z-x)))
- {
- if(!(target[z]&64))
- tosprite=z;
- }
- }
- }
- //FCEU_DispMessage("%d, %d:%d",scanline,x,tosprite);
- }
-
- //C = sprlinebuf+(uint8)x;
- C = &(sprlinebuf[(uint8)x]);
- VB = (PALRAM+0x10)+((atr&3)<<2);
-
- if(atr&SP_BACK)
- {
- if (atr&H_FLIP)
- {
- if (J&0x02) C[1]=VB[c1&3]|0x40;
- if (J&0x01) *C=VB[c2&3]|0x40;
- c1>>=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;
- }
}
-*/
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);
+
}\r
}\r
\r
+#define SCREEN_WIDTH 320\r
+#define SCREEN_OFFS 32\r
+\r
void FCEU_VSUniDraw(uint8 *XBuf)\r
{\r
uint32 *dest;\r
\r
if(!DIPS) return;\r
\r
- dest=(uint32 *)(XBuf+256*12+164);\r
- for(y=24;y;y--,dest+=(256-72)>>2)\r
+ dest=(uint32 *)(XBuf+SCREEN_WIDTH*12+164+SCREEN_OFFS);\r
+ for(y=24;y;y--,dest+=(SCREEN_WIDTH-72)>>2)\r
{\r
for(x=72>>2;x;x--,dest++)\r
*dest=0;\r
}\r
\r
- dest=(uint32 *)(XBuf+256*(12+4)+164+6 );\r
- for(y=16;y;y--,dest+=(256>>2)-16)\r
+ dest=(uint32 *)(XBuf+SCREEN_WIDTH*(12+4)+164+6+SCREEN_OFFS );\r
+ for(y=16;y;y--,dest+=(SCREEN_WIDTH>>2)-16)\r
for(x=8;x;x--)\r
{\r
*dest=0x01010101;\r
dest+=2;\r
}\r
\r
- dest=(uint32 *)(XBuf+256*(12+4)+164+6 );\r
+ dest=(uint32 *)(XBuf+SCREEN_WIDTH*(12+4)+164+6+SCREEN_OFFS );\r
for(x=0;x<8;x++,dest+=2)\r
{\r
- uint32 *da=dest+(256>>2);\r
+ uint32 *da=dest+(SCREEN_WIDTH>>2);\r
\r
if(!((vsdip>>x)&1))\r
- da+=(256>>2)*10;\r
- for(y=4;y;y--,da+=256>>2)\r
+ da+=(SCREEN_WIDTH>>2)*10;\r
+ for(y=4;y;y--,da+=SCREEN_WIDTH>>2)\r
*da=0;\r
}\r
}\r