merge trunk to bgklink

git-svn-id: https://svn.code.sf.net/p/vbam/code/branches/bgk-link@1230 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
squall-leonhart 2014-03-18 10:03:06 +00:00
parent a604ebee68
commit 05435d0f34
40 changed files with 926 additions and 284 deletions

View File

@ -6,7 +6,7 @@ or when stated otherwise in the source file:
Copyright for the modifications to the files mentioned above:
VisualBoyAdvance-M GB/GBA emulator
Copyright (C) 2007-2008 VBA-M development team
Copyright (C) 2007-2013 VBA-M development team
All files excluding gb_apu, modified files from zlib

View File

@ -138,6 +138,7 @@ Spacy
DJRobX
Jonas Quinn
kode54
Normmatt
==============
Special Thanks
@ -172,3 +173,6 @@ kode64:
shuffle2:
- SFML library
- various build fixes
Squarepusher
- Libretro merge

View File

@ -1,45 +1,49 @@
#ifndef SYSTEM_H
#define SYSTEM_H
#include "common/Types.h"
#include <zlib.h>
class SoundDriver;
struct EmulatedSystem {
// main emulation function
void (*emuMain)(int);
// reset emulator
void (*emuReset)();
// clean up memory
void (*emuCleanUp)();
// load battery file
bool (*emuReadBattery)(const char *);
// write battery file
bool (*emuWriteBattery)(const char *);
// load state
bool (*emuReadState)(const char *);
// save state
bool (*emuWriteState)(const char *);
// load memory state (rewind)
bool (*emuReadMemState)(char *, int);
// write memory state (rewind)
bool (*emuWriteMemState)(char *, int);
// write PNG file
bool (*emuWritePNG)(const char *);
// write BMP file
bool (*emuWriteBMP)(const char *);
// emulator update CPSR (ARM only)
void (*emuUpdateCPSR)();
// emulator has debugger
bool emuHasDebugger;
// clock ticks to emulate
int emuCount;
// main emulation function
void (*emuMain)(int);
// reset emulator
void (*emuReset)();
// clean up memory
void (*emuCleanUp)();
// load battery file
bool (*emuReadBattery)(const char *);
// write battery file
bool (*emuWriteBattery)(const char *);
#ifdef __LIBRETRO__
// load state
bool (*emuReadState)(const u8*, unsigned);
// load state
unsigned (*emuWriteState)(u8*, unsigned);
#else
// load state
bool (*emuReadState)(const char *);
// save state
bool (*emuWriteState)(const char *);
#endif
// load memory state (rewind)
bool (*emuReadMemState)(char *, int);
// write memory state (rewind)
bool (*emuWriteMemState)(char *, int);
// write PNG file
bool (*emuWritePNG)(const char *);
// write BMP file
bool (*emuWriteBMP)(const char *);
// emulator update CPSR (ARM only)
void (*emuUpdateCPSR)();
// emulator has debugger
bool emuHasDebugger;
// clock ticks to emulate
int emuCount;
};
extern void log(const char *,...);
extern bool systemPauseOnFrame();
extern void systemGbPrint(u8 *,int,int,int,int,int);
extern void systemScreenCapture(int);
@ -56,14 +60,13 @@ extern void systemOnWriteDataToSoundBuffer(const u16 * finalWave, int length);
extern void systemOnSoundShutdown();
extern void systemScreenMessage(const char *);
extern void systemUpdateMotionSensor();
extern int systemGetSensorX();
extern int systemGetSensorY();
extern int systemGetSensorX();
extern int systemGetSensorY();
extern bool systemCanChangeSoundQuality();
extern void systemShowSpeed(int);
extern void system10Frames(int);
extern void systemFrame();
extern void systemGbBorderOn();
extern void Sm60FPS_Init();
extern bool Sm60FPS_CanSkipFrame();
extern void Sm60FPS_Sleep();
@ -73,10 +76,8 @@ extern void DbgMsg(const char *msg, ...);
#else
extern void winlog(const char *,...);
#endif
extern void (*dbgOutput)(const char *s, u32 addr);
extern void (*dbgSignal)(int sig,int number);
extern u16 systemColorMap16[0x10000];
extern u32 systemColorMap32[0x10000];
extern u16 systemGbPalette[24];
@ -89,8 +90,6 @@ extern int systemVerbose;
extern int systemFrameSkip;
extern int systemSaveUpdateCounter;
extern int systemSpeed;
#define SYSTEM_SAVE_UPDATED 30
#define SYSTEM_SAVE_NOT_UPDATED 0
#endif // SYSTEM_H

View File

