Implemented a more efficient frameskip support, skipping frames at GPU level, which is loads faster.

It only works for Windows port atm, to make it work in the other ports :
call NDS_SkipFrame with param : true = skip the current frame, false = render the current frame.
This commit is contained in:
luigi__ 2009-01-21 22:35:46 +00:00
parent 47785d2015
commit c6c4871020
3 changed files with 287 additions and 270 deletions

View File

@ -1010,6 +1010,10 @@ int NDS_LoadFirmware(const char *filename)
return i; return i;
} }
bool skipThisFrame = false;
void NDS_SkipFrame(bool skip) { skipThisFrame = skip; }
#define INDEX(i) ((((i)>>16)&0xFF0)|(((i)>>4)&0xF)) #define INDEX(i) ((((i)>>16)&0xFF0)|(((i)>>4)&0xF))
@ -1115,8 +1119,11 @@ u32 NDS_exec(s32 nb)
if(nds.VCount<192) if(nds.VCount<192)
{ {
GPU_ligne(&MainScreen, nds.VCount); if(!skipThisFrame)
GPU_ligne(&SubScreen, nds.VCount); {
GPU_ligne(&MainScreen, nds.VCount);
GPU_ligne(&SubScreen, nds.VCount);
}
if(MMU.DMAStartTime[0][0] == 2) if(MMU.DMAStartTime[0][0] == 2)
MMU_doDMA<ARMCPU_ARM9>(0); MMU_doDMA<ARMCPU_ARM9>(0);
@ -1226,7 +1233,8 @@ u32 NDS_exec(s32 nb)
if(MMU.DMAStartTime[1][3] == 1) if(MMU.DMAStartTime[1][3] == 1)
MMU_doDMA<ARMCPU_ARM7>(3); MMU_doDMA<ARMCPU_ARM7>(3);
} }
else if(nds.VCount==215) { else if(nds.VCount==215)
{
gfx3d_VBlankEndSignal(); gfx3d_VBlankEndSignal();
} }
else if(nds.VCount==263) else if(nds.VCount==263)

View File

