Major code cleanup across the board, mostly involving interactions with EMUFILE.

- Function/method parameters for EMUFILE objects are now passed by
reference instead of passed by pointers, where appropriate. This is
true for the vast majority of EMUFILE usage.
- Eliminate duplicate little-endian read/write functions in
readwrite.cpp. Use the equivalent methods in EMUFILE instead.
- Completely standardize the design patterns and usage of the various
little-endian read/write methods. Should help stabilize interactions
with save state files, as well as try to make save states
cross-compatible between big-endian and little-endian systems.
- Replace EMUFILE fread()/fwrite()/fputc() calls with equivalent
size-specific methods where applicable.
- Misc. code readability and stability improvements.
This commit is contained in:
rogerman 2017-08-24 15:14:25 -07:00
parent e17e1bd0af
commit 11cf901336
70 changed files with 1834 additions and 1694 deletions

View File

@ -469,28 +469,28 @@ FORCEINLINE void rot_BMP_map(const s32 auxX, const s32 auxY, const int lg, const
outIndex = ((outColor & 0x8000) == 0) ? 0 : 1;
}
void gpu_savestate(EMUFILE* os)
void gpu_savestate(EMUFILE &os)
{
const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo();
const GPUEngineA *mainEngine = GPU->GetEngineMain();
const GPUEngineB *subEngine = GPU->GetEngineSub();
//version
write32le(1,os);
os.write_32LE(1);
os->fwrite((u8 *)dispInfo.masterCustomBuffer, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(u16) * 2);
os.fwrite((u8 *)dispInfo.masterCustomBuffer, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(u16) * 2);
write32le(mainEngine->savedBG2X.value, os);
write32le(mainEngine->savedBG2Y.value, os);
write32le(mainEngine->savedBG3X.value, os);
write32le(mainEngine->savedBG3Y.value, os);
write32le(subEngine->savedBG2X.value, os);
write32le(subEngine->savedBG2Y.value, os);
write32le(subEngine->savedBG3X.value, os);
write32le(subEngine->savedBG3Y.value, os);
os.write_32LE(mainEngine->savedBG2X.value);
os.write_32LE(mainEngine->savedBG2Y.value);
os.write_32LE(mainEngine->savedBG3X.value);
os.write_32LE(mainEngine->savedBG3Y.value);
os.write_32LE(subEngine->savedBG2X.value);
os.write_32LE(subEngine->savedBG2Y.value);
os.write_32LE(subEngine->savedBG3X.value);
os.write_32LE(subEngine->savedBG3Y.value);
}
bool gpu_loadstate(EMUFILE* is, int size)
bool gpu_loadstate(EMUFILE &is, int size)
{
const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo();
GPUEngineA *mainEngine = GPU->GetEngineMain();
@ -506,28 +506,28 @@ bool gpu_loadstate(EMUFILE* is, int size)
}
else if (size == 0x30024)
{
read32le(&version,is);
is.read_32LE(version);
version = 1;
}
else
{
if(read32le(&version,is) != 1) return false;
if (is.read_32LE(version) != 1) return false;
}
if (version > 1) return false;
is->fread((u8 *)dispInfo.masterCustomBuffer, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(u16) * 2);
is.fread((u8 *)dispInfo.masterCustomBuffer, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(u16) * 2);
if (version == 1)
{
read32le((u32 *)&mainEngine->savedBG2X, is);
read32le((u32 *)&mainEngine->savedBG2Y, is);
read32le((u32 *)&mainEngine->savedBG3X, is);
read32le((u32 *)&mainEngine->savedBG3Y, is);
read32le((u32 *)&subEngine->savedBG2X, is);
read32le((u32 *)&subEngine->savedBG2Y, is);
read32le((u32 *)&subEngine->savedBG3X, is);
read32le((u32 *)&subEngine->savedBG3Y, is);
is.read_32LE(mainEngine->savedBG2X.value);
is.read_32LE(mainEngine->savedBG2Y.value);
is.read_32LE(mainEngine->savedBG3X.value);
is.read_32LE(mainEngine->savedBG3Y.value);
is.read_32LE(subEngine->savedBG2X.value);
is.read_32LE(subEngine->savedBG2Y.value);
is.read_32LE(subEngine->savedBG3X.value);
is.read_32LE(subEngine->savedBG3Y.value);
//removed per nitsuja feedback. anyway, this same thing will happen almost immediately in gpu line=0
//mainEngine->refreshAffineStartRegs(-1,-1);
//subEngine->refreshAffineStartRegs(-1,-1);
@ -536,7 +536,7 @@ bool gpu_loadstate(EMUFILE* is, int size)
mainEngine->ParseAllRegisters();
subEngine->ParseAllRegisters();
return !is->fail();
return !is.fail();
}
/*****************************************************************************/
@ -4877,7 +4877,6 @@ void GPUEngineBase::_PerformWindowTesting(GPUEngineCompositorInfo &compInfo)
__m128i win0HandledMask = _mm_setzero_si128();
__m128i win1HandledMask = _mm_setzero_si128();
__m128i winOBJHandledMask = _mm_setzero_si128();
__m128i winOUTHandledMask = _mm_setzero_si128();
// Window 0 has the highest priority, so always check this first.
if (compInfo.renderState.WIN0_ENABLED && this->_IsWindowInsideVerticalRange<0>(compInfo))
@ -4911,7 +4910,7 @@ void GPUEngineBase::_PerformWindowTesting(GPUEngineCompositorInfo &compInfo)
// If the pixel isn't inside any windows, then the pixel is outside, and therefore uses the WINOUT flags.
// This has the lowest priority, and is always checked last.
winOUTHandledMask = _mm_xor_si128( _mm_or_si128(win0HandledMask, _mm_or_si128(win1HandledMask, winOBJHandledMask)), _mm_set1_epi32(0xFFFFFFFF) );
const __m128i winOUTHandledMask = _mm_xor_si128( _mm_or_si128(win0HandledMask, _mm_or_si128(win1HandledMask, winOBJHandledMask)), _mm_set1_epi32(0xFFFFFFFF) );
didPassWindowTest = _mm_or_si128( didPassWindowTest, _mm_and_si128(winOUTHandledMask, compInfo.renderState.WINOUT_enable_SSE2[layerID]) );
enableColorEffect = _mm_or_si128( enableColorEffect, _mm_and_si128(winOUTHandledMask, compInfo.renderState.WINOUT_enable_SSE2[WINDOWCONTROL_EFFECTFLAG]) );

View File

@ -68,8 +68,8 @@ struct MMU_struct;
#define GPU_VRAM_BLOCK_LINES 256
#define GPU_VRAM_BLANK_REGION_LINES 544
void gpu_savestate(EMUFILE* os);
bool gpu_loadstate(EMUFILE* is, int size);
void gpu_savestate(EMUFILE &os);
bool gpu_loadstate(EMUFILE &is, int size);
typedef void (*PixelLookupFunc)(const s32 auxX, const s32 auxY, const int lg, const u32 map, const u32 tile, const u16 *__restrict pal, u8 &outIndex, u16 &outColor);

View File

@ -46,6 +46,7 @@
#include "encrypt.h"
#include "GPU.h"
#include "SPU.h"
#include "emufile.h"
#ifdef DO_ASSERT_UNALIGNED
#define ASSERT_UNALIGNED(x) assert(x)
@ -1216,32 +1217,32 @@ u16 DSI_TSC::read16()
return 0xFF;
}
bool DSI_TSC::save_state(EMUFILE* os)
bool DSI_TSC::save_state(EMUFILE &os)
{
u32 version = 0;
write32le(version,os);
os.write_32LE(version);
write8le(reg_selection,os);
write8le(read_flag,os);
write32le(state,os);
write32le(readcount,os);
for(int i=0;i<ARRAY_SIZE(registers);i++)
write8le(registers[i],os);
os.write_u8(reg_selection);
os.write_u8(read_flag);
os.write_32LE(state);
os.write_32LE(readcount);
for (int i = 0; i < ARRAY_SIZE(registers); i++)
os.write_u8(registers[i]);
return true;
}
bool DSI_TSC::load_state(EMUFILE* is)
bool DSI_TSC::load_state(EMUFILE &is)
{
u32 version;
read32le(&version,is);
is.read_32LE(version);
read8le(&reg_selection,is);
read8le(&read_flag,is);
read32le(&state,is);
read32le(&readcount,is);
for(int i=0;i<ARRAY_SIZE(registers);i++)
read8le(&registers[i],is);
is.read_u8(reg_selection);
is.read_u8(read_flag);
is.read_32LE(state);
is.read_32LE(readcount);
for (int i = 0; i < ARRAY_SIZE(registers); i++)
is.read_u8(registers[i]);
return true;
}
@ -1982,20 +1983,21 @@ void TGXSTAT::write32(const u32 val)
//}
}
void TGXSTAT::savestate(EMUFILE *f)
void TGXSTAT::savestate(EMUFILE &f)
{
write32le(1,f); //version
write8le(tb,f); write8le(tr,f); write8le(se,f); write8le(gxfifo_irq,f); write8le(sb,f);
f.write_32LE(1); //version
f.write_u8(tb); f.write_u8(tr); f.write_u8(se); f.write_u8(gxfifo_irq); f.write_u8(sb);
}
bool TGXSTAT::loadstate(EMUFILE *f)
bool TGXSTAT::loadstate(EMUFILE &f)
{
u32 version;
if(read32le(&version,f) != 1) return false;
if(version > 1) return false;
if (f.read_32LE(version) != 1) return false;
if (version > 1) return false;
read8le(&tb,f); read8le(&tr,f); read8le(&se,f); read8le(&gxfifo_irq,f);
f.read_u8(tb); f.read_u8(tr); f.read_u8(se); f.read_u8(gxfifo_irq);
if (version >= 1)
read8le(&sb,f);
f.read_u8(sb);
return true;
}
@ -2039,78 +2041,78 @@ MMU_struct_new::MMU_struct_new()
}
}
void DivController::savestate(EMUFILE* os)
void DivController::savestate(EMUFILE &os)
{
write8le(&mode,os);
write8le(&busy,os);
write8le(&div0,os);
os.write_u8(mode);
os.write_u8(busy);
os.write_u8(div0);
}
bool DivController::loadstate(EMUFILE* is, int version)
bool DivController::loadstate(EMUFILE &is, int version)
{
int ret = 1;
ret &= read8le(&mode,is);
ret &= read8le(&busy,is);
ret &= read8le(&div0,is);
ret &= is.read_u8(mode);
ret &= is.read_u8(busy);
ret &= is.read_u8(div0);
return ret==1;
}
void SqrtController::savestate(EMUFILE* os)
void SqrtController::savestate(EMUFILE &os)
{
write8le(&mode,os);
write8le(&busy,os);
os.write_u8(mode);
os.write_u8(busy);
}
bool SqrtController::loadstate(EMUFILE* is, int version)
bool SqrtController::loadstate(EMUFILE &is, int version)
{
int ret=1;
ret &= read8le(&mode,is);
ret &= read8le(&busy,is);
ret &= is.read_u8(mode);
ret &= is.read_u8(busy);
return ret==1;
}
bool DmaController::loadstate(EMUFILE* f)
bool DmaController::loadstate(EMUFILE &f)
{
u32 version;
if(read32le(&version,f) != 1) return false;
if(version >1) return false;
if (f.read_32LE(version) != 1) return false;
if (version > 1) return false;
read8le(&enable,f); read8le(&irq,f); read8le(&repeatMode,f); read8le(&_startmode,f);
read8le(&userEnable,f);
read32le(&wordcount,f);
f.read_u8(enable); f.read_u8(irq); f.read_u8(repeatMode); f.read_u8(_startmode);
f.read_u8(userEnable);
f.read_32LE(wordcount);
u8 temp;
read8le(&temp,f); startmode = (EDMAMode)temp;
read8le(&temp,f); bitWidth = (EDMABitWidth)temp;
read8le(&temp,f); sar = (EDMASourceUpdate)temp;
read8le(&temp,f); dar = (EDMADestinationUpdate)temp;
read32le(&saddr,f); read32le(&daddr,f);
read32le(&dmaCheck,f); read32le(&running,f); read32le(&paused,f); read32le(&triggered,f);
read64le(&nextEvent,f);
f.read_u8(temp); startmode = (EDMAMode)temp;
f.read_u8(temp); bitWidth = (EDMABitWidth)temp;
f.read_u8(temp); sar = (EDMASourceUpdate)temp;
f.read_u8(temp); dar = (EDMADestinationUpdate)temp;
f.read_32LE(saddr); f.read_32LE(daddr);
f.read_32LE(dmaCheck); f.read_32LE(running); f.read_32LE(paused); f.read_32LE(triggered);
f.read_64LE(nextEvent);
if(version==1)
if (version == 1)
{
read32le(&saddr_user,f);
read32le(&daddr_user,f);
f.read_32LE(saddr_user);
f.read_32LE(daddr_user);
}
return true;
}
void DmaController::savestate(EMUFILE *f)
void DmaController::savestate(EMUFILE &f)
{
write32le(1,f); //version
write8le(enable,f); write8le(irq,f); write8le(repeatMode,f); write8le(_startmode,f);
write8le(userEnable,f);
write32le(wordcount,f);
write8le(startmode,f);
write8le(bitWidth,f);
write8le(sar,f);
write8le(dar,f);
write32le(saddr,f); write32le(daddr,f);
write32le(dmaCheck,f); write32le(running,f); write32le(paused,f); write32le(triggered,f);
write64le(nextEvent,f);
write32le(saddr_user,f);
write32le(daddr_user,f);
f.write_32LE(1); //version
f.write_u8(enable); f.write_u8(irq); f.write_u8(repeatMode); f.write_u8(_startmode);
f.write_u8(userEnable);
f.write_32LE(wordcount);
f.write_u8(startmode);
f.write_u8(bitWidth);
f.write_u8(sar);
f.write_u8(dar);
f.write_32LE(saddr); f.write_32LE(daddr);
f.write_32LE(dmaCheck); f.write_32LE(running); f.write_32LE(paused); f.write_32LE(triggered);
f.write_64LE(nextEvent);
f.write_32LE(saddr_user);
f.write_32LE(daddr_user);
}
void DmaController::write32(const u32 val)

View File

@ -1,7 +1,7 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2007 shash
Copyright (C) 2007-2015 DeSmuME team
Copyright (C) 2007-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -130,8 +130,8 @@ struct TGXSTAT : public TRegister_32
virtual u32 read32();
virtual void write32(const u32 val);
void savestate(EMUFILE *f);
bool loadstate(EMUFILE *f);
void savestate(EMUFILE &f);
bool loadstate(EMUFILE &f);
};
void triggerDma(EDMAMode mode);
@ -149,8 +149,8 @@ public:
mode = val&3;
//todo - do we clear the div0 flag here or is that strictly done by the divider unit?
}
void savestate(EMUFILE* os);
bool loadstate(EMUFILE* is, int version);
void savestate(EMUFILE &os);
bool loadstate(EMUFILE &is, int version);
};
class SqrtController
@ -163,8 +163,8 @@ public:
u8 mode, busy;
u16 read16() { return mode|(busy<<15); }
void write16(u16 val) { mode = val&1; }
void savestate(EMUFILE* os);
bool loadstate(EMUFILE* is, int version);
void savestate(EMUFILE &os);
bool loadstate(EMUFILE &is, int version);
};
@ -198,8 +198,8 @@ public:
int procnum, chan;
void savestate(EMUFILE *f);
bool loadstate(EMUFILE *f);
void savestate(EMUFILE &f);
bool loadstate(EMUFILE &f);
void exec();
template<int PROCNUM> void doCopy();
@ -468,8 +468,8 @@ public:
DSI_TSC();
void reset_command();
u16 write16(u16 val);
bool save_state(EMUFILE* os);
bool load_state(EMUFILE* is);
bool save_state(EMUFILE &os);
bool load_state(EMUFILE &is);
private:
u16 read16();

View File

@ -1,7 +1,7 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2007 shash
Copyright (C) 2007-2011 DeSmuME team
Copyright (C) 2007-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -28,6 +28,7 @@
#include "readwrite.h"
#include "debug.h"
#include "NDSSystem.h"
#include "emufile.h"
////////////////////////////////////////////////////////////////
// MEMORY TIMING ACCURACY CONFIGURATION
@ -104,24 +105,24 @@ public:
Reset();
}
void savestate(EMUFILE* os, int version)
void savestate(EMUFILE &os, int version)
{
write32le(m_cacheCache, os);
for(int i = 0; i < NUMBLOCKS; i++)
os.write_32LE(m_cacheCache);
for (int i = 0; i < NUMBLOCKS; i++)
{
for(int j = 0; j < ASSOCIATIVITY; j++)
write32le(m_blocks[i].tag[j],os);
write32le(m_blocks[i].nextWay,os);
for (int j = 0; j < ASSOCIATIVITY; j++)
os.write_32LE(m_blocks[i].tag[j]);
os.write_32LE(m_blocks[i].nextWay);
}
}
bool loadstate(EMUFILE* is, int version)
bool loadstate(EMUFILE &is, int version)
{
read32le(&m_cacheCache, is);
for(int i = 0; i < NUMBLOCKS; i++)
is.read_32LE(m_cacheCache);
for (int i = 0; i < NUMBLOCKS; i++)
{
for(int j = 0; j < ASSOCIATIVITY; j++)
read32le(&m_blocks[i].tag[j],is);
read32le(&m_blocks[i].nextWay,is);
for (int j = 0; j < ASSOCIATIVITY; j++)
is.read_32LE(m_blocks[i].tag[j]);
is.read_32LE(m_blocks[i].nextWay);
}
return true;
}
@ -228,13 +229,13 @@ public:
}
FetchAccessUnit() { this->Reset(); }
void savestate(EMUFILE* os, int version)
void savestate(EMUFILE &os, int version)
{
write32le(m_lastAddress,os);
os.write_32LE(m_lastAddress);
}
bool loadstate(EMUFILE* is, int version)
bool loadstate(EMUFILE &is, int version)
{
read32le(&m_lastAddress,is);
is.read_32LE(m_lastAddress);
return true;
}

View File