@ -439,6 +439,8 @@ static bool utilIsImage(const char *file)
#include <Windows.h>
#endif
IMAGE_TYPE utilFindType(const char *file, char (&buffer)[2048]);
IMAGE_TYPE utilFindType(const char *file)
{
char buffer [2048];
@ -453,11 +455,10 @@ IMAGE_TYPE utilFindType(const char *file, char (&buffer)[2048])
pwText = new wchar_t[dwNum];
if(!pwText)
{
delete []pwText;
return IMAGE_UNKNOWN;
}
MultiByteToWideChar (CP_ACP, 0, file, -1, pwText, dwNum );
char* file_conv = fex_wide_to_path( pwText);
delete []pwText;
// if ( !utilIsImage( file_conv ) ) // TODO: utilIsArchive() instead?
// {
fex_t* fe = scan_arc(file_conv,utilIsImage,buffer);
@ -501,7 +502,7 @@ u8 *utilLoad(const char *file,
pwText = new wchar_t[dwNum];
if(!pwText)
{
delete []pwText;
return NULL;
}
MultiByteToWideChar (CP_ACP, 0, file, -1, pwText, dwNum );
char* file_conv = fex_wide_to_path( pwText);

View File

@ -11,23 +11,22 @@ enum IMAGE_TYPE {
// save game
typedef struct {
void *address;
int size;
void *address;
int size;
} variable_desc;
bool utilWritePNGFile(const char *, int, int, u8 *);
bool utilWriteBMPFile(const char *, int, int, u8 *);
void utilApplyIPS(const char *ips, u8 **rom, int *size);
void utilApplyIPS(const char *ips, uint8_t **rom, int *size);
bool utilIsGBAImage(const char *);
bool utilIsGBImage(const char *);
bool utilIsGzipFile(const char *);
bool utilIsZipFile(const char *);
void utilStripDoubleExtension(const char *, char *);
IMAGE_TYPE utilFindType(const char *);
IMAGE_TYPE utilFindType(const char *, char (&)[2048]);
u8 *utilLoad(const char *, bool (*)(const char*), u8 *, int &);
uint8_t *utilLoad(const char *, bool (*)(const char*), uint8_t *, int &);
void utilPutDword(u8 *, u32);
void utilPutWord(u8 *, u16);
void utilPutDword(uint8_t *, uint32_t);
void utilPutWord(uint8_t *, uint16_t);
void utilWriteData(gzFile, variable_desc *);
void utilReadData(gzFile, variable_desc *);
void utilReadDataSkip(gzFile, variable_desc *);
@ -44,4 +43,15 @@ void utilGBAFindSave(const u8 *, const int);
void utilUpdateSystemColorMaps(bool lcd = false);
bool utilFileExists( const char *filename );
#ifdef __LIBRETRO__
void utilWriteIntMem(uint8_t *& data, int);
void utilWriteMem(uint8_t *& data, const void *in_data, unsigned size);
void utilWriteDataMem(uint8_t *& data, variable_desc *);
int utilReadIntMem(const uint8_t *& data);
void utilReadMem(void *buf, const uint8_t *& data, unsigned size);
void utilReadDataMem(const uint8_t *& data, variable_desc *);
#endif
#endif // UTIL_H

View File

@ -276,7 +276,7 @@ static bool patchApplyUPS(const char *patchname, u8 **rom, int *size)
static int ppfVersion(FILE *f)
{
fseeko64(f, 0, SEEK_SET);
if (fgetc(f) != 'P' || fgetc(f) != 'P' || fgetc(f) != 'F')
if (fgetc(f) != 'P' || fgetc(f) != 'P' || fgetc(f) != 'F') //-V501
return 0;
switch(fgetc(f)){
case '1': return 1;

View File

@ -1,6 +1,16 @@
#ifndef PORT_H
#define PORT_H
#ifdef __CELLOS_LV2__
/* PlayStation3 */
#include <ppu_intrinsics.h>
#endif
#ifdef _XBOX360
/* XBox 360 */
#include <ppcintrinsics.h>
#endif
#include "Types.h"
// swaps a 16-bit value

View File

@ -40,12 +40,22 @@ void SoundSDL::read(u16 * stream, int length)
if (!_initialized || length <= 0 || !emulating)
return;
/* since this is running in a different thread, speedup and
* throttle can change at any time; save the value so locks
* stay in sync */
bool lock = (emulating && !speedup) ? true : false;
if (lock)
SDL_SemWait (_semBufferFull);
SDL_mutexP(_mutex);
_rbuf.read(stream, std::min(static_cast<std::size_t>(length) / 2, _rbuf.used()));
SDL_CondSignal(_cond);
SDL_mutexV(_mutex);
SDL_SemPost (_semBufferEmpty);
}
void SoundSDL::write(u16 * finalWave, int length)
@ -63,23 +73,25 @@ void SoundSDL::write(u16 * finalWave, int length)
std::size_t avail;
while ((avail = _rbuf.avail() / 2) < samples)
{
bool lock = (emulating && !speedup) ? true : false;
_rbuf.write(finalWave, avail * 2);
finalWave += avail * 2;
samples -= avail;
// If emulating and not in speed up mode, synchronize to audio
// by waiting till there is enough room in the buffer
if (emulating && !speedup)
SDL_mutexV(_mutex);
SDL_SemPost(_semBufferFull);
if (lock)
{
SDL_CondWait(_cond, _mutex);
SDL_SemWait(_semBufferEmpty);
}
else
{
// Drop the remaining of the audio data
SDL_mutexV(_mutex);
return;
}
SDL_mutexP(_mutex);
}
_rbuf.write(finalWave, samples * 2);
@ -106,9 +118,10 @@ bool SoundSDL::init(long sampleRate)
_rbuf.reset(_delay * sampleRate * 2);
_cond = SDL_CreateCond();
_mutex = SDL_CreateMutex();
_initialized = true;
_mutex = SDL_CreateMutex();
_semBufferFull = SDL_CreateSemaphore (0);
_semBufferEmpty = SDL_CreateSemaphore (1);
_initialized = true;
return true;
}
@ -121,11 +134,14 @@ SoundSDL::~SoundSDL()
SDL_mutexP(_mutex);
int iSave = emulating;
emulating = 0;
SDL_CondSignal(_cond);
SDL_SemPost(_semBufferFull);
SDL_SemPost(_semBufferEmpty);
SDL_mutexV(_mutex);
SDL_DestroyCond(_cond);
_cond = NULL;
SDL_DestroySemaphore(_semBufferFull);
SDL_DestroySemaphore(_semBufferEmpty);
_semBufferFull = NULL;
_semBufferEmpty = NULL;
SDL_DestroyMutex(_mutex);
_mutex = NULL;

View File

@ -38,8 +38,9 @@ public:
private:
RingBuffer<u16> _rbuf;
SDL_cond * _cond;
SDL_mutex * _mutex;
SDL_sem *_semBufferFull;
SDL_sem *_semBufferEmpty;
bool _initialized;

View File

@ -234,7 +234,7 @@ void gbRenderLine()
if(y >= inUseRegister_WY) {
if (gbWindowLine>143)
if ((gbWindowLine == -1) || (gbWindowLine>144))
gbWindowLine = 0;
int wx = register_WX;
@ -266,7 +266,7 @@ void gbRenderLine()
//bx >>= ((gbSCXLine[0]+(((swx>1) && (swx != 7)) ? 1 : 0)) & 7);
if ((swx == 7))
if (swx == 7)
{
//wx = 0;
if ((gbWindowLine>0) || (wy == 0))

View File

@ -121,6 +121,13 @@ static void reset_apu()
static void remake_stereo_buffer()
{
// APU
if ( !gb_apu )
{
gb_apu = new Gb_Apu; // TODO: handle errors
reset_apu();
}
// Stereo_Buffer
delete stereo_buffer;
stereo_buffer = 0;
@ -129,19 +136,14 @@ static void remake_stereo_buffer()
if ( stereo_buffer->set_sample_rate( soundSampleRate ) ) { } // TODO: handle out of memory
stereo_buffer->clock_rate( gb_apu->clock_rate );
// APU
// Multi_Buffer
static int const chan_types [chan_count] = {
Multi_Buffer::wave_type+1, Multi_Buffer::wave_type+2,
Multi_Buffer::wave_type+3, Multi_Buffer::mixed_type+1
};
if ( stereo_buffer->set_channel_count( chan_count, chan_types ) ) { } // TODO: handle errors
if ( !gb_apu )
{
gb_apu = new Gb_Apu; // TODO: handle errors
reset_apu();
}
// Volume Level
apply_effects();
apply_volume();
}

View File

@ -1,3 +1,4 @@
#ifndef __LIBRETRO__
#include <memory.h>
#include <string.h>
#include <stdio.h>
@ -2896,3 +2897,4 @@ void cheatsWriteByte(u32, u8)
#endif
#endif
}
#endif

View File

@ -1,4 +1,5 @@
#include <memory.h>
#include <string.h>
#include "GBA.h"
#include "EEprom.h"
#include "../Util.h"
@ -9,7 +10,15 @@ int eepromMode = EEPROM_IDLE;
int eepromByte = 0;
int eepromBits = 0;
int eepromAddress = 0;
#ifdef __LIBRETRO__
// Workaround for broken-by-design GBA save semantics
extern u8 libretro_save_buf[0x20000 + 0x2000];
u8 *eepromData = libretro_save_buf + 0x20000;
#else
u8 eepromData[0x2000];
#endif
u8 eepromBuffer[16];
bool eepromInUse = false;
int eepromSize = 512;
@ -27,7 +36,11 @@ variable_desc eepromSaveData[] = {
void eepromInit()
{
memset(eepromData, 255, sizeof(eepromData));
#ifdef __LIBRETRO__
memset(eepromData, 255, 0x2000);
#else
memset(eepromData, 255, sizeof(eepromData));
#endif
}
void eepromReset()
@ -40,6 +53,26 @@ void eepromReset()
eepromSize = 512;
}
#ifdef __LIBRETRO__
void eepromSaveGame(uint8_t *& data)
{
utilWriteDataMem(data, eepromSaveData);
utilWriteIntMem(data, eepromSize);
utilWriteMem(data, eepromData, 0x2000);
}
void eepromReadGame(const uint8_t *& data, int version)
{
utilReadDataMem(data, eepromSaveData);
if (version >= SAVE_GAME_VERSION_3) {
eepromSize = utilReadIntMem(data);
utilReadMem(eepromData, data, 0x2000);
} else {
// prior to 0.7.1, only 4K EEPROM was supported
eepromSize = 512;
}
}
#else
void eepromSaveGame(gzFile gzFile)
{
utilWriteData(gzFile, eepromSaveData);
@ -68,6 +101,7 @@ void eepromReadGameSkip(gzFile gzFile, int version)
utilGzSeek(gzFile, 0x2000, SEEK_CUR);
}
}
#endif
int eepromRead(u32 /* address */)
{

View File

@ -1,14 +1,23 @@
#ifndef EEPROM_H
#define EEPROM_H
#ifdef __LIBRETRO__
extern void eepromSaveGame(u8* &data);
extern void eepromReadGame(const u8 *&data, int version);
#else
extern void eepromSaveGame(gzFile _gzFile);
extern void eepromReadGame(gzFile _gzFile, int version);
#endif
extern void eepromReadGameSkip(gzFile _gzFile, int version);
extern int eepromRead(u32 address);
extern void eepromWrite(u32 address, u8 value);
extern void eepromInit();
extern void eepromReset();
#ifdef __LIBRETRO__
extern u8 *eepromData;
#else
extern u8 eepromData[0x2000];
#endif
extern bool eepromInUse;
extern int eepromSize;

View File

@ -1,4 +1,5 @@
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include "GBA.h"
#include "Globals.h"
@ -17,7 +18,13 @@
#define FLASH_PROGRAM 8
#define FLASH_SETBANK 9
u8 flashSaveMemory[FLASH_128K_SZ];
#ifdef __LIBRETRO__
extern uint8_t libretro_save_buf[0x20000 + 0x2000];
uint8_t *flashSaveMemory = libretro_save_buf;
#else
uint8_t flashSaveMemory[FLASH_128K_SZ];
#endif
int flashState = FLASH_READ_ARRAY;
int flashReadState = FLASH_READ_ARRAY;
int flashSize = 0x10000;
@ -51,7 +58,11 @@ static variable_desc flashSaveData3[] = {
void flashInit()
{
memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory));
#ifdef __LIBRETRO__
memset(flashSaveMemory, 0xff, 0x20000);
#else
memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory));
#endif
}
void flashReset()
@ -61,6 +72,17 @@ void flashReset()
flashBank = 0;
}
#ifdef __LIBRETRO__
void flashSaveGame(uint8_t *& data)
{
utilWriteDataMem(data, flashSaveData3);
}
void flashReadGame(const uint8_t *& data, int)
{
utilReadDataMem(data, flashSaveData3);
}
#else
void flashSaveGame(gzFile gzFile)
{
utilWriteData(gzFile, flashSaveData3);
@ -90,6 +112,8 @@ void flashReadGameSkip(gzFile gzFile, int version)
utilReadDataSkip(gzFile, flashSaveData3);
}
}
#endif
void flashSetSize(int size)
{

View File

@ -3,13 +3,22 @@
#define FLASH_128K_SZ 0x20000
#ifdef __LIBRETRO__
extern void flashSaveGame(u8 *& data);
extern void flashReadGame(const u8 *& data, int);
#else
extern void flashSaveGame(gzFile _gzFile);
extern void flashReadGame(gzFile _gzFile, int version);
#endif
extern void flashReadGameSkip(gzFile _gzFile, int version);
extern u8 flashRead(u32 address);
extern void flashWrite(u32 address, u8 byte);
extern void flashDelayedWrite(u32 address, u8 byte);
#ifdef __LIBRETRO__
extern uint8_t *flashSaveMemory;
#else
extern u8 flashSaveMemory[FLASH_128K_SZ];
#endif
extern void flashSaveDecide(u32 address, u8 byte);
extern void flashReset();
extern void flashSetSize(int size);

View File

@ -356,7 +356,11 @@ static void count(u32 opcode, int cond_res)
EMIT2(and, KONST(0x1F), ecx)
#define VALUE_LOAD_REG \
EMIT2(and, KONST(0x0F), eax) \
EMIT2(mov, REGREF2(eax,4), eax) \
EMIT2(cmp, KONST(0x0F), eax) \
EMIT2(mov, REGREF2(eax,4), eax) \
EMIT1(jne, LABELREF(3,f)) \
EMIT2(add, KONST(4), eax) \
LABEL(3) \
EMIT2(movzx, ch, ecx) \
EMIT2(and, KONST(0x0F), ecx) \
EMIT2(mov, REGREF2(ecx,4), ecx)
@ -1533,7 +1537,7 @@ static INSN_REGPARM void arm121(u32 opcode)
#define OP_LDR reg[dest].I = CPUReadMemory(address)
#define OP_LDRH reg[dest].I = CPUReadHalfWord(address)
#define OP_LDRB reg[dest].I = CPUReadByte(address)
#define OP_LDRSH reg[dest].I = (s16)CPUReadHalfWordSigned(address)
#define OP_LDRSH reg[dest].I = (u32)CPUReadHalfWordSigned(address)
#define OP_LDRSB reg[dest].I = (s8)CPUReadByte(address)
#define WRITEBACK_NONE /*nothing*/
@ -2608,8 +2612,7 @@ static INSN_REGPARM void armA00(u32 opcode)
reg[15].I += 4;
ARM_PREFETCH;
clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
clockTicks += 2 + codeTicksAccess32(armNextPC)
+ codeTicksAccessSeq32(armNextPC);
clockTicks = (clockTicks * 2) + codeTicksAccess32(armNextPC) + 1;
busPrefetchCount = 0;
}
@ -2625,8 +2628,7 @@ static INSN_REGPARM void armB00(u32 opcode)
reg[15].I += 4;
ARM_PREFETCH;
clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
clockTicks += 2 + codeTicksAccess32(armNextPC)
+ codeTicksAccessSeq32(armNextPC);
clockTicks = (clockTicks * 2) + codeTicksAccess32(armNextPC) + 1;
busPrefetchCount = 0;
}
@ -2644,9 +2646,8 @@ static INSN_REGPARM void armE01(u32 opcode)
// SWI <comment>
static INSN_REGPARM void armF00(u32 opcode)
{
clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
clockTicks += 2 + codeTicksAccess32(armNextPC)
+ codeTicksAccessSeq32(armNextPC);
clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
clockTicks = (clockTicks * 2) + codeTicksAccess32(armNextPC) + 1;
busPrefetchCount = 0;
CPUSoftwareInterrupt(opcode & 0x00FFFFFF);
}
@ -2700,7 +2701,7 @@ static insnfunc_t armInsnTable[4096] = {
arm0E0,arm0E1,arm0E2,arm0E3,arm0E4,arm0E5,arm0E6,arm0E7, // 0E0
arm0E0,arm0E9,arm0E2,arm0CB,arm0E4,arm_UI,arm0E6,arm_UI, // 0E8
arm0F0,arm0F1,arm0F2,arm0F3,arm0F4,arm0F5,arm0F6,arm0F7, // 0F0
arm0F0,arm0F9,arm0F2,arm_UI,arm0F4,arm0DD,arm0F6,arm0DF, // 0F8
arm0F0,arm0F9,arm0F2,arm0DB,arm0F4,arm0DD,arm0F6,arm0DF, // 0F8
arm100,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI, // 100
arm_UI,arm109,arm_UI,arm10B,arm_UI,arm_UI,arm_UI,arm_UI, // 108

View File

@ -1421,12 +1421,14 @@ static INSN_REGPARM void thumb45_3(u32 opcode)
static INSN_REGPARM void thumb46_0(u32 opcode)
{
reg[opcode&7].I = reg[((opcode>>3)&7)].I;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
}
// MOV Rd, Hs
static INSN_REGPARM void thumb46_1(u32 opcode)
{
reg[opcode&7].I = reg[((opcode>>3)&7)+8].I;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
}
// MOV Hd, Rs
@ -1473,16 +1475,14 @@ static INSN_REGPARM void thumb47(u32 opcode)
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC)
+ codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 3;
clockTicks = codeTicksAccessSeq16(armNextPC)*2 + codeTicksAccess16(armNextPC) + 3;
} else {
armState = true;
reg[15].I &= 0xFFFFFFFC;
armNextPC = reg[15].I;
reg[15].I += 4;
ARM_PREFETCH;
clockTicks = codeTicksAccessSeq32(armNextPC)
+ codeTicksAccessSeq32(armNextPC) + codeTicksAccess32(armNextPC) + 3;
clockTicks = codeTicksAccessSeq32(armNextPC)*2 + codeTicksAccess32(armNextPC) + 3;
}
}
@ -1576,7 +1576,7 @@ static INSN_REGPARM void thumb5E(u32 opcode)
if (busPrefetchCount == 0)
busPrefetch = busPrefetchEnable;
u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
reg[opcode&7].I = (s16)CPUReadHalfWordSigned(address);
reg[opcode&7].I = (u32)CPUReadHalfWordSigned(address);
clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC);
}
@ -1669,6 +1669,7 @@ static INSN_REGPARM void thumbA0(u32 opcode)
{
u8 regist = (opcode >> 8) & 7;
reg[regist].I = (reg[15].I & 0xFFFFFFFC) + ((opcode&255)<<2);
clockTicks = 1 + codeTicksAccess16(armNextPC);
}
// ADD R0~R7, SP, Imm
@ -1676,6 +1677,7 @@ static INSN_REGPARM void thumbA8(u32 opcode)
{
u8 regist = (opcode >> 8) & 7;
reg[regist].I = reg[13].I + ((opcode&255)<<2);
clockTicks = 1 + codeTicksAccess16(armNextPC);
}
// ADD SP, Imm
@ -1685,6 +1687,7 @@ static INSN_REGPARM void thumbB0(u32 opcode)
if(opcode & 0x80)
offset = -offset;
reg[13].I += offset;
clockTicks = 1 + codeTicksAccess16(armNextPC);
}
// Push and pop ///////////////////////////////////////////////////////////
@ -1882,13 +1885,13 @@ static INSN_REGPARM void thumbC8(u32 opcode)
static INSN_REGPARM void thumbD0(u32 opcode)
{
UPDATE_OLDREG;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
if(Z_FLAG) {
reg[15].I += ((s8)(opcode & 0xFF)) << 1;
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC)+3;
clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2;
busPrefetchCount=0;
}
}
@ -1897,13 +1900,13 @@ static INSN_REGPARM void thumbD0(u32 opcode)
static INSN_REGPARM void thumbD1(u32 opcode)
{
UPDATE_OLDREG;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
if(!Z_FLAG) {
reg[15].I += ((s8)(opcode & 0xFF)) << 1;
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC)+3;
clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2;
busPrefetchCount=0;
}
}
@ -1912,13 +1915,13 @@ static INSN_REGPARM void thumbD1(u32 opcode)
static INSN_REGPARM void thumbD2(u32 opcode)
{
UPDATE_OLDREG;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
if(C_FLAG) {
reg[15].I += ((s8)(opcode & 0xFF)) << 1;
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC)+3;
clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2;
busPrefetchCount=0;
}
}
@ -1927,13 +1930,13 @@ static INSN_REGPARM void thumbD2(u32 opcode)
static INSN_REGPARM void thumbD3(u32 opcode)
{
UPDATE_OLDREG;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
if(!C_FLAG) {
reg[15].I += ((s8)(opcode & 0xFF)) << 1;
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC)+3;
clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2;
busPrefetchCount=0;
}
}
@ -1942,13 +1945,13 @@ static INSN_REGPARM void thumbD3(u32 opcode)
static INSN_REGPARM void thumbD4(u32 opcode)
{
UPDATE_OLDREG;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
if(N_FLAG) {
reg[15].I += ((s8)(opcode & 0xFF)) << 1;
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC)+3;
clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2;
busPrefetchCount=0;
}
}
@ -1957,13 +1960,13 @@ static INSN_REGPARM void thumbD4(u32 opcode)
static INSN_REGPARM void thumbD5(u32 opcode)
{
UPDATE_OLDREG;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
if(!N_FLAG) {
reg[15].I += ((s8)(opcode & 0xFF)) << 1;
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC)+3;
clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2;
busPrefetchCount=0;
}
}
@ -1972,13 +1975,13 @@ static INSN_REGPARM void thumbD5(u32 opcode)
static INSN_REGPARM void thumbD6(u32 opcode)
{
UPDATE_OLDREG;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
if(V_FLAG) {
reg[15].I += ((s8)(opcode & 0xFF)) << 1;
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC)+3;
clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2;
busPrefetchCount=0;
}
}
@ -1987,13 +1990,13 @@ static INSN_REGPARM void thumbD6(u32 opcode)
static INSN_REGPARM void thumbD7(u32 opcode)
{
UPDATE_OLDREG;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
if(!V_FLAG) {
reg[15].I += ((s8)(opcode & 0xFF)) << 1;
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC)+3;
clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2;
busPrefetchCount=0;
}
}
@ -2002,13 +2005,13 @@ static INSN_REGPARM void thumbD7(u32 opcode)
static INSN_REGPARM void thumbD8(u32 opcode)
{
UPDATE_OLDREG;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
if(C_FLAG && !Z_FLAG) {
reg[15].I += ((s8)(opcode & 0xFF)) << 1;
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC)+3;
clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2;
busPrefetchCount=0;
}
}
@ -2017,13 +2020,13 @@ static INSN_REGPARM void thumbD8(u32 opcode)
static INSN_REGPARM void thumbD9(u32 opcode)
{
UPDATE_OLDREG;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
if(!C_FLAG || Z_FLAG) {
reg[15].I += ((s8)(opcode & 0xFF)) << 1;
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC)+3;
clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2;
busPrefetchCount=0;
}
}
@ -2032,13 +2035,13 @@ static INSN_REGPARM void thumbD9(u32 opcode)
static INSN_REGPARM void thumbDA(u32 opcode)
{
UPDATE_OLDREG;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
if(N_FLAG == V_FLAG) {
reg[15].I += ((s8)(opcode & 0xFF)) << 1;
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC)+3;
clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2;
busPrefetchCount=0;
}
}
@ -2047,13 +2050,13 @@ static INSN_REGPARM void thumbDA(u32 opcode)
static INSN_REGPARM void thumbDB(u32 opcode)
{
UPDATE_OLDREG;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
if(N_FLAG != V_FLAG) {
reg[15].I += ((s8)(opcode & 0xFF)) << 1;
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC)+3;
clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2;
busPrefetchCount=0;
}
}
@ -2062,13 +2065,13 @@ static INSN_REGPARM void thumbDB(u32 opcode)
static INSN_REGPARM void thumbDC(u32 opcode)
{
UPDATE_OLDREG;
clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
if(!Z_FLAG && (N_FLAG == V_FLAG)) {
reg[15].I += ((s8)(opcode & 0xFF)) << 1;
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC)+3;
clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2;
busPrefetchCount=0;
}
}
@ -2077,13 +2080,13 @@ static INSN_REGPARM void thumbDC(u32 opcode)
static INSN_REGPARM void thumbDD(u32 opcode)
{
UPDATE_OLDREG;
clockTicks = codeTicksAccessSeq16(armNextPC);
if(Z_FLAG || (N_FLAG != V_FLAG)) {
reg[15].I += ((s8)(opcode & 0xFF)) << 1;
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC)+3;
clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2;
busPrefetchCount=0;
}
}
@ -2094,8 +2097,8 @@ static INSN_REGPARM void thumbDD(u32 opcode)
static INSN_REGPARM void thumbDF(u32 opcode)
{
u32 address = 0;
clockTicks = codeTicksAccessSeq16(address) + codeTicksAccessSeq16(address) +
codeTicksAccess16(address)+3;
//clockTicks = codeTicksAccessSeq16(address)*2 + codeTicksAccess16(address)+3;
clockTicks = 3;
busPrefetchCount=0;
CPUSoftwareInterrupt(opcode & 0xFF);
}
@ -2110,8 +2113,7 @@ static INSN_REGPARM void thumbE0(u32 opcode)
armNextPC = reg[15].I;
reg[15].I += 2;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC) + 3;
clockTicks = codeTicksAccessSeq16(armNextPC)*2 + codeTicksAccess16(armNextPC)+3;
busPrefetchCount=0;
}
@ -2141,8 +2143,7 @@ static INSN_REGPARM void thumbF8(u32 opcode)
reg[15].I += 2;
reg[14].I = temp|1;
THUMB_PREFETCH;
clockTicks = codeTicksAccessSeq16(armNextPC) +
codeTicksAccess16(armNextPC) + codeTicksAccessSeq16(armNextPC) + 3;
clockTicks = codeTicksAccessSeq16(armNextPC)*2 + codeTicksAccess16(armNextPC) + 3;
busPrefetchCount = 0;
}