@ -1,266 +1,268 @@
/* Copyright (C) 2006 yopyop /* Copyright (C) 2006 yopyop
yopyop156@ifrance.com yopyop156@ifrance.com
yopyop156.ifrance.com yopyop156.ifrance.com
This file is part of DeSmuME This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
DeSmuME is distributed in the hope that it will be useful, DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#ifndef NDSSYSTEM_H #ifndef NDSSYSTEM_H
#define NDSSYSTEM_H #define NDSSYSTEM_H
#include "armcpu.h" #include "armcpu.h"
#include "MMU.h" #include "MMU.h"
#include "GPU.h" #include "GPU.h"
#include "SPU.h" #include "SPU.h"
#include "mem.h" #include "mem.h"
#include "wifi.h" #include "wifi.h"
extern volatile BOOL execute; extern volatile BOOL execute;
extern BOOL click; extern BOOL click;
extern char pathToROM[MAX_PATH]; extern char pathToROM[MAX_PATH];
extern char pathFilenameToROMwithoutExt[MAX_PATH]; extern char pathFilenameToROMwithoutExt[MAX_PATH];
/* /*
* The firmware language values * The firmware language values
*/ */
#define NDS_FW_LANG_JAP 0 #define NDS_FW_LANG_JAP 0
#define NDS_FW_LANG_ENG 1 #define NDS_FW_LANG_ENG 1
#define NDS_FW_LANG_FRE 2 #define NDS_FW_LANG_FRE 2
#define NDS_FW_LANG_GER 3 #define NDS_FW_LANG_GER 3
#define NDS_FW_LANG_ITA 4 #define NDS_FW_LANG_ITA 4
#define NDS_FW_LANG_SPA 5 #define NDS_FW_LANG_SPA 5
#define NDS_FW_LANG_CHI 6 #define NDS_FW_LANG_CHI 6
#define NDS_FW_LANG_RES 7 #define NDS_FW_LANG_RES 7
//#define LOG_ARM9 //#define LOG_ARM9
//#define LOG_ARM7 //#define LOG_ARM7
typedef struct typedef struct
{ {
char gameTile[12]; char gameTile[12];
char gameCode[4]; char gameCode[4];
u16 makerCode; u16 makerCode;
u8 unitCode; u8 unitCode;
u8 deviceCode; u8 deviceCode;
u8 cardSize; u8 cardSize;
u8 cardInfo[8]; u8 cardInfo[8];
u8 flags; u8 flags;
u32 ARM9src; u32 ARM9src;
u32 ARM9exe; u32 ARM9exe;
u32 ARM9cpy; u32 ARM9cpy;
u32 ARM9binSize; u32 ARM9binSize;
u32 ARM7src; u32 ARM7src;
u32 ARM7exe; u32 ARM7exe;
u32 ARM7cpy; u32 ARM7cpy;
u32 ARM7binSize; u32 ARM7binSize;
u32 FNameTblOff; u32 FNameTblOff;
u32 FNameTblSize; u32 FNameTblSize;
u32 FATOff; u32 FATOff;
u32 FATSize; u32 FATSize;
u32 ARM9OverlayOff; u32 ARM9OverlayOff;
u32 ARM9OverlaySize; u32 ARM9OverlaySize;
u32 ARM7OverlayOff; u32 ARM7OverlayOff;
u32 ARM7OverlaySize; u32 ARM7OverlaySize;
u32 unknown2a; u32 unknown2a;
u32 unknown2b; u32 unknown2b;
u32 IconOff; u32 IconOff;
u16 CRC16; u16 CRC16;
u16 ROMtimeout; u16 ROMtimeout;
u32 ARM9unk; u32 ARM9unk;
u32 ARM7unk; u32 ARM7unk;
u8 unknown3c[8]; u8 unknown3c[8];
u32 ROMSize; u32 ROMSize;
u32 HeaderSize; u32 HeaderSize;
u8 unknown5[56]; u8 unknown5[56];
u8 logo[156]; u8 logo[156];
u16 logoCRC16; u16 logoCRC16;
u16 headerCRC16; u16 headerCRC16;
u8 reserved[160]; u8 reserved[160];
} NDS_header; } NDS_header;
extern void debug(); extern void debug();
void emu_halt(); void emu_halt();
typedef struct typedef struct
{ {
s32 ARM9Cycle; s32 ARM9Cycle;
s32 ARM7Cycle; s32 ARM7Cycle;
s32 cycles; s32 cycles;
s32 timerCycle[2][4]; s32 timerCycle[2][4];
BOOL timerOver[2][4]; BOOL timerOver[2][4];
s32 nextHBlank; s32 nextHBlank;
u32 VCount; u32 VCount;
u32 old; u32 old;
s32 diff; s32 diff;
BOOL lignerendu; BOOL lignerendu;
u16 touchX; u16 touchX;
u16 touchY; u16 touchY;
BOOL isTouch; BOOL isTouch;
u16 pad; u16 pad;
//this is not essential NDS runtime state. //this is not essential NDS runtime state.
//it was perhaps a mistake to put it here. //it was perhaps a mistake to put it here.
//it is far less important than the above. //it is far less important than the above.
//maybe I should move it. //maybe I should move it.
s32 idleCycles; s32 idleCycles;
s32 runCycleCollector[16]; s32 runCycleCollector[16];
s32 idleFrameCounter; s32 idleFrameCounter;
} NDSSystem; } NDSSystem;
/** /brief A touchscreen calibration point. /** /brief A touchscreen calibration point.
*/ */
struct NDS_fw_touchscreen_cal { struct NDS_fw_touchscreen_cal {
u16 adc_x; u16 adc_x;
u16 adc_y; u16 adc_y;
u8 screen_x; u8 screen_x;
u8 screen_y; u8 screen_y;
}; };
/** /brief The type of DS /** /brief The type of DS
*/ */
enum nds_fw_ds_type { enum nds_fw_ds_type {
NDS_FW_DS_TYPE_FAT, NDS_FW_DS_TYPE_FAT,
NDS_FW_DS_TYPE_LITE, NDS_FW_DS_TYPE_LITE,
NDS_FW_DS_TYPE_iQue NDS_FW_DS_TYPE_iQue
}; };
#define MAX_FW_NICKNAME_LENGTH 10 #define MAX_FW_NICKNAME_LENGTH 10
#define MAX_FW_MESSAGE_LENGTH 26 #define MAX_FW_MESSAGE_LENGTH 26
struct NDS_fw_config_data { struct NDS_fw_config_data {
enum nds_fw_ds_type ds_type; enum nds_fw_ds_type ds_type;
u8 fav_colour; u8 fav_colour;
u8 birth_month; u8 birth_month;
u8 birth_day; u8 birth_day;
u16 nickname[MAX_FW_NICKNAME_LENGTH]; u16 nickname[MAX_FW_NICKNAME_LENGTH];
u8 nickname_len; u8 nickname_len;
u16 message[MAX_FW_MESSAGE_LENGTH]; u16 message[MAX_FW_MESSAGE_LENGTH];
u8 message_len; u8 message_len;
u8 language; u8 language;
/* touchscreen calibration */ /* touchscreen calibration */
struct NDS_fw_touchscreen_cal touch_cal[2]; struct NDS_fw_touchscreen_cal touch_cal[2];
}; };
extern NDSSystem nds; extern NDSSystem nds;
#ifdef GDB_STUB #ifdef GDB_STUB
int NDS_Init( struct armcpu_memory_iface *arm9_mem_if, int NDS_Init( struct armcpu_memory_iface *arm9_mem_if,
struct armcpu_ctrl_iface **arm9_ctrl_iface, struct armcpu_ctrl_iface **arm9_ctrl_iface,
struct armcpu_memory_iface *arm7_mem_if, struct armcpu_memory_iface *arm7_mem_if,
struct armcpu_ctrl_iface **arm7_ctrl_iface); struct armcpu_ctrl_iface **arm7_ctrl_iface);
#else #else
int NDS_Init ( void); int NDS_Init ( void);
#endif #endif
void NDS_DeInit(void); void NDS_DeInit(void);
void void
NDS_FillDefaultFirmwareConfigData( struct NDS_fw_config_data *fw_config); NDS_FillDefaultFirmwareConfigData( struct NDS_fw_config_data *fw_config);
BOOL NDS_SetROM(u8 * rom, u32 mask); BOOL NDS_SetROM(u8 * rom, u32 mask);
NDS_header * NDS_getROMHeader(void); NDS_header * NDS_getROMHeader(void);
void NDS_setTouchPos(u16 x, u16 y); void NDS_setTouchPos(u16 x, u16 y);
void NDS_releaseTouch(void); void NDS_releaseTouch(void);
void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,bool X,bool W,bool E,bool G, bool F); void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,bool X,bool W,bool E,bool G, bool F);
void NDS_setPadFromMovie(u16 pad); void NDS_setPadFromMovie(u16 pad);
#ifdef EXPERIMENTAL_GBASLOT #ifdef EXPERIMENTAL_GBASLOT
int NDS_LoadROM(const char *filename, int bmtype, u32 bmsize); int NDS_LoadROM(const char *filename, int bmtype, u32 bmsize);
#else #else
int NDS_LoadROM(const char *filename, int bmtype, u32 bmsize, int NDS_LoadROM(const char *filename, int bmtype, u32 bmsize,
const char *cflash_disk_image_file); const char *cflash_disk_image_file);
#endif #endif
void NDS_FreeROM(void); void NDS_FreeROM(void);
void NDS_Reset(void); void NDS_Reset(void);
int NDS_ImportSave(const char *filename); int NDS_ImportSave(const char *filename);
int NDS_WriteBMP(const char *filename); int NDS_WriteBMP(const char *filename);
int NDS_LoadFirmware(const char *filename); int NDS_LoadFirmware(const char *filename);
int NDS_CreateDummyFirmware( struct NDS_fw_config_data *user_settings); int NDS_CreateDummyFirmware( struct NDS_fw_config_data *user_settings);
template<bool FORCE> void NDS_SkipFrame(bool skip);
u32 NDS_exec(s32 nb);
template<bool FORCE>
inline u32 NDS_exec(s32 nb) { return NDS_exec<false>(nb); } u32 NDS_exec(s32 nb);
static INLINE void NDS_ARM9HBlankInt(void) inline u32 NDS_exec(s32 nb) { return NDS_exec<false>(nb); }
{
if(T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0x10) static INLINE void NDS_ARM9HBlankInt(void)
{ {
MMU.reg_IF[0] |= 2;// & (MMU.reg_IME[0] << 1);// (MMU.reg_IE[0] & (1<<1)); if(T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0x10)
NDS_ARM9.wIRQ = TRUE; {
} MMU.reg_IF[0] |= 2;// & (MMU.reg_IME[0] << 1);// (MMU.reg_IE[0] & (1<<1));
} NDS_ARM9.wIRQ = TRUE;
}
static INLINE void NDS_ARM7HBlankInt(void) }
{
if(T1ReadWord(MMU.ARM7_REG, 4) & 0x10) static INLINE void NDS_ARM7HBlankInt(void)
{ {
MMU.reg_IF[1] |= 2;// & (MMU.reg_IME[1] << 1);// (MMU.reg_IE[1] & (1<<1)); if(T1ReadWord(MMU.ARM7_REG, 4) & 0x10)
NDS_ARM7.wIRQ = TRUE; {
} MMU.reg_IF[1] |= 2;// & (MMU.reg_IME[1] << 1);// (MMU.reg_IE[1] & (1<<1));
} NDS_ARM7.wIRQ = TRUE;
}
static INLINE void NDS_ARM9VBlankInt(void) }
{
if(T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0x8) static INLINE void NDS_ARM9VBlankInt(void)
{ {
MMU.reg_IF[0] |= 1;// & (MMU.reg_IME[0]);// (MMU.reg_IE[0] & 1); if(T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0x8)
NDS_ARM9.wIRQ = TRUE; {
//emu_halt(); MMU.reg_IF[0] |= 1;// & (MMU.reg_IME[0]);// (MMU.reg_IE[0] & 1);
/*logcount++;*/ NDS_ARM9.wIRQ = TRUE;
} //emu_halt();
} /*logcount++;*/
}
static INLINE void NDS_ARM7VBlankInt(void) }
{
if(T1ReadWord(MMU.ARM7_REG, 4) & 0x8) static INLINE void NDS_ARM7VBlankInt(void)
MMU.reg_IF[1] |= 1;// & (MMU.reg_IME[1]);// (MMU.reg_IE[1] & 1); {
NDS_ARM7.wIRQ = TRUE; if(T1ReadWord(MMU.ARM7_REG, 4) & 0x8)
//emu_halt(); MMU.reg_IF[1] |= 1;// & (MMU.reg_IME[1]);// (MMU.reg_IE[1] & 1);
} NDS_ARM7.wIRQ = TRUE;
//emu_halt();
static INLINE void NDS_swapScreen(void) }
{
u16 tmp = MainScreen.offset; static INLINE void NDS_swapScreen(void)
MainScreen.offset = SubScreen.offset; {
SubScreen.offset = tmp; u16 tmp = MainScreen.offset;
} MainScreen.offset = SubScreen.offset;
SubScreen.offset = tmp;
int NDS_WriteBMP_32bppBuffer(int width, int height, const void* buf, const char *filename); }
#endif int NDS_WriteBMP_32bppBuffer(int width, int height, const void* buf, const char *filename);
#endif