@ -131,13 +131,13 @@ void NDS_SetupDefaultFirmware()
void NDS_RunAdvansceneAutoImport()
{
if(CommonSettings.run_advanscene_import != "")
if (CommonSettings.run_advanscene_import != "")
{
std::string fname = CommonSettings.run_advanscene_import;
std::string fname_out = fname + ".ddb";
EMUFILE_FILE outf(fname_out,"wb");
u32 ret = advsc.convertDB(fname.c_str(),&outf);
if(ret == 0)
u32 ret = advsc.convertDB(fname.c_str(),outf);
if (ret == 0)
exit(0);
else exit(1);
}
@ -909,18 +909,18 @@ struct TSequenceItem
u32 param;
bool enabled;
virtual void save(EMUFILE* os)
virtual void save(EMUFILE &os)
{
write64le(timestamp,os);
write32le(param,os);
writebool(enabled,os);
os.write_64LE(timestamp);
os.write_32LE(param);
os.write_bool32(enabled);
}
virtual bool load(EMUFILE* is)
virtual bool load(EMUFILE &is)
{
if(read64le(&timestamp,is) != 1) return false;
if(read32le(&param,is) != 1) return false;
if(readbool(&enabled,is) != 1) return false;
if (is.read_64LE(timestamp) != 1) return false;
if (is.read_32LE(param) != 1) return false;
if (is.read_bool32(enabled) != 1) return false;
return true;
}
@ -1191,11 +1191,11 @@ struct Sequencer
void execHardware();
u64 findNext();
void save(EMUFILE* os)
void save(EMUFILE &os)
{
write64le(nds_timer,os);
write64le(nds_arm9_timer,os);
write64le(nds_arm7_timer,os);
os.write_64LE(nds_timer);
os.write_64LE(nds_arm9_timer);
os.write_64LE(nds_arm7_timer);
dispcnt.save(os);
divider.save(os);
sqrtunit.save(os);
@ -1210,17 +1210,17 @@ struct Sequencer
#undef SAVE
}
bool load(EMUFILE* is, int version)
bool load(EMUFILE &is, int version)
{
if(read64le(&nds_timer,is) != 1) return false;
if(read64le(&nds_arm9_timer,is) != 1) return false;
if(read64le(&nds_arm7_timer,is) != 1) return false;
if(!dispcnt.load(is)) return false;
if(!divider.load(is)) return false;
if(!sqrtunit.load(is)) return false;
if(!gxfifo.load(is)) return false;
if(!readslot1.load(is)) return false;
if(version >= 1) if(!wifi.load(is)) return false;
if (is.read_64LE(nds_timer) != 1) return false;
if (is.read_64LE(nds_arm9_timer) != 1) return false;
if (is.read_64LE(nds_arm7_timer) != 1) return false;
if (!dispcnt.load(is)) return false;
if (!divider.load(is)) return false;
if (!sqrtunit.load(is)) return false;
if (!gxfifo.load(is)) return false;
if (!readslot1.load(is)) return false;
if (version >= 1) if(!wifi.load(is)) return false;
#define LOAD(I,X,Y) if(!I##_##X##_##Y .load(is)) return false;
LOAD(timer,0,0); LOAD(timer,0,1); LOAD(timer,0,2); LOAD(timer,0,3);
LOAD(timer,1,0); LOAD(timer,1,1); LOAD(timer,1,2); LOAD(timer,1,3);
@ -1742,23 +1742,23 @@ void Sequencer::execHardware()
void execHardware_interrupts();
static void saveUserInput(EMUFILE* os);
static bool loadUserInput(EMUFILE* is, int version);
static void saveUserInput(EMUFILE &os);
static bool loadUserInput(EMUFILE &is, int version);
void nds_savestate(EMUFILE* os)
void nds_savestate(EMUFILE &os)
{
//version
write32le(3,os);
os.write_32LE(3);
sequencer.save(os);
saveUserInput(os);
write32le(LidClosed,os);
write8le(countLid,os);
os.write_32LE(LidClosed);
os.write_u8(countLid);
}
bool nds_loadstate(EMUFILE* is, int size)
bool nds_loadstate(EMUFILE &is, int size)
{
// this isn't part of the savestate loading logic, but
// don't skip the next frame after loading a savestate
@ -1766,19 +1766,19 @@ bool nds_loadstate(EMUFILE* is, int size)
//read version
u32 version;
if(read32le(&version,is) != 1) return false;
if (is.read_32LE(version) != 1) return false;
if(version > 3) return false;
if (version > 3) return false;
bool temp = true;
temp &= sequencer.load(is, version);
if(version <= 1 || !temp) return temp;
if (version <= 1 || !temp) return temp;
temp &= loadUserInput(is, version);
if(version < 3) return temp;
if (version < 3) return temp;
read32le(&LidClosed,is);
read8le(&countLid,is);
is.read_32LE(LidClosed);
is.read_u8(countLid);
return temp;
}
@ -2688,7 +2688,7 @@ static std::string MakeInputDisplayString(u16 pad, u16 padExt) {
buttonstruct<bool> Turbo;
buttonstruct<int> TurboTime;
buttonstruct<u32> TurboTime;
buttonstruct<bool> AutoHold;
void ClearAutoHold(void) {
@ -2740,44 +2740,45 @@ const UserInput& NDS_getFinalUserInput()
}
static void saveUserInput(EMUFILE* os, UserInput& input)
static void saveUserInput(EMUFILE &os, UserInput &input)
{
os->fwrite((const char*)input.buttons.array, 14);
writebool(input.touch.isTouch, os);
write16le(input.touch.touchX, os);
write16le(input.touch.touchY, os);
write32le(input.mic.micButtonPressed, os);
os.fwrite(input.buttons.array, 14);
os.write_bool32(input.touch.isTouch);
os.write_16LE(input.touch.touchX);
os.write_16LE(input.touch.touchY);
os.write_32LE(input.mic.micButtonPressed);
}
static bool loadUserInput(EMUFILE* is, UserInput& input, int version)
static bool loadUserInput(EMUFILE &is, UserInput &input, int version)
{
is->fread((char*)input.buttons.array, 14);
readbool(&input.touch.isTouch, is);
read16le(&input.touch.touchX, is);
read16le(&input.touch.touchY, is);
read32le(&input.mic.micButtonPressed, is);
is.fread(input.buttons.array, 14);
is.read_bool32(input.touch.isTouch);
is.read_16LE(input.touch.touchX);
is.read_16LE(input.touch.touchY);
is.read_32LE(input.mic.micButtonPressed);
return true;
}
static void resetUserInput(UserInput& input)
static void resetUserInput(UserInput &input)
{
memset(&input, 0, sizeof(UserInput));
}
// (userinput is kind of a misnomer, e.g. finalUserInput has to mirror nds.pad, nds.touchX, etc.)
static void saveUserInput(EMUFILE* os)
static void saveUserInput(EMUFILE &os)
{
saveUserInput(os, finalUserInput);
saveUserInput(os, intermediateUserInput); // saved in case a savestate is made during input processing (which Lua could do if nothing else)
writebool(validToProcessInput, os);
for(int i = 0; i < 14; i++)
write32le(TurboTime.array[i], os); // saved to make autofire more tolerable to use with re-recording
os.write_bool32(validToProcessInput);
for (int i = 0; i < 14; i++)
os.write_32LE(TurboTime.array[i]); // saved to make autofire more tolerable to use with re-recording
}
static bool loadUserInput(EMUFILE* is, int version)
static bool loadUserInput(EMUFILE &is, int version)
{
bool rv = true;
rv &= loadUserInput(is, finalUserInput, version);
rv &= loadUserInput(is, intermediateUserInput, version);
readbool(&validToProcessInput, is);
for(int i = 0; i < 14; i++)
read32le((u32*)&TurboTime.array[i], is);
is.read_bool32(validToProcessInput);
for (int i = 0; i < 14; i++)
is.read_32LE(TurboTime.array[i]);
return rv;
}
static void resetUserInput()

View File

@ -55,7 +55,7 @@ struct buttonstruct {
};
extern buttonstruct<bool> Turbo;
extern buttonstruct<int> TurboTime;
extern buttonstruct<u32> TurboTime;
extern buttonstruct<bool> AutoHold;
extern volatile bool execute;
extern BOOL click;
@ -453,8 +453,8 @@ void NDS_Reset();
bool NDS_LegitBoot();
bool NDS_FakeBoot();
void nds_savestate(EMUFILE* os);
bool nds_loadstate(EMUFILE* is, int size);
void nds_savestate(EMUFILE &os);
bool nds_loadstate(EMUFILE &is, int size);
void NDS_Sleep();
void NDS_TriggerCardEjectIRQ();

View File

@ -39,6 +39,7 @@
#include "readwrite.h"
#include "armcpu.h"
#include "NDSSystem.h"
#include "emufile.h"
#include "matrix.h"
#include "utils/bits.h"
@ -701,26 +702,26 @@ s16 SPUFifo::dequeue()
return ret;
}
void SPUFifo::save(EMUFILE* fp)
void SPUFifo::save(EMUFILE &fp)
{
u32 version = 1;
write32le(version,fp);
write32le(head,fp);
write32le(tail,fp);
write32le(size,fp);
for(int i=0;i<16;i++)
write16le(buffer[i],fp);
fp.write_32LE(version);
fp.write_32LE(head);
fp.write_32LE(tail);
fp.write_32LE(size);
for (int i = 0; i < 16; i++)
fp.write_16LE(buffer[i]);
}
bool SPUFifo::load(EMUFILE* fp)
bool SPUFifo::load(EMUFILE &fp)
{
u32 version;
if(read32le(&version,fp) != 1) return false;
read32le(&head,fp);
read32le(&tail,fp);
read32le(&size,fp);
for(int i=0;i<16;i++)
read16le(&buffer[i],fp);
if (fp.read_32LE(version) != 1) return false;
fp.read_32LE(head);
fp.read_32LE(tail);
fp.read_32LE(size);
for (int i = 0; i < 16; i++)
fp.read_16LE(buffer[i]);
return true;
}
@ -1356,11 +1357,11 @@ static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length)
bool skipcap = false;
//-----------------
s32 samp0[2];
s32 samp0[2] = {0,0};
//believe it or not, we are going to do this one sample at a time.
//like i said, it is slower.
for(int samp=0;samp<length;samp++)
for (int samp = 0; samp < length; samp++)
{
SPU->sndbuf[0] = 0;
SPU->sndbuf[1] = 0;
@ -1372,7 +1373,7 @@ static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length)
s32 submix[32];
//generate each channel, and helpfully mix it at the same time
for(int i=0;i<16;i++)
for (int i = 0; i < 16; i++)
{
channel_struct *chan = &SPU->channels[i];
@ -1381,17 +1382,17 @@ static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length)
SPU->bufpos = 0;
bool bypass = false;
if(i==1 && SPU->regs.ctl_ch1bypass) bypass=true;
if(i==3 && SPU->regs.ctl_ch3bypass) bypass=true;
if (i==1 && SPU->regs.ctl_ch1bypass) bypass=true;
if (i==3 && SPU->regs.ctl_ch3bypass) bypass=true;
//output to mixer unless we are bypassed.
//dont output to mixer if the user muted us
bool outputToMix = true;
if(CommonSettings.spu_muteChannels[i]) outputToMix = false;
if(bypass) outputToMix = false;
if (CommonSettings.spu_muteChannels[i]) outputToMix = false;
if (bypass) outputToMix = false;
bool outputToCap = outputToMix;
if(CommonSettings.spu_captureMuted && !bypass) outputToCap = true;
if (CommonSettings.spu_captureMuted && !bypass) outputToCap = true;
//channels 1 and 3 should probably always generate their audio
//internally at least, just in case they get used by the spu output
@ -1409,14 +1410,14 @@ static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length)
submix[i*2+1] = SPU->sndbuf[1];
//send sample to our capture mix
if(outputToCap)
if (outputToCap)
{
capmix[0] += submix[i*2];
capmix[1] += submix[i*2+1];
}
//send sample to our main mixer
if(outputToMix)
if (outputToMix)
{
mix[0] += submix[i*2];
mix[1] += submix[i*2+1];
@ -1436,32 +1437,32 @@ static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length)
s32 capout[2];
//create SPU output
switch(SPU->regs.ctl_left)
switch (SPU->regs.ctl_left)
{
case SPU_struct::REGS::LOM_LEFT_MIXER: sndout[0] = mixout[0]; break;
case SPU_struct::REGS::LOM_CH1: sndout[0] = submix[1*2+0]; break;
case SPU_struct::REGS::LOM_CH3: sndout[0] = submix[3*2+0]; break;
case SPU_struct::REGS::LOM_CH1_PLUS_CH3: sndout[0] = submix[1*2+0] + submix[3*2+0]; break;
case SPU_struct::REGS::LOM_LEFT_MIXER: sndout[0] = mixout[0]; break;
case SPU_struct::REGS::LOM_CH1: sndout[0] = submix[1*2+0]; break;
case SPU_struct::REGS::LOM_CH3: sndout[0] = submix[3*2+0]; break;
case SPU_struct::REGS::LOM_CH1_PLUS_CH3: sndout[0] = submix[1*2+0] + submix[3*2+0]; break;
}
switch(SPU->regs.ctl_right)
switch (SPU->regs.ctl_right)
{
case SPU_struct::REGS::ROM_RIGHT_MIXER: sndout[1] = mixout[1]; break;
case SPU_struct::REGS::ROM_CH1: sndout[1] = submix[1*2+1]; break;
case SPU_struct::REGS::ROM_CH3: sndout[1] = submix[3*2+1]; break;
case SPU_struct::REGS::ROM_CH1_PLUS_CH3: sndout[1] = submix[1*2+1] + submix[3*2+1]; break;
case SPU_struct::REGS::ROM_RIGHT_MIXER: sndout[1] = mixout[1]; break;
case SPU_struct::REGS::ROM_CH1: sndout[1] = submix[1*2+1]; break;
case SPU_struct::REGS::ROM_CH3: sndout[1] = submix[3*2+1]; break;
case SPU_struct::REGS::ROM_CH1_PLUS_CH3: sndout[1] = submix[1*2+1] + submix[3*2+1]; break;
}
//generate capture output ("capture bugs" from gbatek are not emulated)
if(SPU->regs.cap[0].source==0)
if (SPU->regs.cap[0].source == 0)
capout[0] = capmixout[0]; //cap0 = L-mix
else if(SPU->regs.cap[0].add)
else if (SPU->regs.cap[0].add)
capout[0] = chanout[0] + chanout[1]; //cap0 = ch0+ch1
else capout[0] = chanout[0]; //cap0 = ch0
if(SPU->regs.cap[1].source==0)
if (SPU->regs.cap[1].source == 0)
capout[1] = capmixout[1]; //cap1 = R-mix
else if(SPU->regs.cap[1].add)
else if (SPU->regs.cap[1].add)
capout[1] = chanout[2] + chanout[3]; //cap1 = ch2+ch3
else capout[1] = chanout[2]; //cap1 = ch2
@ -1469,7 +1470,7 @@ static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length)
capout[1] = MinMax(capout[1],-0x8000,0x7FFF);
//write the output sample where it is supposed to go
if(samp==0)
if (samp == 0)
{
samp0[0] = sndout[0];
samp0[1] = sndout[1];
@ -1480,15 +1481,15 @@ static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length)
SPU->sndbuf[samp*2+1] = sndout[1];
}
for(int capchan=0;capchan<2;capchan++)
for (int capchan = 0; capchan < 2; capchan++)
{
if(SPU->regs.cap[capchan].runtime.running)
if (SPU->regs.cap[capchan].runtime.running)
{
SPU_struct::REGS::CAP& cap = SPU->regs.cap[capchan];
u32 last = sputrunc(cap.runtime.sampcnt);
cap.runtime.sampcnt += SPU->channels[1+2*capchan].sampinc;
u32 curr = sputrunc(cap.runtime.sampcnt);
for(u32 j=last;j<curr;j++)
for (u32 j = last; j < curr; j++)
{
//so, this is a little strange. why go through a fifo?
//it seems that some games will set up a reverb effect by capturing
@ -1504,7 +1505,7 @@ static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length)
//Subjectively, it seems to be working.
//Don't do anything until the fifo is filled, so as to delay it
if(cap.runtime.fifo.size<16)
if (cap.runtime.fifo.size < 16)
{
cap.runtime.fifo.enqueue(capout[capchan]);
continue;
@ -1519,10 +1520,10 @@ static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length)
//if(!fp) fp = fopen("d:\\capout.raw","wb");
//fwrite(&sample,2,1,fp);
if(cap.bits8)
if (cap.bits8)
{
s8 sample8 = sample>>8;
if(skipcap) _MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,0);
s8 sample8 = sample >> 8;
if (skipcap) _MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,0);
else _MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,sample8);
cap.runtime.curdad++;
multiplier = 4;
@ -1530,13 +1531,14 @@ static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length)
else
{
s16 sample16 = sample;
if(skipcap) _MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,0);
if (skipcap) _MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,0);
else _MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,sample16);
cap.runtime.curdad+=2;
multiplier = 2;
}
if(cap.runtime.curdad>=cap.runtime.maxdad) {
if (cap.runtime.curdad >= cap.runtime.maxdad)
{
cap.runtime.curdad = cap.dad;
cap.runtime.sampcnt -= cap.len*multiplier;
}
@ -1552,7 +1554,7 @@ static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length)
//ENTER
static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length)
{
if(actuallyMix)
if (actuallyMix)
{
memset(SPU->sndbuf, 0, length*4*2);
memset(SPU->outbuf, 0, length*2*2);
@ -1569,14 +1571,14 @@ static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length)
//branch here so that slow computers don't have to take the advanced (slower) codepath.
//it remainds to be seen exactly how much slower it is
//if it isnt much slower then we should refactor everything to be simpler, once it is working
if(advanced && SPU == SPU_core)
if (advanced && SPU == SPU_core)
{
SPU_MixAudio_Advanced(actuallyMix, SPU, length);
}
else
{
//non-advanced mode
for(int i=0;i<16;i++)
for (int i = 0; i < 16; i++)
{
channel_struct *chan = &SPU->channels[i];
@ -1595,32 +1597,33 @@ static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length)
//this code is bulkier and slower than it might otherwise be to reduce the chance of bugs
//IDEALLY the non-advanced codepath would be removed (while the advanced codepath was optimized and improved)
//and this code would disappear, to be replaced with code more capable of emitting zeroes at the opportune time.
for(int capchan=0;capchan<2;capchan++)
{
SPU_struct::REGS::CAP& cap = SPU->regs.cap[capchan];
if(cap.runtime.running)
{
for(int samp=0;samp<length;samp++)
{
u32 last = sputrunc(cap.runtime.sampcnt);
cap.runtime.sampcnt += SPU->channels[1+2*capchan].sampinc;
u32 curr = sputrunc(cap.runtime.sampcnt);
for(u32 j=last;j<curr;j++)
for (int capchan = 0; capchan < 2; capchan++)
{
SPU_struct::REGS::CAP& cap = SPU->regs.cap[capchan];
if (cap.runtime.running)
{
for (int samp = 0; samp < length; samp++)
{
u32 last = sputrunc(cap.runtime.sampcnt);
cap.runtime.sampcnt += SPU->channels[1+2*capchan].sampinc;
u32 curr = sputrunc(cap.runtime.sampcnt);
for (u32 j = last; j < curr; j++)
{
if(cap.bits8)
{
_MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,0);
cap.runtime.curdad++;
}
else
{
_MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,0);
cap.runtime.curdad+=2;
if (cap.bits8)
{
_MMU_write08<1,MMU_AT_DMA>(cap.runtime.curdad,0);
cap.runtime.curdad++;
}
else
{
_MMU_write16<1,MMU_AT_DMA>(cap.runtime.curdad,0);
cap.runtime.curdad+=2;
}
if(cap.runtime.curdad>=cap.runtime.maxdad) {
cap.runtime.curdad = cap.dad;
cap.runtime.sampcnt -= cap.len*(cap.bits8?4:2);
if (cap.runtime.curdad >= cap.runtime.maxdad)
{
cap.runtime.curdad = cap.dad;
cap.runtime.sampcnt -= cap.len*(cap.bits8?4:2);
}
}
}
@ -1638,7 +1641,7 @@ static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length)
u8 vol = SPU->regs.mastervol;
// convert from 32-bit->16-bit
if(actuallyMix && speakers)
if (actuallyMix && speakers)
for (int i = 0; i < length*2; i++)
{
// Apply Master Volume
@ -1948,168 +1951,169 @@ void WAV_WavSoundUpdate(void* soundData, int numSamples, WAVMode mode)
//////////////////////////////////////////////////////////////////////////////
void spu_savestate(EMUFILE* os)
void spu_savestate(EMUFILE &os)
{
//version
write32le(6,os);
os.write_32LE(6);
SPU_struct *spu = SPU_core;
for(int j=0;j<16;j++) {
channel_struct &chan = spu->channels[j];
write32le(chan.num,os);
write8le(chan.vol,os);
write8le(chan.volumeDiv,os);
write8le(chan.hold,os);
write8le(chan.pan,os);
write8le(chan.waveduty,os);
write8le(chan.repeat,os);
write8le(chan.format,os);
write8le(chan.status,os);
write32le(chan.addr,os);
write16le(chan.timer,os);
write16le(chan.loopstart,os);
write32le(chan.length,os);
write64le(double_to_u64(chan.sampcnt),os);
write64le(double_to_u64(chan.sampinc),os);
write32le(chan.lastsampcnt,os);
write16le(chan.pcm16b,os);
write16le(chan.pcm16b_last,os);
write32le(chan.index,os);
write16le(chan.x,os);
write16le(chan.psgnoise_last,os);
write8le(chan.keyon,os);
}
write64le(double_to_u64(samples),os);
write8le(spu->regs.mastervol,os);
write8le(spu->regs.ctl_left,os);
write8le(spu->regs.ctl_right,os);
write8le(spu->regs.ctl_ch1bypass,os);
write8le(spu->regs.ctl_ch3bypass,os);
write8le(spu->regs.masteren,os);
write16le(spu->regs.soundbias,os);
for(int i=0;i<2;i++)
for (int j = 0; j < 16; j++)
{
write8le(spu->regs.cap[i].add,os);
write8le(spu->regs.cap[i].source,os);
write8le(spu->regs.cap[i].oneshot,os);
write8le(spu->regs.cap[i].bits8,os);
write8le(spu->regs.cap[i].active,os);
write32le(spu->regs.cap[i].dad,os);
write16le(spu->regs.cap[i].len,os);
write8le(spu->regs.cap[i].runtime.running,os);
write32le(spu->regs.cap[i].runtime.curdad,os);
write32le(spu->regs.cap[i].runtime.maxdad,os);
write_double_le(spu->regs.cap[i].runtime.sampcnt,os);
channel_struct &chan = spu->channels[j];
os.write_32LE(chan.num);
os.write_u8(chan.vol);
os.write_u8(chan.volumeDiv);
os.write_u8(chan.hold);
os.write_u8(chan.pan);
os.write_u8(chan.waveduty);
os.write_u8(chan.repeat);
os.write_u8(chan.format);
os.write_u8(chan.status);
os.write_32LE(chan.addr);
os.write_16LE(chan.timer);
os.write_16LE(chan.loopstart);
os.write_32LE(chan.length);
os.write_doubleLE(chan.sampcnt);
os.write_doubleLE(chan.sampinc);
os.write_32LE(chan.lastsampcnt);
os.write_16LE(chan.pcm16b);
os.write_16LE(chan.pcm16b_last);
os.write_32LE(chan.index);
os.write_16LE(chan.x);
os.write_16LE(chan.psgnoise_last);
os.write_u8(chan.keyon);
}
for(int i=0;i<2;i++)
os.write_doubleLE(samples);
os.write_u8(spu->regs.mastervol);
os.write_u8(spu->regs.ctl_left);
os.write_u8(spu->regs.ctl_right);
os.write_u8(spu->regs.ctl_ch1bypass);
os.write_u8(spu->regs.ctl_ch3bypass);
os.write_u8(spu->regs.masteren);
os.write_16LE(spu->regs.soundbias);
for (int i = 0; i < 2; i++)
{
os.write_u8(spu->regs.cap[i].add);
os.write_u8(spu->regs.cap[i].source);
os.write_u8(spu->regs.cap[i].oneshot);
os.write_u8(spu->regs.cap[i].bits8);
os.write_u8(spu->regs.cap[i].active);
os.write_32LE(spu->regs.cap[i].dad);
os.write_16LE(spu->regs.cap[i].len);
os.write_u8(spu->regs.cap[i].runtime.running);
os.write_32LE(spu->regs.cap[i].runtime.curdad);
os.write_32LE(spu->regs.cap[i].runtime.maxdad);
os.write_doubleLE(spu->regs.cap[i].runtime.sampcnt);
}
for (int i = 0; i < 2; i++)
spu->regs.cap[i].runtime.fifo.save(os);
}
bool spu_loadstate(EMUFILE* is, int size)
bool spu_loadstate(EMUFILE &is, int size)
{
//note! if we load a state created with advanced spu logic on a system without it,
//there's a high likelihood of captured data existing.
//this would get played back forever without being replaced by captured data.
//it's been solved by capturing zeroes though even when advanced spu logic is disabled.
u64 temp64;
//read version
u32 version;
if(read32le(&version,is) != 1) return false;
if (is.read_32LE(version) != 1) return false;
SPU_struct *spu = SPU_core;
reconstruct(&SPU_core->regs);
for(int j=0;j<16;j++) {
for (int j = 0; j < 16; j++)
{
channel_struct &chan = spu->channels[j];
read32le(&chan.num,is);
read8le(&chan.vol,is);
read8le(&chan.volumeDiv,is);
is.read_32LE(chan.num);
is.read_u8(chan.vol);
is.read_u8(chan.volumeDiv);
if (chan.volumeDiv == 4) chan.volumeDiv = 3;
read8le(&chan.hold,is);
read8le(&chan.pan,is);
read8le(&chan.waveduty,is);
read8le(&chan.repeat,is);
read8le(&chan.format,is);
read8le(&chan.status,is);
read32le(&chan.addr,is);
read16le(&chan.timer,is);
read16le(&chan.loopstart,is);
read32le(&chan.length,is);
is.read_u8(chan.hold);
is.read_u8(chan.pan);
is.read_u8(chan.waveduty);
is.read_u8(chan.repeat);
is.read_u8(chan.format);
is.read_u8(chan.status);
is.read_32LE(chan.addr);
is.read_16LE(chan.timer);
is.read_16LE(chan.loopstart);
is.read_32LE(chan.length);
chan.totlength = chan.length + chan.loopstart;
chan.double_totlength_shifted = (double)(chan.totlength << format_shift[chan.format]);
//printf("%f\n",chan.double_totlength_shifted);
if(version >= 2)
if (version >= 2)
{
read64le(&temp64,is); chan.sampcnt = u64_to_double(temp64);
read64le(&temp64,is); chan.sampinc = u64_to_double(temp64);
is.read_doubleLE(chan.sampcnt);
is.read_doubleLE(chan.sampinc);
}
else
{
read32le((u32*)&chan.sampcnt,is);
read32le((u32*)&chan.sampinc,is);
is.read_32LE(*(u32 *)&chan.sampcnt);
is.read_32LE(*(u32 *)&chan.sampinc);
}
read32le(&chan.lastsampcnt,is);
read16le(&chan.pcm16b,is);
read16le(&chan.pcm16b_last,is);
read32le(&chan.index,is);
read16le(&chan.x,is);
read16le(&chan.psgnoise_last,is);
is.read_32LE(chan.lastsampcnt);
is.read_16LE(chan.pcm16b);
is.read_16LE(chan.pcm16b_last);
is.read_32LE(chan.index);
is.read_16LE(chan.x);
is.read_16LE(chan.psgnoise_last);
if(version>=4)
read8le(&chan.keyon,is);
if (version >= 4)
is.read_u8(chan.keyon);
//hopefully trigger a recovery of the adpcm looping system
chan.loop_index = K_ADPCM_LOOPING_RECOVERY_INDEX;
}
if(version>=2) {
read64le(&temp64,is); samples = u64_to_double(temp64);
if (version >= 2)
{
is.read_doubleLE(samples);
}
if(version>=4)
if (version >= 4)
{
read8le(&spu->regs.mastervol,is);
read8le(&spu->regs.ctl_left,is);
read8le(&spu->regs.ctl_right,is);
read8le(&spu->regs.ctl_ch1bypass,is);
read8le(&spu->regs.ctl_ch3bypass,is);
read8le(&spu->regs.masteren,is);
read16le(&spu->regs.soundbias,is);
is.read_u8(spu->regs.mastervol);
is.read_u8(spu->regs.ctl_left);
is.read_u8(spu->regs.ctl_right);
is.read_u8(spu->regs.ctl_ch1bypass);
is.read_u8(spu->regs.ctl_ch3bypass);
is.read_u8(spu->regs.masteren);
is.read_16LE(spu->regs.soundbias);
}
if(version>=5)
if (version >= 5)
{
for(int i=0;i<2;i++)
for (int i = 0; i < 2; i++)
{
read8le(&spu->regs.cap[i].add,is);
read8le(&spu->regs.cap[i].source,is);
read8le(&spu->regs.cap[i].oneshot,is);
read8le(&spu->regs.cap[i].bits8,is);
read8le(&spu->regs.cap[i].active,is);
read32le(&spu->regs.cap[i].dad,is);
read16le(&spu->regs.cap[i].len,is);
read8le(&spu->regs.cap[i].runtime.running,is);
read32le(&spu->regs.cap[i].runtime.curdad,is);
read32le(&spu->regs.cap[i].runtime.maxdad,is);
read_double_le(&spu->regs.cap[i].runtime.sampcnt,is);
is.read_u8(spu->regs.cap[i].add);
is.read_u8(spu->regs.cap[i].source);
is.read_u8(spu->regs.cap[i].oneshot);
is.read_u8(spu->regs.cap[i].bits8);
is.read_u8(spu->regs.cap[i].active);
is.read_32LE(spu->regs.cap[i].dad);
is.read_16LE(spu->regs.cap[i].len);
is.read_u8(spu->regs.cap[i].runtime.running);
is.read_32LE(spu->regs.cap[i].runtime.curdad);
is.read_32LE(spu->regs.cap[i].runtime.maxdad);
is.read_doubleLE(spu->regs.cap[i].runtime.sampcnt);
}
}
if(version>=6)
for(int i=0;i<2;i++) spu->regs.cap[i].runtime.fifo.load(is);
if (version >= 6)
for (int i=0;i<2;i++) spu->regs.cap[i].runtime.fifo.load(is);
else
for(int i=0;i<2;i++) spu->regs.cap[i].runtime.fifo.reset();
for (int i=0;i<2;i++) spu->regs.cap[i].runtime.fifo.reset();
//older versions didnt store a mastervol;
//we must reload this or else games will start silent
if(version<4)
if (version < 4)
{
spu->regs.mastervol = T1ReadByte(MMU.ARM7_REG, 0x500) & 0x7F;
spu->regs.masteren = BIT15(T1ReadWord(MMU.ARM7_REG, 0x500));

View File

@ -137,8 +137,8 @@ public:
s16 dequeue();
s16 buffer[16];
s32 head,tail,size;
void save(EMUFILE* fp);
bool load(EMUFILE* fp);
void save(EMUFILE &fp);
bool load(EMUFILE &fp);
void reset();
};
@ -267,8 +267,8 @@ void SPU_Emulate_user(bool mix = true);
void SPU_DefaultFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
size_t SPU_DefaultPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
void spu_savestate(EMUFILE* os);
bool spu_loadstate(EMUFILE* is, int size);
void spu_savestate(EMUFILE &os);
bool spu_loadstate(EMUFILE &is, int size);
enum WAVMode
{

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2010-2015 DeSmuME team
Copyright (C) 2010-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -119,15 +119,15 @@ public:
virtual u32 slot1client_read_GCDATAIN(eSlot1Operation operation)
{
if(operation != eSlot1Operation_Unknown)
if (operation != eSlot1Operation_Unknown)
return 0;
u32 val;
u32 val = 0;
int cmd = protocol.command.bytes[0];
switch(cmd)
switch (cmd)
{
case 0xB0:
val = (img) ? 0x1F4 : 0x1F2;
val = (img != NULL) ? 0x1F4 : 0x1F2;
break;
case 0xB9:
val = (rand() % 100) ? (img) ? 0x1F4 : 0x1F2 : 0;
@ -138,7 +138,7 @@ public:
break;
case 0xBA:
//INFO("Read from sd at sector %08X at adr %08X ",card.address/512,ftell(img));
img->fread(&val, 4);
img->read_32LE(val);
//INFO("val %08X\n",val);
break;
default:
@ -151,22 +151,23 @@ public:
void slot1client_write_GCDATAIN(eSlot1Operation operation, u32 val)
{
if(operation != eSlot1Operation_Unknown)
if (operation != eSlot1Operation_Unknown)
return;
int cmd = protocol.command.bytes[0];
switch(cmd)
switch (cmd)
{
case 0xBB:
{
if(write_count && write_enabled)
if (write_count && write_enabled)
{
img->fwrite(&val, 4);
img->write_32LE(val);
img->fflush();
write_count--;
}
break;
}
default:
break;
}
@ -186,7 +187,7 @@ public:
//can someone tell me ... what the hell is this doing, anyway?
//seems odd to use card.command[4] for this... isnt it part of the address?
if(protocol.command.bytes[4])
if (protocol.command.bytes[4])
{
// transfer is done
//are you SURE this is logical? there doesnt seem to be any way for the card to signal that
@ -198,23 +199,24 @@ public:
}
int cmd = protocol.command.bytes[0];
switch(cmd)
switch (cmd)
{
case 0xBB:
{
if(write_count && write_enabled)
if (write_count && write_enabled)
{
img->fwrite(&val, 4);
img->write_32LE(val);
img->fflush();
write_count--;
}
break;
}
default:
break;
}
if(write_count==0)
if (write_count == 0)
{
write_enabled = 0;

View File

@ -89,12 +89,12 @@ public:
mSelectedImplementation->post_fakeboot(PROCNUM);
}
virtual void savestate(EMUFILE* os)
virtual void savestate(EMUFILE &os)
{
mSelectedImplementation->savestate(os);
}
virtual void loadstate(EMUFILE* is)
virtual void loadstate(EMUFILE &is)
{
mSelectedImplementation->loadstate(is);
}

View File

@ -84,13 +84,13 @@ public:
protocol.mode = eCardMode_NORMAL;
}
virtual void savestate(EMUFILE* os)
virtual void savestate(EMUFILE &os)
{
protocol.savestate(os);
rom.savestate(os);
}
virtual void loadstate(EMUFILE* is)
virtual void loadstate(EMUFILE &is)
{
protocol.loadstate(is);
rom.loadstate(is);

View File

@ -96,13 +96,13 @@ public:
protocol.mode = eCardMode_NORMAL;
}
virtual void savestate(EMUFILE* os)
virtual void savestate(EMUFILE &os)
{
protocol.savestate(os);
rom.savestate(os);
}
virtual void loadstate(EMUFILE* is)
virtual void loadstate(EMUFILE &is)
{
protocol.loadstate(is);
rom.loadstate(is);

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2010-2015 DeSmuME team
Copyright (C) 2010-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -107,6 +107,9 @@ public:
case eSlot1Operation_2x_SecureAreaLoad:
rom.start(operation,protocol.address);
return;
default:
break;
}
//handle special commands ourselves
@ -274,39 +277,39 @@ public:
protocol.mode = eCardMode_NORMAL;
}
virtual void savestate(EMUFILE* os)
virtual void savestate(EMUFILE &os)
{
s32 version = 0;
protocol.savestate(os);
rom.savestate(os);
os->write32le(version);
os.write_32LE(version);
os->write32le(mode);
os->write32le(handle_save);
os->write32le(save_adr);
os->write32le(save_start);
os->write32le(subAdr);
os.write_32LE(mode);
os.write_32LE(handle_save);
os.write_32LE(save_adr);
os.write_32LE(save_start);
os.write_32LE(subAdr);
}
virtual void loadstate(EMUFILE* is)
virtual void loadstate(EMUFILE &is)
{
s32 version = 0;
protocol.loadstate(is);
rom.loadstate(is);
is->read32le(&version);
is.read_32LE(version);
// version 0
if (version >= 0)
{
is->read32le(&mode);
is->read32le(&handle_save);
is->read32le(&save_adr);
is->read32le(&save_start);
is->read32le(&subAdr);
is.read_32LE(mode);
is.read_32LE(handle_save);
is.read_32LE(save_adr);
is.read_32LE(save_start);
is.read_32LE(subAdr);
}
}

View File

@ -228,29 +228,29 @@ u32 Slot1Comp_Protocol::read_GCDATAIN(u8 PROCNUM)
return 0xFFFFFFFF;
}
void Slot1Comp_Protocol::savestate(EMUFILE* os)
void Slot1Comp_Protocol::savestate(EMUFILE &os)
{
s32 version = 0;
os->write32le(version);
os->write32le((s32)mode);
os->write32le((s32)operation);
os->fwrite(command.bytes,8);
os->write32le(address);
os->write32le(length);
os->write32le(delay);
os->write32le(chipId);
os->write32le(gameCode);
os.write_32LE(version);
os.write_32LE((s32)mode);
os.write_32LE((s32)operation);
os.fwrite(command.bytes,8);
os.write_32LE(address);
os.write_32LE(length);
os.write_32LE(delay);
os.write_32LE(chipId);
os.write_32LE(gameCode);
}
void Slot1Comp_Protocol::loadstate(EMUFILE* is)
void Slot1Comp_Protocol::loadstate(EMUFILE &is)
{
s32 version = is->read32le();
mode = (eCardMode)is->read32le();
operation = (eSlot1Operation)is->read32le();
is->fread(command.bytes,8);
address = is->read32le();
length = is->read32le();
delay = is->read32le();
chipId = is->read32le();
gameCode = is->read32le();
s32 version = is.read_s32LE();
mode = (eCardMode)is.read_s32LE();
operation = (eSlot1Operation)is.read_s32LE();
is.fread(command.bytes,8);
is.read_32LE(address);
is.read_32LE(length);
is.read_32LE(delay);
is.read_32LE(chipId);
is.read_32LE(gameCode);
}

View File

@ -69,8 +69,8 @@ class Slot1Comp_Protocol
{
public:
void savestate(EMUFILE* os);
void loadstate(EMUFILE* is);
void savestate(EMUFILE &os);
void loadstate(EMUFILE &is);
//set some kind of protocol/hardware reset state
void reset(ISlot1Comp_Protocol_Client* client);
@ -111,4 +111,4 @@ public:
u32 gameCode;
};
#endif //_SLOT1COMP_PROTOCOL_H
#endif //_SLOT1COMP_PROTOCOL_H

View File

@ -106,17 +106,17 @@ u32 Slot1Comp_Rom::incAddress()
}
void Slot1Comp_Rom::savestate(EMUFILE* os)
void Slot1Comp_Rom::savestate(EMUFILE &os)
{
s32 version = 0;
os->write32le(version);
os->write32le((s32)operation);
os->write32le(address);
os.write_32LE(version);
os.write_32LE((s32)operation);
os.write_32LE(address);
}
void Slot1Comp_Rom::loadstate(EMUFILE* is)
void Slot1Comp_Rom::loadstate(EMUFILE &is)
{
s32 version = is->read32le();
operation = (eSlot1Operation)is->read32le();
address = is->read32le();
}
s32 version = is.read_s32LE();
operation = (eSlot1Operation)is.read_s32LE();
address = is.read_u32LE();
}

View File

@ -34,8 +34,8 @@ public:
u32 getAddress();
u32 incAddress();
void savestate(EMUFILE* os);
void loadstate(EMUFILE* is);
void savestate(EMUFILE &os);
void loadstate(EMUFILE &is);
private:
u32 address;

View File

@ -58,12 +58,12 @@ public:
virtual u16 readWord(u8 PROCNUM, u32 addr) { return mSelectedImplementation->readWord(PROCNUM, addr); }
virtual u32 readLong(u8 PROCNUM, u32 addr) { return mSelectedImplementation->readLong(PROCNUM, addr); }
virtual void savestate(EMUFILE* os)
virtual void savestate(EMUFILE &os)
{
mSelectedImplementation->savestate(os);
}
virtual void loadstate(EMUFILE* is)
virtual void loadstate(EMUFILE &is)
{
mSelectedImplementation->loadstate(is);
}

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2009 CrazyMax
Copyright (C) 2009-2015 DeSmuME team
Copyright (C) 2009-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -169,29 +169,27 @@ public:
return 0xFFFFFFFF;
}
virtual void savestate(EMUFILE* os)
virtual void savestate(EMUFILE &os)
{
s32 version = 0;
EMUFILE_MEMORY *ram = new EMUFILE_MEMORY(expMemory, EXPANSION_MEMORY_SIZE);
os->write32le(version);
os->write32le((u32)ext_ram_lock);
os->writeMemoryStream(ram);
delete ram;
EMUFILE_MEMORY ram = EMUFILE_MEMORY(expMemory, EXPANSION_MEMORY_SIZE);
os.write_32LE(version);
os.write_bool32(ext_ram_lock);
os.write_MemoryStream(ram);
}
virtual void loadstate(EMUFILE* is)
virtual void loadstate(EMUFILE &is)
{
EMUFILE_MEMORY *ram = new EMUFILE_MEMORY();
EMUFILE_MEMORY ram = EMUFILE_MEMORY();
s32 version = is->read32le();
s32 version = is.read_s32LE();
if (version >= 0)
{
is->read32le((u32*)&ext_ram_lock);
is->readMemoryStream(ram);
memcpy(expMemory, ram->buf(), std::min(EXPANSION_MEMORY_SIZE, ram->size()));
is.read_bool32(ext_ram_lock);
is.read_MemoryStream(ram);
memcpy(expMemory, ram.buf(), std::min(EXPANSION_MEMORY_SIZE, ram.size()));
}
delete ram;
}
};

View File

@ -134,7 +134,7 @@ private:
return 2;
case FLASH:
{
u32 tmp = fROM->read32le();
u32 tmp = fROM->read_u32LE();
return ((tmp == FLASH1M_)?3:5);
}
case SIIRTC_V:

View File

@ -1,7 +1,7 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2006 Mic
Copyright (C) 2009-2015 DeSmuME team
Copyright (C) 2009-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -158,7 +158,7 @@ static unsigned int cflash_read(unsigned int address)
{
if(file)
{
u8 data[2];
u8 data[2] = {0,0};
file->fseek(currLBA, SEEK_SET);
elems_read += file->fread(data,2);
ret_value = data[1] << 8 | data[0];

View File

@ -455,76 +455,76 @@ BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2)
}
// Save state
void armcp15_t::saveone(EMUFILE* os)
void armcp15_t::saveone(EMUFILE &os)
{
write32le(IDCode,os);
write32le(cacheType,os);
write32le(TCMSize,os);
write32le(ctrl,os);
write32le(DCConfig,os);
write32le(ICConfig,os);
write32le(writeBuffCtrl,os);
write32le(und,os);
write32le(DaccessPerm,os);
write32le(IaccessPerm,os);
for(int i=0;i<8;i++) write32le(protectBaseSize[i],os);
write32le(cacheOp,os);
write32le(DcacheLock,os);
write32le(IcacheLock,os);
write32le(ITCMRegion,os);
write32le(DTCMRegion,os);
write32le(processID,os);
write32le(RAM_TAG,os);
write32le(testState,os);
write32le(cacheDbg,os);
for(int i=0;i<8;i++) write32le(regionWriteMask_USR[i],os);
for(int i=0;i<8;i++) write32le(regionWriteMask_SYS[i],os);
for(int i=0;i<8;i++) write32le(regionReadMask_USR[i],os);
for(int i=0;i<8;i++) write32le(regionReadMask_SYS[i],os);
for(int i=0;i<8;i++) write32le(regionExecuteMask_USR[i],os);
for(int i=0;i<8;i++) write32le(regionExecuteMask_SYS[i],os);
for(int i=0;i<8;i++) write32le(regionWriteSet_USR[i],os);
for(int i=0;i<8;i++) write32le(regionWriteSet_SYS[i],os);
for(int i=0;i<8;i++) write32le(regionReadSet_USR[i],os);
for(int i=0;i<8;i++) write32le(regionReadSet_SYS[i],os);
for(int i=0;i<8;i++) write32le(regionExecuteSet_USR[i],os);
for(int i=0;i<8;i++) write32le(regionExecuteSet_SYS[i],os);
os.write_32LE(IDCode);
os.write_32LE(cacheType);
os.write_32LE(TCMSize);
os.write_32LE(ctrl);
os.write_32LE(DCConfig);
os.write_32LE(ICConfig);
os.write_32LE(writeBuffCtrl);
os.write_32LE(und);
os.write_32LE(DaccessPerm);
os.write_32LE(IaccessPerm);
for (int i=0;i<8;i++) os.write_32LE(protectBaseSize[i]);
os.write_32LE(cacheOp);
os.write_32LE(DcacheLock);
os.write_32LE(IcacheLock);
os.write_32LE(ITCMRegion);
os.write_32LE(DTCMRegion);
os.write_32LE(processID);
os.write_32LE(RAM_TAG);
os.write_32LE(testState);
os.write_32LE(cacheDbg);
for (int i=0;i<8;i++) os.write_32LE(regionWriteMask_USR[i]);
for (int i=0;i<8;i++) os.write_32LE(regionWriteMask_SYS[i]);
for (int i=0;i<8;i++) os.write_32LE(regionReadMask_USR[i]);
for (int i=0;i<8;i++) os.write_32LE(regionReadMask_SYS[i]);
for (int i=0;i<8;i++) os.write_32LE(regionExecuteMask_USR[i]);
for (int i=0;i<8;i++) os.write_32LE(regionExecuteMask_SYS[i]);
for (int i=0;i<8;i++) os.write_32LE(regionWriteSet_USR[i]);
for (int i=0;i<8;i++) os.write_32LE(regionWriteSet_SYS[i]);
for (int i=0;i<8;i++) os.write_32LE(regionReadSet_USR[i]);
for (int i=0;i<8;i++) os.write_32LE(regionReadSet_SYS[i]);
for (int i=0;i<8;i++) os.write_32LE(regionExecuteSet_USR[i]);
for (int i=0;i<8;i++) os.write_32LE(regionExecuteSet_SYS[i]);
}
bool armcp15_t::loadone(EMUFILE* is)
bool armcp15_t::loadone(EMUFILE &is)
{
if(!read32le(&IDCode,is)) return false;
if(!read32le(&cacheType,is)) return false;
if(!read32le(&TCMSize,is)) return false;
if(!read32le(&ctrl,is)) return false;
if(!read32le(&DCConfig,is)) return false;
if(!read32le(&ICConfig,is)) return false;
if(!read32le(&writeBuffCtrl,is)) return false;
if(!read32le(&und,is)) return false;
if(!read32le(&DaccessPerm,is)) return false;
if(!read32le(&IaccessPerm,is)) return false;
for(int i=0;i<8;i++) if(!read32le(&protectBaseSize[i],is)) return false;
if(!read32le(&cacheOp,is)) return false;
if(!read32le(&DcacheLock,is)) return false;
if(!read32le(&IcacheLock,is)) return false;
if(!read32le(&ITCMRegion,is)) return false;
if(!read32le(&DTCMRegion,is)) return false;
if(!read32le(&processID,is)) return false;
if(!read32le(&RAM_TAG,is)) return false;
if(!read32le(&testState,is)) return false;
if(!read32le(&cacheDbg,is)) return false;
for(int i=0;i<8;i++) if(!read32le(&regionWriteMask_USR[i],is)) return false;
for(int i=0;i<8;i++) if(!read32le(&regionWriteMask_SYS[i],is)) return false;
for(int i=0;i<8;i++) if(!read32le(&regionReadMask_USR[i],is)) return false;
for(int i=0;i<8;i++) if(!read32le(&regionReadMask_SYS[i],is)) return false;
for(int i=0;i<8;i++) if(!read32le(&regionExecuteMask_USR[i],is)) return false;
for(int i=0;i<8;i++) if(!read32le(&regionExecuteMask_SYS[i],is)) return false;
for(int i=0;i<8;i++) if(!read32le(&regionWriteSet_USR[i],is)) return false;
for(int i=0;i<8;i++) if(!read32le(&regionWriteSet_SYS[i],is)) return false;
for(int i=0;i<8;i++) if(!read32le(&regionReadSet_USR[i],is)) return false;
for(int i=0;i<8;i++) if(!read32le(&regionReadSet_SYS[i],is)) return false;
for(int i=0;i<8;i++) if(!read32le(&regionExecuteSet_USR[i],is)) return false;
for(int i=0;i<8;i++) if(!read32le(&regionExecuteSet_SYS[i],is)) return false;
if (!is.read_32LE(IDCode)) return false;
if (!is.read_32LE(cacheType)) return false;
if (!is.read_32LE(TCMSize)) return false;
if (!is.read_32LE(ctrl)) return false;
if (!is.read_32LE(DCConfig)) return false;
if (!is.read_32LE(ICConfig)) return false;
if (!is.read_32LE(writeBuffCtrl)) return false;
if (!is.read_32LE(und)) return false;
if (!is.read_32LE(DaccessPerm)) return false;
if (!is.read_32LE(IaccessPerm)) return false;
for (int i=0;i<8;i++) if (!is.read_32LE(protectBaseSize[i])) return false;
if (!is.read_32LE(cacheOp)) return false;
if (!is.read_32LE(DcacheLock)) return false;
if (!is.read_32LE(IcacheLock)) return false;
if (!is.read_32LE(ITCMRegion)) return false;
if (!is.read_32LE(DTCMRegion)) return false;
if (!is.read_32LE(processID)) return false;
if (!is.read_32LE(RAM_TAG)) return false;
if (!is.read_32LE(testState)) return false;
if (!is.read_32LE(cacheDbg)) return false;
for (int i=0;i<8;i++) if (!is.read_32LE(regionWriteMask_USR[i])) return false;
for (int i=0;i<8;i++) if (!is.read_32LE(regionWriteMask_SYS[i])) return false;
for (int i=0;i<8;i++) if (!is.read_32LE(regionReadMask_USR[i])) return false;
for (int i=0;i<8;i++) if (!is.read_32LE(regionReadMask_SYS[i])) return false;
for (int i=0;i<8;i++) if (!is.read_32LE(regionExecuteMask_USR[i])) return false;
for (int i=0;i<8;i++) if (!is.read_32LE(regionExecuteMask_SYS[i])) return false;
for (int i=0;i<8;i++) if (!is.read_32LE(regionWriteSet_USR[i])) return false;
for (int i=0;i<8;i++) if (!is.read_32LE(regionWriteSet_SYS[i])) return false;
for (int i=0;i<8;i++) if (!is.read_32LE(regionReadSet_USR[i])) return false;
for (int i=0;i<8;i++) if (!is.read_32LE(regionReadSet_SYS[i])) return false;
for (int i=0;i<8;i++) if (!is.read_32LE(regionExecuteSet_USR[i])) return false;
for (int i=0;i<8;i++) if (!is.read_32LE(regionExecuteSet_SYS[i])) return false;
return true;
}

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2006-2015 DeSmuME team
Copyright (C) 2006-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -123,8 +123,8 @@ public:
BOOL moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2);
BOOL isAccessAllowed(u32 address,u32 access);
// savestate
void saveone(EMUFILE* os);
bool loadone(EMUFILE* is);
void saveone(EMUFILE &os);
bool loadone(EMUFILE &is);
};
extern armcp15_t cp15;

View File

@ -223,24 +223,24 @@ void DEBUG_reset()
printf("DEBUG_reset: %08X\n",&DebugStatistics::print); //force a reference to this function
}
static void DEBUG_dumpMemory_fill(EMUFILE *fp, u32 size)
static void DEBUG_dumpMemory_fill(EMUFILE &fp, u32 size)
{
static std::vector<u8> buf;
buf.resize(size);
memset(&buf[0],0,size);
fp->fwrite(&buf[0],size);
fp.fwrite(&buf[0],size);
}
void DEBUG_dumpMemory(EMUFILE* fp)
void DEBUG_dumpMemory(EMUFILE &fp)
{
fp->fseek(0x000000,SEEK_SET); fp->fwrite(MMU.MAIN_MEM,0x800000); //arm9 main mem (8192K)
fp->fseek(0x900000,SEEK_SET); fp->fwrite(MMU.ARM9_DTCM,0x4000); //arm9 DTCM (16K)
fp->fseek(0xA00000,SEEK_SET); fp->fwrite(MMU.ARM9_ITCM,0x8000); //arm9 ITCM (32K)
fp->fseek(0xB00000,SEEK_SET); fp->fwrite(MMU.ARM9_LCD,0xA4000); //LCD mem 656K
fp->fseek(0xC00000,SEEK_SET); fp->fwrite(MMU.ARM9_VMEM,0x800); //OAM
fp->fseek(0xD00000,SEEK_SET); fp->fwrite(MMU.ARM7_ERAM,0x10000); //arm7 WRAM (64K)
fp->fseek(0xE00000,SEEK_SET); fp->fwrite(MMU.ARM7_WIRAM,0x10000); //arm7 wifi RAM ?
fp->fseek(0xF00000,SEEK_SET); fp->fwrite(MMU.SWIRAM,0x8000); //arm9/arm7 shared WRAM (32KB)
fp.fseek(0x000000,SEEK_SET); fp.fwrite(MMU.MAIN_MEM,0x800000); //arm9 main mem (8192K)
fp.fseek(0x900000,SEEK_SET); fp.fwrite(MMU.ARM9_DTCM,0x4000); //arm9 DTCM (16K)
fp.fseek(0xA00000,SEEK_SET); fp.fwrite(MMU.ARM9_ITCM,0x8000); //arm9 ITCM (32K)
fp.fseek(0xB00000,SEEK_SET); fp.fwrite(MMU.ARM9_LCD,0xA4000); //LCD mem 656K
fp.fseek(0xC00000,SEEK_SET); fp.fwrite(MMU.ARM9_VMEM,0x800); //OAM
fp.fseek(0xD00000,SEEK_SET); fp.fwrite(MMU.ARM7_ERAM,0x10000); //arm7 WRAM (64K)
fp.fseek(0xE00000,SEEK_SET); fp.fwrite(MMU.ARM7_WIRAM,0x10000); //arm7 wifi RAM ?
fp.fseek(0xF00000,SEEK_SET); fp.fwrite(MMU.SWIRAM,0x8000); //arm9/arm7 shared WRAM (32KB)
}
//----------------------------------------------------

View File

@ -48,7 +48,7 @@ struct DebugStatistics
extern DebugStatistics DEBUG_statistics;
void DEBUG_reset();
void DEBUG_dumpMemory(EMUFILE* fp);
void DEBUG_dumpMemory(EMUFILE &fp);
struct armcpu_t;

View File

@ -1,7 +1,7 @@
/*
The MIT License
Copyright (C) 2009-2015 DeSmuME team
Copyright (C) 2009-2017 DeSmuME team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -166,163 +166,298 @@ EMUFILE* EMUFILE_MEMORY::memwrap()
return this;
}
void EMUFILE::write64le(u64* val)
size_t EMUFILE::write_64LE(s64 s64valueIn)
{
write64le(*val);
return write_64LE(*(u64 *)&s64valueIn);
}
void EMUFILE::write64le(u64 val)
size_t EMUFILE::write_64LE(u64 u64valueIn)
{
val = LOCAL_TO_LE_64(val);
fwrite(&val,8);
u64valueIn = LOCAL_TO_LE_64(u64valueIn);
fwrite(&u64valueIn,8);
return 8;
}
size_t EMUFILE::read64le(u64 *Bufo)
size_t EMUFILE::read_64LE(s64 &s64valueOut)
{
u64 buf;
if(fread((char*)&buf,8) != 8)
return read_64LE(*(u64 *)&s64valueOut);
}
size_t EMUFILE::read_64LE(u64 &u64valueOut)
{
u64 temp = 0;
if (fread(&temp,8) != 8)
return 0;
*Bufo = LE_TO_LOCAL_64(buf);
u64valueOut = LE_TO_LOCAL_64(temp);
return 1;
}
u64 EMUFILE::read64le()
s64 EMUFILE::read_s64LE()
{
u64 temp;
read64le(&temp);
return temp;
s64 value = 0;
read_64LE(value);
return value;
}
void EMUFILE::write32le(u32* val)
u64 EMUFILE::read_u64LE()
{
write32le(*val);
u64 value = 0;
read_64LE(value);
return value;
}
void EMUFILE::write32le(u32 val)
size_t EMUFILE::write_32LE(s32 s32valueIn)
{
val = LOCAL_TO_LE_32(val);
fwrite(&val,4);
return write_32LE(*(u32 *)&s32valueIn);
}
size_t EMUFILE::read32le(s32* Bufo) { return read32le((u32*)Bufo); }
size_t EMUFILE::read32le(u32* Bufo)
size_t EMUFILE::write_32LE(u32 u32valueIn)
{
u32 buf;
if(fread(&buf,4)<4)
u32valueIn = LOCAL_TO_LE_32(u32valueIn);
fwrite(&u32valueIn,4);
return 4;
}
size_t EMUFILE::read_32LE(s32 &s32valueOut)
{
return read_32LE(*(u32 *)&s32valueOut);
}
size_t EMUFILE::read_32LE(u32 &u32valueOut)
{
u32 temp = 0;
if (fread(&temp,4) != 4)
return 0;
*Bufo = LE_TO_LOCAL_32(buf);
u32valueOut = LE_TO_LOCAL_32(temp);
return 1;
}
u32 EMUFILE::read32le()
s32 EMUFILE::read_s32LE()
{
u32 ret;
read32le(&ret);
return ret;
s32 value = 0;
read_32LE(value);
return value;
}
void EMUFILE::write16le(u16* val)
u32 EMUFILE::read_u32LE()
{
write16le(*val);
u32 value = 0;
read_32LE(value);
return value;
}
void EMUFILE::write16le(u16 val)
size_t EMUFILE::write_16LE(s16 s16valueIn)
{
val = LOCAL_TO_LE_16(val);
fwrite(&val,2);
return write_16LE(*(u16 *)&s16valueIn);
}
size_t EMUFILE::read16le(s16* Bufo) { return read16le((u16*)Bufo); }
size_t EMUFILE::read16le(u16* Bufo)
size_t EMUFILE::write_16LE(u16 u16valueIn)
{
u32 buf;
if(fread(&buf,2)<2)
u16valueIn = LOCAL_TO_LE_16(u16valueIn);
fwrite(&u16valueIn,2);
return 2;
}
size_t EMUFILE::read_16LE(s16 &s16valueOut)
{
return read_16LE(*(u16 *)&s16valueOut);
}
size_t EMUFILE::read_16LE(u16 &u16valueOut)
{
u32 temp = 0;
if (fread(&temp,2) != 2)
return 0;
*Bufo = LE_TO_LOCAL_16(buf);
u16valueOut = LE_TO_LOCAL_16(temp);
return 1;
}
u16 EMUFILE::read16le()
s16 EMUFILE::read_s16LE()
{
u16 ret;
read16le(&ret);
s16 value = 0;
read_16LE(value);
return value;
}
u16 EMUFILE::read_u16LE()
{
u16 value = 0;
read_16LE(value);
return value;
}
size_t EMUFILE::write_u8(u8 u8valueIn)
{
fwrite(&u8valueIn,1);
return 1;
}
size_t EMUFILE::read_u8(u8 &u8valueOut)
{
return fread(&u8valueOut,1);
}
u8 EMUFILE::read_u8()
{
u8 value = 0;
fread(&value,1);
return value;
}
size_t EMUFILE::write_doubleLE(double doubleValueIn)
{
return write_64LE(double_to_u64(doubleValueIn));
}
size_t EMUFILE::read_doubleLE(double &doubleValueOut)
{
u64 temp = 0;
size_t ret = read_64LE(temp);
doubleValueOut = u64_to_double(temp);
return ret;
}
void EMUFILE::write8le(u8* val)
double EMUFILE::read_doubleLE()
{
write8le(*val);
double value = 0.0;
read_doubleLE(value);
return value;
}
void EMUFILE::write8le(u8 val)
size_t EMUFILE::write_floatLE(float floatValueIn)
{
fwrite(&val,1);
return write_32LE(float_to_u32(floatValueIn));
}
size_t EMUFILE::read8le(u8* val)
size_t EMUFILE::read_floatLE(float &floatValueOut)
{
return fread(val,1);
}
u8 EMUFILE::read8le()
{
u8 temp;
fread(&temp,1);
return temp;
}
void EMUFILE::writedouble(double* val)
{
write64le(double_to_u64(*val));
}
void EMUFILE::writedouble(double val)
{
write64le(double_to_u64(val));
}
double EMUFILE::readdouble()
{
double temp;
readdouble(&temp);
return temp;
}
size_t EMUFILE::readdouble(double* val)
{
u64 temp;
size_t ret = read64le(&temp);
*val = u64_to_double(temp);
u32 temp = 0;
size_t ret = read_32LE(temp);
floatValueOut = u32_to_float(temp);
return ret;
}
void EMUFILE::writeMemoryStream(EMUFILE_MEMORY* ms)
float EMUFILE::read_floatLE()
{
s32 size = (s32)ms->size();
write32le(size);
if(size>0)
float value = 0.0f;
read_floatLE(value);
return value;
}
size_t EMUFILE::write_bool32(bool boolValueIn)
{
return write_32LE((boolValueIn) ? 1 : 0);
}
size_t EMUFILE::read_bool32(bool &boolValueOut)
{
u32 temp = 0;
size_t ret = read_32LE(temp);
if (ret != 0)
boolValueOut = (temp != 0);
return ret;
}
bool EMUFILE::read_bool32()
{
bool value = false;
read_bool32(value);
return value;
}
size_t EMUFILE::write_bool8(bool boolValueIn)
{
return write_u8((boolValueIn) ? 1 : 0);
}
size_t EMUFILE::read_bool8(bool &boolValueOut)
{
u8 temp = 0;
size_t ret = read_u8(temp);
if (ret != 0)
boolValueOut = (temp != 0);
return ret;
}
bool EMUFILE::read_bool8()
{
bool value = false;
read_bool8(value);
return value;
}
size_t EMUFILE::write_buffer(std::vector<u8> &vec)
{
u32 size = (u32)vec.size();
write_32LE(size);
if (size > 0)
fwrite(&vec[0],size);
return (size + 4);
}
size_t EMUFILE::read_buffer(std::vector<u8> &vec)
{
u32 size = 0;
if (read_32LE(size) != 1)
return 0;
vec.resize(size);
if (size > 0)
{
std::vector<u8>* vec = ms->get_vec();
size_t ret = fread(&vec[0],size);
if (ret != size)
return 0;
}
return 1;
}
size_t EMUFILE::write_MemoryStream(EMUFILE_MEMORY &ms)
{
u32 size = (u32)ms.size();
write_32LE(size);
if (size > 0)
{
std::vector<u8> *vec = ms.get_vec();
fwrite(&vec->at(0),size);
}
return (size + 4);
}
void EMUFILE::readMemoryStream(EMUFILE_MEMORY* ms)
size_t EMUFILE::read_MemoryStream(EMUFILE_MEMORY &ms)
{
s32 size = read32le();
if(size != 0)
u32 size = 0;
if (read_32LE(size) != 1)
return 0;
if (size > 0)
{
std::vector<u8> temp(size);
fread(&temp[0],size);
ms->fwrite(&temp[0],size);
std::vector<u8> vec(size);
size_t ret = fread(&vec[0],size);
if (ret != size)
return 0;
ms.fwrite(&vec[0],size);
}
return 1;
}

View File

@ -1,7 +1,7 @@
/*
The MIT License
Copyright (C) 2009-2015 DeSmuME team
Copyright (C) 2009-2017 DeSmuME team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -85,32 +85,54 @@ public:
virtual size_t _fread(const void *ptr, size_t bytes) = 0;
virtual size_t fwrite(const void *ptr, size_t bytes) = 0;
void write64le(u64* val);
void write64le(u64 val);
size_t read64le(u64* val);
u64 read64le();
void write32le(u32* val);
void write32le(s32* val) { write32le((u32*)val); }
void write32le(u32 val);
size_t read32le(u32* val);
size_t read32le(s32* val);
u32 read32le();
void write16le(u16* val);
void write16le(s16* val) { write16le((u16*)val); }
void write16le(u16 val);
size_t read16le(s16* Bufo);
size_t read16le(u16* val);
u16 read16le();
void write8le(u8* val);
void write8le(u8 val);
size_t read8le(u8* val);
u8 read8le();
void writedouble(double* val);
void writedouble(double val);
double readdouble();
size_t readdouble(double* val);
size_t write_64LE(s64 s64valueIn);
size_t write_64LE(u64 u64valueIn);
size_t read_64LE(s64 &s64valueOut);
size_t read_64LE(u64 &u64valueOut);
s64 read_s64LE();
u64 read_u64LE();
size_t write_32LE(s32 s32valueIn);
size_t write_32LE(u32 u32valueIn);
size_t read_32LE(s32 &s32valueOut);
size_t read_32LE(u32 &u32valueOut);
s32 read_s32LE();
u32 read_u32LE();
size_t write_16LE(s16 s16valueIn);
size_t write_16LE(u16 u16valueIn);
size_t read_16LE(s16 &s16valueOut);
size_t read_16LE(u16 &u16valueOut);
s16 read_s16LE();
u16 read_u16LE();
size_t write_u8(u8 u8valueIn);
size_t read_u8(u8 &u8valueOut);
u8 read_u8();
size_t write_bool32(bool boolValueIn);
size_t read_bool32(bool &boolValueOut);
bool read_bool32();
size_t write_bool8(bool boolValueIn);
size_t read_bool8(bool &boolValueOut);
bool read_bool8();
size_t write_doubleLE(double doubleValueIn);
size_t read_doubleLE(double &doubleValueOut);
double read_doubleLE();
size_t write_floatLE(float floatValueIn);
size_t read_floatLE(float &floatValueOut);
float read_floatLE();
size_t write_buffer(std::vector<u8> &vec);
size_t read_buffer(std::vector<u8> &vec);
size_t write_MemoryStream(EMUFILE_MEMORY &ms);
size_t read_MemoryStream(EMUFILE_MEMORY &ms);
virtual int fseek(int offset, int origin) = 0;
virtual int ftell() = 0;
@ -118,10 +140,6 @@ public:
virtual void fflush() = 0;
virtual void truncate(s32 length) = 0;
void writeMemoryStream(EMUFILE_MEMORY* ms);
void readMemoryStream(EMUFILE_MEMORY* ms);
};
//todo - handle read-only specially?

View File

@ -1034,9 +1034,9 @@ void Scale_2xSaI (u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u32 E, F, G, H;
u32 I, J, K, L;
u32 x1, x2, a1, f1, f2;
u32 position, product1;
position = w >> 16;
u32 position = w >> 16;
A = bP[position]; // current pixel
B = bP[position + 1]; // next pixel
C = bP[position + Nextline];
@ -1053,6 +1053,8 @@ void Scale_2xSaI (u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
x1 = w & 0xffff; // fraction part of fixed point
x2 = 0x10000 - x1;
u32 product1 = A;
/*0*/
if (A == B && C == D && A == C)
product1 = A;

View File

@ -288,10 +288,6 @@ void Bilinear32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *db = next_row++;
// upper left pixel in quad: just copy it in
int m = *ar;
int mm = *ag;
int mmmm = *ab;
int mmm = RGB1(*ar, *ag, *ab);
*to++ = RGB1(*ar, *ag, *ab);
// upper right

View File

@ -1,20 +1,18 @@
/* Copyright (C) 2009 DeSmuME team
This file is part of DeSmuME
DeSmuME 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.
DeSmuME 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 DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/*
Copyright (C) 2009-2017 DeSmuME team
This file 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 file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "filter.h"
@ -25,31 +23,31 @@
// where each corner is selected based on equivalence of neighboring pixels
void RenderEPX (SSurface Src, SSurface Dst)
{
uint32 *lpSrc;
u32 *lpSrc;
const uint32 srcHeight = Src.Height;
const uint32 srcWidth = Src.Width;
const u32 srcHeight = Src.Height;
const u32 srcWidth = Src.Width;
const unsigned int srcPitch = Src.Pitch >> 1;
lpSrc = reinterpret_cast<uint32 *>(Src.Surface);
lpSrc = reinterpret_cast<u32 *>(Src.Surface);
const unsigned int dstPitch = Dst.Pitch >> 1;
uint32 *lpDst = (uint32*)Dst.Surface;
u32 *lpDst = (u32*)Dst.Surface;
for(uint32 j = 0; j < srcHeight; j++)
for(u32 j = 0; j < srcHeight; j++)
{
uint32* SrcLine = lpSrc + srcPitch*j;
uint32* DstLine1 = lpDst + dstPitch*(j*2);
uint32* DstLine2 = lpDst + dstPitch*(j*2+1);
for(uint32 i = 0; i < srcWidth; i++)
u32* SrcLine = lpSrc + srcPitch*j;
u32* DstLine1 = lpDst + dstPitch*(j*2);
u32* DstLine2 = lpDst + dstPitch*(j*2+1);
for(u32 i = 0; i < srcWidth; i++)
{
uint32 L = *(SrcLine-1);
uint32 C = *(SrcLine);
uint32 R = *(SrcLine+1);
u32 L = *(SrcLine-1);
u32 C = *(SrcLine);
u32 R = *(SrcLine+1);
if(L != R)
{
uint32 U = *(SrcLine-srcPitch);
uint32 D = *(SrcLine+srcPitch);
u32 U = *(SrcLine-srcPitch);
u32 D = *(SrcLine+srcPitch);
if(U != D)
{
*DstLine1++ = (U == L) ? U : C;
@ -77,8 +75,6 @@ void RenderEPX_1Point5x (SSurface Src, SSurface Dst)
u32 srcHeight = Src.Height;
u32 srcWidth = Src.Width;
u32 dstHeight = Dst.Height;
u32 dstWidth = Dst.Width;
const unsigned int srcPitch = Src.Pitch >> 1;
lpSrc = reinterpret_cast<u32 *>(Src.Surface);
@ -86,18 +82,18 @@ void RenderEPX_1Point5x (SSurface Src, SSurface Dst)
const unsigned int dstPitch = Dst.Pitch >> 1;
u32 *lpDst = (u32*)Dst.Surface;
for(uint32 yi=0, yo=0; yi < srcHeight; yi+=2, yo+=3)
for(u32 yi=0, yo=0; yi < srcHeight; yi+=2, yo+=3)
{
u32* SrcLine = lpSrc + srcPitch*yi;
u32* DstLine1 = lpDst + dstPitch*(yo);
u32* DstLine2 = lpDst + dstPitch*(yo+1);
u32* DstLine3 = lpDst + dstPitch*(yo+2);
for(uint32 xi=0; xi < srcWidth; xi+=2)
for(u32 xi=0; xi < srcWidth; xi+=2)
{
u32 s10 = *(SrcLine-srcPitch), s20 = *(SrcLine-srcPitch+1), s30 = *(SrcLine-srcPitch+2);
u32 s01 = *(SrcLine-1), s11 = *(SrcLine), s21 = *(SrcLine+1), s31 = *(SrcLine+2);
u32 s02 = *(SrcLine+srcPitch-1), s12 = *(SrcLine+srcPitch), s22 = *(SrcLine+srcPitch+1), s32 = *(SrcLine+srcPitch+2);
u32 s03 = *(SrcLine+2*srcPitch-1), s13 = *(SrcLine+2*srcPitch), s23 = *(SrcLine+2*srcPitch+1), s33 = *(SrcLine+2*srcPitch+2);
u32 s03 = *(SrcLine+2*srcPitch-1), s13 = *(SrcLine+2*srcPitch), s23 = *(SrcLine+2*srcPitch+1);
*DstLine1++ = s01==s10 && s10!=s21 && s01!=s12
? s01:s11;
*DstLine1++ = s10==s21 && s10!=s01 && s21!=s12
@ -136,29 +132,29 @@ static u32 dist(u32 a, u32 b)
// where each corner is selected based on relative equivalence of neighboring pixels
void RenderEPXPlus (SSurface Src, SSurface Dst)
{
uint32 *lpSrc;
u32 *lpSrc;
const uint32 srcHeight = Src.Height;
const uint32 srcWidth = Src.Width;
const u32 srcHeight = Src.Height;
const u32 srcWidth = Src.Width;
const unsigned int srcPitch = Src.Pitch >> 1;
lpSrc = reinterpret_cast<uint32 *>(Src.Surface);
lpSrc = reinterpret_cast<u32 *>(Src.Surface);
const unsigned int dstPitch = Dst.Pitch >> 1;
uint32 *lpDst = (uint32*)Dst.Surface;
u32 *lpDst = (u32*)Dst.Surface;
for(uint32 j = 0; j < srcHeight; j++)
for(u32 j = 0; j < srcHeight; j++)
{
uint32* SrcLine = lpSrc + srcPitch*j;
uint32* DstLine1 = lpDst + dstPitch*(j*2);
uint32* DstLine2 = lpDst + dstPitch*(j*2+1);
for(uint32 i = 0; i < srcWidth; i++)
u32* SrcLine = lpSrc + srcPitch*j;
u32* DstLine1 = lpDst + dstPitch*(j*2);
u32* DstLine2 = lpDst + dstPitch*(j*2+1);
for(u32 i = 0; i < srcWidth; i++)
{
uint32 L = *(SrcLine-1);
uint32 C = *(SrcLine);
uint32 R = *(SrcLine+1);
uint32 U = *(SrcLine-srcPitch);
uint32 D = *(SrcLine+srcPitch);
u32 L = *(SrcLine-1);
u32 C = *(SrcLine);
u32 R = *(SrcLine+1);
u32 U = *(SrcLine-srcPitch);
u32 D = *(SrcLine+srcPitch);
*DstLine1++ = dist(L,U) < min(dist(L,D),dist(R,U)) ? mix(L,U) : C;
*DstLine1++ = dist(R,U) < min(dist(L,U),dist(R,D)) ? mix(R,U) : C;
*DstLine2++ = dist(L,D) < min(dist(L,U),dist(R,D)) ? mix(L,D) : C;
@ -176,8 +172,6 @@ void RenderEPXPlus_1Point5x (SSurface Src, SSurface Dst)
u32 srcHeight = Src.Height;
u32 srcWidth = Src.Width;
u32 dstHeight = Dst.Height;
u32 dstWidth = Dst.Width;
const unsigned int srcPitch = Src.Pitch >> 1;
lpSrc = reinterpret_cast<u32 *>(Src.Surface);
@ -185,18 +179,18 @@ void RenderEPXPlus_1Point5x (SSurface Src, SSurface Dst)
const unsigned int dstPitch = Dst.Pitch >> 1;
u32 *lpDst = (u32*)Dst.Surface;
for(uint32 yi=0, yo=0; yi < srcHeight; yi+=2, yo+=3)
for(u32 yi=0, yo=0; yi < srcHeight; yi+=2, yo+=3)
{
u32* SrcLine = lpSrc + srcPitch*yi;
u32* DstLine1 = lpDst + dstPitch*(yo);
u32* DstLine2 = lpDst + dstPitch*(yo+1);
u32* DstLine3 = lpDst + dstPitch*(yo+2);
for(uint32 xi=0; xi < srcWidth; xi+=2)
for(u32 xi=0; xi < srcWidth; xi+=2)
{
u32 s10 = *(SrcLine-srcPitch), s20 = *(SrcLine-srcPitch+1), s30 = *(SrcLine-srcPitch+2);
u32 s01 = *(SrcLine-1), s11 = *(SrcLine), s21 = *(SrcLine+1), s31 = *(SrcLine+2);
u32 s02 = *(SrcLine+srcPitch-1), s12 = *(SrcLine+srcPitch), s22 = *(SrcLine+srcPitch+1), s32 = *(SrcLine+srcPitch+2);
u32 s03 = *(SrcLine+2*srcPitch-1), s13 = *(SrcLine+2*srcPitch), s23 = *(SrcLine+2*srcPitch+1), s33 = *(SrcLine+2*srcPitch+2);
u32 s03 = *(SrcLine+2*srcPitch-1), s13 = *(SrcLine+2*srcPitch), s23 = *(SrcLine+2*srcPitch+1);
*DstLine1++ = dist(s01,s10) < min( dist(s10,s21),dist(s01,s12))
? mix(s01,s10):s11;
*DstLine1++ = dist(s10,s21) < min( dist(s10,s01),dist(s21,s12))
@ -226,20 +220,18 @@ void RenderEPXPlus_1Point5x (SSurface Src, SSurface Dst)
// which are selected stupidly from neighboring pixels in the original 2x2 block
void RenderNearest_1Point5x (SSurface Src, SSurface Dst)
{
uint32 *lpSrc;
u32 *lpSrc;
uint32 srcHeight = Src.Height;
uint32 srcWidth = Src.Width;
uint32 dstHeight = Dst.Height;
uint32 dstWidth = Dst.Width;
u32 srcHeight = Src.Height;
u32 srcWidth = Src.Width;
const unsigned int srcPitch = Src.Pitch >> 1;
lpSrc = reinterpret_cast<uint32 *>(Src.Surface);
lpSrc = reinterpret_cast<u32 *>(Src.Surface);
const unsigned int dstPitch = Dst.Pitch >> 1;
uint32 *lpDst = (uint32*)Dst.Surface;
u32 *lpDst = (u32*)Dst.Surface;
for(uint32 yi = 0, yo = 0; yi < srcHeight; yi+=2, yo+=3)
for(u32 yi = 0, yo = 0; yi < srcHeight; yi+=2, yo+=3)
{
u32* srcPix1 = lpSrc + srcPitch*(yi);
u32* srcPix2 = lpSrc + srcPitch*(yi+1);
@ -247,7 +239,7 @@ void RenderNearest_1Point5x (SSurface Src, SSurface Dst)
u32* dstPix2 = lpDst + dstPitch*(yo+1);
u32* dstPix3 = lpDst + dstPitch*(yo+2);
for(uint32 xi = 0; xi < srcWidth; xi+=2)
for(u32 xi = 0; xi < srcWidth; xi+=2)
{
*dstPix1++ = *srcPix1++;
*dstPix1++ = *srcPix1;
@ -273,30 +265,28 @@ int CLAMP(const int value, const int high)
// which are selected from neighboring pixels depending on matching diagonals
void RenderNearestPlus_1Point5x (SSurface Src, SSurface Dst)
{
uint32 *lpSrc;
u32 *lpSrc;
uint32 srcHeight = Src.Height;
uint32 srcWidth = Src.Width;
uint32 dstHeight = Dst.Height;
uint32 dstWidth = Dst.Width;
u32 srcHeight = Src.Height;
u32 srcWidth = Src.Width;
const unsigned int srcPitch = Src.Pitch >> 1;
lpSrc = reinterpret_cast<uint32 *>(Src.Surface);
lpSrc = reinterpret_cast<u32 *>(Src.Surface);
const unsigned int dstPitch = Dst.Pitch >> 1;
uint32 *lpDst = (uint32*)Dst.Surface;
u32 *lpDst = (u32*)Dst.Surface;
u32* srcPix = lpSrc;
u32* dstPix = lpDst;
for(uint32 j = 0, y = 0; j < srcHeight; j+=2, y+=3)
for(u32 j = 0, y = 0; j < srcHeight; j+=2, y+=3)
{
#define GET(dx,dy) *(srcPix+(CLAMP((dy)+j,srcHeight))*srcPitch+(CLAMP((dx)+i,srcWidth)))
#define SET(dx,dy,val) *(dstPix+(dy+y)*dstPitch+(dx+x)) = (val)
#define BETTER(dx,dy,dx2,dy2) (GET(dx,dy) == GET(dx2,dy2) && GET(dx2,dy) != GET(dx,dy2))
for(uint32 i = 0, x = 0; i < srcWidth; i+=2, x+=3) //, srcPix+=2, dstPix+=3
for(u32 i = 0, x = 0; i < srcWidth; i+=2, x+=3) //, srcPix+=2, dstPix+=3
{
SET(0,0,GET(0,0));
SET(1,0,GET(1,0));

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2011-2012 Roger Manuel
Copyright (C) 2013-2015 DeSmuME team
Copyright (C) 2013-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -617,12 +617,14 @@ void VideoFilter::RunFilterCustomByAttributes(const uint32_t *__restrict srcBuff
srcSurface.Pitch = srcWidth*2;
srcSurface.Width = srcWidth;
srcSurface.Height = srcHeight;
srcSurface.userData = NULL;
SSurface dstSurface;
dstSurface.Surface = (unsigned char *)dstBuffer;
dstSurface.Pitch = dstWidth*2;
dstSurface.Width = dstWidth;
dstSurface.Height = dstHeight;
srcSurface.userData = NULL;
if (filterFunction == NULL)
{

View File

@ -4559,12 +4559,18 @@ GLuint OGLShaderProgram::LoadShaderOGL(GLenum shaderType, const char *shaderProg
{
static const size_t logBytes = 16384; // 16KB should be more than enough
GLchar *logBuf = (GLchar *)calloc(logBytes, sizeof(GLchar));
GLsizei logSize = 0;
glGetShaderInfoLog(shaderID, logBytes * sizeof(GLchar), &logSize, logBuf);
printf("OpenGL Error - Failed to compile %s.\n%s\n",
(shaderType == GL_VERTEX_SHADER) ? "GL_VERTEX_SHADER" : ((shaderType == GL_FRAGMENT_SHADER) ? "GL_FRAGMENT_SHADER" : "OTHER SHADER TYPE"),
(char *)logBuf);
if (logBuf != NULL)
{
GLsizei logSize = 0;
glGetShaderInfoLog(shaderID, logBytes * sizeof(GLchar), &logSize, logBuf);
printf("OpenGL Error - Failed to compile %s.\n%s\n",
(shaderType == GL_VERTEX_SHADER) ? "GL_VERTEX_SHADER" : ((shaderType == GL_FRAGMENT_SHADER) ? "GL_FRAGMENT_SHADER" : "OTHER SHADER TYPE"),
(char *)logBuf);
}
free(logBuf);
glDeleteShader(shaderID);
return shaderID;

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2011 Roger Manuel
Copyright (C) 2012-2015 DeSmuME team
Copyright (C) 2012-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -1071,7 +1071,12 @@ static NSImage *iconCodeBreaker = nil;
u32 itemCount = cheatList->getSize();
for (u32 i = 0; i < itemCount; i++)
{
[newList addObject:[[[CocoaDSCheatItem alloc] initWithCheatData:cheatList->getItemByIndex(i)] autorelease]];
CocoaDSCheatItem *newItem = [[CocoaDSCheatItem alloc] initWithCheatData:cheatList->getItemByIndex(i)];
if (newItem != nil)
{
[newList addObject:[newItem autorelease]];
}
}
return newList;
@ -1184,7 +1189,7 @@ static NSImage *iconCodeBreaker = nil;
}
else if (theRwlock == NULL && !isUsingDummyRWlock)
{
rwlockCoreExecute = (pthread_rwlock_t *)malloc(sizeof(pthread_mutex_t));
rwlockCoreExecute = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t));
pthread_rwlock_init(rwlockCoreExecute, NULL);
isUsingDummyRWlock = YES;
return;

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2011 Roger Manuel
Copyright (C) 2011-2015 DeSmuME team
Copyright (C) 2011-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -101,7 +101,7 @@ typedef struct
@property (retain) CocoaDSController *cdsController;
@property (retain) CocoaDSFirmware *cdsFirmware;
@property (retain) CocoaDSGPU *cdsGPU;
@property (assign) NSMutableArray *cdsOutputList;
@property (retain) NSMutableArray *cdsOutputList;
@property (assign) BOOL masterExecute;
@property (assign) BOOL isFrameSkipEnabled;

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2011 Roger Manuel
Copyright (C) 2011-2015 DeSmuME team
Copyright (C) 2011-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -151,7 +151,7 @@ volatile bool execute = true;
cdsController = nil;
cdsFirmware = nil;
cdsGPU = [[[[CocoaDSGPU alloc] init] autorelease] retain];
cdsOutputList = [[NSMutableArray alloc] initWithCapacity:32];
cdsOutputList = [[[[NSMutableArray alloc] initWithCapacity:32] autorelease] retain];
emulationFlags = EMULATION_ADVANCED_BUS_LEVEL_TIMING_MASK;
emuFlagAdvancedBusLevelTiming = YES;
@ -235,11 +235,11 @@ volatile bool execute = true;
[self setCoreState:CORESTATE_PAUSE];
[self removeAllOutputs];
[cdsOutputList release];
[self setCdsController:nil];
[self setCdsFirmware:nil];
[self setCdsGPU:nil];
[self setCdsOutputList:nil];
pthread_cancel(coreThread);
pthread_join(coreThread, NULL);

View File

@ -110,6 +110,13 @@ SineWaveGenerator sineWaveGenerator(250.0, MIC_SAMPLE_RATE);
{
delete CAInputDevice;
delete _hwMicLevelList;
[self setDelegate:nil];
[self setHardwareMicInfoString:nil];
[self setHardwareMicNameString:nil];
[self setHardwareMicManufacturerString:nil];
[self setHardwareMicSampleRateString:nil];
[super dealloc];
}

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2012-2015 DeSmuME team
Copyright (C) 2012-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -25,8 +25,6 @@
CoreAudioInput::CoreAudioInput()
{
OSStatus error = noErr;
_spinlockAUHAL = (OSSpinLock *)malloc(sizeof(OSSpinLock));
*_spinlockAUHAL = OS_SPINLOCK_INIT;
@ -89,19 +87,19 @@ CoreAudioInput::CoreAudioInput()
CreateAudioUnitInstance(&_auHALInputDevice, &halInputDeviceDesc);
error = NewAUGraph(&_auGraph);
error = AUGraphOpen(_auGraph);
NewAUGraph(&_auGraph);
AUGraphOpen(_auGraph);
#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
error = AUGraphAddNode(_auGraph, (AudioComponentDescription *)&formatConverterDesc, &_auFormatConverterNode);
error = AUGraphAddNode(_auGraph, (AudioComponentDescription *)&outputDesc, &_auOutputNode);
AUGraphAddNode(_auGraph, (AudioComponentDescription *)&formatConverterDesc, &_auFormatConverterNode);
AUGraphAddNode(_auGraph, (AudioComponentDescription *)&outputDesc, &_auOutputNode);
#else
error = AUGraphAddNode(_auGraph, (ComponentDescription *)&formatConverterDesc, &_auFormatConverterNode);
error = AUGraphAddNode(_auGraph, (ComponentDescription *)&outputDesc, &_auOutputNode);
AUGraphAddNode(_auGraph, (ComponentDescription *)&formatConverterDesc, &_auFormatConverterNode);
AUGraphAddNode(_auGraph, (ComponentDescription *)&outputDesc, &_auOutputNode);
#endif
error = AUGraphConnectNodeInput(_auGraph, _auFormatConverterNode, 0, _auOutputNode, 0);
AUGraphConnectNodeInput(_auGraph, _auFormatConverterNode, 0, _auOutputNode, 0);
error = AUGraphNodeInfo(_auGraph, _auFormatConverterNode, NULL, &_auFormatConverterUnit);
error = AUGraphNodeInfo(_auGraph, _auOutputNode, NULL, &_auOutputUnit);
AUGraphNodeInfo(_auGraph, _auFormatConverterNode, NULL, &_auFormatConverterUnit);
AUGraphNodeInfo(_auGraph, _auOutputNode, NULL, &_auOutputUnit);
static const UInt32 disableFlag = 0;
static const UInt32 enableFlag = 1;
@ -109,19 +107,19 @@ CoreAudioInput::CoreAudioInput()
static const AudioUnitScope outputBus = 0;
UInt32 propertySize = 0;
error = AudioUnitSetProperty(_auHALInputDevice,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
inputBus,
&enableFlag,
sizeof(enableFlag) );
AudioUnitSetProperty(_auHALInputDevice,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
inputBus,
&enableFlag,
sizeof(enableFlag) );
error = AudioUnitSetProperty(_auHALInputDevice,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
outputBus,
&disableFlag,
sizeof(disableFlag) );
AudioUnitSetProperty(_auHALInputDevice,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
outputBus,
&disableFlag,
sizeof(disableFlag) );
AudioStreamBasicDescription outputFormat;
propertySize = sizeof(AudioStreamBasicDescription);
@ -135,48 +133,48 @@ CoreAudioInput::CoreAudioInput()
outputFormat.mBitsPerChannel = MIC_SAMPLE_RESOLUTION;
AudioStreamBasicDescription deviceOutputFormat;
error = AudioUnitGetProperty(_auOutputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0,
&deviceOutputFormat,
&propertySize);
AudioUnitGetProperty(_auOutputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0,
&deviceOutputFormat,
&propertySize);
error = AudioUnitSetProperty(_auFormatConverterUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&outputFormat,
propertySize);
AudioUnitSetProperty(_auFormatConverterUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&outputFormat,
propertySize);
error = AudioUnitSetProperty(_auFormatConverterUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0,
&outputFormat,
propertySize);
AudioUnitSetProperty(_auFormatConverterUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0,
&outputFormat,
propertySize);
error = AudioUnitSetProperty(_auOutputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&outputFormat,
propertySize);
AudioUnitSetProperty(_auOutputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&outputFormat,
propertySize);
error = AudioUnitSetProperty(_auOutputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0,
&outputFormat,
propertySize);
AudioUnitSetProperty(_auOutputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0,
&outputFormat,
propertySize);
static const UInt32 bestQuality = kAudioUnitSampleRateConverterComplexity_Mastering;
error = AudioUnitSetProperty(_auFormatConverterUnit,
kAudioUnitProperty_SampleRateConverterComplexity,
kAudioUnitScope_Global,
0,
&bestQuality,
sizeof(bestQuality));
AudioUnitSetProperty(_auFormatConverterUnit,
kAudioUnitProperty_SampleRateConverterComplexity,
kAudioUnitScope_Global,
0,
&bestQuality,
sizeof(bestQuality));
// Set up the capture buffers.
const size_t audioBufferListSize = offsetof(AudioBufferList, mBuffers[0]) + sizeof(AudioBuffer);
@ -201,39 +199,39 @@ CoreAudioInput::CoreAudioInput()
inputCaptureCallback.inputProc = &CoreAudioInputCaptureCallback;
inputCaptureCallback.inputProcRefCon = this;
error = AudioUnitSetProperty(_auHALInputDevice,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
0,
&inputCaptureCallback,
sizeof(inputCaptureCallback) );
AudioUnitSetProperty(_auHALInputDevice,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
0,
&inputCaptureCallback,
sizeof(inputCaptureCallback) );
error = AudioUnitAddPropertyListener(this->_auHALInputDevice,
kAudioDevicePropertyVolumeScalar,
&CoreAudioInputAUHALChanged,
this);
AudioUnitAddPropertyListener(this->_auHALInputDevice,
kAudioDevicePropertyVolumeScalar,
&CoreAudioInputAUHALChanged,
this);
error = AudioUnitAddPropertyListener(this->_auHALInputDevice,
kAudioHardwarePropertyDefaultInputDevice,
&CoreAudioInputAUHALChanged,
this);
AudioUnitAddPropertyListener(this->_auHALInputDevice,
kAudioHardwarePropertyDefaultInputDevice,
&CoreAudioInputAUHALChanged,
this);
error = AudioUnitAddPropertyListener(this->_auHALInputDevice,
kAudioDevicePropertyHogMode,
&CoreAudioInputAUHALChanged,
this);
AudioUnitAddPropertyListener(this->_auHALInputDevice,
kAudioDevicePropertyHogMode,
&CoreAudioInputAUHALChanged,
this);
error = AudioUnitAddPropertyListener(this->_auHALInputDevice,
kAudioDevicePropertyJackIsConnected,
&CoreAudioInputAUHALChanged,
this);
AudioUnitAddPropertyListener(this->_auHALInputDevice,
kAudioDevicePropertyJackIsConnected,
&CoreAudioInputAUHALChanged,
this);
AudioObjectPropertyAddress defaultDeviceProperty;
defaultDeviceProperty.mSelector = kAudioHardwarePropertyDefaultInputDevice;
defaultDeviceProperty.mScope = kAudioObjectPropertyScopeGlobal;
defaultDeviceProperty.mElement = kAudioObjectPropertyElementMaster;
error = AudioObjectAddPropertyListener(kAudioObjectSystemObject,
AudioObjectAddPropertyListener(kAudioObjectSystemObject,
&defaultDeviceProperty,
&CoreAudioInputDeviceChanged,
this);
@ -243,14 +241,14 @@ CoreAudioInput::CoreAudioInput()
inputReceiveCallback.inputProc = &CoreAudioInputReceiveCallback;
inputReceiveCallback.inputProcRefCon = this->_samplesCaptured;
error = AudioUnitSetProperty(_auFormatConverterUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Global,
0,
&inputReceiveCallback,
sizeof(inputReceiveCallback) );
AudioUnitSetProperty(_auFormatConverterUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Global,
0,
&inputReceiveCallback,
sizeof(inputReceiveCallback) );
error = AUGraphAddRenderNotify(_auGraph, &CoreAudioInputConvertCallback, this->_samplesConverted);
AUGraphAddRenderNotify(_auGraph, &CoreAudioInputConvertCallback, this->_samplesConverted);
}
CoreAudioInput::~CoreAudioInput()
@ -472,12 +470,12 @@ void CoreAudioInput::Start()
defaultDeviceProperty.mScope = kAudioObjectPropertyScopeGlobal;
defaultDeviceProperty.mElement = kAudioObjectPropertyElementMaster;
error = AudioObjectGetPropertyData(kAudioObjectSystemObject,
&defaultDeviceProperty,
0,
NULL,
&propertySize,
&defaultInputDeviceID);
AudioObjectGetPropertyData(kAudioObjectSystemObject,
&defaultDeviceProperty,
0,
NULL,
&propertySize,
&defaultInputDeviceID);
// Set the default input device to the audio unit.
OSSpinLockLock(this->_spinlockAUHAL);
@ -518,15 +516,15 @@ void CoreAudioInput::Start()
if (this->IsHardwareEnabled() && !this->IsHardwareLocked() && !this->GetPauseState())
{
error = AudioOutputUnitStart(this->_auHALInputDevice);
AudioOutputUnitStart(this->_auHALInputDevice);
}
OSSpinLockUnlock(this->_spinlockAUHAL);
error = AUGraphInitialize(_auGraph);
AUGraphInitialize(_auGraph);
if (!this->GetPauseState())
{
error = AUGraphStart(this->_auGraph);
AUGraphStart(this->_auGraph);
}
this->_samplesCaptured->clear();
@ -555,15 +553,14 @@ void CoreAudioInput::Stop()
size_t CoreAudioInput::Pull()
{
OSStatus error = noErr;
AudioUnitRenderActionFlags ioActionFlags = 0;
error = AudioUnitRender(this->_auOutputUnit,
&ioActionFlags,
&this->_timeStamp,
0,
MIC_CAPTURE_FRAMES,
this->_convertBufferList);
AudioUnitRender(this->_auOutputUnit,
&ioActionFlags,
&this->_timeStamp,
0,
MIC_CAPTURE_FRAMES,
this->_convertBufferList);
return MIC_CAPTURE_FRAMES;
}
@ -610,17 +607,16 @@ float CoreAudioInput::GetGain() const
void CoreAudioInput::SetGain(float normalizedGain)
{
OSStatus error = noErr;
Float32 gainValue = normalizedGain;
UInt32 gainPropSize = sizeof(gainValue);
OSSpinLockLock(this->_spinlockAUHAL);
error = AudioUnitSetProperty(this->_auHALInputDevice,
kAudioDevicePropertyVolumeScalar,
kAudioUnitScope_Input,
this->_inputElement,
&gainValue,
gainPropSize);
AudioUnitSetProperty(this->_auHALInputDevice,
kAudioDevicePropertyVolumeScalar,
kAudioUnitScope_Input,
this->_inputElement,
&gainValue,
gainPropSize);
OSSpinLockUnlock(this->_spinlockAUHAL);
}
@ -671,17 +667,16 @@ void CoreAudioInput::UpdateHardwareLock()
&propertySize);
if (error == noErr)
{
// If the kAudioDevicePropertyJackIsConnected property is supported,
// then lock the hardware if the jack isn't connected.
//
// If the kAudioDevicePropertyJackIsConnected property is not supported,
// then always assume that the hardware device is always plugged in.
if (isJackConnected == 0)
{
hardwareLocked = true;
}
}
else
{
// If this property is not supported, then always assume that
// the hardware device is always plugged in.
isJackConnected = 1;
}
}
else
{

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2011 Roger Manuel
Copyright (C) 2012-2015 DeSmuME team
Copyright (C) 2012-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -69,14 +69,14 @@ void Mic_SetSampleReadCallback(MicSampleReadCallback callbackFunc, void *inParam
_sampleReadCallbackParam2 = inParam2;
}
void mic_savestate(EMUFILE* os)
void mic_savestate(EMUFILE &os)
{
write32le(-1, os);
os.write_32LE(-1);
}
bool mic_loadstate(EMUFILE* is, int size)
bool mic_loadstate(EMUFILE &is, int size)
{
is->fseek(size, SEEK_CUR);
is.fseek(size, SEEK_CUR);
return true;
}

View File

@ -1209,7 +1209,6 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
if ([(id)theItem isMemberOfClass:[NSMenuItem class]])
{
[(NSMenuItem *)theItem setState:([self videoSourceDeposterize]) ? NSOnState : NSOffState];
enable = [[self view] canUseShaderBasedFilters];
}
enable = [[self view] canUseShaderBasedFilters];

View File

@ -272,11 +272,7 @@
#pragma mark NSOutlineViewDataSource Protocol
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
if (item == nil)
{
return [_fileTreeVersionList objectAtIndex:index];
}
else if ([item isKindOfClass:[NSString class]])
if ([item isKindOfClass:[NSString class]])
{
NSArray *versionKeys = [(NSDictionary *)[_fileTree objectForKey:(NSString *)item] allKeys];
return [(NSDictionary *)[_fileTree objectForKey:(NSString *)item] objectForKey:[versionKeys objectAtIndex:index]];
@ -286,7 +282,7 @@
return [(NSArray *)item objectAtIndex:index];
}
return nil;
return [_fileTreeVersionList objectAtIndex:index];
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2011 Roger Manuel
Copyright (C) 2012-2015 DeSmuME Team
Copyright (C) 2012-2017 DeSmuME Team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -314,14 +314,13 @@ static NSDictionary *hidUsageTable = nil;
if (theRunLoop == nil)
{
IOHIDQueueRegisterValueAvailableCallback(hidQueueRef, NULL, NULL);
IOHIDQueueUnscheduleFromRunLoop(hidQueueRef, [runLoop getCFRunLoop], kCFRunLoopDefaultMode);
}
else
{
[theRunLoop retain];
IOHIDQueueScheduleWithRunLoop(hidQueueRef, [theRunLoop getCFRunLoop], kCFRunLoopDefaultMode);
IOHIDQueueRegisterValueAvailableCallback(hidQueueRef, HandleQueueValueAvailableCallback, self);
IOHIDQueueScheduleWithRunLoop(hidQueueRef, [theRunLoop getCFRunLoop], kCFRunLoopDefaultMode);
}
[runLoop release];
@ -546,23 +545,23 @@ InputAttributesList InputListFromHIDValue(IOHIDValueRef hidValueRef, InputManage
{
InputAttributes hatUp = inputAttr;
hatUp.isAnalog = false;
strncat(hatUp.elementName, "/Up", INPUT_HANDLER_STRING_LENGTH);
strncat(hatUp.elementCode, "/Up", INPUT_HANDLER_STRING_LENGTH);
strncat(hatUp.elementName, "/Up", 4);
strncat(hatUp.elementCode, "/Up", 4);
InputAttributes hatRight = inputAttr;
hatRight.isAnalog = false;
strncat(hatRight.elementName, "/Right", INPUT_HANDLER_STRING_LENGTH);
strncat(hatRight.elementCode, "/Right", INPUT_HANDLER_STRING_LENGTH);
strncat(hatRight.elementName, "/Right", 7);
strncat(hatRight.elementCode, "/Right", 7);
InputAttributes hatDown = inputAttr;
hatDown.isAnalog = false;
strncat(hatDown.elementName, "/Down", INPUT_HANDLER_STRING_LENGTH);
strncat(hatDown.elementCode, "/Down", INPUT_HANDLER_STRING_LENGTH);
strncat(hatDown.elementName, "/Down", 6);
strncat(hatDown.elementCode, "/Down", 6);
InputAttributes hatLeft = inputAttr;
hatLeft.isAnalog = false;
strncat(hatLeft.elementName, "/Left", INPUT_HANDLER_STRING_LENGTH);
strncat(hatLeft.elementCode, "/Left", INPUT_HANDLER_STRING_LENGTH);
strncat(hatLeft.elementName, "/Left", 6);
strncat(hatLeft.elementCode, "/Left", 6);
if (inputAttr.intCoordX == -1)
{
@ -626,13 +625,13 @@ InputAttributesList InputListFromHIDValue(IOHIDValueRef hidValueRef, InputManage
{
InputAttributes loInputAttr = inputAttr;
loInputAttr.isAnalog = false;
strncat(loInputAttr.elementName, "-", INPUT_HANDLER_STRING_LENGTH);
strncat(loInputAttr.elementCode, "/LowerThreshold", INPUT_HANDLER_STRING_LENGTH);
strncat(loInputAttr.elementName, "-", 2);
strncat(loInputAttr.elementCode, "/LowerThreshold", 16);
InputAttributes hiInputAttr = inputAttr;
hiInputAttr.isAnalog = false;
strncat(hiInputAttr.elementName, "+", INPUT_HANDLER_STRING_LENGTH);
strncat(hiInputAttr.elementCode, "/UpperThreshold", INPUT_HANDLER_STRING_LENGTH);
strncat(hiInputAttr.elementName, "+", 2);
strncat(hiInputAttr.elementCode, "/UpperThreshold", 16);
if (loInputAttr.scalar <= 0.30f)
{
@ -881,6 +880,7 @@ void HandleQueueValueAvailableCallback(void *inContext, IOReturn inResult, void
- (void)dealloc
{
[self setRunLoop:nil];
[self setDeviceListController:nil];
[self setInputManager:nil];
[self setTarget:nil];

View File

@ -132,18 +132,14 @@
#pragma mark NSOutlineViewDataSource Protocol
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
if (item == nil)
{
NSDictionary *mappings = [(NSDictionary *)[self content] valueForKey:@"Mappings"];
NSString *commandTag = [[inputManager commandTagList] objectAtIndex:index];
return [mappings valueForKey:commandTag];
}
else if ([item isKindOfClass:[NSArray class]])
if ([item isKindOfClass:[NSArray class]])
{
return [(NSArray *)item objectAtIndex:index];
}
return nil;
NSDictionary *mappings = [(NSDictionary *)[self content] valueForKey:@"Mappings"];
NSString *commandTag = [[inputManager commandTagList] objectAtIndex:index];
return [mappings valueForKey:commandTag];
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item

View File

@ -209,7 +209,7 @@
texDisplayPostprocessNativeTouch = [[device newTextureWithDescriptor:texDisplayLoad32Desc] retain];
texDisplayPostprocessCustomTouch = [[device newTextureWithDescriptor:texDisplayLoad32Desc] retain];
uint16_t *blankBuffer = (uint16_t *)calloc(GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT, sizeof(uint32_t));
uint32_t *blankBuffer = (uint32_t *)calloc(GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT, sizeof(uint32_t));
const MTLRegion texRegionNative = MTLRegionMake2D(0, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT);
[texDisplayFetch32NativeMain replaceRegion:texRegionNative
mipmapLevel:0

View File

@ -90,17 +90,18 @@ void MacOGLClientFetchObject::operator delete(void *ptr)
[(MacClientSharedObject *)(fetchObjectPtr->GetClientData()) release];
CGLContextObj context = fetchObjectPtr->GetContext();
OGLContextInfo *contextInfo = fetchObjectPtr->GetContextInfo();
if (context != NULL)
{
OGLContextInfo *contextInfo = fetchObjectPtr->GetContextInfo();
CGLContextObj prevContext = CGLGetCurrentContext();
CGLSetCurrentContext(context);
::operator delete(ptr);
CGLSetCurrentContext(prevContext);
delete contextInfo;
[fetchObjectPtr->GetNSContext() release];
delete contextInfo;
::operator delete(ptr);
CGLSetCurrentContext(prevContext);
}
}
@ -216,18 +217,19 @@ void MacOGLClientFetchObject::FetchFromBufferIndex(const u8 index)
void MacOGLDisplayView::operator delete(void *ptr)
{
CGLContextObj context = ((MacOGLDisplayView *)ptr)->GetContext();
OGLContextInfo *contextInfo = ((MacOGLDisplayView *)ptr)->GetContextInfo();
if (context != NULL)
{
OGLContextInfo *contextInfo = ((MacOGLDisplayView *)ptr)->GetContextInfo();
CGLContextObj prevContext = CGLGetCurrentContext();
CGLSetCurrentContext(context);
::operator delete(ptr);
CGLSetCurrentContext(prevContext);
delete contextInfo;
[((MacOGLDisplayView *)ptr)->GetNSContext() release];
[((MacOGLDisplayView *)ptr)->GetNSPixelFormat() release];
delete contextInfo;
::operator delete(ptr);
CGLSetCurrentContext(prevContext);
}
}
@ -266,7 +268,6 @@ MacOGLDisplayView::MacOGLDisplayView()
{
// If we can't get a 3.2 Core Profile context, then switch to using a
// legacy context instead.
useContext_3_2 = false;
attributes[9] = (NSOpenGLPixelFormatAttribute)0;
attributes[10] = (NSOpenGLPixelFormatAttribute)0;
_nsPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];

View File

@ -69,6 +69,7 @@
return nil;
}
selectedDevice = nil;
deviceManager = [[[[CocoaDSSlot2Manager alloc] init] retain] autorelease];
hidManager = nil;
currentDeviceView = viewNoSelection;
@ -90,8 +91,10 @@
- (void)dealloc
{
[self setSelectedDevice:nil];
[self setDeviceManager:nil];
[self setHidManager:nil];
[self setAutoSelectedDeviceText:nil];
[self setMpcfFolderURL:nil];
[self setMpcfDiskImageURL:nil];
[self setGbaCartridgeURL:nil];

View File

@ -113,6 +113,9 @@
[inputSettingsMappings release];
[savedProfilesList release];
[self setConfigInputTargetID:nil];
[self setInputSettingsInEdit:nil];
[super dealloc];
}
@ -577,17 +580,13 @@
#pragma mark NSOutlineViewDataSource Protocol
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
if (item == nil)
{
NSString *commandTag = [[inputManager commandTagList] objectAtIndex:index];
return [[inputManager inputMappings] valueForKey:commandTag];
}
else if ([item isKindOfClass:[NSArray class]])
if ([item isKindOfClass:[NSArray class]])
{
return [(NSArray *)item objectAtIndex:index];
}
return nil;
NSString *commandTag = [[inputManager commandTagList] objectAtIndex:index];
return [[inputManager inputMappings] valueForKey:commandTag];
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item

View File

@ -5632,7 +5632,7 @@ DOKEYDOWN:
}
EMUFILE_FILE outf(advsc.getDatabase(),"wb");
u32 count = advsc.convertDB(ImportSavName,&outf);
u32 count = advsc.convertDB(ImportSavName,outf);
if (count > 0)
{
sprintf(buffer, "ADVANsCEne database was successfully imported\n(%i records)", count);

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2008-2016 DeSmuME team
Copyright (C) 2008-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -88,27 +88,30 @@ static FILE* fp = NULL;
EMUFILE_MEMORY newWavData;
static bool dataChunk(EMUFILE* inf)
static bool dataChunk(EMUFILE &inf)
{
bool found = false;
// seek to just after the RIFF header
inf->fseek(12,SEEK_SET);
inf.fseek(12,SEEK_SET);
// search for a format chunk
for (;;) {
for (;;)
{
char chunk_id[4];
u32 chunk_length;
u32 chunk_length;
if(inf->eof()) return found;
if(inf->fread(chunk_id, 4) != 4) return found;
if(!read32le(&chunk_length, inf)) return found;
if (inf.eof()) return found;
if (inf.fread(chunk_id, 4) != 4) return found;
if (!inf.read_32LE(chunk_length)) return found;
// if we found a data chunk, excellent!
if (memcmp(chunk_id, "data", 4) == 0) {
if (memcmp(chunk_id, "data", 4) == 0)
{
found = true;
u8* temp = new u8[chunk_length];
if(inf->fread(temp,chunk_length) != chunk_length) {
u8 *temp = new u8[chunk_length];
if (inf.fread(temp,chunk_length) != chunk_length)
{
delete[] temp;
return false;
}
@ -117,27 +120,29 @@ static bool dataChunk(EMUFILE* inf)
chunk_length = 0;
}
inf->fseek(chunk_length,SEEK_CUR);
inf.fseek(chunk_length,SEEK_CUR);
}
return found;
}
static bool formatChunk(EMUFILE* inf)
static bool formatChunk(EMUFILE &inf)
{
// seek to just after the RIFF header
inf->fseek(12,SEEK_SET);
inf.fseek(12,SEEK_SET);
// search for a format chunk
for (;;) {
for (;;)
{
char chunk_id[4];
u32 chunk_length;
u32 chunk_length;
inf->fread(chunk_id, 4);
if(!read32le(&chunk_length, inf)) return false;
inf.fread(chunk_id, 4);
if (!inf.read_32LE(chunk_length)) return false;
// if we found a format chunk, excellent!
if (memcmp(chunk_id, "fmt ", 4) == 0 && chunk_length >= 16) {
if (memcmp(chunk_id, "fmt ", 4) == 0 && chunk_length >= 16)
{
// read format chunk
u16 format_tag;
@ -147,11 +152,11 @@ static bool formatChunk(EMUFILE* inf)
//u16 block_align = read16_le(chunk + 12);
u16 bits_per_sample;
if(read16le(&format_tag,inf)!=1) return false;
if(read16le(&channel_count,inf)!=1) return false;
if(read32le(&samples_per_second,inf)!=1) return false;
inf->fseek(6,SEEK_CUR);
if(read16le(&bits_per_sample,inf)!=1) return false;
if (inf.read_16LE(format_tag) != 1) return false;
if (inf.read_16LE(channel_count) != 1) return false;
if (inf.read_32LE(samples_per_second) != 1) return false;
inf.fseek(6,SEEK_CUR);
if (inf.read_16LE(bits_per_sample) != 1) return false;
chunk_length -= 16;
@ -159,7 +164,8 @@ static bool formatChunk(EMUFILE* inf)
// we only support mono 8bit
if (format_tag != 1 ||
channel_count != 1 ||
bits_per_sample != 8) {
bits_per_sample != 8)
{
MessageBox(0,"not a valid RIFF WAVE file; must be 8bit mono pcm",0,0);
return false;
}
@ -167,7 +173,7 @@ static bool formatChunk(EMUFILE* inf)
return true;
}
inf->fseek(chunk_length,SEEK_CUR);
inf.fseek(chunk_length,SEEK_CUR);
}
return false;
}
@ -175,10 +181,10 @@ static bool formatChunk(EMUFILE* inf)
bool LoadSample(const char *name)
{
SampleLoaded = 0;
if(!name) return true;
if (!name) return true;
EMUFILE_FILE inf(name,"rb");
if(inf.fail()) return false;
if (inf.fail()) return false;
//wav reading code adapted from AUDIERE (LGPL)
@ -188,7 +194,7 @@ bool LoadSample(const char *name)
u8 riff_datatype[4];
inf.fread(riff_id, 4);
read32le(&riff_length,&inf);
inf.read_32LE(riff_length);
inf.fread(riff_datatype, 4);
if (inf.size() < 12 ||
@ -202,7 +208,8 @@ bool LoadSample(const char *name)
if (!formatChunk(&inf))
return false;
if(!dataChunk(&inf)) {
if (!dataChunk(&inf))
{
MessageBox(0,"not a valid WAVE file. some unknown problem.",0,0);
return false;
}
@ -235,7 +242,7 @@ BOOL Mic_DeInit_Physical()
BOOL Mic_Init_Physical()
{
if(Mic_Inited)
if (Mic_Inited)
return TRUE;
Mic_Inited = FALSE;
@ -282,8 +289,8 @@ BOOL Mic_Init_Physical()
return TRUE;
}
BOOL Mic_Init() {
BOOL Mic_Init()
{
micReadSamplePos = 0;
return TRUE;
@ -293,7 +300,7 @@ void Mic_Reset()
{
micReadSamplePos = 0;
if(!Mic_Inited)
if (!Mic_Inited)
return;
//reset physical
@ -310,8 +317,7 @@ void Mic_DeInit()
{
}
static const u8 random[32] =
{
static const u8 random[32] = {
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0x8E, 0xFF,
0xF4, 0xE1, 0xBF, 0x9A, 0x71, 0x58, 0x5B, 0x5F, 0x62, 0xC2, 0x25, 0x05, 0x01, 0x01, 0x01, 0x01,
} ;
@ -322,9 +328,9 @@ u8 Mic_ReadSample()
{
u8 ret;
u8 tmp;
if(CommonSettings.micMode == TCommonSettings::Physical)
if (CommonSettings.micMode == TCommonSettings::Physical)
{
if(movieMode == MOVIEMODE_INACTIVE)
if (movieMode == MOVIEMODE_INACTIVE)
{
//normal mic behavior
tmp = (u8)Mic_Buffer[Mic_PlayBuf][Mic_BufPos >> 1];
@ -337,9 +343,9 @@ u8 Mic_ReadSample()
}
else
{
if(NDS_getFinalUserInput().mic.micButtonPressed)
if (NDS_getFinalUserInput().mic.micButtonPressed)
{
if(SampleLoaded)
if (SampleLoaded)
{
//use a sample
//TODO: what if a movie is active?
@ -348,17 +354,17 @@ u8 Mic_ReadSample()
// or they're playing a game where it doesn't even matter or they never press the mic button.
tmp = samplebuffer[micReadSamplePos >> 1];
micReadSamplePos++;
if(micReadSamplePos == samplebuffersize*2)
if (micReadSamplePos == samplebuffersize*2)
micReadSamplePos=0;
}
else
{
//use the "random" values
if(CommonSettings.micMode == TCommonSettings::InternalNoise)
if (CommonSettings.micMode == TCommonSettings::InternalNoise)
tmp = random[micReadSamplePos >> 1];
else tmp = rand();
micReadSamplePos++;
if(micReadSamplePos == ARRAY_SIZE(random)*2)
if (micReadSamplePos == ARRAY_SIZE(random)*2)
micReadSamplePos=0;
}
}
@ -371,7 +377,7 @@ u8 Mic_ReadSample()
}
}
if(Mic_BufPos & 0x1)
if (Mic_BufPos & 0x1)
{
ret = ((tmp & 0x1) << 7);
}
@ -383,7 +389,7 @@ u8 Mic_ReadSample()
MicDisplay = tmp;
Mic_BufPos++;
if(Mic_BufPos >= (MIC_BUFSIZE << 1))
if (Mic_BufPos >= (MIC_BUFSIZE << 1))
{
Mic_BufPos = 0;
Mic_PlayBuf ^= 1;
@ -393,31 +399,31 @@ u8 Mic_ReadSample()
}
// maybe a bit paranoid...
void mic_savestate(EMUFILE* os)
void mic_savestate(EMUFILE &os)
{
//version
write32le(1,os);
os.write_32LE(1);
assert(MIC_BUFSIZE == 4096); // else needs new version
os->fwrite((char*)Mic_Buffer[0], MIC_BUFSIZE);
os->fwrite((char*)Mic_Buffer[1], MIC_BUFSIZE);
write16le(Mic_BufPos,os);
write8le(Mic_WriteBuf,os); // seems OK to save...
write8le(Mic_PlayBuf,os);
write32le(micReadSamplePos,os);
os.fwrite(Mic_Buffer[0], MIC_BUFSIZE);
os.fwrite(Mic_Buffer[1], MIC_BUFSIZE);
os.write_16LE(Mic_BufPos);
os.write_u8(Mic_WriteBuf); // seems OK to save...
os.write_u8(Mic_PlayBuf);
os.write_32LE(micReadSamplePos);
}
bool mic_loadstate(EMUFILE* is, int size)
bool mic_loadstate(EMUFILE &is, int size)
{
u32 version;
if(read32le(&version,is) != 1) return false;
if(version > 1 || version == 0) { is->fseek(size-4, SEEK_CUR); return true; }
if (is.read_32LE(version) != 1) return false;
if (version > 1 || version == 0) { is.fseek(size-4, SEEK_CUR); return true; }
is->fread((char*)Mic_Buffer[0], MIC_BUFSIZE);
is->fread((char*)Mic_Buffer[1], MIC_BUFSIZE);
read16le(&Mic_BufPos,is);
read8le(&Mic_WriteBuf,is);
read8le(&Mic_PlayBuf,is);
read32le(&micReadSamplePos,is);
is.fread(Mic_Buffer[0], MIC_BUFSIZE);
is.fread(Mic_Buffer[1], MIC_BUFSIZE);
is.read_16LE(Mic_BufPos);
is.read_u8(Mic_WriteBuf);
is.read_u8(Mic_PlayBuf);
is.read_32LE(micReadSamplePos);
return true;
}

View File

@ -209,17 +209,17 @@ private:
public:
void savestate(EMUFILE *f)
void savestate(EMUFILE &f)
{
write32le(2,f); //version
write32le(shiftCommand,f);
write32le(paramCounter,f);
f.write_32LE(2); //version
f.write_32LE(shiftCommand);
f.write_32LE(paramCounter);
}
bool loadstate(EMUFILE *f)
bool loadstate(EMUFILE &f)
{
u32 version;
if(read32le(&version,f) != 1) return false;
if (f.read_32LE(version) != 1) return false;
u8 junk8;
u32 junk32;
@ -227,26 +227,26 @@ public:
if (version == 0)
{
//untested
read32le(&junk32,f);
f.read_32LE(junk32);
int commandCursor = 4-junk32;
for(u32 i=commandCursor;i<4;i++) read8le(&junk8,f);
read32le(&junk32,f);
for(u32 i=commandCursor;i<4;i++) read8le(&junk8,f);
read8le(&junk8,f);
for (u32 i=commandCursor;i<4;i++) f.read_u8(junk8);
f.read_32LE(junk32);
for (u32 i=commandCursor;i<4;i++) f.read_u8(junk8);
f.read_u8(junk8);
}
else if (version == 1)
{
//untested
read32le(&junk32,f);
read32le(&junk32,f);
for(u32 i=0;i<4;i++) read8le(&junk8,f);
for(u32 i=0;i<4;i++) read8le(&junk8,f);
read8le(&junk8,f);
f.read_32LE(junk32);
f.read_32LE(junk32);
for (u32 i=0;i<4;i++) f.read_u8(junk8);
for (u32 i=0;i<4;i++) f.read_u8(junk8);
f.read_u8(junk8);
}
else if (version == 2)
{
read32le(&shiftCommand,f);
read32le(&paramCounter,f);
f.read_32LE(shiftCommand);
f.read_32LE(paramCounter);
}
return true;
@ -431,42 +431,68 @@ static void makeTables()
}
}
#define OSWRITE(x) os->fwrite((char*)&(x),sizeof((x)));
#define OSREAD(x) is->fread((char*)&(x),sizeof((x)));
void POLY::save(EMUFILE* os)
void POLY::save(EMUFILE &os)
{
OSWRITE(type);
OSWRITE(vertIndexes[0]); OSWRITE(vertIndexes[1]); OSWRITE(vertIndexes[2]); OSWRITE(vertIndexes[3]);
OSWRITE(polyAttr); OSWRITE(texParam); OSWRITE(texPalette);
OSWRITE(viewport);
OSWRITE(miny);
OSWRITE(maxy);
os.write_32LE((u32)type);
os.write_16LE(vertIndexes[0]);
os.write_16LE(vertIndexes[1]);
os.write_16LE(vertIndexes[2]);
os.write_16LE(vertIndexes[3]);
os.write_32LE(polyAttr);
os.write_32LE(texParam);
os.write_32LE(texPalette);
os.write_32LE(viewport);
os.write_floatLE(miny);
os.write_floatLE(maxy);
}
void POLY::load(EMUFILE* is)
void POLY::load(EMUFILE &is)
{
OSREAD(type);
OSREAD(vertIndexes[0]); OSREAD(vertIndexes[1]); OSREAD(vertIndexes[2]); OSREAD(vertIndexes[3]);
OSREAD(polyAttr); OSREAD(texParam); OSREAD(texPalette);
OSREAD(viewport);
OSREAD(miny);
OSREAD(maxy);
u32 polyType32;
is.read_32LE(polyType32);
type = (PolygonType)polyType32;
is.read_16LE(vertIndexes[0]);
is.read_16LE(vertIndexes[1]);
is.read_16LE(vertIndexes[2]);
is.read_16LE(vertIndexes[3]);
is.read_32LE(polyAttr);
is.read_32LE(texParam);
is.read_32LE(texPalette);
is.read_32LE(viewport);
is.read_floatLE(miny);
is.read_floatLE(maxy);
}
void VERT::save(EMUFILE* os)
void VERT::save(EMUFILE &os)
{
OSWRITE(x); OSWRITE(y); OSWRITE(z); OSWRITE(w);
OSWRITE(u); OSWRITE(v);
OSWRITE(color[0]); OSWRITE(color[1]); OSWRITE(color[2]);
OSWRITE(fcolor[0]); OSWRITE(fcolor[1]); OSWRITE(fcolor[2]);
os.write_floatLE(x);
os.write_floatLE(y);
os.write_floatLE(z);
os.write_floatLE(w);
os.write_floatLE(u);
os.write_floatLE(v);
os.write_u8(color[0]);
os.write_u8(color[1]);
os.write_u8(color[2]);
os.write_floatLE(fcolor[0]);
os.write_floatLE(fcolor[1]);
os.write_floatLE(fcolor[2]);
}
void VERT::load(EMUFILE* is)
void VERT::load(EMUFILE &is)
{
OSREAD(x); OSREAD(y); OSREAD(z); OSREAD(w);
OSREAD(u); OSREAD(v);
OSREAD(color[0]); OSREAD(color[1]); OSREAD(color[2]);
OSREAD(fcolor[0]); OSREAD(fcolor[1]); OSREAD(fcolor[2]);
is.read_floatLE(x);
is.read_floatLE(y);
is.read_floatLE(z);
is.read_floatLE(w);
is.read_floatLE(u);
is.read_floatLE(v);
is.read_u8(color[0]);
is.read_u8(color[1]);
is.read_u8(color[2]);
is.read_floatLE(fcolor[0]);
is.read_floatLE(fcolor[1]);
is.read_floatLE(fcolor[2]);
}
void gfx3d_init()
@ -1641,7 +1667,7 @@ static BOOL gfx3d_glBoxTest(u32 v)
CACHE_ALIGN float temp1[16] = {mtxCurrent[1][0]/4096.0f,mtxCurrent[1][1]/4096.0f,mtxCurrent[1][2]/4096.0f,mtxCurrent[1][3]/4096.0f,mtxCurrent[1][4]/4096.0f,mtxCurrent[1][5]/4096.0f,mtxCurrent[1][6]/4096.0f,mtxCurrent[1][7]/4096.0f,mtxCurrent[1][8]/4096.0f,mtxCurrent[1][9]/4096.0f,mtxCurrent[1][10]/4096.0f,mtxCurrent[1][11]/4096.0f,mtxCurrent[1][12]/4096.0f,mtxCurrent[1][13]/4096.0f,mtxCurrent[1][14]/4096.0f,mtxCurrent[1][15]/4096.0f};
CACHE_ALIGN float temp0[16] = {mtxCurrent[0][0]/4096.0f,mtxCurrent[0][1]/4096.0f,mtxCurrent[0][2]/4096.0f,mtxCurrent[0][3]/4096.0f,mtxCurrent[0][4]/4096.0f,mtxCurrent[0][5]/4096.0f,mtxCurrent[0][6]/4096.0f,mtxCurrent[0][7]/4096.0f,mtxCurrent[0][8]/4096.0f,mtxCurrent[0][9]/4096.0f,mtxCurrent[0][10]/4096.0f,mtxCurrent[0][11]/4096.0f,mtxCurrent[0][12]/4096.0f,mtxCurrent[0][13]/4096.0f,mtxCurrent[0][14]/4096.0f,mtxCurrent[0][15]/4096.0f};
DS_ALIGN(16) VERT_POS4f vert = { verts[i].x, verts[i].y, verts[i].z, verts[i].w };
//DS_ALIGN(16) VERT_POS4f vert = { verts[i].x, verts[i].y, verts[i].z, verts[i].w };
_NOSSE_MatrixMultVec4x4(temp1,verts[i].coord);
_NOSSE_MatrixMultVec4x4(temp0,verts[i].coord);
@ -2580,7 +2606,7 @@ void gfx3d_Update3DFramebuffers(FragmentColor *framebufferMain, u16 *framebuffer
}
//-------------savestate
void gfx3d_savestate(EMUFILE* os)
void gfx3d_savestate(EMUFILE &os)
{
if (CurrentRenderer->GetRenderNeedsFinish())
{
@ -2588,37 +2614,49 @@ void gfx3d_savestate(EMUFILE* os)
}
//version
write32le(4,os);
os.write_32LE(4);
//dump the render lists
const u32 vertListCount32 = (u32)vertlist->count;
const u32 polyListCount32 = (u32)polylist->count;
OSWRITE(vertListCount32);
os.write_32LE((u32)vertlist->count);
for (size_t i = 0; i < vertlist->count; i++)
vertlist->list[i].save(os);
OSWRITE(polyListCount32);
os.write_32LE((u32)polylist->count);
for (size_t i = 0; i < polylist->count; i++)
polylist->list[i].save(os);
for (size_t i = 0; i < ARRAY_SIZE(mtxStack); i++)
{
OSWRITE(mtxStack[i].position);
for(size_t j = 0; j < mtxStack[i].size*16; j++)
OSWRITE(mtxStack[i].matrix[j]);
os.write_32LE(mtxStack[i].position);
for (size_t j = 0; j < mtxStack[i].size*16; j++)
os.write_32LE(mtxStack[i].matrix[j]);
}
gxf_hardware.savestate(os);
// evidently these need to be saved because we don't cache the matrix that would need to be used to properly regenerate them
OSWRITE(cacheLightDirection);
OSWRITE(cacheHalfVector);
for (size_t i = 0; i < 4; i++)
{
for (size_t j = 0; j < 4; j++)
{
os.write_32LE(cacheLightDirection[i][j]);
}
}
for (size_t i = 0; i < 4; i++)
{
for (size_t j = 0; j < 4; j++)
{
os.write_32LE(cacheHalfVector[i][j]);
}
}
}
bool gfx3d_loadstate(EMUFILE* is, int size)
bool gfx3d_loadstate(EMUFILE &is, int size)
{
int version;
if (read32le(&version,is) != 1) return false;
if (is.read_32LE(version) != 1) return false;
if (size == 8) version = 0;
if (CurrentRenderer->GetRenderNeedsFinish())
@ -2645,12 +2683,12 @@ bool gfx3d_loadstate(EMUFILE* is, int size)
u32 vertListCount32 = 0;
u32 polyListCount32 = 0;
OSREAD(vertListCount32);
is.read_32LE(vertListCount32);
vertlist->count = vertListCount32;
for (size_t i = 0; i < vertlist->count; i++)
vertlist->list[i].load(is);
OSREAD(polyListCount32);
is.read_32LE(polyListCount32);
polylist->count = polyListCount32;
for (size_t i = 0; i < polylist->count; i++)
polylist->list[i].load(is);
@ -2658,11 +2696,12 @@ bool gfx3d_loadstate(EMUFILE* is, int size)
if (version >= 2)
{
for (size_t i=0; i < ARRAY_SIZE(mtxStack); i++)
for (size_t i = 0; i < ARRAY_SIZE(mtxStack); i++)
{
OSREAD(mtxStack[i].position);
for(size_t j = 0; j < mtxStack[i].size*16; j++)
OSREAD(mtxStack[i].matrix[j]);
is.read_32LE(mtxStack[i].position);
for (size_t j = 0; j < mtxStack[i].size*16; j++)
is.read_32LE(mtxStack[i].matrix[j]);
}
}
@ -2673,13 +2712,26 @@ bool gfx3d_loadstate(EMUFILE* is, int size)
gfx3d.polylist = &polylists[listTwiddle^1];
gfx3d.vertlist = &vertlists[listTwiddle^1];
gfx3d.polylist->count=0;
gfx3d.vertlist->count=0;
gfx3d.polylist->count = 0;
gfx3d.vertlist->count = 0;
if (version >= 4)
{
OSREAD(cacheLightDirection);
OSREAD(cacheHalfVector);
for (size_t i = 0; i < 4; i++)
{
for (size_t j = 0; j < 4; j++)
{
is.read_32LE(cacheLightDirection[i][j]);
}
}
for (size_t i = 0; i < 4; i++)
{
for (size_t j = 0; j < 4; j++)
{
is.read_32LE(cacheHalfVector[i][j]);
}
}
}
return true;

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2008-2015 DeSmuME team
Copyright (C) 2008-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -473,8 +473,8 @@ struct POLY {
return false;
}
void save(EMUFILE* os);
void load(EMUFILE* is);
void save(EMUFILE &os);
void load(EMUFILE &is);
};
#define POLYLIST_SIZE 20000
@ -542,8 +542,8 @@ struct VERT {
fcolor[1] = color[1];
fcolor[2] = color[2];
}
void save(EMUFILE* os);
void load(EMUFILE* is);
void save(EMUFILE &os);
void load(EMUFILE &is);
};
#define VERTLIST_SIZE (POLYLIST_SIZE * 4)
@ -728,8 +728,8 @@ void gfx3d_glGetLightColor(const size_t index, u32 &dst);
struct SFORMAT;
extern SFORMAT SF_GFX3D[];
void gfx3d_Update3DFramebuffers(FragmentColor *framebufferMain, u16 *framebuffer16);
void gfx3d_savestate(EMUFILE* os);
bool gfx3d_loadstate(EMUFILE* is, int size);
void gfx3d_savestate(EMUFILE &os);
bool gfx3d_loadstate(EMUFILE &is, int size);
void gfx3d_ClearStack();

View File

@ -1,7 +1,7 @@
/*
Copyright (C) 2006 thoduv
Copyright (C) 2006-2007 Theo Berkau
Copyright (C) 2008-2016 DeSmuME team
Copyright (C) 2008-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -119,7 +119,7 @@ void backup_setManualBackupType(int type)
CommonSettings.manualBackupType = type;
}
bool BackupDevice::save_state(EMUFILE* os)
bool BackupDevice::save_state(EMUFILE &os)
{
u32 savePos = fpMC->ftell();
std::vector<u8> data(fsize);
@ -129,25 +129,25 @@ bool BackupDevice::save_state(EMUFILE* os)
u32 version = 5;
//v0
write32le(version,os);
write32le(write_enable,os);
write32le(com,os);
write32le(addr_size,os);
write32le(addr_counter,os);
write32le((u32)state,os);
writebuffer(data,os);
writebuffer(data_autodetect,os);
os.write_32LE(version);
os.write_bool32(write_enable);
os.write_32LE(com);
os.write_32LE(addr_size);
os.write_32LE(addr_counter);
os.write_32LE((u32)state);
os.write_buffer(data);
os.write_buffer(data_autodetect);
//v1
write32le(addr,os);
os.write_32LE(addr);
//v2
write8le(motionInitState,os);
write8le(motionFlag,os);
os.write_u8(motionInitState);
os.write_u8(motionFlag);
//v3
writebool(reset_command_state,os);
os.write_bool32(reset_command_state);
//v4
write8le(write_protect,os);
os.write_u8(write_protect);
//v5
write32le(savePos,os);
os.write_32LE(savePos);
fpMC->fseek(savePos, SEEK_SET);
@ -156,53 +156,53 @@ bool BackupDevice::save_state(EMUFILE* os)
return true;
}
bool BackupDevice::load_state(EMUFILE* is)
bool BackupDevice::load_state(EMUFILE &is)
{
u32 version;
u32 temp;
std::vector<u8> data;
if(read32le(&version,is)!=1) return false;
if (is.read_32LE(version) != 1) return false;
readbool(&write_enable,is);
read32le(&com,is);
read32le(&addr_size,is);
read32le(&addr_counter,is);
read32le(&temp,is);
is.read_bool32(write_enable);
is.read_32LE(com);
is.read_32LE(addr_size);
is.read_32LE(addr_counter);
is.read_32LE(temp);
state = (STATE)temp;
readbuffer(data,is);
readbuffer(data_autodetect,is);
is.read_buffer(data);
is.read_buffer(data_autodetect);
if(version>=1)
read32le(&addr,is);
if (version >= 1)
is.read_32LE(addr);
if(version>=2)
if (version >= 2)
{
read8le(&motionInitState,is);
read8le(&motionFlag,is);
is.read_u8(motionInitState);
is.read_u8(motionFlag);
}
if(version>=3)
if (version >= 3)
{
readbool(&reset_command_state,is);
is.read_bool32(reset_command_state);
}
if(version>=4)
if (version >= 4)
{
read8le(&write_protect,is);
is.read_u8(write_protect);
}
fsize = data.size();
#ifndef _DONT_SAVE_BACKUP
fpMC->fseek(0, SEEK_SET);
if(data.size()!=0)
if (data.size() != 0)
fpMC->fwrite((char *)&data[0], fsize);
ensure(data.size(), fpMC);
#endif
if(version>=5)
if (version >= 5)
{
read32le(&temp,is);
is.read_32LE(temp);
fpMC->fseek(temp, SEEK_SET);
}
else
@ -240,34 +240,30 @@ BackupDevice::BackupDevice()
if (fexists && CommonSettings.backupSave)
{
std::string tmp_fsav = std::string(buf) + ".dsv.bak";
EMUFILE_FILE *in = new EMUFILE_FILE(filename, "rb");
if (!in->fail())
EMUFILE_FILE in = EMUFILE_FILE(filename, "rb");
if (!in.fail())
{
u32 sz = in->size();
u32 sz = in.size();
if (sz > 0)
{
EMUFILE_FILE *out = new EMUFILE_FILE(tmp_fsav, "wb");
if (!out->fail())
EMUFILE_FILE out = EMUFILE_FILE(tmp_fsav, "wb");
if (!out.fail())
{
u8 *data = new u8[sz];
in->fread(data, sz);
out->fwrite(data, sz);
in.fread(data, sz);
out.fwrite(data, sz);
delete [] data;
}
else
{
printf("BackupDevice: Could not create the backup save file.\n");
}
delete out;
}
}
else
{
printf("BackupDevice: Could not read the save file for creating a backup.\n");
}
delete in;
}
if (!fexists)
@ -275,18 +271,18 @@ BackupDevice::BackupDevice()
printf("BackupDevice: DeSmuME .dsv save file not found. Trying to load a .sav file.\n");
std::string tmp_fsav = std::string(buf) + ".sav";
EMUFILE_FILE *fpTmp = new EMUFILE_FILE(tmp_fsav, "rb");
if (!fpTmp->fail())
EMUFILE_FILE fpTmp = EMUFILE_FILE(tmp_fsav, "rb");
if (!fpTmp.fail())
{
u32 sz = fpTmp->size();
u32 sz = fpTmp.size();
if (sz > 0)
{
EMUFILE_FILE *fpOut = new EMUFILE_FILE(filename, "wb");
if (!fpOut->fail())
EMUFILE_FILE fpOut = EMUFILE_FILE(filename, "wb");
if (!fpOut.fail())
{
u8 *buf = new u8[sz + 1];
if ((buf) && (fpTmp->fread(buf, sz) == sz))
if ((buf) && (fpTmp.fread(buf, sz) == sz))
{
if (no_gba_unpack(buf, sz))
{
@ -300,7 +296,7 @@ BackupDevice::BackupDevice()
//sz = trim(buf, sz);
}
if (fpOut->fwrite(buf, sz) == sz)
if (fpOut.fwrite(buf, sz) == sz)
{
u8 res = searchFileSaveType(sz);
if (res != 0xFF)
@ -308,8 +304,8 @@ BackupDevice::BackupDevice()
info.type = (res + 1);
addr_size = info.addr_size = save_types[info.type].addr_size;
info.size = fsize = sz;
fpMC = fpOut; //so ensure() works
ensure(sz, fpOut);
fpMC = &fpOut; //so ensure() works
ensure(sz, &fpOut);
fsize = 0;
}
else
@ -323,10 +319,8 @@ BackupDevice::BackupDevice()
}
delete [] buf;
}
delete fpOut;
}
}
delete fpTmp;
}
fpMC = new EMUFILE_FILE(filename, fexists?"rb+":"wb+");
@ -441,16 +435,16 @@ int BackupDevice::readFooter()
fpMC->fseek(-4, SEEK_CUR);
u32 version = 0xFFFFFFFF;
fpMC->read32le(&version);
fpMC->read_32LE(version);
if (version != 0)
return -2;
fpMC->fseek(-24, SEEK_CUR);
fpMC->read32le(&info.size);
fpMC->read32le(&info.padSize);
fpMC->read32le(&info.type);
fpMC->read32le(&info.addr_size);
fpMC->read32le(&info.mem_size);
fpMC->read_32LE(info.size);
fpMC->read_32LE(info.padSize);
fpMC->read_32LE(info.type);
fpMC->read_32LE(info.addr_size);
fpMC->read_32LE(info.mem_size);
MCLOG("DeSmuME backup footer:\n");
MCLOG("\t* size:\t\t%u\n", info.size);
@ -465,7 +459,7 @@ int BackupDevice::readFooter()
u8 BackupDevice::read()
{
u8 val = 0xFF;
fpMC->read8le(&val);
fpMC->read_u8(val);
return val;
}
@ -475,7 +469,7 @@ u8 BackupDevice::readByte(u32 addr, const u8 init)
u8 val = init;
fpMC->fseek(addr, SEEK_SET);
fpMC->read8le(&val);
fpMC->read_u8(val);
return val;
}
@ -484,7 +478,7 @@ u16 BackupDevice::readWord(u32 addr, const u16 init)
u16 val = init;
fpMC->fseek(addr, SEEK_SET);
fpMC->read16le(&val);
fpMC->read_16LE(val);
return val;
}
@ -493,7 +487,7 @@ u32 BackupDevice::readLong(u32 addr, const u32 init)
u32 val = init;
fpMC->fseek(addr, SEEK_SET);
fpMC->read32le(&val);
fpMC->read_32LE(val);
return val;
}
@ -501,21 +495,21 @@ u32 BackupDevice::readLong(u32 addr, const u32 init)
u8 BackupDevice::readByte(const u8 init)
{
u8 val = init;
fpMC->read8le(&val);
fpMC->read_u8(val);
return val;
}
u16 BackupDevice::readWord(const u16 init)
{
u16 val = init;
fpMC->read16le(&val);
fpMC->read_16LE(val);
return val;
}
u32 BackupDevice::readLong(const u32 init)
{
u32 val = init;
fpMC->read32le(&val);
fpMC->read_32LE(val);
return val;
}
@ -535,35 +529,35 @@ void BackupDevice::writeByte(u32 addr, u8 val)
{
if (isMovieMode) return;
fpMC->fseek(addr, SEEK_SET);
fpMC->write8le(val);
fpMC->write_u8(val);
}
void BackupDevice::writeWord(u32 addr, u16 val)
{
if (isMovieMode) return;
fpMC->fseek(addr, SEEK_SET);
fpMC->write16le(val);
fpMC->write_16LE(val);
}
void BackupDevice::writeLong(u32 addr, u32 val)
{
if (isMovieMode) return;
fpMC->fseek(addr, SEEK_SET);
fpMC->write32le(val);
fpMC->write_32LE(val);
}
void BackupDevice::writeByte(u8 val)
{
if (isMovieMode) return;
fpMC->write8le(val);
fpMC->write_u8(val);
}
void BackupDevice::writeWord(u16 val)
{
if (isMovieMode) return;
fpMC->write16le(val);
fpMC->write_16LE(val);
}
void BackupDevice::writeLong(u32 val)
{
if (isMovieMode) return;
fpMC->write32le(val);
fpMC->write_32LE(val);
}
void BackupDevice::seek(u32 pos)
@ -627,11 +621,11 @@ void BackupDevice::reset()
if(state == DETECTING)
{
if(!memcmp(gameInfo.header.gameCode,"ASMK", 4)) addr_size = 1; //super mario 64 ds (KOR, which is different somehow)
else if(!memcmp(gameInfo.header.gameCode,"ASM", 3)) addr_size = 2; //super mario 64 ds
else if(!memcmp(gameInfo.header.gameCode,"BDE", 3)) addr_size = 2; // Dementium II
else if(!memcmp(gameInfo.header.gameCode,"AL3", 3)) addr_size = 1; //spongebob atlantis squarepantis.
else if(!memcmp(gameInfo.header.gameCode,"AH5", 3)) addr_size = 1; //over the hedge
else if(!memcmp(gameInfo.header.gameCode,"AVH", 3)) addr_size = 1; //over the hedge - Hammy Goes Nuts!
else if(!memcmp(gameInfo.header.gameCode,"ASM", 3)) addr_size = 2; //super mario 64 ds
else if(!memcmp(gameInfo.header.gameCode,"BDE", 3)) addr_size = 2; // Dementium II
else if(!memcmp(gameInfo.header.gameCode,"AL3", 3)) addr_size = 1; //spongebob atlantis squarepantis.
else if(!memcmp(gameInfo.header.gameCode,"AH5", 3)) addr_size = 1; //over the hedge
else if(!memcmp(gameInfo.header.gameCode,"AVH", 3)) addr_size = 1; //over the hedge - Hammy Goes Nuts!
else if(!memcmp(gameInfo.header.gameCode,"AQ3", 3)) addr_size = 1; //spider-man 3
else if(!memcmp(gameInfo.header.gameCode,"BPV", 3)) addr_size = 2; //puzzler world (should be eeprom 64KBits)
@ -950,7 +944,7 @@ void BackupDevice::ensure(u32 addr, u8 val, EMUFILE *fpOut)
{
if (!fpOut && (addr < fsize)) return;
EMUFILE *fp = fpOut?fpOut:fpMC;
EMUFILE *fp = (fpOut != NULL) ? fpOut : fpMC;
#ifndef _DONT_SAVE_BACKUP
fp->fseek(fsize, SEEK_SET);
@ -975,12 +969,12 @@ void BackupDevice::ensure(u32 addr, u8 val, EMUFILE *fpOut)
fp->fprintf(DESMUME_BACKUP_FOOTER_TXT);
//and now the actual footer
fp->write32le(addr); //the size of data that has actually been written
fp->write32le(padSize); //the size we padded it to
fp->write32le(info.type); //save memory type
fp->write32le(addr_size);
fp->write32le(info.size); //save memory size
fp->write32le((u32)0); //version number
fp->write_32LE(addr); //the size of data that has actually been written
fp->write_32LE(padSize); //the size we padded it to
fp->write_32LE(info.type); //save memory type
fp->write_32LE(addr_size);
fp->write_32LE(info.size); //save memory size
fp->write_32LE((u32)0); //version number
fp->fprintf("%s", kDesmumeSaveCookie); //this is what we'll use to recognize the desmume format save
fp->fflush();
@ -1344,7 +1338,7 @@ bool BackupDevice::no_gba_unpack(u8 *&buf, u32 &size)
}
}
delete out_buf;
delete [] out_buf;
return false;
}
@ -1579,33 +1573,34 @@ bool BackupDevice::import_duc(const char* filename, u32 force_size)
}
bool BackupDevice::load_movie(EMUFILE* is) {
bool BackupDevice::load_movie(EMUFILE &is)
{
const s32 cookieLen = (s32)strlen(kDesmumeSaveCookie);
is->fseek(-cookieLen, SEEK_END);
is->fseek(-4, SEEK_CUR);
is.fseek(-cookieLen, SEEK_END);
is.fseek(-4, SEEK_CUR);
u32 version = 0xFFFFFFFF;
is->fread((char*)&version,4);
if(version!=0) {
u32 version = is.read_u32LE();
if (version != 0)
{
printf("Unknown save file format\n");
return false;
}
is->fseek(-24, SEEK_CUR);
is.fseek(-24, SEEK_CUR);
struct{
struct
{
u32 size,padSize,type,addr_size,mem_size;
}info;
} info;
is.read_32LE(info.size);
is.read_32LE(info.padSize);
is.read_32LE(info.type);
is.read_32LE(info.addr_size);
is.read_32LE(info.mem_size);
is->fread((char*)&info.size,4);
is->fread((char*)&info.padSize,4);
is->fread((char*)&info.type,4);
is->fread((char*)&info.addr_size,4);
is->fread((char*)&info.mem_size,4);
is->fseek(0, SEEK_SET);
fpMC = (EMUFILE*)&is;
is.fseek(0, SEEK_SET);
fpMC = &is;
state = RUNNING;
addr_size = info.addr_size;

View File

@ -1,7 +1,7 @@
/*
Copyright (C) 2006 thoduv
Copyright (C) 2006 Theo Berkau
Copyright (C) 2008-2015 DeSmuME team
Copyright (C) 2008-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -90,8 +90,8 @@ public:
u8 searchFileSaveType(u32 size);
bool save_state(EMUFILE* os);
bool load_state(EMUFILE* is);
bool save_state(EMUFILE &os);
bool load_state(EMUFILE &is);
//commands from mmu
void reset_command() { reset_command_state = true; };
@ -128,7 +128,7 @@ public:
bool export_raw(const char* filename);
bool no_gba_unpack(u8 *&buf, u32 &size);
bool load_movie(EMUFILE* is);
bool load_movie(EMUFILE &is);
struct {
u32 size,padSize,type,addr_size,mem_size;

View File

@ -1,6 +1,6 @@
/* mic.cpp - this file is part of DeSmuME
*
* Copyright (C) 2009-2015 DeSmuME Team
* Copyright (C) 2009-2017 DeSmuME Team
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -195,14 +195,14 @@ void Mic_DoNoise(BOOL noise)
}
}
void mic_savestate(EMUFILE* os)
void mic_savestate(EMUFILE &os)
{
write32le(-1,os);
write_32LE(-1,os);
}
bool mic_loadstate(EMUFILE* is, int size)
bool mic_loadstate(EMUFILE &is, int size)
{
is->fseek(size, SEEK_CUR);
is.fseek(size, SEEK_CUR);
return TRUE;
}

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2009-2015 DeSmuME Team
Copyright (C) 2009-2017 DeSmuME Team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -38,7 +38,7 @@ void Mic_Reset(void);
void Mic_DeInit(void);
u8 Mic_ReadSample(void);
void mic_savestate(EMUFILE* os);
bool mic_loadstate(EMUFILE* is, int size);
void mic_savestate(EMUFILE &os);
bool mic_loadstate(EMUFILE &is, int size);
#endif // MIC_H

View File

@ -1,5 +1,5 @@
/*
Copyright 2008-2016 DeSmuME team
Copyright 2008-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -57,10 +57,10 @@ bool autoMovieBackup = true;
EMOVIEMODE movieMode = MOVIEMODE_INACTIVE;
//this should not be set unless we are in MOVIEMODE_RECORD!
EMUFILE* osRecordingMovie = 0;
EMUFILE *osRecordingMovie = NULL;
int currFrameCounter;
uint32 cur_input_display = 0;
u32 cur_input_display = 0;
int pauseframe = -1;
bool movie_readonly = true;
@ -121,72 +121,72 @@ bool MovieRecord::Compare(MovieRecord& compareRec)
}
const char MovieRecord::mnemonics[13] = {'R','L','D','U','T','S','B','A','Y','X','W','E','G'};
void MovieRecord::dumpPad(EMUFILE* fp, u16 pad)
void MovieRecord::dumpPad(EMUFILE &fp, u16 inPad)
{
//these are mnemonics for each joystick bit.
//since we usually use the regular joypad, these will be more helpful.
//but any character other than ' ' or '.' should count as a set bit
//maybe other input types will need to be encoded another way..
for(int bit=0;bit<13;bit++)
for (int bit = 0; bit < 13; bit++)
{
int bitmask = (1<<(12-bit));
char mnemonic = mnemonics[bit];
//if the bit is set write the mnemonic
if(pad & bitmask)
fp->fputc(mnemonic);
if (pad & bitmask)
fp.fputc(mnemonic);
else //otherwise write an unset bit
fp->fputc('.');
fp.fputc('.');
}
}
void MovieRecord::parsePad(EMUFILE* fp, u16& pad)
void MovieRecord::parsePad(EMUFILE &fp, u16 &outPad)
{
char buf[13];
fp->fread(buf,13);
char buf[13] = {};
fp.fread(buf,13);
pad = 0;
for(int i=0;i<13;i++)
for (int i = 0; i < 13; i++)
{
pad <<= 1;
pad |= ((buf[i]=='.'||buf[i]==' ')?0:1);
pad |= ((buf[i] == '.' || buf[i] == ' ') ? 0 : 1);
}
}
void MovieRecord::parse(EMUFILE* fp)
void MovieRecord::parse(EMUFILE &fp)
{
//by the time we get in here, the initial pipe has already been extracted
//extract the commands
commands = u32DecFromIstream(fp);
fp->fgetc(); //eat the pipe
fp.fgetc(); //eat the pipe
parsePad(fp, pad);
touch.x = u32DecFromIstream(fp);
touch.y = u32DecFromIstream(fp);
touch.touch = u32DecFromIstream(fp);
fp->fgetc(); //eat the pipe
fp.fgetc(); //eat the pipe
//should be left at a newline
}
void MovieRecord::dump(EMUFILE* fp)
void MovieRecord::dump(EMUFILE &fp)
{
//dump the misc commands
//*os << '|' << setw(1) << (int)commands;
fp->fputc('|');
fp.fputc('|');
putdec<uint8,1,true>(fp,commands);
fp->fputc('|');
fp.fputc('|');
dumpPad(fp, pad);
putdec<u8,3,true>(fp,touch.x); fp->fputc(' ');
putdec<u8,3,true>(fp,touch.y); fp->fputc(' ');
putdec<u8,3,true>(fp,touch.x); fp.fputc(' ');
putdec<u8,3,true>(fp,touch.y); fp.fputc(' ');
putdec<u8,1,true>(fp,touch.touch);
fp->fputc('|');
fp.fputc('|');
//each frame is on a new line
fp->fputc('\n');
fp.fputc('\n');
}
DateTime FCEUI_MovieGetRTCDefault()
@ -248,7 +248,6 @@ void MovieData::installValue(std::string& key, std::string& val)
}
}
if (validFormat) {
struct tm t;
const char *s = val.data();
int year = atoi(&s[0]);
int mon = atoi(&s[5]);
@ -277,84 +276,86 @@ void MovieData::installValue(std::string& key, std::string& val)
}
int MovieData::dump(EMUFILE* fp, bool binary)
int MovieData::dump(EMUFILE &fp, bool binary)
{
int start = fp->ftell();
fp->fprintf("version %d\n", version);
fp->fprintf("emuVersion %d\n", emuVersion);
fp->fprintf("rerecordCount %d\n", rerecordCount);
int start = fp.ftell();
fp.fprintf("version %d\n", version);
fp.fprintf("emuVersion %d\n", emuVersion);
fp.fprintf("rerecordCount %d\n", rerecordCount);
fp->fprintf("romFilename %s\n", romFilename.c_str());
fp->fprintf("romChecksum %s\n", u32ToHexString(gameInfo.crc).c_str());
fp->fprintf("romSerial %s\n", romSerial.c_str());
fp->fprintf("guid %s\n", guid.toString().c_str());
fp->fprintf("useExtBios %d\n", CommonSettings.UseExtBIOS?1:0);
fp->fprintf("advancedTiming %d\n", CommonSettings.advanced_timing?1:0);
fp.fprintf("romFilename %s\n", romFilename.c_str());
fp.fprintf("romChecksum %s\n", u32ToHexString(gameInfo.crc).c_str());
fp.fprintf("romSerial %s\n", romSerial.c_str());
fp.fprintf("guid %s\n", guid.toString().c_str());
fp.fprintf("useExtBios %d\n", CommonSettings.UseExtBIOS?1:0);
fp.fprintf("advancedTiming %d\n", CommonSettings.advanced_timing?1:0);
if(CommonSettings.UseExtBIOS)
fp->fprintf("swiFromBios %d\n", CommonSettings.SWIFromBIOS?1:0);
if (CommonSettings.UseExtBIOS)
fp.fprintf("swiFromBios %d\n", CommonSettings.SWIFromBIOS?1:0);
fp->fprintf("useExtFirmware %d\n", CommonSettings.UseExtFirmware?1:0);
fp.fprintf("useExtFirmware %d\n", CommonSettings.UseExtFirmware?1:0);
if(CommonSettings.UseExtFirmware) {
fp->fprintf("bootFromFirmware %d\n", CommonSettings.BootFromFirmware?1:0);
if (CommonSettings.UseExtFirmware)
{
fp.fprintf("bootFromFirmware %d\n", CommonSettings.BootFromFirmware?1:0);
}
else {
else
{
std::wstring wnick((wchar_t*)CommonSettings.fw_config.nickname,CommonSettings.fw_config.nickname_len);
std::string nick = wcstombs(wnick);
std::wstring wmessage((wchar_t*)CommonSettings.fw_config.message,CommonSettings.fw_config.message_len);
std::string message = wcstombs(wmessage);
fp->fprintf("firmNickname %s\n", nick.c_str());
fp->fprintf("firmMessage %s\n", message.c_str());
fp->fprintf("firmFavColour %d\n", CommonSettings.fw_config.fav_colour);
fp->fprintf("firmBirthMonth %d\n", CommonSettings.fw_config.birth_month);
fp->fprintf("firmBirthDay %d\n", CommonSettings.fw_config.birth_day);
fp->fprintf("firmLanguage %d\n", CommonSettings.fw_config.language);
fp.fprintf("firmNickname %s\n", nick.c_str());
fp.fprintf("firmMessage %s\n", message.c_str());
fp.fprintf("firmFavColour %d\n", CommonSettings.fw_config.fav_colour);
fp.fprintf("firmBirthMonth %d\n", CommonSettings.fw_config.birth_month);
fp.fprintf("firmBirthDay %d\n", CommonSettings.fw_config.birth_day);
fp.fprintf("firmLanguage %d\n", CommonSettings.fw_config.language);
}
fp->fprintf("rtcStartNew %s\n", rtcStart.ToString().c_str());
fp.fprintf("rtcStartNew %s\n", rtcStart.ToString().c_str());
for(uint32 i=0;i<comments.size();i++)
fp->fprintf("comment %s\n", wcstombs(comments[i]).c_str());
for (u32 i = 0; i < comments.size(); i++)
fp.fprintf("comment %s\n", wcstombs(comments[i]).c_str());
if(binary)
fp->fprintf("binary 1\n");
if (binary)
fp.fprintf("binary 1\n");
if(savestate.size() != 0)
fp->fprintf("savestate %s\n", BytesToString(&savestate[0],savestate.size()).c_str());
if(sram.size() != 0)
fp->fprintf("sram %s\n", BytesToString(&sram[0],sram.size()).c_str());
if (savestate.size() != 0)
fp.fprintf("savestate %s\n", BytesToString(&savestate[0],savestate.size()).c_str());
if (sram.size() != 0)
fp.fprintf("sram %s\n", BytesToString(&sram[0],sram.size()).c_str());
if(binary)
if (binary)
{
//put one | to start the binary dump
fp->fputc('|');
for(int i=0;i<(int)records.size();i++)
fp.fputc('|');
for (int i = 0; i < (int)records.size(); i++)
records[i].dumpBinary(fp);
}
else
for(int i=0;i<(int)records.size();i++)
for (int i = 0; i < (int)records.size(); i++)
records[i].dump(fp);
int end = fp->ftell();
int end = fp.ftell();
return end-start;
}
//yuck... another custom text parser.
bool LoadFM2(MovieData& movieData, EMUFILE* fp, int size, bool stopAfterHeader)
bool LoadFM2(MovieData &movieData, EMUFILE &fp, int size, bool stopAfterHeader)
{
//TODO - start with something different. like 'desmume movie version 1"
int curr = fp->ftell();
int curr = fp.ftell();
//movie must start with "version 1"
char buf[9];
curr = fp->ftell();
fp->fread(buf,9);
fp->fseek(curr, SEEK_SET);
curr = fp.ftell();
fp.fread(buf,9);
fp.fseek(curr, SEEK_SET);
// if(fp->fail()) return false;
if(memcmp(buf,"version 1",9))
if (memcmp(buf,"version 1",9))
return false;
std::string key,value;
@ -367,7 +368,7 @@ bool LoadFM2(MovieData& movieData, EMUFILE* fp, int size, bool stopAfterHeader)
bool iswhitespace, isrecchar, isnewline;
int c;
if(size--<=0) goto bail;
c = fp->fgetc();
c = fp.fgetc();
if(c == -1)
goto bail;
iswhitespace = (c==' '||c=='\t');
@ -396,9 +397,9 @@ bool LoadFM2(MovieData& movieData, EMUFILE* fp, int size, bool stopAfterHeader)
if (stopAfterHeader) return true;
int currcount = movieData.records.size();
movieData.records.resize(currcount+1);
int preparse = fp->ftell();
int preparse = fp.ftell();
movieData.records[currcount].parse(fp);
int postparse = fp->ftell();
int postparse = fp.ftell();
size -= (postparse-preparse);
state = NEWLINE;
break;
@ -526,10 +527,10 @@ const char* _CDECL_ FCEUI_LoadMovie(const char *fname, bool _read_only, bool tas
bool loadedfm2 = false;
bool opened = false;
// {
EMUFILE* fp = new EMUFILE_FILE(fname, "rb");
EMUFILE *fp = new EMUFILE_FILE(fname, "rb");
// if(fs.is_open())
// {
loadedfm2 = LoadFM2(currMovieData, fp, INT_MAX, false);
loadedfm2 = LoadFM2(currMovieData, *fp, INT_MAX, false);
opened = true;
// }
// fs.close();
@ -539,7 +540,7 @@ const char* _CDECL_ FCEUI_LoadMovie(const char *fname, bool _read_only, bool tas
{
// for some reason fs.open doesn't work, it has to be a whole new fstream object
// fstream fs (fname, std::ios_base::in);
loadedfm2 = LoadFM2(currMovieData, fp, INT_MAX, false);
loadedfm2 = LoadFM2(currMovieData, *fp, INT_MAX, false);
// fs.close();
delete fp;
}
@ -604,7 +605,7 @@ static void openRecordingMovie(const char* fname)
bool MovieData::loadSramFrom(std::vector<u8>* buf)
{
EMUFILE_MEMORY ms(buf);
MMU_new.backupDevice.load_movie(&ms);
MMU_new.backupDevice.load_movie(ms);
return true;
}
@ -683,7 +684,7 @@ void FCEUI_SaveMovie(const char *fname, std::wstring author, int flag, std::stri
EMUFILE::readAllBytes(&currMovieData.sram, sramfname);
//we are going to go ahead and dump the header. from now on we will only be appending frames
currMovieData.dump(osRecordingMovie, false);
currMovieData.dump(*osRecordingMovie, false);
currFrameCounter=0;
lagframecounter=0;
@ -768,7 +769,7 @@ void FCEUI_SaveMovie(const char *fname, std::wstring author, int flag, std::stri
//assert(nds.touchX == input.touch.touchX && nds.touchY == input.touch.touchY);
//assert((mr.touch.x << 4) == nds.touchX && (mr.touch.y << 4) == nds.touchY);
mr.dump(osRecordingMovie);
mr.dump(*osRecordingMovie);
currMovieData.records.push_back(mr);
// it's apparently un-threadsafe to do this here
@ -801,7 +802,7 @@ static void FCEUMOV_AddCommand(int cmd)
static const int kMOVI = 0x49564F4D;
static const int kNOMO = 0x4F4D4F4E;
void mov_savestate(EMUFILE* fp)
void mov_savestate(EMUFILE &fp)
{
//we are supposed to dump the movie data into the savestate
//if(movieMode == MOVIEMODE_RECORD || movieMode == MOVIEMODE_PLAY)
@ -809,12 +810,12 @@ void mov_savestate(EMUFILE* fp)
//else return 0;
if(movieMode != MOVIEMODE_INACTIVE)
{
write32le(kMOVI,fp);
fp.write_32LE(kMOVI);
currMovieData.dump(fp, true);
}
else
{
write32le(kNOMO,fp);
fp.write_32LE(kNOMO);
}
}
@ -848,19 +849,19 @@ bool CheckTimelines(MovieData& stateMovie, MovieData& currMovie, int& errorFr)
static bool load_successful;
bool mov_loadstate(EMUFILE* fp, int size)
bool mov_loadstate(EMUFILE &fp, int size)
{
load_successful = false;
u32 cookie;
if(read32le(&cookie,fp) != 1) return false;
if(cookie == kNOMO)
if (fp.read_32LE(cookie) != 1) return false;
if (cookie == kNOMO)
{
if(movieMode == MOVIEMODE_RECORD || movieMode == MOVIEMODE_PLAY)
FinishPlayback();
return true;
}
else if(cookie != kMOVI)
else if (cookie != kMOVI)
return false;
size -= 4;
@ -883,7 +884,7 @@ bool mov_loadstate(EMUFILE* fp, int size)
//int curr = fp->ftell();
if(!LoadFM2(tempMovieData, fp, size, false)) {
// is->seekg((uint32)curr+size);
// is->seekg((u32)curr+size);
/* extern bool FCEU_state_loading_old_format;
if(FCEU_state_loading_old_format) {
if(movieMode == MOVIEMODE_PLAY || movieMode == MOVIEMODE_RECORD) {
@ -1021,7 +1022,7 @@ bool mov_loadstate(EMUFILE* fp, int size)
}
//printf("DUMPING MOVIE: %d FRAMES\n",currMovieData.records.size());
currMovieData.dump(osRecordingMovie, false);
currMovieData.dump(*osRecordingMovie, false);
movieMode = MOVIEMODE_RECORD;
}
}
@ -1046,7 +1047,7 @@ static bool FCEUMOV_PostLoad(void)
}
bool FCEUI_MovieGetInfo(EMUFILE* fp, MOVIE_INFO& info, bool skipFrameCount)
bool FCEUI_MovieGetInfo(EMUFILE &fp, MOVIE_INFO &info, bool skipFrameCount)
{
//MovieData md;
//if(!LoadFM2(md, fp, INT_MAX, skipFrameCount))
@ -1066,27 +1067,28 @@ bool FCEUI_MovieGetInfo(EMUFILE* fp, MOVIE_INFO& info, bool skipFrameCount)
return true;
}
bool MovieRecord::parseBinary(EMUFILE* fp)
bool MovieRecord::parseBinary(EMUFILE &fp)
{
commands=fp->fgetc();
fp->fread((char *) &pad, sizeof pad);
fp->fread((char *) &touch.x, sizeof touch.x);
fp->fread((char *) &touch.y, sizeof touch.y);
fp->fread((char *) &touch.touch, sizeof touch.touch);
fp.read_u8(this->commands);
fp.read_16LE(this->pad);
fp.read_u8(this->touch.x);
fp.read_u8(this->touch.y);
fp.read_u8(this->touch.touch);
return true;
}
void MovieRecord::dumpBinary(EMUFILE* fp)
void MovieRecord::dumpBinary(EMUFILE &fp)
{
fp->fputc(this->commands);
fp->fwrite((char *) &this->pad, sizeof(this->pad));
fp->fwrite((char *) &this->touch.x, sizeof(this->touch.x));
fp->fwrite((char *) &this->touch.y, sizeof(this->touch.y));
fp->fwrite((char *) &this->touch.touch, sizeof(this->touch.touch));
fp.write_u8(this->commands);
fp.write_16LE(this->pad);
fp.write_u8(this->touch.x);
fp.write_u8(this->touch.y);
fp.write_u8(this->touch.touch);
}
void LoadFM2_binarychunk(MovieData& movieData, EMUFILE* fp, int size)
void LoadFM2_binarychunk(MovieData &movieData, EMUFILE &fp, int size)
{
int recordsize = 1; //1 for the command
@ -1095,11 +1097,11 @@ void LoadFM2_binarychunk(MovieData& movieData, EMUFILE* fp, int size)
assert(size%6==0);
//find out how much remains in the file
int curr = fp->ftell();
fp->fseek(0,SEEK_END);
int end = fp->ftell();
int curr = fp.ftell();
fp.fseek(0,SEEK_END);
int end = fp.ftell();
int flen = end-curr;
fp->fseek(curr,SEEK_SET);
fp.fseek(curr,SEEK_SET);
//the amount todo is the min of the limiting size we received and the remaining contents of the file
int todo = std::min(size, flen);
@ -1183,9 +1185,8 @@ void FCEUI_MakeBackupMovie(bool dispMessage)
}
MovieData md = currMovieData; //Get current movie data
EMUFILE* outf = new EMUFILE_FILE(backupFn.c_str(),"wb"); //FCEUD_UTF8_fstream(backupFn, "wb"); //open/create file
EMUFILE_FILE outf = EMUFILE_FILE(backupFn.c_str(),"wb"); //FCEUD_UTF8_fstream(backupFn, "wb"); //open/create file
md.dump(outf,false); //dump movie data
delete outf; //clean up, delete file object
//TODO, decide if fstream successfully opened the file and print error message if it doesn't

View File

@ -1,5 +1,5 @@
/*
Copyright 2008-2015 DeSmuME team
Copyright 2008-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -115,12 +115,12 @@ public:
bool Compare(MovieRecord& compareRec);
void clear();
void parse(EMUFILE* fp);
bool parseBinary(EMUFILE* fp);
void dump(EMUFILE* fp);
void dumpBinary(EMUFILE* fp);
void parsePad(EMUFILE* fp, u16& pad);
void dumpPad(EMUFILE* fp, u16 pad);
void parse(EMUFILE &fp);
bool parseBinary(EMUFILE &fp);
void dump(EMUFILE &fp);
void dumpBinary(EMUFILE &fp);
void parsePad(EMUFILE &fp, u16 &outPad);
void dumpPad(EMUFILE &fp, u16 inPad);
static const char mnemonics[13];
@ -187,7 +187,7 @@ public:
void truncateAt(int frame);
void installValue(std::string& key, std::string& val);
int dump(EMUFILE* fp, bool binary);
int dump(EMUFILE &fp, bool binary);
void clearRecordRange(int start, int len);
void insertEmpty(int at, int frames);
@ -215,17 +215,17 @@ extern MovieData currMovieData; //adelikat: main needs this for frame counter d
extern bool movie_reset_command;
bool FCEUI_MovieGetInfo(EMUFILE* fp, MOVIE_INFO& info, bool skipFrameCount);
bool FCEUI_MovieGetInfo(EMUFILE &fp, MOVIE_INFO &info, bool skipFrameCount);
void FCEUI_SaveMovie(const char *fname, std::wstring author, int flag, std::string sramfname, const DateTime &rtcstart);
const char* _CDECL_ FCEUI_LoadMovie(const char *fname, bool _read_only, bool tasedit, int _pauseframe); // returns NULL on success, errmsg on failure
void FCEUI_StopMovie();
void FCEUMOV_AddInputState();
void FCEUMOV_HandlePlayback();
void FCEUMOV_HandleRecording();
void mov_savestate(EMUFILE* fp);
bool mov_loadstate(EMUFILE* fp, int size);
void LoadFM2_binarychunk(MovieData& movieData, EMUFILE* fp, int size);
bool LoadFM2(MovieData& movieData, EMUFILE* fp, int size, bool stopAfterHeader);
void mov_savestate(EMUFILE &fp);
bool mov_loadstate(EMUFILE &fp, int size);
void LoadFM2_binarychunk(MovieData& movieData, EMUFILE &fp, int size);
bool LoadFM2(MovieData &movieData, EMUFILE &fp, int size, bool stopAfterHeader);
extern bool movie_readonly;
extern bool ShowInputDisplay;
void FCEUI_MakeBackupMovie(bool dispMessage);

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2006-2015 DeSmuME team
Copyright (C) 2006-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -16,129 +16,26 @@
*/
#include "readwrite.h"
#include "emufile.h"
//well. just for the sake of consistency
int write8le(u8 b, EMUFILE*os)
{
os->fwrite((char*)&b,1);
return 1;
}
//well. just for the sake of consistency
int read8le(u8 *Bufo, EMUFILE*is)
{
if(is->_fread((char*)Bufo,1) != 1)
return 0;
return 1;
}
///writes a little endian 16bit value to the specified file
int write16le(u16 b, EMUFILE *fp)
{
u8 s[2];
s[0]=(u8)b;
s[1]=(u8)(b>>8);
fp->fwrite(s,2);
return 2;
}
///writes a little endian 32bit value to the specified file
int write32le(u32 b, EMUFILE *fp)
{
u8 s[4];
s[0]=(u8)b;
s[1]=(u8)(b>>8);
s[2]=(u8)(b>>16);
s[3]=(u8)(b>>24);
fp->fwrite(s,4);
return 4;
}
void writebool(bool b, EMUFILE* os) { write32le(b?1:0,os); }
int write64le(u64 b, EMUFILE* os)
{
u8 s[8];
s[0]=(u8)b;
s[1]=(u8)(b>>8);
s[2]=(u8)(b>>16);
s[3]=(u8)(b>>24);
s[4]=(u8)(b>>32);
s[5]=(u8)(b>>40);
s[6]=(u8)(b>>48);
s[7]=(u8)(b>>56);
os->fwrite((char*)&s,8);
return 8;
}
int read32le(u32 *Bufo, EMUFILE *fp)
{
u32 buf = 0;
if(fp->_fread(&buf,4)<4)
return 0;
*Bufo = LE_TO_LOCAL_32(buf);
return 1;
}
int read16le(u16 *Bufo, EMUFILE *is)
{
u16 buf;
if(is->_fread((char*)&buf,2) != 2)
return 0;
*Bufo = LE_TO_LOCAL_16(buf);
return 1;
}
int read64le(u64 *Bufo, EMUFILE *is)
{
u64 buf;
if(is->_fread((char*)&buf,8) != 8)
return 0;
*Bufo = LE_TO_LOCAL_64(buf);
return 1;
}
static int read32le(u32 *Bufo, std::istream *is)
{
u32 buf;
if(is->read((char*)&buf,4).gcount() != 4)
return 0;
*Bufo = LE_TO_LOCAL_32(buf);
return 1;
}
int readbool(bool *b, EMUFILE* is)
size_t read_32LE(u32 &u32valueOut, std::istream *is)
{
u32 temp;
int ret = read32le(&temp,is);
*b = temp!=0;
return ret;
}
int readbuffer(std::vector<u8> &vec, EMUFILE* is)
{
u32 size;
if(read32le(&size,is) != 1) return 0;
vec.resize(size);
if(size>0) is->fread((char*)&vec[0],size);
if (is->read((char*)&temp,4).gcount() != 4)
return 0;
u32valueOut = LE_TO_LOCAL_32(temp);
return 1;
}
int writebuffer(std::vector<u8>& vec, EMUFILE* os)
size_t read_16LE(u16 &u16valueOut, std::istream *is)
{
u32 size = vec.size();
write32le(size,os);
if(size>0) os->fwrite((char*)&vec[0],size);
u16 temp;
if (is->read((char*)&temp,2).gcount() != 2)
return 0;
u16valueOut = LE_TO_LOCAL_16(temp);
return 1;
}

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2008-2015 DeSmuME team
Copyright (C) 2008-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -24,46 +24,7 @@
#include "types.h"
class EMUFILE;
//well. just for the sake of consistency
int write8le(u8 b, EMUFILE *fp);
inline int write8le(u8* b, EMUFILE *fp) { return write8le(*b,fp); }
int write16le(u16 b, EMUFILE* os);
int write32le(u32 b, EMUFILE* os);
int write64le(u64 b, EMUFILE* os);
inline int write_double_le(double b, EMUFILE*is) { u64 temp = double_to_u64(b); int ret = write64le(temp,is); return ret; }
int read8le(u8 *Bufo, EMUFILE*is);
int read16le(u16 *Bufo, EMUFILE*is);
inline int read16le(s16 *Bufo, EMUFILE*is) { return read16le((u16*)Bufo,is); }
int read32le(u32 *Bufo, EMUFILE*is);
inline int read32le(s32 *Bufo, EMUFILE*is) { return read32le((u32*)Bufo,is); }
int read64le(u64 *Bufo, EMUFILE*is);
inline int read_double_le(double *Bufo, EMUFILE*is) { u64 temp; int ret = read64le(&temp,is); *Bufo = u64_to_double(temp); return ret; }
int read16le(u16 *Bufo, std::istream *is);
template<typename T>
int readle(T *Bufo, EMUFILE*is)
{
CTASSERT(sizeof(T)==1||sizeof(T)==2||sizeof(T)==4||sizeof(T)==8);
switch(sizeof(T)) {
case 1: return read8le((u8*)Bufo,is);
case 2: return read16le((u16*)Bufo,is);
case 4: return read32le((u32*)Bufo,is);
case 8: return read64le((u64*)Bufo,is);
default:
return 0;
}
}
int readbool(bool *b, EMUFILE* is);
void writebool(bool b, EMUFILE* os);
int readbuffer(std::vector<u8> &vec, EMUFILE* is);
int writebuffer(std::vector<u8>& vec, EMUFILE* os);
size_t read_32LE(u32 &u32valueOut, std::istream *is);
size_t read_16LE(u16 &u16valueOut, std::istream *is);
#endif

View File

@ -409,12 +409,12 @@ static INLINE void FlipByteOrder(u8 *src, u32 count)
}
#endif
static bool s_slot1_loadstate(EMUFILE* is, int size)
static bool s_slot1_loadstate(EMUFILE &is, int size)
{
u32 version = is->read32le();
u32 version = is.read_u32LE();
/* version 0: */
u8 slotID = is->read32le();
u8 slotID = is.read_u32LE();
slot1Type = NDS_SLOT1_RETAIL_AUTO;
if (version >= 1)
slot1_getTypeByID(slotID, slot1Type);
@ -422,63 +422,63 @@ static bool s_slot1_loadstate(EMUFILE* is, int size)
slot1_Change(slot1Type);
EMUFILE_MEMORY temp;
is->readMemoryStream(&temp);
is.read_MemoryStream(temp);
temp.fseek(0,SEEK_SET);
slot1_Loadstate(&temp);
slot1_Loadstate(temp);
return true;
}
static void s_slot1_savestate(EMUFILE* os)
static void s_slot1_savestate(EMUFILE &os)
{
u32 version = 1;
os->write32le(version);
os.write_32LE(version);
u8 slotID = (u8)slot1_List[slot1_GetSelectedType()]->info()->id();
os->write32le(slotID);
os.write_32LE(slotID);
EMUFILE_MEMORY temp;
slot1_Savestate(&temp);
os->writeMemoryStream(&temp);
slot1_Savestate(temp);
os.write_MemoryStream(temp);
}
static bool s_slot2_loadstate(EMUFILE* is, int size)
static bool s_slot2_loadstate(EMUFILE &is, int size)
{
u32 version = is->read32le();
u32 version = is.read_u32LE();
/* version 0: */
slot2Type = NDS_SLOT2_AUTO;
u8 slotID = is->read32le();
u8 slotID = is.read_u32LE();
if (version == 0)
slot2_getTypeByID(slotID, slot2Type);
slot2_Change(slot2Type);
EMUFILE_MEMORY temp;
is->readMemoryStream(&temp);
is.read_MemoryStream(temp);
temp.fseek(0,SEEK_SET);
slot2_Loadstate(&temp);
slot2_Loadstate(temp);
return true;
}
static void s_slot2_savestate(EMUFILE* os)
static void s_slot2_savestate(EMUFILE &os)
{
u32 version = 0;
os->write32le(version);
os.write_32LE(version);
//version 0:
u8 slotID = (u8)slot2_List[slot2_GetSelectedType()]->info()->id();
os->write32le(slotID);
os.write_32LE(slotID);
EMUFILE_MEMORY temp;
slot2_Savestate(&temp);
os->writeMemoryStream(&temp);
slot2_Savestate(temp);
os.write_MemoryStream(temp);
}
static void mmu_savestate(EMUFILE* os)
static void mmu_savestate(EMUFILE &os)
{
u32 version = 8;
write32le(version,os);
os.write_32LE(version);
//version 2:
MMU_new.backupDevice.save_state(os);
@ -504,61 +504,61 @@ static void mmu_savestate(EMUFILE* os)
MMU_new.dsi_tsc.save_state(os);
//version 8:
os->write32le(MMU.fw.size);
os->fwrite(MMU.fw.data,MMU.fw.size);
os.write_32LE(MMU.fw.size);
os.fwrite(MMU.fw.data,MMU.fw.size);
}
static bool mmu_loadstate(EMUFILE* is, int size)
static bool mmu_loadstate(EMUFILE &is, int size)
{
//read version
u32 version;
if(read32le(&version,is) != 1) return false;
if (is.read_32LE(version) != 1) return false;
if(version == 0 || version == 1)
if (version == 0 || version == 1)
{
u32 bupmem_size;
u32 addr_size;
u32 addr_size = 0xFFFFFFFF;
if(version == 0)
if (version == 0)
{
//version 0 was buggy and didnt save the type.
//it would silently fail if there was a size mismatch
SAV_silent_fail_flag = true;
if(read32le(&bupmem_size,is) != 1) return false;
if (is.read_32LE(bupmem_size) != 1) return false;
//if(bupmem_size != MMU.bupmem.size) return false; //mismatch between current initialized and saved size
addr_size = BackupDevice::addr_size_for_old_save_size(bupmem_size);
}
else if(version == 1)
else if (version == 1)
{
//version 1 reinitializes the save system with the type that was saved
u32 bupmem_type;
if(read32le(&bupmem_type,is) != 1) return false;
if(read32le(&bupmem_size,is) != 1) return false;
if (is.read_32LE(bupmem_type) != 1) return false;
if (is.read_32LE(bupmem_size) != 1) return false;
addr_size = BackupDevice::addr_size_for_old_save_type(bupmem_type);
if(addr_size == 0xFFFFFFFF)
if (addr_size == 0xFFFFFFFF)
addr_size = BackupDevice::addr_size_for_old_save_size(bupmem_size);
}
if(addr_size == 0xFFFFFFFF)
if (addr_size == 0xFFFFFFFF)
return false;
u8* temp = new u8[bupmem_size];
is->fread((char*)temp,bupmem_size);
u8 *temp = new u8[bupmem_size];
is.fread(temp,bupmem_size);
MMU_new.backupDevice.load_old_state(addr_size,temp,bupmem_size);
delete[] temp;
if(is->fail()) return false;
if (is.fail()) return false;
}
if(version < 2) return true;
if (version < 2) return true;
bool ok = MMU_new.backupDevice.load_state(is);
if(version < 3) return ok;
if (version < 3) return ok;
ok &= MMU_new.gxstat.loadstate(is);
for(int i=0;i<2;i++)
for(int j=0;j<4;j++)
for (int i = 0; i < 2; i++)
for (int j = 0; j < 4; j++)
ok &= MMU_new.dma[i][j].loadstate(is);
ok &= MMU_timing.arm9codeFetch.loadstate(is, version);
@ -568,7 +568,7 @@ static bool mmu_loadstate(EMUFILE* is, int size)
ok &= MMU_timing.arm9codeCache.loadstate(is, version);
ok &= MMU_timing.arm9dataCache.loadstate(is, version);
if(version < 4) return ok;
if (version < 4) return ok;
ok &= MMU_new.sqrt.loadstate(is,version);
ok &= MMU_new.div.loadstate(is,version);
@ -580,56 +580,62 @@ static bool mmu_loadstate(EMUFILE* is, int size)
MMU_new.gxstat.fifo_low = gxFIFO.size <= 127;
MMU_new.gxstat.fifo_empty = gxFIFO.size == 0;
if(version < 5) return ok;
if(version < 6) return ok;
if (version < 5) return ok;
if (version < 6) return ok;
MMU_new.dsi_tsc.load_state(is);
//version 6
if(version < 7)
if (version < 7)
{
//recover WRAMCNT from the stashed WRAMSTAT memory location
MMU.WRAMCNT = MMU.MMU_MEM[ARMCPU_ARM7][0x40][0x241];
}
if(version<8) return ok;
if (version < 8) return ok;
//version 8:
delete[] MMU.fw.data;
MMU.fw.size = is->read32le();
MMU.fw.size = is.read_u32LE();
MMU.fw.data = new u8[size];
is->fread(MMU.fw.data,MMU.fw.size);
is.fread(MMU.fw.data,MMU.fw.size);
return ok;
}
static void cp15_savestate(EMUFILE* os)
static void cp15_savestate(EMUFILE &os)
{
//version
write32le(1,os);
os.write_32LE(1);
cp15.saveone(os);
//ARM7 not have coprocessor
//cp15_saveone((armcp15_t *)NDS_ARM7.coproc[15],os);
}
static bool cp15_loadstate(EMUFILE* is, int size)
static bool cp15_loadstate(EMUFILE &is, int size)
{
//read version
u32 version;
if(read32le(&version,is) != 1) return false;
if(version > 1) return false;
if (is.read_32LE(version) != 1) return false;
if (version > 1) return false;
if(!cp15.loadone(is)) return false;
if (!cp15.loadone(is)) return false;
if(version == 0)
if (version == 0)
{
//ARM7 not have coprocessor
// TODO: What's going on here with tmp_buf?
u8 *tmp_buf = new u8 [sizeof(armcp15_t)];
if (!tmp_buf) return false;
if(!cp15.loadone(is)) return false;
if (!cp15.loadone(is))
{
delete [] tmp_buf;
return false;
}
delete [] tmp_buf;
tmp_buf = NULL;
}
return true;
@ -741,8 +747,9 @@ void loadstate_slot(int num)
// in the (most common) case that we already know where the next entry is.
static const SFORMAT *CheckS(const SFORMAT *guessSF, const SFORMAT *firstSF, u32 size, u32 count, char *desc)
{
const SFORMAT *sf = guessSF ? guessSF : firstSF;
while(sf->v)
const SFORMAT *sf = (guessSF != NULL) ? guessSF : firstSF;
while (sf->v)
{
//NOT SUPPORTED RIGHT NOW
//if(sf->size==~0) // Link to another SFORMAT structure.
@ -753,15 +760,20 @@ static const SFORMAT *CheckS(const SFORMAT *guessSF, const SFORMAT *firstSF, u32
// sf++;
// continue;
//}
if(!memcmp(desc,sf->desc,4))
if (!memcmp(desc,sf->desc,4))
{
if(sf->size != size || sf->count != count)
return 0;
return sf;
if (sf->size != size || sf->count != count)
{
return NULL;
}
else
{
return sf;
}
}
// failed to find it, have to keep iterating
if(guessSF)
if (guessSF != NULL)
{
sf = firstSF;
guessSF = NULL;
@ -771,50 +783,56 @@ static const SFORMAT *CheckS(const SFORMAT *guessSF, const SFORMAT *firstSF, u32
sf++;
}
}
return 0;
return NULL;
}
static bool ReadStateChunk(EMUFILE* is, const SFORMAT *sf, int size)
static bool ReadStateChunk(EMUFILE &is, const SFORMAT *sf, int size)
{
const SFORMAT *tmp = NULL;
const SFORMAT *guessSF = NULL;
int temp = is->ftell();
int temp = is.ftell();
while(is->ftell()<temp+size)
while (is.ftell() < (temp+size))
{
u32 sz, count;
char toa[4];
is->fread(toa,4);
if(is->fail())
is.fread(toa,4);
if (is.fail())
return false;
if(!read32le(&sz,is)) return false;
if(!read32le(&count,is)) return false;
if((tmp=CheckS(guessSF,sf,sz,count,toa)))
if (!is.read_32LE(sz)) return false;
if (!is.read_32LE(count)) return false;
tmp = CheckS(guessSF,sf,sz,count,toa);
if (tmp != NULL)
{
#ifdef MSB_FIRST
if(sz == 1) {
if (sz == 1)
{
//special case: read a huge byte array
is->fread((char *)tmp->v,count);
} else {
for(unsigned int i=0;i<count;i++)
is.fread(tmp->v,count);
}
else
{
for (size_t i = 0; i < count; i++)
{
is->fread((char *)tmp->v + i*sz,sz);
FlipByteOrder((u8*)tmp->v + i*sz,sz);
is.fread((u8 *)tmp->v + i*sz,sz);
FlipByteOrder((u8 *)tmp->v + i*sz,sz);
}
}
#else
// no need to ever loop one at a time if not flipping byte order
is->fread((char *)tmp->v,sz*count);
is.fread(tmp->v,sz*count);
#endif
guessSF = tmp + 1;
}
else
{
is->fseek(sz*count,SEEK_CUR);
is.fseek(sz*count,SEEK_CUR);
guessSF = NULL;
}
} // while(...)
@ -823,9 +841,9 @@ static bool ReadStateChunk(EMUFILE* is, const SFORMAT *sf, int size)
static int SubWrite(EMUFILE* os, const SFORMAT *sf)
static int SubWrite(EMUFILE *os, const SFORMAT *sf)
{
uint32 acc=0;
u32 acc=0;
#ifdef DEBUG
std::set<std::string> keyset;
@ -843,12 +861,12 @@ static int SubWrite(EMUFILE* os, const SFORMAT *sf)
temp++;
}
while(sf->v)
while (sf->v)
{
//not supported right now
//if(sf->size==~0) //Link to another struct
//{
// uint32 tmp;
// u32 tmp;
// if(!(tmp=SubWrite(os,(SFORMAT *)sf->v)))
// return(0);
@ -864,11 +882,11 @@ static int SubWrite(EMUFILE* os, const SFORMAT *sf)
acc += 4 + sizeof(sf->size) + sizeof(sf->count);
acc += count * size;
if(os) //Are we writing or calculating the size of this block?
if (os != NULL) //Are we writing or calculating the size of this block?
{
os->fwrite(sf->desc,4);
write32le(sf->size,os);
write32le(sf->count,os);
os->write_32LE(sf->size);
os->write_32LE(sf->count);
#ifdef DEBUG
//make sure we dont dup any keys
@ -882,20 +900,24 @@ static int SubWrite(EMUFILE* os, const SFORMAT *sf)
#ifdef MSB_FIRST
if(size == 1) {
if (size == 1)
{
//special case: write a huge byte array
os->fwrite((char *)sf->v,count);
} else {
for(int i=0;i<count;i++) {
FlipByteOrder((u8*)sf->v + i*size, size);
os->fwrite((char*)sf->v + i*size,size);
os->fwrite(sf->v,count);
}
else
{
for (int i = 0; i < count; i++)
{
FlipByteOrder((u8 *)sf->v + i*size, size);
os->fwrite((u8 *)sf->v + i*size,size);
//Now restore the original byte order.
FlipByteOrder((u8*)sf->v + i*size, size);
FlipByteOrder((u8 *)sf->v + i*size, size);
}
}
#else
// no need to ever loop one at a time if not flipping byte order
os->fwrite((char *)sf->v,size*count);
os->fwrite(sf->v,size*count);
#endif
}
sf++;
@ -904,38 +926,38 @@ static int SubWrite(EMUFILE* os, const SFORMAT *sf)
return(acc);
}
static int savestate_WriteChunk(EMUFILE* os, int type, const SFORMAT *sf)
static int savestate_WriteChunk(EMUFILE &os, int type, const SFORMAT *sf)
{
write32le(type,os);
if(!sf) return 4;
int bsize = SubWrite((EMUFILE*)0,sf);
write32le(bsize,os);
os.write_32LE(type);
if (!sf) return 4;
int bsize = SubWrite(NULL,sf);
os.write_32LE(bsize);
if(!SubWrite(os,sf))
if (!SubWrite(&os,sf))
{
return 8;
}
return (bsize+8);
}
static void savestate_WriteChunk(EMUFILE* os, int type, void (*saveproc)(EMUFILE* os))
static void savestate_WriteChunk(EMUFILE &os, int type, void (*saveproc)(EMUFILE &os))
{
u32 pos1 = os->ftell();
u32 pos1 = os.ftell();
//write the type, size(placeholder), and data
write32le(type,os);
os->fseek(4, SEEK_CUR); // skip the size, we write that later
os.write_32LE(type);
os.fseek(4, SEEK_CUR); // skip the size, we write that later
saveproc(os);
//get the size
u32 pos2 = os->ftell();
u32 pos2 = os.ftell();
assert(pos2 != (u32)-1); // if this assert fails, saveproc did something bad
u32 size = (pos2 - pos1) - (2 * sizeof(u32));
//fill in the actual size
os->fseek(pos1 + sizeof(u32),SEEK_SET);
write32le(size,os);
os->fseek(pos2,SEEK_SET);
os.fseek(pos1 + sizeof(u32),SEEK_SET);
os.write_32LE(size);
os.fseek(pos2,SEEK_SET);
/*
// old version of this function,
@ -951,15 +973,15 @@ static void savestate_WriteChunk(EMUFILE* os, int type, void (*saveproc)(EMUFILE
u32 size = mstemp.size();
//write the type, size, and data
write32le(type,os);
write32le(size,os);
write_32LE(type,os);
write_32LE(size,os);
os->write(mstemp.buf(),size);
*/
}
static void writechunks(EMUFILE* os);
static void writechunks(EMUFILE &os);
bool savestate_save(EMUFILE* outstream, int compressionLevel)
bool savestate_save(EMUFILE &outstream, int compressionLevel)
{
#ifdef HAVE_JIT
arm_jit_sync();
@ -969,30 +991,24 @@ bool savestate_save(EMUFILE* outstream, int compressionLevel)
#endif
EMUFILE_MEMORY ms;
EMUFILE* os;
EMUFILE &os = (compressionLevel != Z_NO_COMPRESSION) ? (EMUFILE &)ms : (EMUFILE &)outstream;
if(compressionLevel != Z_NO_COMPRESSION)
if (compressionLevel == Z_NO_COMPRESSION)
{
//generate the savestate in memory first
os = (EMUFILE*)&ms;
writechunks(os);
}
else
{
os = outstream;
os->fseek(32,SEEK_SET); //skip the header
writechunks(os);
os.fseek(32,SEEK_SET); //skip the header
}
writechunks(os);
//save the length of the file
u32 len = os->ftell();
u32 len = os.ftell();
u32 comprlen = 0xFFFFFFFF;
u8* cbuf;
//compress the data
int error = Z_OK;
if(compressionLevel != Z_NO_COMPRESSION)
if (compressionLevel != Z_NO_COMPRESSION)
{
cbuf = ms.buf();
uLongf comprlen2;
@ -1007,16 +1023,16 @@ bool savestate_save(EMUFILE* outstream, int compressionLevel)
}
//dump the header
outstream->fseek(0,SEEK_SET);
outstream->fwrite(magic,16);
write32le(SAVESTATE_VERSION,outstream);
write32le(EMU_DESMUME_VERSION_NUMERIC(),outstream); //desmume version
write32le(len,outstream); //uncompressed length
write32le(comprlen,outstream); //compressed length (-1 if it is not compressed)
outstream.fseek(0,SEEK_SET);
outstream.fwrite(magic,16);
outstream.write_32LE(SAVESTATE_VERSION);
outstream.write_32LE(EMU_DESMUME_VERSION_NUMERIC()); //desmume version
outstream.write_32LE(len); //uncompressed length
outstream.write_32LE(comprlen); //compressed length (-1 if it is not compressed)
if(compressionLevel != Z_NO_COMPRESSION)
if (compressionLevel != Z_NO_COMPRESSION)
{
outstream->fwrite((char*)cbuf,comprlen==(u32)-1?len:comprlen);
outstream.fwrite(cbuf,comprlen==(u32)-1?len:comprlen);
delete[] cbuf;
}
@ -1028,9 +1044,9 @@ bool savestate_save (const char *file_name)
EMUFILE_MEMORY ms;
size_t elems_written;
#ifdef HAVE_LIBZ
if(!savestate_save(&ms, Z_DEFAULT_COMPRESSION))
if (!savestate_save(ms, Z_DEFAULT_COMPRESSION))
#else
if(!savestate_save(&ms, 0))
if (!savestate_save(ms, 0))
#endif
return false;
FILE* file = fopen(file_name,"wb");
@ -1042,7 +1058,8 @@ bool savestate_save (const char *file_name)
} else return false;
}
static void writechunks(EMUFILE* os) {
static void writechunks(EMUFILE &os)
{
DateTime tm = DateTime::get_Now();
svn_rev = 0;
@ -1077,7 +1094,7 @@ static void writechunks(EMUFILE* os) {
savestate_WriteChunk(os,0xFFFFFFFF,(SFORMAT*)0);
}
static bool ReadStateChunks(EMUFILE* is, s32 totalsize)
static bool ReadStateChunks(EMUFILE &is, s32 totalsize)
{
bool ret = true;
bool haveInfo = false;
@ -1101,13 +1118,14 @@ static bool ReadStateChunks(EMUFILE* is, s32 totalsize)
};
memset(&header, 0, sizeof(header));
while(totalsize > 0)
while (totalsize > 0)
{
u32 size = 0;
u32 t = 0;
if(!read32le(&t,is)) { ret=false; break; }
if(t == 0xFFFFFFFF) break;
if(!read32le(&size,is)) { ret=false; break; }
if (!is.read_32LE(t)) { ret=false; break; }
if (t == 0xFFFFFFFF) break;
if (!is.read_32LE(size)) { ret=false; break; }
switch(t)
{
case 1: if(!ReadStateChunk(is,SF_ARM9,size)) ret=false; break;
@ -1161,7 +1179,7 @@ static bool ReadStateChunks(EMUFILE* is, s32 totalsize)
{
static const char *wday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
DateTime tm = save_time;
printf("\tSave created: %04d-%03s-%02d %s %02d:%02d:%02d\n", tm.get_Year(), DateTime::GetNameOfMonth(tm.get_Month()), tm.get_Day(), wday[tm.get_DayOfWeek()%7], tm.get_Hour(), tm.get_Minute(), tm.get_Second());
printf("\tSave created: %04d-%.3s-%02d %s %02d:%02d:%02d\n", tm.get_Year(), DateTime::GetNameOfMonth(tm.get_Month()), tm.get_Day(), wday[tm.get_DayOfWeek()%7], tm.get_Hour(), tm.get_Minute(), tm.get_Second());
}
//nope. create a common method elsewhere for printing this.
@ -1214,41 +1232,44 @@ static void loadstate()
execute = !driver->EMU_IsEmulationPaused();
}
bool savestate_load(EMUFILE* is)
bool savestate_load(EMUFILE &is)
{
SAV_silent_fail_flag = false;
char header[16];
is->fread(header,16);
if(is->fail() || memcmp(header,magic,16))
is.fread(header,16);
if (is.fail() || memcmp(header,magic,16))
return false;
u32 ssversion,len,comprlen;
if(!read32le(&ssversion,is)) return false;
if(!read32le(&_DESMUME_version,is)) return false;
if(!read32le(&len,is)) return false;
if(!read32le(&comprlen,is)) return false;
if (!is.read_32LE(ssversion)) return false;
if (!is.read_32LE(_DESMUME_version)) return false;
if (!is.read_32LE(len)) return false;
if (!is.read_32LE(comprlen)) return false;
if(ssversion != SAVESTATE_VERSION) return false;
if (ssversion != SAVESTATE_VERSION) return false;
std::vector<u8> buf(len);
if(comprlen != 0xFFFFFFFF) {
if (comprlen != 0xFFFFFFFF)
{
#ifndef HAVE_LIBZ
//without libz, we can't decompress this savestate
return false;
#endif
std::vector<char> cbuf(comprlen);
is->fread(&cbuf[0],comprlen);
if(is->fail()) return false;
is.fread(&cbuf[0],comprlen);
if (is.fail()) return false;
#ifdef HAVE_LIBZ
uLongf uncomprlen = len;
int error = uncompress((uint8*)&buf[0],&uncomprlen,(uint8*)&cbuf[0],comprlen);
if(error != Z_OK || uncomprlen != len)
if (error != Z_OK || uncomprlen != len)
return false;
#endif
} else {
is->fread((char*)&buf[0],len-32);
}
else
{
is.fread(&buf[0],len-32);
}
//GO!! READ THE SAVESTATE
@ -1273,9 +1294,9 @@ bool savestate_load(EMUFILE* is)
//SPU_Reset();
EMUFILE_MEMORY mstemp(&buf);
bool x = ReadStateChunks(&mstemp,(s32)len);
bool x = ReadStateChunks(mstemp,(s32)len);
if(!x && !SAV_silent_fail_flag)
if (!x && !SAV_silent_fail_flag)
{
msgbox->error("Error loading savestate. It failed halfway through;\nSince there is no savestate backup system, your current game session is wrecked");
return false;
@ -1283,11 +1304,13 @@ bool savestate_load(EMUFILE* is)
loadstate();
if(nds.ConsoleType != CommonSettings.ConsoleType) {
if (nds.ConsoleType != CommonSettings.ConsoleType)
{
printf("WARNING: forcing console type to: ConsoleType=%d\n",nds.ConsoleType);
}
if((nds._DebugConsole!=0) != CommonSettings.DebugConsole) {
if ((nds._DebugConsole != 0) != CommonSettings.DebugConsole)
{
printf("WARNING: forcing console debug mode to: debugmode=%s\n",nds._DebugConsole?"TRUE":"FALSE");
}
@ -1298,7 +1321,7 @@ bool savestate_load(EMUFILE* is)
bool savestate_load(const char *file_name)
{
EMUFILE_FILE f(file_name,"rb");
if(f.fail()) return false;
if (f.fail()) return false;
return savestate_load(&f);
return savestate_load(f);
}

View File

@ -1,7 +1,7 @@
/*
Copyright (C) 2006 Normmatt
Copyright (C) 2007 Pascal Giard
Copyright (C) 2007-2012 DeSmuME team
Copyright (C) 2007-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -63,7 +63,7 @@ bool savestate_save (const char *file_name);
void savestate_slot(int num);
void loadstate_slot(int num);
bool savestate_load(class EMUFILE* is);
bool savestate_save(class EMUFILE* outstream, int compressionLevel);
bool savestate_load(class EMUFILE &is);
bool savestate_save(class EMUFILE &outstream, int compressionLevel);
#endif

View File

@ -198,11 +198,11 @@ NDS_SLOT1_TYPE slot1_GetSelectedType()
return slot1_device_type;
}
void slot1_Savestate(EMUFILE* os)
void slot1_Savestate(EMUFILE &os)
{
slot1_device->savestate(os);
}
void slot1_Loadstate(EMUFILE* is)
void slot1_Loadstate(EMUFILE &is)
{
slot1_device->loadstate(is);
}

View File

@ -88,9 +88,9 @@ public:
//called when NDS_FakeBoot terminates, emulate in here the BIOS behaviour
virtual void post_fakeboot(int PROCNUM) {}
virtual void savestate(EMUFILE* os) {}
virtual void savestate(EMUFILE &os) {}
virtual void loadstate(EMUFILE* is) {}
virtual void loadstate(EMUFILE &is) {}
};
typedef ISlot1Interface* TISlot1InterfaceConstructor();
@ -114,8 +114,8 @@ void slot1_Init();
bool slot1_Connect();
void slot1_Disconnect();
void slot1_Shutdown();
void slot1_Savestate(EMUFILE* os);
void slot1_Loadstate(EMUFILE* is);
void slot1_Savestate(EMUFILE &os);
void slot1_Loadstate(EMUFILE &is);
//just disconnects and reconnects the device. ideally, the disconnection and connection would be called with sensible timing
void slot1_Reset();

View File

@ -266,12 +266,12 @@ NDS_SLOT2_TYPE slot2_DetermineTypeByGameCode(const char *theGameCode)
return theType;
}
void slot2_Savestate(EMUFILE* os)
void slot2_Savestate(EMUFILE &os)
{
slot2_device->savestate(os);
}
void slot2_Loadstate(EMUFILE* is)
void slot2_Loadstate(EMUFILE &is)
{
slot2_device->loadstate(is);
}

View File

@ -78,9 +78,9 @@ public:
virtual u16 readWord(u8 PROCNUM, u32 addr) { return 0xFFFF; };
virtual u32 readLong(u8 PROCNUM, u32 addr) { return 0xFFFFFFFF; };
virtual void savestate(EMUFILE* os) {}
virtual void savestate(EMUFILE &os) {}
virtual void loadstate(EMUFILE* is) {}
virtual void loadstate(EMUFILE &is) {}
};
typedef ISlot2Interface* TISlot2InterfaceConstructor();
@ -108,8 +108,8 @@ void slot2_Init();
bool slot2_Connect();
void slot2_Disconnect();
void slot2_Shutdown();
void slot2_Savestate(EMUFILE* os);
void slot2_Loadstate(EMUFILE* is);
void slot2_Savestate(EMUFILE &os);
void slot2_Loadstate(EMUFILE &is);
//just disconnects and reconnects the device. ideally, the disconnection and connection would be called with sensible timing
void slot2_Reset();

View File

@ -1,7 +1,7 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2006-2007 shash
Copyright (C) 2008-2016 DeSmuME team
Copyright (C) 2008-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -1258,6 +1258,11 @@ void NDSTextureUnpack4x4(const size_t srcSize, const u32 *__restrict srcData, co
tmp_col[3] = COLOR555TO8888_OPAQUE(tmp2);
break;
}
default:
tmp_col[2] = 0;
tmp_col[3] = 0;
break;
}
if (TEXCACHEFORMAT == TexFormat_15bpp)

View File

@ -330,20 +330,50 @@ typedef enum
ARM7 = 1
} cpu_id_t;
inline u64 double_to_u64(double d) {
union {
inline u64 double_to_u64(double d)
{
union
{
u64 a;
double b;
} fuxor;
fuxor.b = d;
return fuxor.a;
}
inline double u64_to_double(u64 u) {
union {
inline double u64_to_double(u64 u)
{
union
{
u64 a;
double b;
} fuxor;
fuxor.a = u;
return fuxor.b;
}
inline u32 float_to_u32(float f)
{
union
{
u32 a;
float b;
} fuxor;
fuxor.b = f;
return fuxor.a;
}
inline float u32_to_float(u32 u)
{
union
{
u32 a;
float b;
} fuxor;
fuxor.a = u;
return fuxor.b;
}
@ -430,4 +460,4 @@ FORCEINLINE s32 sfx32_shiftdown(const s64 a)
return fx32_shiftdown(a);
}
#endif
#endif

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2011-2015 DeSmuME team
Copyright (C) 2011-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -122,7 +122,7 @@ bool ADVANsCEne::getXMLConfig(const char *in_filename)
return true;
}
u32 ADVANsCEne::convertDB(const char *in_filename, EMUFILE* output)
u32 ADVANsCEne::convertDB(const char *in_filename, EMUFILE &output)
{
//these strings are contained in the xml file, verbatim, so they function as enum values
//we leave the strings here rather than pooled elsewhere to remind us that theyre part of the advanscene format.
@ -156,20 +156,22 @@ u32 ADVANsCEne::convertDB(const char *in_filename, EMUFILE* output)
printf("Converting DB...\n");
if (getXMLConfig(in_filename))
{
if (datName.size()==0) return 0;
if (datName.size() == 0) return 0;
if (datName != _ADVANsCEne_BASE_NAME) return 0;
}
// Header
output->fwrite(_ADVANsCEne_BASE_ID, strlen(_ADVANsCEne_BASE_ID));
output->fputc(_ADVANsCEne_BASE_VERSION_MAJOR);
output->fputc(_ADVANsCEne_BASE_VERSION_MINOR);
output.fwrite(_ADVANsCEne_BASE_ID, strlen(_ADVANsCEne_BASE_ID));
output.write_u8(_ADVANsCEne_BASE_VERSION_MAJOR);
output.write_u8(_ADVANsCEne_BASE_VERSION_MINOR);
if (datVersion.size())
output->fwrite(&datVersion[0], datVersion.size());
output.fwrite(&datVersion[0], datVersion.size());
else
output->fputc(0);
output.write_u8(0);
time_t __time = time(NULL);
output->fwrite(&__time, sizeof(time_t));
output.fwrite(&__time, sizeof(time_t));
xml = new TiXmlDocument();
if (!xml) return 0;
@ -181,10 +183,11 @@ u32 ADVANsCEne::convertDB(const char *in_filename, EMUFILE* output)
el = el_games->FirstChildElement("game");
if (!el) return 0;
u32 count = 0;
while (el)
{
TiXmlElement* title = el->FirstChildElement("title");
if(title)
TiXmlElement *title = el->FirstChildElement("title");
if (title)
{
//just a little diagnostic
//printf("Importing %s\n",title->GetText());
@ -193,17 +196,17 @@ u32 ADVANsCEne::convertDB(const char *in_filename, EMUFILE* output)
el_serial = el->FirstChildElement("serial");
if(!el_serial)
if (!el_serial)
{
lastImportErrorMessage = "Missing <serial> element. Did you use the right xml file? We need the RtoolDS one.";
return 0;
}
output->fwrite(el_serial->GetText(), 8);
output.fwrite(el_serial->GetText(), 8);
// CRC32
el_crc32 = el->FirstChildElement("files");
sscanf(el_crc32->FirstChildElement("romCRC")->GetText(), "%x", &crc32);
output->fwrite(&crc32, sizeof(u32));
output.write_32LE(crc32);
// Save type
el_saveType = el->FirstChildElement("saveType");
@ -213,7 +216,7 @@ u32 ADVANsCEne::convertDB(const char *in_filename, EMUFILE* output)
const char *tmp = el_saveType->GetText();
if (tmp)
{
if (strcmp(tmp, "None") == 0)
if (strcmp(tmp, "None") == 0)
selectedSaveType = 0xFE;
else
{
@ -229,18 +232,23 @@ u32 ADVANsCEne::convertDB(const char *in_filename, EMUFILE* output)
}
}
}
output->fputc(selectedSaveType);
output->fwrite(&reserved, sizeof(u32));
output->fwrite(&reserved, sizeof(u32));
output.write_u8(selectedSaveType);
output.write_32LE(reserved);
output.write_32LE(reserved);
count++;
el = el->NextSiblingElement("game");
}
printf("\n");
delete xml;
if (count > 0)
printf("done\n");
else
printf("error\n");
printf("ADVANsCEne converter: %i found\n", count);
return count;
}

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2011-2015 DeSmuME team
Copyright (C) 2011-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -53,7 +53,7 @@ public:
}
void setDatabase(const char *path);
std::string getDatabase() const { return database_path; }
u32 convertDB(const char *in_filename, EMUFILE* output);
u32 convertDB(const char *in_filename, EMUFILE &output);
u8 checkDB(const char *ROMserial, u32 crc);
u32 getSaveType() { return saveType; }
u32 getCRC32() { return crc32; }

View File

@ -2,7 +2,7 @@
//subsequently modified for desmume
/*
Copyright (C) 2008-2009 DeSmuME team
Copyright (C) 2008-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -49,14 +49,14 @@ std::vector<std::string> tokenize_str(const std::string & str,const std::string
std::string stditoa(int n);
//extracts a decimal uint from an istream
template<typename T> T templateIntegerDecFromIstream(EMUFILE* is)
template<typename T> T templateIntegerDecFromIstream(EMUFILE &is)
{
unsigned int ret = 0;
bool pre = true;
for(;;)
{
int c = is->fgetc();
int c = is.fgetc();
if(c == -1) return ret;
int d = c - '0';
if((d<0 || d>9))
@ -71,33 +71,35 @@ template<typename T> T templateIntegerDecFromIstream(EMUFILE* is)
ret += d;
}
}
is->unget();
is.unget();
return ret;
}
inline u32 u32DecFromIstream(EMUFILE* is) { return templateIntegerDecFromIstream<u32>(is); }
inline u64 u64DecFromIstream(EMUFILE* is) { return templateIntegerDecFromIstream<u64>(is); }
inline u32 u32DecFromIstream(EMUFILE &is) { return templateIntegerDecFromIstream<u32>(is); }
inline u64 u64DecFromIstream(EMUFILE &is) { return templateIntegerDecFromIstream<u64>(is); }
//puts an optionally 0-padded decimal integer of type T into the ostream (0-padding is quicker)
template<typename T, int DIGITS, bool PAD> void putdec(EMUFILE* os, T dec)
template<typename T, int DIGITS, bool PAD> void putdec(EMUFILE &os, T dec)
{
char temp[DIGITS];
int ctr = 0;
for(int i=0;i<DIGITS;i++)
for (int i = 0; i < DIGITS; i++)
{
int quot = dec/10;
int rem = dec%10;
int quot = dec / 10;
int rem = dec % 10;
temp[DIGITS-1-i] = '0' + rem;
if(!PAD)
if (!PAD)
{
if(rem != 0) ctr = i;
if (rem != 0) ctr = i;
}
dec = quot;
}
if(!PAD)
os->fwrite(temp+DIGITS-ctr-1,ctr+1);
if (!PAD)
os.fwrite(temp+DIGITS-ctr-1,ctr+1);
else
os->fwrite(temp,DIGITS);
os.fwrite(temp,DIGITS);
}
std::string mass_replace(const std::string &source, const std::string &victim, const std::string &replacement);