View File

@ -120,6 +120,9 @@ int capture = 0;
int capturePrevious = 0;
int captureNumber = 0;
int armOpcodeCount = 0;
int thumbOpcodeCount = 0;
const int TIMER_TICKS[4] = {
0,
6,
@ -574,6 +577,44 @@ void CPUUpdateRenderBuffers(bool force)
}
}
#ifdef __LIBRETRO__
#include <cstddef>
unsigned int CPUWriteState(u8* data, unsigned size)
{
uint8_t *orig = data;
utilWriteIntMem(data, SAVE_GAME_VERSION);
utilWriteMem(data, &rom[0xa0], 16);
utilWriteIntMem(data, useBios);
utilWriteMem(data, &reg[0], sizeof(reg));
utilWriteDataMem(data, saveGameStruct);
utilWriteIntMem(data, stopState);
utilWriteIntMem(data, IRQTicks);
utilWriteMem(data, internalRAM, 0x8000);
utilWriteMem(data, paletteRAM, 0x400);
utilWriteMem(data, workRAM, 0x40000);
utilWriteMem(data, vram, 0x20000);
utilWriteMem(data, oam, 0x400);
utilWriteMem(data, pix, 4 * 241 * 162);
utilWriteMem(data, ioMem, 0x400);
eepromSaveGame(data);
flashSaveGame(data);
soundSaveGame(data);
rtcSaveGame(data);
return (ptrdiff_t)data - (ptrdiff_t)orig;
}
bool CPUWriteMemState(char *memory, int available)
{
return false;
}
#else
static bool CPUWriteState(gzFile gzFile)
{
utilWriteInt(gzFile, SAVE_GAME_VERSION);
@ -627,6 +668,7 @@ bool CPUWriteState(const char *file)
return res;
}
bool CPUWriteMemState(char *memory, int available)
{
gzFile gzFile = utilMemGzOpen(memory, available, "w");
@ -646,7 +688,108 @@ bool CPUWriteMemState(char *memory, int available)
return res;
}
#endif
#ifdef __LIBRETRO__
bool CPUReadState(const u8* data, unsigned size)
{
// Don't really care about version.
int version = utilReadIntMem(data);
if (version != SAVE_GAME_VERSION)
return false;
char romname[16];
utilReadMem(romname, data, 16);
if (memcmp(&rom[0xa0], romname, 16) != 0)
return false;
// Don't care about use bios ...
utilReadIntMem(data);
utilReadMem(&reg[0], data, sizeof(reg));
utilReadDataMem(data, saveGameStruct);
stopState = utilReadIntMem(data) ? true : false;
IRQTicks = utilReadIntMem(data);
if (IRQTicks > 0)
intState = true;
else
{
intState = false;
IRQTicks = 0;
}
utilReadMem(internalRAM, data, 0x8000);
utilReadMem(paletteRAM, data, 0x400);
utilReadMem(workRAM, data, 0x40000);
utilReadMem(vram, data, 0x20000);
utilReadMem(oam, data, 0x400);
utilReadMem(pix, data, 4*241*162);
utilReadMem(ioMem, data, 0x400);
eepromReadGame(data, version);
flashReadGame(data, version);
soundReadGame(data, version);
rtcReadGame(data);
//// Copypasta stuff ...
// set pointers!
layerEnable = layerSettings & DISPCNT;
CPUUpdateRender();
// CPU Update Render Buffers set to true
CLEAR_ARRAY(line0);
CLEAR_ARRAY(line1);
CLEAR_ARRAY(line2);
CLEAR_ARRAY(line3);
// End of CPU Update Render Buffers set to true
CPUUpdateWindow0();
CPUUpdateWindow1();
gbaSaveType = 0;
switch(saveType) {
case 0:
cpuSaveGameFunc = flashSaveDecide;
break;
case 1:
cpuSaveGameFunc = sramWrite;
gbaSaveType = 1;
break;
case 2:
cpuSaveGameFunc = flashWrite;
gbaSaveType = 2;
break;
case 3:
break;
case 5:
gbaSaveType = 5;
break;
default:
#ifdef CELL_VBA_DEBUG
systemMessage(MSG_UNSUPPORTED_SAVE_TYPE,
N_("Unsupported save type %d"), saveType);
#endif
break;
}
if(eepromInUse)
gbaSaveType = 3;
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
if(armState) {
ARM_PREFETCH;
} else {
THUMB_PREFETCH;
}
CPUUpdateRegister(0x204, CPUReadHalfWordQuick(0x4000204));
return true;
}
#else
static bool CPUReadState(gzFile gzFile)
{
int version = utilReadInt(gzFile);
@ -843,6 +986,7 @@ bool CPUReadState(const char * file)
return res;
}
#endif
bool CPUExportEepromFile(const char *fileName)
{
@ -934,7 +1078,7 @@ bool CPUReadGSASnapshot(const char *fileName)
fseek(file, 0x0, SEEK_SET);
fread(&i, 1, 4, file);
fseek(file, i, SEEK_CUR); // Skip SharkPortSave
fseek(file, 4, SEEK_CUR); // skip some sort of flag
// fseek(file, 4, SEEK_CUR); // skip some sort of flag
fread(&i, 1, 4, file); // name length
fseek(file, i, SEEK_CUR); // skip name
fread(&i, 1, 4, file); // desc length
@ -1806,8 +1950,8 @@ void CPUSoftwareInterrupt(int comment)
case 0x02:
#ifdef GBA_LOGGING
if(systemVerbose & VERBOSE_SWI) {
log("Halt: (VCOUNT = %2d)\n",
VCOUNT);
/*log("Halt: (VCOUNT = %2d)\n",
VCOUNT);*/
}
#endif
holdState = true;
@ -1817,8 +1961,8 @@ void CPUSoftwareInterrupt(int comment)
case 0x03:
#ifdef GBA_LOGGING
if(systemVerbose & VERBOSE_SWI) {
log("Stop: (VCOUNT = %2d)\n",
VCOUNT);
/*log("Stop: (VCOUNT = %2d)\n",
VCOUNT);*/
}
#endif
holdState = true;
@ -2073,6 +2217,7 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32)
int dw = 0;
int sc = c;
cpuDmaHack = true;
cpuDmaCount = c;
// This is done to get the correct waitstates.
if (sm>15)
@ -2141,7 +2286,7 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32)
}
cpuDmaTicksToUpdate += totalTicks;
cpuDmaHack = false;
}
void CPUCheckDMA(int reason, int dmamask)
@ -2184,7 +2329,6 @@ void CPUCheckDMA(int reason, int dmamask)
doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement,
DM0CNT_L ? DM0CNT_L : 0x4000,
DM0CNT_H & 0x0400);
cpuDmaHack = true;
if(DM0CNT_H & 0x4000) {
IF |= 0x0100;
@ -2253,7 +2397,6 @@ void CPUCheckDMA(int reason, int dmamask)
DM1CNT_L ? DM1CNT_L : 0x4000,
DM1CNT_H & 0x0400);
}
cpuDmaHack = true;
if(DM1CNT_H & 0x4000) {
IF |= 0x0200;
@ -2323,7 +2466,6 @@ void CPUCheckDMA(int reason, int dmamask)
DM2CNT_L ? DM2CNT_L : 0x4000,
DM2CNT_H & 0x0400);
}
cpuDmaHack = true;
if(DM2CNT_H & 0x4000) {
IF |= 0x0400;
@ -2380,6 +2522,7 @@ void CPUCheckDMA(int reason, int dmamask)
doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement,
DM3CNT_L ? DM3CNT_L : 0x10000,
DM3CNT_H & 0x0400);
if(DM3CNT_H & 0x4000) {
IF |= 0x0800;
UPDATE_REG(0x202, IF);
@ -2426,7 +2569,7 @@ void CPUUpdateRegister(u32 address, u16 value)
windowOn = (layerEnable & 0x6000) ? true : false;
if(change && !((value & 0x80))) {
if(!(DISPSTAT & 1)) {
lcdTicks = 1008;
//lcdTicks = 1008;
// VCOUNT = 0;
// UPDATE_REG(0x06, VCOUNT);
DISPSTAT &= 0xFFFC;
@ -3479,9 +3622,11 @@ void CPULoop(int ticks)
if(!holdState && !SWITicks) {
if(armState) {
armOpcodeCount++;
if (!armExecute())
return;
} else {
thumbOpcodeCount++;
if (!thumbExecute())
return;
}
@ -3504,7 +3649,6 @@ void CPULoop(int ticks)
clockTicks = cpuNextEvent;
cpuTotalTicks = 0;
cpuDmaHack = false;
updateLoop:
@ -3538,7 +3682,7 @@ void CPULoop(int ticks)
}
}
if(VCOUNT >= 228) { //Reaching last line
if(VCOUNT > 227) { //Reaching last line
DISPSTAT &= 0xFFFC;
UPDATE_REG(0x04, DISPSTAT);
VCOUNT = 0;
@ -3903,7 +4047,6 @@ void CPULoop(int ticks)
cpuDmaTicksToUpdate -= clockTicks;
if(cpuDmaTicksToUpdate < 0)
cpuDmaTicksToUpdate = 0;
cpuDmaHack = true;
goto updateLoop;
}
@ -3976,6 +4119,256 @@ void CPULoop(int ticks)
}
}
#ifdef TILED_RENDERING
union u8h
{
struct
{
/* 0*/ unsigned lo:4;
/* 4*/ unsigned hi:4;
} __attribute__ ((packed));
u8 val;
};
union TileEntry
{
struct
{
/* 0*/ unsigned tileNum:10;
/*12*/ unsigned hFlip:1;
/*13*/ unsigned vFlip:1;
/*14*/ unsigned palette:4;
};
u16 val;
};
struct TileLine
{
u32 pixels[8];
};
typedef const TileLine (*TileReader) (const u16 *, const int, const u8 *, u16 *, const u32);
static inline void gfxDrawPixel(u32 *dest, const u8 color, const u16 *palette, const u32 prio)
{
*dest = color ? (READ16LE(&palette[color]) | prio): 0x80000000;
}
inline const TileLine gfxReadTile(const u16 *screenSource, const int yyy, const u8 *charBase, u16 *palette, const u32 prio)
{
TileEntry tile;
tile.val = READ16LE(screenSource);
int tileY = yyy & 7;
if (tile.vFlip) tileY = 7 - tileY;
TileLine tileLine;
const u8 *tileBase = &charBase[tile.tileNum * 64 + tileY * 8];
if (!tile.hFlip)
{
gfxDrawPixel(&tileLine.pixels[0], tileBase[0], palette, prio);
gfxDrawPixel(&tileLine.pixels[1], tileBase[1], palette, prio);
gfxDrawPixel(&tileLine.pixels[2], tileBase[2], palette, prio);
gfxDrawPixel(&tileLine.pixels[3], tileBase[3], palette, prio);
gfxDrawPixel(&tileLine.pixels[4], tileBase[4], palette, prio);
gfxDrawPixel(&tileLine.pixels[5], tileBase[5], palette, prio);
gfxDrawPixel(&tileLine.pixels[6], tileBase[6], palette, prio);
gfxDrawPixel(&tileLine.pixels[7], tileBase[7], palette, prio);
}
else
{
gfxDrawPixel(&tileLine.pixels[0], tileBase[7], palette, prio);
gfxDrawPixel(&tileLine.pixels[1], tileBase[6], palette, prio);
gfxDrawPixel(&tileLine.pixels[2], tileBase[5], palette, prio);
gfxDrawPixel(&tileLine.pixels[3], tileBase[4], palette, prio);
gfxDrawPixel(&tileLine.pixels[4], tileBase[3], palette, prio);
gfxDrawPixel(&tileLine.pixels[5], tileBase[2], palette, prio);
gfxDrawPixel(&tileLine.pixels[6], tileBase[1], palette, prio);
gfxDrawPixel(&tileLine.pixels[7], tileBase[0], palette, prio);
}
return tileLine;
}
inline const TileLine gfxReadTilePal(const u16 *screenSource, const int yyy, const u8 *charBase, u16 *palette, const u32 prio)
{
TileEntry tile;
tile.val = READ16LE(screenSource);
int tileY = yyy & 7;
if (tile.vFlip) tileY = 7 - tileY;
palette += tile.palette * 16;
TileLine tileLine;
const u8h *tileBase = (u8h*) &charBase[tile.tileNum * 32 + tileY * 4];
if (!tile.hFlip)
{
gfxDrawPixel(&tileLine.pixels[0], tileBase[0].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[1], tileBase[0].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[2], tileBase[1].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[3], tileBase[1].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[4], tileBase[2].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[5], tileBase[2].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[6], tileBase[3].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[7], tileBase[3].hi, palette, prio);
}
else
{
gfxDrawPixel(&tileLine.pixels[0], tileBase[3].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[1], tileBase[3].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[2], tileBase[2].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[3], tileBase[2].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[4], tileBase[1].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[5], tileBase[1].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[6], tileBase[0].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[7], tileBase[0].lo, palette, prio);
}
return tileLine;
}
static inline void gfxDrawTile(const TileLine &tileLine, u32 *line)
{
memcpy(line, tileLine.pixels, sizeof(tileLine.pixels));
}
static inline void gfxDrawTileClipped(const TileLine &tileLine, u32 *line, const int start, int w)
{
memcpy(line, tileLine.pixels + start, w * sizeof(u32));
}
template<TileReader readTile>
static void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
u32 *line)
{
u16 *palette = (u16 *)paletteRAM;
u8 *charBase = &vram[((control >> 2) & 0x03) * 0x4000];
u16 *screenBase = (u16 *)&vram[((control >> 8) & 0x1f) * 0x800];
u32 prio = ((control & 3)<<25) + 0x1000000;
int sizeX = 256;
int sizeY = 256;
switch ((control >> 14) & 3)
{
case 0:
break;
case 1:
sizeX = 512;
break;
case 2:
sizeY = 512;
break;
case 3:
sizeX = 512;
sizeY = 512;
break;
}
int maskX = sizeX-1;
int maskY = sizeY-1;
bool mosaicOn = (control & 0x40) ? true : false;
int xxx = hofs & maskX;
int yyy = (vofs + VCOUNT) & maskY;
int mosaicX = (MOSAIC & 0x000F)+1;
int mosaicY = ((MOSAIC & 0x00F0)>>4)+1;
if (mosaicOn)
{
if ((VCOUNT % mosaicY) != 0)
{
mosaicY = VCOUNT - (VCOUNT % mosaicY);
yyy = (vofs + mosaicY) & maskY;
}
}
if (yyy > 255 && sizeY > 256)
{
yyy &= 255;
screenBase += 0x400;
if (sizeX > 256)
screenBase += 0x400;
}
int yshift = ((yyy>>3)<<5);
u16 *screenSource = screenBase + 0x400 * (xxx>>8) + ((xxx & 255)>>3) + yshift;
int x = 0;
const int firstTileX = xxx & 7;
// First tile, if clipped
if (firstTileX)
{
gfxDrawTileClipped(readTile(screenSource, yyy, charBase, palette, prio), &line[x], firstTileX, 8 - firstTileX);
screenSource++;
x += 8 - firstTileX;
xxx += 8 - firstTileX;
if (xxx == 256 && sizeX > 256)
{
screenSource = screenBase + 0x400 + yshift;
}
else if (xxx >= sizeX)
{
xxx = 0;
screenSource = screenBase + yshift;
}
}
// Middle tiles, full
while (x < 240 - firstTileX)
{
gfxDrawTile(readTile(screenSource, yyy, charBase, palette, prio), &line[x]);
screenSource++;
xxx += 8;
x += 8;
if (xxx == 256 && sizeX > 256)
{
screenSource = screenBase + 0x400 + yshift;
}
else if (xxx >= sizeX)
{
xxx = 0;
screenSource = screenBase + yshift;
}
}
// Last tile, if clipped
if (firstTileX)
{
gfxDrawTileClipped(readTile(screenSource, yyy, charBase, palette, prio), &line[x], 0, firstTileX);
}
if (mosaicOn)
{
if (mosaicX > 1)
{
int m = 1;
for (int i = 0; i < 239; i++)
{
line[i+1] = line[i];
m++;
if (m == mosaicX)
{
m = 1;
i++;
}
}
}
}
}
void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs, u32 *line)
{
if (control & 0x80) // 1 pal / 256 col
gfxDrawTextScreen<gfxReadTile>(control, hofs, vofs, line);
else // 16 pal / 16 col
gfxDrawTextScreen<gfxReadTilePal>(control, hofs, vofs, line);
}
#endif
struct EmulatedSystem GBASystem = {
@ -3994,7 +4387,11 @@ struct EmulatedSystem GBASystem = {
// emuWriteState
CPUWriteState,
// emuReadMemState
#ifdef __LIBRETRO__
NULL,
#else
CPUReadMemState,
#endif
// emuWriteMemState
CPUWriteMemState,
// emuWritePNG

View File

@ -90,9 +90,14 @@ extern void CPUCleanUp();
extern void CPUUpdateRender();
extern void CPUUpdateRenderBuffers(bool);
extern bool CPUReadMemState(char *, int);
extern bool CPUReadState(const char *);
extern bool CPUWriteMemState(char *, int);
#ifdef __LIBRETRO__
extern bool CPUReadState(const u8*, unsigned);
extern unsigned int CPUWriteState(u8 *data, unsigned int size);
#else
extern bool CPUReadState(const char *);
extern bool CPUWriteState(const char *);
#endif
extern int CPULoadRom(const char *);
extern void doMirroring(bool);
extern void CPUUpdateRegister(u32, u16);

View File

@ -8,7 +8,11 @@
//#define SPRITE_DEBUG
#ifdef TILED_RENDERING
extern void gfxDrawTextScreen(u16, u16, u16, u32 *);
#else
static void gfxDrawTextScreen(u16, u16, u16, u32 *);
#endif
static void gfxDrawRotScreen(u16,
u16, u16,
u16, u16,
@ -98,6 +102,7 @@ static inline void gfxClearArray(u32 *array)
}
}
#ifndef TILED_RENDERING
static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
u32 *line)
{
@ -238,6 +243,7 @@ static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
}
}
}
#endif
static inline void gfxDrawRotScreen(u16 control,
u16 x_l, u16 x_h,

View File

@ -49,11 +49,9 @@ static inline u32 CPUReadMemory(u32 address)
u32 value;
u32 oldAddress = address;
#ifdef C_CORE
if(address & 3) {
address &= ~0x03;
}
#endif
switch(address >> 24) {
case 0:
@ -79,18 +77,18 @@ static inline u32 CPUReadMemory(u32 address)
value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC]));
break;
case 4:
if((address < 0x4000400) && ioReadable[address & 0x3fc]) {
if(ioReadable[(address & 0x3fc) + 2]) {
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
if ((address & 0x3fc) == COMM_JOY_RECV_L)
UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) & ~JOYSTAT_RECV);
} else {
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
}
}
else
goto unreadable;
break;
if((address < 0x4000400) && ioReadable[address & 0x3fc]) {
if(ioReadable[(address & 0x3fc) + 2]) {
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
if ((address & 0x3fc) == COMM_JOY_RECV_L)
UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) & ~JOYSTAT_RECV);
} else {
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
}
}
else
goto unreadable;
break;
case 5:
value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC]));
break;
@ -116,14 +114,12 @@ static inline u32 CPUReadMemory(u32 address)
value = READ32LE(((u32 *)&rom[address&0x1FFFFFC]));
break;
case 13:
if(cpuEEPROMEnabled)
// no need to swap this
return eepromRead(address);
goto unreadable;
value = eepromRead(address);
break;
case 14:
if(cpuFlashEnabled | cpuSramEnabled)
// no need to swap this
return flashRead(address);
case 15:
value = flashRead(address) * 0x01010101;
break;
// default
default:
unreadable:
@ -133,18 +129,17 @@ unreadable:
armNextPC - 4 : armNextPC - 2);
}
#endif
if(cpuDmaHack) {
value = cpuDmaLast;
} else {
if(cpuDmaHack) {
value = cpuDmaLast;
} else {
if(armState) {
value = CPUReadMemoryQuick(reg[15].I);
return CPUReadMemoryQuick(reg[15].I);
} else {
value = CPUReadHalfWordQuick(reg[15].I) |
CPUReadHalfWordQuick(reg[15].I) << 16;
return CPUReadHalfWordQuick(reg[15].I) |
CPUReadHalfWordQuick(reg[15].I) << 16;
}
}
return value;
}
break;
}
if(oldAddress & 3) {
@ -187,11 +182,9 @@ static inline u32 CPUReadHalfWord(u32 address)
u32 value;
u32 oldAddress = address;
//#ifdef C_CORE
if(address & 1) {
address &= ~0x01;
}
//#endif
switch(address >> 24) {
case 0:
@ -233,6 +226,10 @@ static inline u32 CPUReadHalfWord(u32 address)
value = 0xFFFF - ((timer3Ticks-cpuTotalTicks) >> timer3ClockReload);
}
}
else if((address < 0x4000400) && ioReadable[address & 0x3fc])
{
value = 0;
}
else goto unreadable;
break;
case 5:
@ -263,34 +260,30 @@ static inline u32 CPUReadHalfWord(u32 address)
value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE]));
break;
case 13:
if(cpuEEPROMEnabled)
// no need to swap this
return eepromRead(address);
goto unreadable;
value = eepromRead(address);
break;
case 14:
if(cpuFlashEnabled | cpuSramEnabled)
// no need to swap this
return flashRead(address);
case 15:
value = flashRead(address) * 0x0101;
break;
// default
default:
unreadable:
#ifdef GBA_LOGGING
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
log("Illegal halfword read: %08x at %08x\n", oldAddress, armMode ?
armNextPC - 4 : armNextPC - 2);
}
#endif
if(cpuDmaHack) {
value = cpuDmaLast & 0xFFFF;
} else {
if(cpuDmaHack) {
value = cpuDmaLast & 0xFFFF;
} else {
if(armState) {
value = CPUReadMemoryQuick(reg[15].I);
value = CPUReadHalfWordQuick(reg[15].I + (address & 2));
} else {
value = CPUReadHalfWordQuick(reg[15].I) |
CPUReadHalfWordQuick(reg[15].I) << 16;
value = CPUReadHalfWordQuick(reg[15].I);
}
}
return value;
}
#ifdef GBA_LOGGING
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
log("Illegal halfword read: %08x at %08x (%08x)\n", oldAddress, reg[15].I, value);
}
#endif
return value;
}
if(oldAddress & 1) {
@ -306,24 +299,19 @@ unreadable:
return value;
}
static inline u16 CPUReadHalfWordSigned(u32 address)
static inline s16 CPUReadHalfWordSigned(u32 address)
{
u32 oldAddress = address;
if(address & 1) {
address &= ~0x01;
}
u16 value = CPUReadHalfWord(address);
if((oldAddress & 1))
s32 value = (s32)CPUReadHalfWord(address);
if((address & 1))
{
value = (s8)value;
#ifdef GBA_LOGGING
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
log("Unaligned signed halfword read from: %08x at %08x (%08x)\n", oldAddress, armMode ?
log("Unaligned signed halfword read from: %08x at %08x (%08x)\n", address, armMode ?
armNextPC - 4 : armNextPC - 2, value);
}
#endif
}
return value;
return (s16)value;
}
static inline u8 CPUReadByte(u32 address)
@ -368,24 +356,24 @@ static inline u8 CPUReadByte(u32 address)
case 12:
return rom[address & 0x1FFFFFF];
case 13:
if(cpuEEPROMEnabled)
return eepromRead(address);
goto unreadable;
return eepromRead(address);
case 14:
if(cpuSramEnabled | cpuFlashEnabled)
return flashRead(address);
if(cpuEEPROMSensorEnabled) {
switch(address & 0x00008f00) {
case 0x8200:
return systemGetSensorX() & 255;
case 0x8300:
return (systemGetSensorX() >> 8)|0x80;
case 0x8400:
return systemGetSensorY() & 255;
case 0x8500:
return systemGetSensorY() >> 8;
}
}
case 15:
{
if (cpuEEPROMSensorEnabled) {
switch (address & 0x00008f00) {
case 0x8200:
return systemGetSensorX() & 255;
case 0x8300:
return (systemGetSensorX() >> 8) | 0x80;
case 0x8400:
return systemGetSensorY() & 255;
case 0x8500:
return systemGetSensorY() >> 8;
}
}
return flashRead(address);
}
// default
default:
unreadable:
@ -395,17 +383,15 @@ unreadable:
armNextPC - 4 : armNextPC - 2);
}
#endif
if(cpuDmaHack) {
return cpuDmaLast & 0xFF;
} else {
if(cpuDmaHack) {
return cpuDmaLast & 0xFF;
} else {
if(armState) {
return CPUReadMemoryQuick(reg[15].I);
return CPUReadByteQuick(reg[15].I + (address & 3));
} else {
return CPUReadHalfWordQuick(reg[15].I) |
CPUReadHalfWordQuick(reg[15].I) << 16;
return CPUReadByteQuick(reg[15].I + (address & 1));
}
}
break;
}
}
}
@ -423,6 +409,8 @@ static inline void CPUWriteMemory(u32 address, u32 value)
}
#endif
address &= 0xFFFFFFFC;
switch(address >> 24) {
case 0x02:
#ifdef BKPT_SUPPORT
@ -488,6 +476,7 @@ static inline void CPUWriteMemory(u32 address, u32 value)
}
goto unwritable;
case 0x0E:
case 0x0F:
if((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled) {
(*cpuSaveGameFunc)(address, (u8)value);
break;
@ -520,6 +509,8 @@ static inline void CPUWriteHalfWord(u32 address, u16 value)
}
#endif
address &= 0xFFFFFFFE;
switch(address >> 24) {
case 2:
#ifdef BKPT_SUPPORT
@ -590,6 +581,7 @@ static inline void CPUWriteHalfWord(u32 address, u16 value)
}
goto unwritable;
case 14:
case 15:
if((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled) {
(*cpuSaveGameFunc)(address, (u8)value);
break;
@ -726,6 +718,7 @@ static inline void CPUWriteByte(u32 address, u8 b)
}
goto unwritable;
case 14:
case 15:
if ((saveType != 5) && ((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled)) {
//if(!cpuEEPROMEnabled && (cpuSramEnabled | cpuFlashEnabled)) {

View File

@ -7,8 +7,15 @@
#include <time.h>
#include <memory.h>
#include <string.h>
enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
enum RTCSTATE
{
IDLE = 0,
COMMAND,
DATA,
READDATA
};
typedef struct {
u8 byte0;
@ -197,6 +204,17 @@ void rtcReset()
rtcClockData.state = IDLE;
}
#ifdef __LIBRETRO__
void rtcSaveGame(u8 *&data)
{
utilWriteMem(data, &rtcClockData, sizeof(rtcClockData));
}
void rtcReadGame(const u8 *&data)
{
utilReadMem(&rtcClockData, data, sizeof(rtcClockData));
}
#else
void rtcSaveGame(gzFile gzFile)
{
utilGzWrite(gzFile, &rtcClockData, sizeof(rtcClockData));
@ -206,3 +224,4 @@ void rtcReadGame(gzFile gzFile)
{
utilGzRead(gzFile, &rtcClockData, sizeof(rtcClockData));
}
#endif

View File

@ -7,7 +7,12 @@ void rtcEnable(bool);
bool rtcIsEnabled();
void rtcReset();
#ifdef __LIBRETRO__
void rtcReadGame(const u8 *&data);
void rtcSaveGame(u8 *&data);
#else
void rtcReadGame(gzFile gzFile);
void rtcSaveGame(gzFile gzFile);
#endif
#endif // RTC_H

View File

@ -183,15 +183,19 @@ void Gba_Pcm_Fifo::timer_overflowed( int which_timer )
{
if ( which_timer == timer && enabled )
{
if ( count <= 16 )
/* Mother 3 fix, refined to not break Metroid Fusion */
if ( count == 16 || count == 0 )
{
// Need to fill FIFO
int saved_count = count;
CPUCheckDMA( 3, which ? 4 : 2 );
if ( count <= 16 )
if ( saved_count == 0 && count == 16 )
CPUCheckDMA( 3, which ? 4 : 2 );
if ( count == 0 )
{
// Not filled by DMA, so fill with 16 bytes of silence
int reg = which ? FIFOB_L : FIFOA_L;
for ( int n = 4; n--; )
for ( int n = 8; n--; )
{
soundEvent(reg , (u16)0);
soundEvent(reg+2, (u16)0);
@ -348,6 +352,11 @@ static void end_frame( blip_time_t time )
void flush_samples(Multi_Buffer * buffer)
{
#ifdef __LIBRETRO__
int numSamples = buffer->read_samples( (blip_sample_t*) soundFinalWave, buffer->samples_avail() );
soundDriver->write(soundFinalWave, numSamples);
systemOnWriteDataToSoundBuffer(soundFinalWave, numSamples);
#else
// We want to write the data frame by frame to support legacy audio drivers
// that don't use the length parameter of the write method.
// TODO: Update the Win32 audio drivers (DS, OAL, XA2), and flush all the
@ -370,6 +379,7 @@ void flush_samples(Multi_Buffer * buffer)
soundDriver->write(soundFinalWave, soundBufferLen);
systemOnWriteDataToSoundBuffer(soundFinalWave, soundBufferLen);
}
#endif
}
static void apply_filtering()
@ -446,6 +456,13 @@ static void remake_stereo_buffer()
pcm [0].pcm.init();
pcm [1].pcm.init();
// APU
if ( !gb_apu )
{
gb_apu = new Gb_Apu; // TODO: handle out of memory
reset_apu();
}
// Stereo_Buffer
delete stereo_buffer;
stereo_buffer = 0;
@ -459,13 +476,7 @@ static void remake_stereo_buffer()
pcm [1].which = 1;
apply_filtering();
// APU
if ( !gb_apu )
{
gb_apu = new Gb_Apu; // TODO: handle out of memory
reset_apu();
}
// Volume Level
apply_muting();
apply_volume();
}
@ -743,16 +754,25 @@ static void skip_read( gzFile in, int count )
}
}
#ifdef __LIBRETRO__
void soundSaveGame( u8 *&out )
#else
void soundSaveGame( gzFile out )
#endif
{
gb_apu->save_state( &state.apu );
// Be sure areas for expansion get written as zero
memset( dummy_state, 0, sizeof dummy_state );
#ifdef __LIBRETRO__
utilWriteDataMem( out, gba_state );
#else
utilWriteData( out, gba_state );
#endif
}
#ifndef __LIBRETRO__
static void soundReadGameOld( gzFile in, int version )
{
// Read main data
@ -787,19 +807,28 @@ static void soundReadGameOld( gzFile in, int version )
(void) utilReadInt( in ); // ignore quality
}
#endif
#include <stdio.h>
#ifdef __LIBRETRO__
void soundReadGame(const u8*& in, int version )
#else
void soundReadGame( gzFile in, int version )
#endif
{
// Prepare APU and default state
reset_apu();
gb_apu->save_state( &state.apu );
if ( version > SAVE_GAME_VERSION_9 )
#ifdef __LIBRETRO__
utilReadDataMem( in, gba_state );
#else
utilReadData( in, gba_state );
else
soundReadGameOld( in, version );
#endif
gb_apu->load_state( state.apu );
write_SGCNT0_H( READ16LE( &ioMem [SGCNT0_H] ) & 0x770F );

View File

@ -74,8 +74,13 @@ extern int SOUND_CLOCK_TICKS; // Number of 16.8 MHz clocks between calls to so
extern int soundTicks; // Number of 16.8 MHz clocks until soundTick() will be called
// Saves/loads emulator state
#ifdef __LIBRETRO__
void soundSaveGame( u8 *& );
void soundReadGame(const u8*& in, int version );
#else
void soundSaveGame( gzFile );
void soundReadGame( gzFile, int version );
#endif
class Multi_Buffer;

View File

@ -1058,7 +1058,7 @@ void elfParseCFA(u8 *top)
if(id == 0xffffffff) {
// skip version
*data++;
(*data)++;
ELFcie *cie = (ELFcie *)calloc(1, sizeof(ELFcie));

View File

@ -1,3 +1,4 @@
#ifndef __LIBRETRO__
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -75,7 +76,11 @@ bool remoteTcpInit()
remoteListenSocket = s;
#ifdef _WIN32
if(s == INVALID_SOCKET) {
#else
if(s < 0) {
#endif
fprintf(stderr,"Error opening socket\n");
exit(-1);
}
@ -719,3 +724,4 @@ void remoteCleanUp()
if(remoteCleanUpFnc)
remoteCleanUpFnc();
}
#endif

View File

@ -30,6 +30,7 @@ const DirectoriesConfigDialog::SDirEntry DirectoriesConfigDialog::m_astDirs[] =
{ "gba_roms", N_("GBA roms :"), "GBARomsDirEntry" },
{ "gb_roms", N_("GB roms :"), "GBRomsDirEntry" },
{ "batteries", N_("Batteries :"), "BatteriesDirEntry" },
{ "cheats", N_("Cheats :"), "CheatsDirEntry" },
{ "saves", N_("Saves :"), "SavesDirEntry" },
{ "captures", N_("Captures :"), "CapturesDirEntry" }
};

View File

@ -47,7 +47,7 @@ private:
Config::Section * m_poConfig;
static const SDirEntry m_astDirs[];
Gtk::FileChooserButton * m_poButtons[5];
Gtk::FileChooserButton * m_poButtons[6];
};
} // namespace VBA

View File

@ -27,6 +27,16 @@
namespace VBA
{
static const VBA::Window::EEmulatorType aEmulatorType[] =
{
VBA::Window::EmulatorAuto,
VBA::Window::EmulatorCGB,
VBA::Window::EmulatorSGB,
VBA::Window::EmulatorGB,
VBA::Window::EmulatorGBA,
VBA::Window::EmulatorSGB2
};
GameBoyConfigDialog::GameBoyConfigDialog(GtkDialog* _pstDialog, const Glib::RefPtr<Gtk::Builder>& refBuilder) :
Gtk::Dialog(_pstDialog),
m_poConfig(0)
@ -49,8 +59,6 @@ void GameBoyConfigDialog::vSetConfig(Config::Section * _poConfig, VBA::Window *
m_poConfig = _poConfig;
m_poWindow = _poWindow;
const int aEmulatorType[] = { 0, 2, 3, 5, 1, 4 };
VBA::Window::EEmulatorType eDefaultEmulatorType = (VBA::Window::EEmulatorType)m_poConfig->oGetKey<int>("emulator_type");
m_poSystemComboBox->set_active(aEmulatorType[eDefaultEmulatorType]);
@ -70,16 +78,6 @@ void GameBoyConfigDialog::vSetConfig(Config::Section * _poConfig, VBA::Window *
void GameBoyConfigDialog::vOnSystemChanged()
{
const VBA::Window::EEmulatorType aEmulatorType[] =
{
VBA::Window::EmulatorAuto,
VBA::Window::EmulatorCGB,
VBA::Window::EmulatorSGB,
VBA::Window::EmulatorGB,
VBA::Window::EmulatorGBA,
VBA::Window::EmulatorSGB2
};
int iSystem = m_poSystemComboBox->get_active_row_number();
m_poConfig->vSetKey("emulator_type", aEmulatorType[iSystem]);

View File

@ -1,11 +1,10 @@
[Desktop Entry]
Version=1.0
Encoding=UTF-8
Type=Application
Name=VBA-M
GenericName=GameBoy Advance Emulator
Comment=Nindendo GameBoy Advance Emulator
Exec=gvbam
Exec=gvbam %f
Icon=vbam
Categories=Application;Game;Emulator;GTK
MimeType=application/x-gameboy-rom;application/x-gameboy-advance-rom;application/x-dmg-rom;application/x-agb-rom;application/x-gb-rom;application/x-gba-rom
Categories=Game;Emulator;GTK;
MimeType=application/x-gameboy-rom;application/x-gameboy-advance-rom;application/x-dmg-rom;application/x-agb-rom;application/x-gb-rom;application/x-gba-rom;

View File

@ -49,10 +49,10 @@ JoypadConfigDialog::JoypadConfigDialog(Config::Section * _poConfig) :
m_oTitleLabel(_("Joypad :"), Gtk::ALIGN_RIGHT),
m_oDefaultJoypad(_("Default joypad")),
m_oTable(G_N_ELEMENTS(m_astKeys), 2, false),
m_iCurrentEntry(-1),
m_bUpdating(false),
m_ePad(PAD_MAIN),
m_poConfig(_poConfig),
m_iCurrentEntry(-1)
m_poConfig(_poConfig)
{
// Joypad selection
m_oTitleCombo.append_text("1");
@ -115,7 +115,7 @@ void JoypadConfigDialog::vUpdateEntries()
for (guint i = 0; i < m_oEntries.size(); i++)
{
const char * csName = 0;
std::string csName;
guint uiKeyval = inputGetKeymap(m_ePad, m_astKeys[i].m_eKeyFlag);
int dev = uiKeyval >> 16;
@ -158,10 +158,10 @@ void JoypadConfigDialog::vUpdateEntries()
}
}
csName = os.str().c_str();
csName = os.str();
}
if (csName == 0)
if (csName.empty())
{
m_oEntries[i]->set_text(_("<Undefined>"));
}

View File

@ -504,6 +504,7 @@ void Window::vInitConfig()
m_poDirConfig->vSetKey("gb_roms", Glib::get_home_dir());
m_poDirConfig->vSetKey("gba_roms", Glib::get_home_dir());
m_poDirConfig->vSetKey("batteries", m_sUserDataDir);
m_poDirConfig->vSetKey("cheats", m_sUserDataDir);
m_poDirConfig->vSetKey("saves", m_sUserDataDir);
m_poDirConfig->vSetKey("captures", m_sUserDataDir);
@ -588,6 +589,11 @@ void Window::vCheckConfig()
{
m_poDirConfig->vSetKey("batteries", m_sUserDataDir);
}
sValue = m_poDirConfig->sGetKey("cheats");
if (sValue != "" && ! Glib::file_test(sValue, Glib::FILE_TEST_IS_DIR))
{
m_poDirConfig->vSetKey("cheats", m_sUserDataDir);
}
sValue = m_poDirConfig->sGetKey("saves");
if (sValue != "" && ! Glib::file_test(sValue, Glib::FILE_TEST_IS_DIR))
{
@ -1078,6 +1084,7 @@ bool Window::bLoadROM(const std::string & _rsFile)
}
vLoadBattery();
vLoadCheats();
vUpdateScreen();
emulating = 1;
@ -1342,6 +1349,30 @@ void Window::vLoadBattery()
}
}
void Window::vLoadCheats()
{
std::string sCheats;
std::string sDir = m_poDirConfig->sGetKey("cheats");
if (sDir == "")
{
sDir = m_sUserDataDir;
}
sCheats = sDir + "/" + sCutSuffix(Glib::path_get_basename(m_sRomFile)) + ".clt";
if (Glib::file_test(sCheats, Glib::FILE_TEST_EXISTS))
{
if (m_eCartridge == CartridgeGB)
{
gbCheatsLoadCheatList(sCheats.c_str());
}
else if (m_eCartridge == CartridgeGBA)
{
cheatsLoadCheatList(sCheats.c_str());
}
}
}
void Window::vSaveBattery()
{
std::string sBattery;
@ -1359,6 +1390,27 @@ void Window::vSaveBattery()
}
}
void Window::vSaveCheats()
{
std::string sCheats;
std::string sDir = m_poDirConfig->sGetKey("cheats");
if (sDir == "")
{
sDir = m_sUserDataDir;
}
sCheats = sDir + "/" + sCutSuffix(Glib::path_get_basename(m_sRomFile)) + ".clt";
if (m_eCartridge == CartridgeGB)
{
gbCheatsSaveCheatList(sCheats.c_str());
}
else if (m_eCartridge == CartridgeGBA)
{
cheatsSaveCheatList(sCheats.c_str());
}
}
void Window::vStartEmu()
{
if (m_oEmuSig.connected())

View File

@ -272,7 +272,9 @@ private:
void vSetDefaultTitle();
void vCreateFileOpenDialog();
void vLoadBattery();
void vLoadCheats();
void vSaveBattery();
void vSaveCheats();
void vStartEmu();
void vStopEmu();
void vUpdateGameSlots();

View File

@ -335,6 +335,7 @@ void Window::vOnFileClose()
vSetDefaultTitle();
vDrawDefaultScreen();
vSaveBattery();
vSaveCheats();
m_stEmulator.emuCleanUp();
m_eCartridge = CartridgeNone;
emulating = 0;

View File

@ -125,6 +125,7 @@ int desktopHeight = 0;
Filter filter = kStretch2x;
u8 *delta = NULL;
static const int delta_size = 322*242*4;
int filter_enlarge = 2;
@ -1395,7 +1396,7 @@ void sdlPollEvents()
soundPause();
}
memset(delta,255,sizeof(delta));
memset(delta,255,delta_size);
}
}
break;
@ -2311,8 +2312,8 @@ int main(int argc, char **argv)
utilUpdateSystemColorMaps();
if(delta == NULL) {
delta = (u8*)malloc(322*242*4);
memset(delta, 255, 322*242*4);
delta = (u8*)malloc(delta_size);
memset(delta, 255, delta_size);
}
ifbFunction = initIFBFilter(ifbType, systemColorDepth);

View File

@ -345,9 +345,9 @@ bool OpenGLDisplay::initialize()
cpu_mmx = 0;
#endif
systemRedShift = 3;
systemRedShift = 19;
systemGreenShift = 11;
systemBlueShift = 19;
systemBlueShift = 3;
systemColorDepth = 32;
theApp.fsColorDepth = 32;
@ -401,7 +401,7 @@ void OpenGLDisplay::render()
} else {
glPixelStorei( GL_UNPACK_ROW_LENGTH, theApp.sizeX + 1 );
}
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,width,height,GL_RGBA,GL_UNSIGNED_BYTE,data );
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,width,height,GL_BGRA,GL_UNSIGNED_BYTE,data );
glBegin( GL_QUADS );