View File

@ -971,8 +971,8 @@ DWORD WINAPI run()
DRV_AviSoundUpdate(SPU_core->outbuf,spu_core_samples); DRV_AviSoundUpdate(SPU_core->outbuf,spu_core_samples);
DRV_AviVideoUpdate((u16*)GPU_screen); DRV_AviVideoUpdate((u16*)GPU_screen);
if (!skipnextframe) // if (!skipnextframe)
{ // {
input->process(); input->process();
if (FpsDisplay) osd->addFixed(0, 5, "%02d Fps", fps); if (FpsDisplay) osd->addFixed(0, 5, "%02d Fps", fps);
@ -1002,10 +1002,15 @@ DWORD WINAPI run()
SetWindowText(hwnd, txt); SetWindowText(hwnd, txt);
} }
if(!skipnextframe)
{
framesskipped = 0; framesskipped = 0;
if (framestoskip > 0) if (framestoskip > 0)
skipnextframe = 1; skipnextframe = 1;
NDS_SkipFrame(false);
} }
else else
{ {
@ -1017,6 +1022,8 @@ DWORD WINAPI run()
skipnextframe = 1; skipnextframe = 1;
framesskipped++; framesskipped++;
NDS_SkipFrame(true);
} }
while(SpeedThrottle()) while(SpeedThrottle())