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:
parent
47785d2015
commit
c6c4871020
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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())
|
||||||
|
|
Loading…
Reference in New Issue