mirror of
https://github.com/libretro/mgba.git
synced 2024-11-27 02:00:42 +00:00
commit
85be5565f8
5
CHANGES
5
CHANGES
@ -6,6 +6,8 @@ Bugfixes:
|
|||||||
Misc:
|
Misc:
|
||||||
- GBA Savedata: EEPROM performance fixes
|
- GBA Savedata: EEPROM performance fixes
|
||||||
- GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash
|
- GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash
|
||||||
|
- GB Memory: Support running from blocked memory
|
||||||
|
- GB Audio: Skip frame if enabled when clock is high
|
||||||
|
|
||||||
0.7.0: (Future)
|
0.7.0: (Future)
|
||||||
Features:
|
Features:
|
||||||
@ -139,6 +141,9 @@ Bugfixes:
|
|||||||
- GBA Savedata: Fix EEPROM writing codepath when savetype is not EEPROM
|
- GBA Savedata: Fix EEPROM writing codepath when savetype is not EEPROM
|
||||||
- Core: Reroot timing list when (de)scheduling
|
- Core: Reroot timing list when (de)scheduling
|
||||||
- GB Video: Changing LYC while LCDC off doesn't affect STAT (fixes mgba.io/i/1224)
|
- GB Video: Changing LYC while LCDC off doesn't affect STAT (fixes mgba.io/i/1224)
|
||||||
|
- GBA I/O: SOUNDCNT_HI is readable when sound is off
|
||||||
|
- SDL: Fix handling of invalid gamepads (fixes mgba.io/i/1239)
|
||||||
|
- Libretro: Fix adding codes with hooks
|
||||||
Misc:
|
Misc:
|
||||||
- mGUI: Add SGB border configuration option
|
- mGUI: Add SGB border configuration option
|
||||||
- mGUI: Add support for different settings types
|
- mGUI: Add support for different settings types
|
||||||
|
@ -187,6 +187,7 @@ struct GBAudio {
|
|||||||
uint8_t* nr52;
|
uint8_t* nr52;
|
||||||
|
|
||||||
int frame;
|
int frame;
|
||||||
|
bool skipFrame;
|
||||||
|
|
||||||
int32_t sampleInterval;
|
int32_t sampleInterval;
|
||||||
enum GBAudioStyle style;
|
enum GBAudioStyle style;
|
||||||
|
@ -195,6 +195,7 @@ DECL_BITS(GBSerializedAudioFlags, Frame, 22, 3);
|
|||||||
DECL_BIT(GBSerializedAudioFlags, Ch1SweepEnabled, 25);
|
DECL_BIT(GBSerializedAudioFlags, Ch1SweepEnabled, 25);
|
||||||
DECL_BIT(GBSerializedAudioFlags, Ch1SweepOccurred, 26);
|
DECL_BIT(GBSerializedAudioFlags, Ch1SweepOccurred, 26);
|
||||||
DECL_BIT(GBSerializedAudioFlags, Ch3Readable, 27);
|
DECL_BIT(GBSerializedAudioFlags, Ch3Readable, 27);
|
||||||
|
DECL_BIT(GBSerializedAudioFlags, SkipFrame, 28);
|
||||||
|
|
||||||
DECL_BITFIELD(GBSerializedAudioEnvelope, uint32_t);
|
DECL_BITFIELD(GBSerializedAudioEnvelope, uint32_t);
|
||||||
DECL_BITS(GBSerializedAudioEnvelope, Length, 0, 7);
|
DECL_BITS(GBSerializedAudioEnvelope, Length, 0, 7);
|
||||||
|
@ -470,7 +470,15 @@ void GBAudioWriteNR52(struct GBAudio* audio, uint8_t value) {
|
|||||||
}
|
}
|
||||||
*audio->nr52 &= ~0x000F;
|
*audio->nr52 &= ~0x000F;
|
||||||
} else if (!wasEnable) {
|
} else if (!wasEnable) {
|
||||||
|
audio->skipFrame = false;
|
||||||
audio->frame = 7;
|
audio->frame = 7;
|
||||||
|
|
||||||
|
if (audio->p) {
|
||||||
|
unsigned timingFactor = 0x400 >> !audio->p->doubleSpeed;
|
||||||
|
if (audio->p->timer.internalDiv & timingFactor) {
|
||||||
|
audio->skipFrame = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,6 +491,13 @@ void _updateFrame(struct mTiming* timing, void* user, uint32_t cyclesLate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GBAudioUpdateFrame(struct GBAudio* audio, struct mTiming* timing) {
|
void GBAudioUpdateFrame(struct GBAudio* audio, struct mTiming* timing) {
|
||||||
|
if (!audio->enable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (audio->skipFrame) {
|
||||||
|
audio->skipFrame = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
int frame = (audio->frame + 1) & 7;
|
int frame = (audio->frame + 1) & 7;
|
||||||
audio->frame = frame;
|
audio->frame = frame;
|
||||||
|
|
||||||
@ -929,6 +944,7 @@ void GBAudioPSGSerialize(const struct GBAudio* audio, struct GBSerializedPSGStat
|
|||||||
uint32_t ch4Flags = 0;
|
uint32_t ch4Flags = 0;
|
||||||
|
|
||||||
flags = GBSerializedAudioFlagsSetFrame(flags, audio->frame);
|
flags = GBSerializedAudioFlagsSetFrame(flags, audio->frame);
|
||||||
|
flags = GBSerializedAudioFlagsSetSkipFrame(flags, audio->skipFrame);
|
||||||
STORE_32LE(audio->frameEvent.when - mTimingCurrentTime(audio->timing), 0, &state->ch1.nextFrame);
|
STORE_32LE(audio->frameEvent.when - mTimingCurrentTime(audio->timing), 0, &state->ch1.nextFrame);
|
||||||
|
|
||||||
flags = GBSerializedAudioFlagsSetCh1Volume(flags, audio->ch1.envelope.currentVolume);
|
flags = GBSerializedAudioFlagsSetCh1Volume(flags, audio->ch1.envelope.currentVolume);
|
||||||
@ -987,6 +1003,7 @@ void GBAudioPSGDeserialize(struct GBAudio* audio, const struct GBSerializedPSGSt
|
|||||||
|
|
||||||
LOAD_32LE(flags, 0, flagsIn);
|
LOAD_32LE(flags, 0, flagsIn);
|
||||||
audio->frame = GBSerializedAudioFlagsGetFrame(flags);
|
audio->frame = GBSerializedAudioFlagsGetFrame(flags);
|
||||||
|
audio->skipFrame = GBSerializedAudioFlagsGetSkipFrame(flags);
|
||||||
|
|
||||||
LOAD_32LE(ch1Flags, 0, &state->ch1.envelope);
|
LOAD_32LE(ch1Flags, 0, &state->ch1.envelope);
|
||||||
audio->ch1.envelope.currentVolume = GBSerializedAudioFlagsGetCh1Volume(flags);
|
audio->ch1.envelope.currentVolume = GBSerializedAudioFlagsGetCh1Volume(flags);
|
||||||
|
@ -45,6 +45,8 @@ static const enum GBBus _oamBlockCGB[] = {
|
|||||||
GB_BUS_CPU // 0xE000
|
GB_BUS_CPU // 0xE000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const uint8_t _blockedRegion[1] = { 0xFF };
|
||||||
|
|
||||||
static void _pristineCow(struct GB* gba);
|
static void _pristineCow(struct GB* gba);
|
||||||
|
|
||||||
static uint8_t GBFastLoad8(struct LR35902Core* cpu, uint16_t address) {
|
static uint8_t GBFastLoad8(struct LR35902Core* cpu, uint16_t address) {
|
||||||
@ -92,6 +94,15 @@ static void GBSetActiveRegion(struct LR35902Core* cpu, uint16_t address) {
|
|||||||
cpu->memory.cpuLoad8 = GBLoad8;
|
cpu->memory.cpuLoad8 = GBLoad8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (gb->memory.dmaRemaining) {
|
||||||
|
const enum GBBus* block = gb->model < GB_MODEL_CGB ? _oamBlockDMG : _oamBlockCGB;
|
||||||
|
enum GBBus dmaBus = block[memory->dmaSource >> 13];
|
||||||
|
enum GBBus accessBus = block[address >> 13];
|
||||||
|
if ((dmaBus != GB_BUS_CPU && dmaBus == accessBus) || (address >= GB_BASE_OAM && address < GB_BASE_UNUSABLE)) {
|
||||||
|
cpu->memory.activeRegion = _blockedRegion;
|
||||||
|
cpu->memory.activeMask = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _GBMemoryDMAService(struct mTiming* timing, void* context, uint32_t cyclesLate);
|
static void _GBMemoryDMAService(struct mTiming* timing, void* context, uint32_t cyclesLate);
|
||||||
|
@ -80,7 +80,8 @@ void GBTimerDivReset(struct GBTimer* timer) {
|
|||||||
mTimingSchedule(&timer->p->timing, &timer->irq, 7 - (timer->p->cpu->executionState & 3));
|
mTimingSchedule(&timer->p->timing, &timer->irq, 7 - (timer->p->cpu->executionState & 3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (timer->internalDiv & 0x200) {
|
unsigned timingFactor = 0x400 >> !timer->p->doubleSpeed;
|
||||||
|
if (timer->internalDiv & timingFactor) {
|
||||||
GBAudioUpdateFrame(&timer->p->audio, &timer->p->timing);
|
GBAudioUpdateFrame(&timer->p->audio, &timer->p->timing);
|
||||||
}
|
}
|
||||||
timer->p->memory.io[REG_DIV] = 0;
|
timer->p->memory.io[REG_DIV] = 0;
|
||||||
|
@ -276,6 +276,9 @@ static void GBACheatRefresh(struct mCheatSet* cheats, struct mCheatDevice* devic
|
|||||||
struct GBACheatSet* gbaset = (struct GBACheatSet*) cheats;
|
struct GBACheatSet* gbaset = (struct GBACheatSet*) cheats;
|
||||||
if (cheats->enabled) {
|
if (cheats->enabled) {
|
||||||
_patchROM(device, gbaset);
|
_patchROM(device, gbaset);
|
||||||
|
if (gbaset->hook && !gbaset->hook->reentries) {
|
||||||
|
_addBreakpoint(device, gbaset);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_unpatchROM(device, gbaset);
|
_unpatchROM(device, gbaset);
|
||||||
}
|
}
|
||||||
|
@ -841,7 +841,6 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
|
|||||||
case REG_SOUND4CNT_LO:
|
case REG_SOUND4CNT_LO:
|
||||||
case REG_SOUND4CNT_HI:
|
case REG_SOUND4CNT_HI:
|
||||||
case REG_SOUNDCNT_LO:
|
case REG_SOUNDCNT_LO:
|
||||||
case REG_SOUNDCNT_HI:
|
|
||||||
if (!GBAudioEnableIsEnable(gba->memory.io[REG_SOUNDCNT_X >> 1])) {
|
if (!GBAudioEnableIsEnable(gba->memory.io[REG_SOUNDCNT_X >> 1])) {
|
||||||
// TODO: Is writing allowed when the circuit is disabled?
|
// TODO: Is writing allowed when the circuit is disabled?
|
||||||
return 0;
|
return 0;
|
||||||
@ -858,6 +857,7 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
|
|||||||
case REG_WINOUT:
|
case REG_WINOUT:
|
||||||
case REG_BLDCNT:
|
case REG_BLDCNT:
|
||||||
case REG_BLDALPHA:
|
case REG_BLDALPHA:
|
||||||
|
case REG_SOUNDCNT_HI:
|
||||||
case REG_SOUNDCNT_X:
|
case REG_SOUNDCNT_X:
|
||||||
case REG_WAVE_RAM0_LO:
|
case REG_WAVE_RAM0_LO:
|
||||||
case REG_WAVE_RAM0_HI:
|
case REG_WAVE_RAM0_HI:
|
||||||
|
@ -789,6 +789,7 @@ void retro_cheat_set(unsigned index, bool enabled, const char* code) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
cheatSet->refresh(cheatSet, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned retro_get_region(void) {
|
unsigned retro_get_region(void) {
|
||||||
|
@ -75,9 +75,11 @@ void GBAApp::cleanup() {
|
|||||||
finishJob(m_workerJobs.firstKey());
|
finishJob(m_workerJobs.firstKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_SQLITE3
|
||||||
if (m_db) {
|
if (m_db) {
|
||||||
NoIntroDBDestroy(m_db);
|
NoIntroDBDestroy(m_db);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GBAApp::event(QEvent* event) {
|
bool GBAApp::event(QEvent* event) {
|
||||||
|
@ -15,7 +15,7 @@ endif()
|
|||||||
if(SDL_VERSION EQUAL "1.2" OR NOT SDL2_FOUND)
|
if(SDL_VERSION EQUAL "1.2" OR NOT SDL2_FOUND)
|
||||||
find_package(SDL 1.2)
|
find_package(SDL 1.2)
|
||||||
if(SDL_FOUND)
|
if(SDL_FOUND)
|
||||||
set(SDL_VERSION "1.2" PARENT_SCOPE)
|
set(SDL_VERSION "1.2")
|
||||||
set(SDL_VERSION_DEBIAN "1.2debian")
|
set(SDL_VERSION_DEBIAN "1.2debian")
|
||||||
set(USE_PIXMAN ON)
|
set(USE_PIXMAN ON)
|
||||||
endif()
|
endif()
|
||||||
@ -26,6 +26,7 @@ if (NOT SDL2_FOUND AND NOT SDL_FOUND)
|
|||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(SDL_VERSION "${SDL_VERSION}" PARENT_SCOPE)
|
||||||
add_definitions(-DBUILD_SDL)
|
add_definitions(-DBUILD_SDL)
|
||||||
|
|
||||||
find_feature(USE_PIXMAN "pixman-1")
|
find_feature(USE_PIXMAN "pixman-1")
|
||||||
@ -85,7 +86,11 @@ else()
|
|||||||
include_directories(${OPENGLES2_INCLUDE_DIR})
|
include_directories(${OPENGLES2_INCLUDE_DIR})
|
||||||
endif()
|
endif()
|
||||||
if(NOT BUILD_GL AND NOT BUILD_GLES2)
|
if(NOT BUILD_GL AND NOT BUILD_GLES2)
|
||||||
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl.c)
|
if(SDL_VERSION EQUAL "2")
|
||||||
|
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl2.c)
|
||||||
|
else()
|
||||||
|
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl1.c)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -55,5 +55,6 @@ void mSDLGLCommonInit(struct mSDLRenderer* renderer) {
|
|||||||
#else
|
#else
|
||||||
SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_OPENGL | (SDL_FULLSCREEN * renderer->fullscreen));
|
SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_OPENGL | (SDL_FULLSCREEN * renderer->fullscreen));
|
||||||
#endif
|
#endif
|
||||||
|
SDL_WM_SetCaption(projectName, "");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -64,8 +64,12 @@ bool mSDLInitEvents(struct mSDLEvents* context) {
|
|||||||
if (!SDL_JoystickListSize(&context->joysticks)) {
|
if (!SDL_JoystickListSize(&context->joysticks)) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < nJoysticks; ++i) {
|
for (i = 0; i < nJoysticks; ++i) {
|
||||||
|
SDL_Joystick* sdlJoystick = SDL_JoystickOpen(i);
|
||||||
|
if (!sdlJoystick) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
struct SDL_JoystickCombo* joystick = SDL_JoystickListAppend(&context->joysticks);
|
struct SDL_JoystickCombo* joystick = SDL_JoystickListAppend(&context->joysticks);
|
||||||
joystick->joystick = SDL_JoystickOpen(i);
|
joystick->joystick = sdlJoystick;
|
||||||
joystick->index = SDL_JoystickListSize(&context->joysticks) - 1;
|
joystick->index = SDL_JoystickListSize(&context->joysticks) - 1;
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
joystick->id = SDL_JoystickInstanceID(joystick->joystick);
|
joystick->id = SDL_JoystickInstanceID(joystick->joystick);
|
||||||
@ -203,6 +207,9 @@ bool mSDLAttachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) {
|
|||||||
#else
|
#else
|
||||||
joystickName = SDL_JoystickName(SDL_JoystickIndex(SDL_JoystickListGetPointer(&events->joysticks, i)->joystick));
|
joystickName = SDL_JoystickName(SDL_JoystickIndex(SDL_JoystickListGetPointer(&events->joysticks, i)->joystick));
|
||||||
#endif
|
#endif
|
||||||
|
if (!joystickName) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (events->preferredJoysticks[player->playerId] && strcmp(events->preferredJoysticks[player->playerId], joystickName) == 0) {
|
if (events->preferredJoysticks[player->playerId] && strcmp(events->preferredJoysticks[player->playerId], joystickName) == 0) {
|
||||||
index = i;
|
index = i;
|
||||||
break;
|
break;
|
||||||
@ -253,6 +260,9 @@ void mSDLPlayerLoadConfig(struct mSDLPlayer* context, const struct Configuration
|
|||||||
#else
|
#else
|
||||||
const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick));
|
const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick));
|
||||||
#endif
|
#endif
|
||||||
|
if (!name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
mInputProfileLoad(context->bindings, SDL_BINDING_BUTTON, config, name);
|
mInputProfileLoad(context->bindings, SDL_BINDING_BUTTON, config, name);
|
||||||
|
|
||||||
const char* value;
|
const char* value;
|
||||||
@ -304,6 +314,9 @@ void mSDLPlayerSaveConfig(const struct mSDLPlayer* context, struct Configuration
|
|||||||
#else
|
#else
|
||||||
const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick));
|
const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick));
|
||||||
#endif
|
#endif
|
||||||
|
if (!name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
char value[16];
|
char value[16];
|
||||||
snprintf(value, sizeof(value), "%i", context->rotation.axisX);
|
snprintf(value, sizeof(value), "%i", context->rotation.axisX);
|
||||||
mInputSetCustomValue(config, "gba", SDL_BINDING_BUTTON, "tiltAxisX", value, name);
|
mInputSetCustomValue(config, "gba", SDL_BINDING_BUTTON, "tiltAxisX", value, name);
|
||||||
@ -332,8 +345,12 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration*
|
|||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED) > 0) {
|
while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED) > 0) {
|
||||||
if (event.type == SDL_JOYDEVICEADDED) {
|
if (event.type == SDL_JOYDEVICEADDED) {
|
||||||
|
SDL_Joystick* sdlJoystick = SDL_JoystickOpen(event.jdevice.which);
|
||||||
|
if (!sdlJoystick) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
struct SDL_JoystickCombo* joystick = SDL_JoystickListAppend(&events->joysticks);
|
struct SDL_JoystickCombo* joystick = SDL_JoystickListAppend(&events->joysticks);
|
||||||
joystick->joystick = SDL_JoystickOpen(event.jdevice.which);
|
joystick->joystick = sdlJoystick;
|
||||||
joystick->id = SDL_JoystickInstanceID(joystick->joystick);
|
joystick->id = SDL_JoystickInstanceID(joystick->joystick);
|
||||||
joystick->index = SDL_JoystickListSize(&events->joysticks) - 1;
|
joystick->index = SDL_JoystickListSize(&events->joysticks) - 1;
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
@ -347,16 +364,18 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration*
|
|||||||
joystickName = SDL_JoystickName(SDL_JoystickIndex(joystick->joystick));
|
joystickName = SDL_JoystickName(SDL_JoystickIndex(joystick->joystick));
|
||||||
#endif
|
#endif
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; (int) i < events->playersAttached; ++i) {
|
if (joystickName) {
|
||||||
if (events->players[i]->joystick) {
|
for (i = 0; (int) i < events->playersAttached; ++i) {
|
||||||
continue;
|
if (events->players[i]->joystick) {
|
||||||
}
|
continue;
|
||||||
if (events->preferredJoysticks[i] && strcmp(events->preferredJoysticks[i], joystickName) == 0) {
|
}
|
||||||
events->players[i]->joystick = joystick;
|
if (events->preferredJoysticks[i] && strcmp(events->preferredJoysticks[i], joystickName) == 0) {
|
||||||
if (config) {
|
events->players[i]->joystick = joystick;
|
||||||
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName);
|
if (config) {
|
||||||
|
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; (int) i < events->playersAttached; ++i) {
|
for (i = 0; (int) i < events->playersAttached; ++i) {
|
||||||
@ -364,7 +383,7 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration*
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
events->players[i]->joystick = joystick;
|
events->players[i]->joystick = joystick;
|
||||||
if (config) {
|
if (config && joystickName) {
|
||||||
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName);
|
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -21,35 +21,15 @@ void mSDLSWCreate(struct mSDLRenderer* renderer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool mSDLSWInit(struct mSDLRenderer* renderer) {
|
bool mSDLSWInit(struct mSDLRenderer* renderer) {
|
||||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
|
||||||
#ifdef COLOR_16_BIT
|
#ifdef COLOR_16_BIT
|
||||||
SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_DOUBLEBUF | SDL_HWSURFACE);
|
SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_DOUBLEBUF | SDL_HWSURFACE | (SDL_FULLSCREEN * renderer->fullscreen));
|
||||||
#else
|
#else
|
||||||
SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_DOUBLEBUF | SDL_HWSURFACE);
|
SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_DOUBLEBUF | SDL_HWSURFACE | (SDL_FULLSCREEN * renderer->fullscreen));
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
SDL_WM_SetCaption(projectName, "");
|
||||||
|
|
||||||
unsigned width, height;
|
unsigned width, height;
|
||||||
renderer->core->desiredVideoDimensions(renderer->core, &width, &height);
|
renderer->core->desiredVideoDimensions(renderer->core, &width, &height);
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
||||||
renderer->window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->player.fullscreen));
|
|
||||||
SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight);
|
|
||||||
renderer->player.window = renderer->window;
|
|
||||||
renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
|
||||||
#ifdef COLOR_16_BIT
|
|
||||||
#ifdef COLOR_5_6_5
|
|
||||||
renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height);
|
|
||||||
#else
|
|
||||||
renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR1555, SDL_TEXTUREACCESS_STREAMING, width, height);
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, width, height);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int stride;
|
|
||||||
SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->outputBuffer, &stride);
|
|
||||||
renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, stride / BYTES_PER_PIXEL);
|
|
||||||
#else
|
|
||||||
SDL_Surface* surface = SDL_GetVideoSurface();
|
SDL_Surface* surface = SDL_GetVideoSurface();
|
||||||
SDL_LockSurface(surface);
|
SDL_LockSurface(surface);
|
||||||
|
|
||||||
@ -81,7 +61,6 @@ bool mSDLSWInit(struct mSDLRenderer* renderer) {
|
|||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -89,9 +68,7 @@ bool mSDLSWInit(struct mSDLRenderer* renderer) {
|
|||||||
void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user) {
|
void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user) {
|
||||||
struct mCoreThread* context = user;
|
struct mCoreThread* context = user;
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
|
||||||
SDL_Surface* surface = SDL_GetVideoSurface();
|
SDL_Surface* surface = SDL_GetVideoSurface();
|
||||||
#endif
|
|
||||||
|
|
||||||
while (mCoreThreadIsActive(context)) {
|
while (mCoreThreadIsActive(context)) {
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
@ -99,14 +76,6 @@ void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mCoreSyncWaitFrameStart(&context->impl->sync)) {
|
if (mCoreSyncWaitFrameStart(&context->impl->sync)) {
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
||||||
SDL_UnlockTexture(renderer->sdlTex);
|
|
||||||
SDL_RenderCopy(renderer->sdlRenderer, renderer->sdlTex, 0, 0);
|
|
||||||
SDL_RenderPresent(renderer->sdlRenderer);
|
|
||||||
int stride;
|
|
||||||
SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->outputBuffer, &stride);
|
|
||||||
renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, stride / BYTES_PER_PIXEL);
|
|
||||||
#else
|
|
||||||
#ifdef USE_PIXMAN
|
#ifdef USE_PIXMAN
|
||||||
if (renderer->ratio > 1) {
|
if (renderer->ratio > 1) {
|
||||||
pixman_image_composite32(PIXMAN_OP_SRC, renderer->pix, 0, renderer->screenpix,
|
pixman_image_composite32(PIXMAN_OP_SRC, renderer->pix, 0, renderer->screenpix,
|
||||||
@ -132,7 +101,6 @@ void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user) {
|
|||||||
SDL_UnlockSurface(surface);
|
SDL_UnlockSurface(surface);
|
||||||
SDL_Flip(surface);
|
SDL_Flip(surface);
|
||||||
SDL_LockSurface(surface);
|
SDL_LockSurface(surface);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
mCoreSyncWaitFrameEnd(&context->impl->sync);
|
mCoreSyncWaitFrameEnd(&context->impl->sync);
|
||||||
}
|
}
|
||||||
@ -141,13 +109,11 @@ void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user) {
|
|||||||
void mSDLSWDeinit(struct mSDLRenderer* renderer) {
|
void mSDLSWDeinit(struct mSDLRenderer* renderer) {
|
||||||
if (renderer->ratio > 1) {
|
if (renderer->ratio > 1) {
|
||||||
free(renderer->outputBuffer);
|
free(renderer->outputBuffer);
|
||||||
|
#ifdef USE_PIXMAN
|
||||||
|
pixman_image_unref(renderer->pix);
|
||||||
|
pixman_image_unref(renderer->screenpix);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
|
||||||
SDL_Surface* surface = SDL_GetVideoSurface();
|
SDL_Surface* surface = SDL_GetVideoSurface();
|
||||||
SDL_UnlockSurface(surface);
|
SDL_UnlockSurface(surface);
|
||||||
#ifdef USE_PIXMAN
|
|
||||||
pixman_image_unref(renderer->pix);
|
|
||||||
pixman_image_unref(renderer->screenpix);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
72
src/platform/sdl/sw-sdl2.c
Normal file
72
src/platform/sdl/sw-sdl2.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/* Copyright (c) 2013-2015 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#include <mgba/core/core.h>
|
||||||
|
#include <mgba/core/thread.h>
|
||||||
|
#include <mgba/core/version.h>
|
||||||
|
#include <mgba-util/arm-algo.h>
|
||||||
|
|
||||||
|
static bool mSDLSWInit(struct mSDLRenderer* renderer);
|
||||||
|
static void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user);
|
||||||
|
static void mSDLSWDeinit(struct mSDLRenderer* renderer);
|
||||||
|
|
||||||
|
void mSDLSWCreate(struct mSDLRenderer* renderer) {
|
||||||
|
renderer->init = mSDLSWInit;
|
||||||
|
renderer->deinit = mSDLSWDeinit;
|
||||||
|
renderer->runloop = mSDLSWRunloop;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mSDLSWInit(struct mSDLRenderer* renderer) {
|
||||||
|
unsigned width, height;
|
||||||
|
renderer->core->desiredVideoDimensions(renderer->core, &width, &height);
|
||||||
|
renderer->window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->player.fullscreen));
|
||||||
|
SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight);
|
||||||
|
renderer->player.window = renderer->window;
|
||||||
|
renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||||
|
#ifdef COLOR_16_BIT
|
||||||
|
#ifdef COLOR_5_6_5
|
||||||
|
renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height);
|
||||||
|
#else
|
||||||
|
renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR1555, SDL_TEXTUREACCESS_STREAMING, width, height);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, width, height);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int stride;
|
||||||
|
SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->outputBuffer, &stride);
|
||||||
|
renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, stride / BYTES_PER_PIXEL);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user) {
|
||||||
|
struct mCoreThread* context = user;
|
||||||
|
SDL_Event event;
|
||||||
|
|
||||||
|
while (mCoreThreadIsActive(context)) {
|
||||||
|
while (SDL_PollEvent(&event)) {
|
||||||
|
mSDLHandleEvent(context, &renderer->player, &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCoreSyncWaitFrameStart(&context->impl->sync)) {
|
||||||
|
SDL_UnlockTexture(renderer->sdlTex);
|
||||||
|
SDL_RenderCopy(renderer->sdlRenderer, renderer->sdlTex, 0, 0);
|
||||||
|
SDL_RenderPresent(renderer->sdlRenderer);
|
||||||
|
int stride;
|
||||||
|
SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->outputBuffer, &stride);
|
||||||
|
renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, stride / BYTES_PER_PIXEL);
|
||||||
|
}
|
||||||
|
mCoreSyncWaitFrameEnd(&context->impl->sync);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mSDLSWDeinit(struct mSDLRenderer* renderer) {
|
||||||
|
if (renderer->ratio > 1) {
|
||||||
|
free(renderer->outputBuffer);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user