View File

@ -287,9 +287,9 @@ bool XAudio2_Output::init(long sampleRate)
// Initialize XAudio2
UINT32 flags = 0;
#ifdef _DEBUG
flags = XAUDIO2_DEBUG_ENGINE;
#endif
//#ifdef _DEBUG
// flags = XAUDIO2_DEBUG_ENGINE;
//#endif
hr = XAudio2Create( &xaud, flags );
if( hr != S_OK ) {

View File

@ -138,7 +138,7 @@ void rpiFilter(u8 *srcPtr, u32 srcPitch, u8 *deltaPtr, u8 *dstPtr, u32 dstPitch,
*(pOCur++) = ((*pICur & 0xF800) << rshiftDiff) |
((*pICur & 0x07E0) << gshiftDiff) |
((*pICur & 0x001F) << bshiftDiff);
*pICur++;
*(pICur++);
}
pI = pICur = (u16 *)((char *)pI + dstPitch);
pO = pOCur = (u32 *)((char *)pO + dstPitch);
@ -157,7 +157,7 @@ void rpiFilter(u8 *srcPtr, u32 srcPitch, u8 *deltaPtr, u8 *dstPtr, u32 dstPitch,
*(pOCur++) = ((*pICur & 0xF800) >> rshiftDiff) |
((*pICur & 0x07E0) << gshiftDiff) |
((*pICur & 0x001F) << bshiftDiff);
*pICur++;
*(pICur++);
}
pI = pICur = (u16 *)((char *)pI + dstPitch);
pO = pOCur = (u32 *)((char *)pO + dstPitch);