PSP2: Use runner

This commit is contained in:
Jeffrey Pfau 2015-08-30 17:32:05 -07:00
parent cc1fb12d2f
commit 58ff10457d
3 changed files with 97 additions and 151 deletions

View File

@ -6,6 +6,7 @@
#include "psp2-context.h"
#include "gba/gba.h"
#include "gba/context/gui-runner.h"
#include "util/gui.h"
#include "util/gui/font.h"
#include "util/gui/file-select.h"
@ -63,49 +64,25 @@ int main() {
vita2d_init();
struct GUIFont* font = GUIFontCreate();
GBAPSP2Setup();
struct GUIParams params = {
PSP2_HORIZONTAL_PIXELS, PSP2_VERTICAL_PIXELS,
font, "cache0:", _drawStart, _drawEnd, _pollInput, 0, 0,
struct GBAGUIRunner runner = {
.params = {
PSP2_HORIZONTAL_PIXELS, PSP2_VERTICAL_PIXELS,
font, "cache0:", _drawStart, _drawEnd, _pollInput, 0, 0,
GUI_PARAMS_TRAIL
GUI_PARAMS_TRAIL
},
.setup = GBAPSP2Setup,
.teardown = GBAPSP2Teardown,
.gameLoaded = GBAPSP2LoadROM,
.gameUnloaded = GBAPSP2UnloadROM,
.prepareForFrame = GBAPSP2PrepareForFrame,
.drawFrame = GBAPSP2Draw,
.pollGameInput = GBAPSP2PollInput
};
GUIInit(&params);
while (true) {
bool running = true;
char path[256];
if (!GUISelectFile(&params, path, sizeof(path), GBAIsROM)) {
break;
}
if (!GBAPSP2LoadROM(path)) {
continue;
}
while (running) {
GBAPSP2Runloop();
GUIInvalidateKeys(&params);
while (true) {
int keys = 0;
_drawStart();
GBAPSP2Draw(0x80);
_drawEnd();
GUIPollInput(&params, &keys, 0);
if (keys & (1 << GUI_INPUT_CANCEL)) {
running = false;
break;
}
if (keys & (1 << GUI_INPUT_SELECT)) {
while (keys & (1 << GUI_INPUT_SELECT)) {
GUIPollInput(&params, 0, &keys);
}
break;
}
}
}
GBAPSP2UnloadROM();
}
GBAPSP2Teardown();
GBAGUIInit(&runner, 0);
GBAGUIRunloop(&runner);
GBAGUIDeinit(&runner);
GUIFontDestroy(font);
vita2d_fini();

View File

@ -6,9 +6,10 @@
#include "psp2-context.h"
#include "gba/gba.h"
#include "gba/input.h"
#include "gba/audio.h"
#include "gba/context/context.h"
#include "gba/context/gui-runner.h"
#include "gba/input.h"
#include "gba/renderers/video-software.h"
#include "util/circle-buffer.h"
@ -35,7 +36,6 @@ enum ScreenMode {
SM_MAX
};
static struct GBAContext context;
static struct GBAVideoSoftwareRenderer renderer;
static vita2d_texture* tex;
static Thread audioThread;
@ -113,65 +113,77 @@ static int32_t _readGyroZ(struct GBARotationSource* source) {
return rotation->state.gyro.z * 0x10000000;
}
void GBAPSP2Setup() {
uint16_t GBAPSP2PollInput(struct GBAGUIRunner* runner) {
SceCtrlData pad;
sceCtrlPeekBufferPositive(0, &pad, 1);
int activeKeys = GBAInputMapKeyBits(&runner->context.inputMap, PSP2_INPUT, pad.buttons, 0);
enum GBAKey angles = GBAInputMapAxis(&runner->context.inputMap, PSP2_INPUT, 0, pad.ly);
if (angles != GBA_KEY_NONE) {
activeKeys |= 1 << angles;
}
angles = GBAInputMapAxis(&runner->context.inputMap, PSP2_INPUT, 1, pad.lx);
if (angles != GBA_KEY_NONE) {
activeKeys |= 1 << angles;
}
angles = GBAInputMapAxis(&runner->context.inputMap, PSP2_INPUT, 2, pad.ry);
if (angles != GBA_KEY_NONE) {
activeKeys |= 1 << angles;
}
angles = GBAInputMapAxis(&runner->context.inputMap, PSP2_INPUT, 3, pad.rx);
if (angles != GBA_KEY_NONE) {
activeKeys |= 1 << angles;
}
return activeKeys;
}
void GBAPSP2Setup(struct GBAGUIRunner* runner) {
scePowerSetArmClockFrequency(80);
GBAContextInit(&context, 0);
struct GBAOptions opts = {
.useBios = true,
.logLevel = 0,
.idleOptimization = IDLE_LOOP_DETECT
};
GBAConfigLoadDefaults(&context.config, &opts);
_mapVitaKey(&context.inputMap, PSP2_CTRL_CROSS, GBA_KEY_A);
_mapVitaKey(&context.inputMap, PSP2_CTRL_CIRCLE, GBA_KEY_B);
_mapVitaKey(&context.inputMap, PSP2_CTRL_START, GBA_KEY_START);
_mapVitaKey(&context.inputMap, PSP2_CTRL_SELECT, GBA_KEY_SELECT);
_mapVitaKey(&context.inputMap, PSP2_CTRL_UP, GBA_KEY_UP);
_mapVitaKey(&context.inputMap, PSP2_CTRL_DOWN, GBA_KEY_DOWN);
_mapVitaKey(&context.inputMap, PSP2_CTRL_LEFT, GBA_KEY_LEFT);
_mapVitaKey(&context.inputMap, PSP2_CTRL_RIGHT, GBA_KEY_RIGHT);
_mapVitaKey(&context.inputMap, PSP2_CTRL_LTRIGGER, GBA_KEY_L);
_mapVitaKey(&context.inputMap, PSP2_CTRL_RTRIGGER, GBA_KEY_R);
GBAConfigLoadDefaults(&runner->context.config, &opts);
_mapVitaKey(&runner->context.inputMap, PSP2_CTRL_CROSS, GBA_KEY_A);
_mapVitaKey(&runner->context.inputMap, PSP2_CTRL_CIRCLE, GBA_KEY_B);
_mapVitaKey(&runner->context.inputMap, PSP2_CTRL_START, GBA_KEY_START);
_mapVitaKey(&runner->context.inputMap, PSP2_CTRL_SELECT, GBA_KEY_SELECT);
_mapVitaKey(&runner->context.inputMap, PSP2_CTRL_UP, GBA_KEY_UP);
_mapVitaKey(&runner->context.inputMap, PSP2_CTRL_DOWN, GBA_KEY_DOWN);
_mapVitaKey(&runner->context.inputMap, PSP2_CTRL_LEFT, GBA_KEY_LEFT);
_mapVitaKey(&runner->context.inputMap, PSP2_CTRL_RIGHT, GBA_KEY_RIGHT);
_mapVitaKey(&runner->context.inputMap, PSP2_CTRL_LTRIGGER, GBA_KEY_L);
_mapVitaKey(&runner->context.inputMap, PSP2_CTRL_RTRIGGER, GBA_KEY_R);
struct GBAAxis desc = { GBA_KEY_DOWN, GBA_KEY_UP, 192, 64 };
GBAInputBindAxis(&context.inputMap, PSP2_INPUT, 0, &desc);
GBAInputBindAxis(&runner->context.inputMap, PSP2_INPUT, 0, &desc);
desc = (struct GBAAxis) { GBA_KEY_RIGHT, GBA_KEY_LEFT, 192, 64 };
GBAInputBindAxis(&context.inputMap, PSP2_INPUT, 1, &desc);
GBAInputBindAxis(&runner->context.inputMap, PSP2_INPUT, 1, &desc);
tex = vita2d_create_empty_texture_format(256, 256, SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1BGR);
GBAVideoSoftwareRendererCreate(&renderer);
renderer.outputBuffer = vita2d_texture_get_datap(tex);
renderer.outputBufferStride = 256;
context.renderer = &renderer.d;
runner->context.renderer = &renderer.d;
rotation.d.sample = _sampleRotation;
rotation.d.readTiltX = _readTiltX;
rotation.d.readTiltY = _readTiltY;
rotation.d.readGyroZ = _readGyroZ;
context.gba->rotationSource = &rotation.d;
runner->context.gba->rotationSource = &rotation.d;
backdrop = vita2d_load_PNG_buffer(_binary_backdrop_png_start);
printf("%s starting", projectName);
}
bool GBAPSP2LoadROM(const char* path) {
void GBAPSP2LoadROM(struct GBAGUIRunner* runner) {
scePowerSetArmClockFrequency(444);
if (!GBAContextLoadROM(&context, path, true)) {
printf("%s failed to load!", path);
return false;
}
printf("%s loaded, starting...", path);
GBAContextStart(&context);
char gameTitle[13];
GBAGetGameTitle(context.gba, gameTitle);
printf("%s started!", gameTitle);
double ratio = GBAAudioCalculateRatio(1, 60, 1);
blip_set_rates(context.gba->audio.left, GBA_ARM7TDMI_FREQUENCY, 48000 * ratio);
blip_set_rates(context.gba->audio.right, GBA_ARM7TDMI_FREQUENCY, 48000 * ratio);
blip_set_rates(runner->context.gba->audio.left, GBA_ARM7TDMI_FREQUENCY, 48000 * ratio);
blip_set_rates(runner->context.gba->audio.right, GBA_ARM7TDMI_FREQUENCY, 48000 * ratio);
if (context.gba->memory.hw.devices & (HW_TILT | HW_GYRO)) {
if (runner->context.gba->memory.hw.devices & (HW_TILT | HW_GYRO)) {
sceMotionStartSampling();
}
@ -180,101 +192,57 @@ bool GBAPSP2LoadROM(const char* path) {
ConditionInit(&audioContext.cond);
audioContext.running = true;
ThreadCreate(&audioThread, _audioThread, &audioContext);
return true;
}
void GBAPSP2Runloop(void) {
int activeKeys = 0;
bool fsToggle = false;
while (true) {
SceCtrlData pad;
sceCtrlPeekBufferPositive(0, &pad, 1);
if (pad.buttons & PSP2_CTRL_TRIANGLE) {
void GBAPSP2PrepareForFrame(struct GBAGUIRunner* runner) {
MutexLock(&audioContext.mutex);
while (blip_samples_avail(runner->context.gba->audio.left) >= PSP2_SAMPLES) {
if (CircleBufferSize(&audioContext.buffer) + PSP2_SAMPLES * sizeof(struct GBAStereoSample) > CircleBufferCapacity(&audioContext.buffer)) {
break;
}
if (pad.buttons & PSP2_CTRL_SQUARE) {
if (!fsToggle) {
++screenMode;
screenMode %= SM_MAX;
}
fsToggle = true;
} else {
fsToggle = false;
struct GBAStereoSample samples[PSP2_SAMPLES];
blip_read_samples(runner->context.gba->audio.left, &samples[0].left, PSP2_SAMPLES, true);
blip_read_samples(runner->context.gba->audio.right, &samples[0].right, PSP2_SAMPLES, true);
int i;
for (i = 0; i < PSP2_SAMPLES; ++i) {
CircleBufferWrite16(&audioContext.buffer, samples[i].left);
CircleBufferWrite16(&audioContext.buffer, samples[i].right);
}
activeKeys = GBAInputMapKeyBits(&context.inputMap, PSP2_INPUT, pad.buttons, 0);
enum GBAKey angles = GBAInputMapAxis(&context.inputMap, PSP2_INPUT, 0, pad.ly);
if (angles != GBA_KEY_NONE) {
activeKeys |= 1 << angles;
}
angles = GBAInputMapAxis(&context.inputMap, PSP2_INPUT, 1, pad.lx);
if (angles != GBA_KEY_NONE) {
activeKeys |= 1 << angles;
}
angles = GBAInputMapAxis(&context.inputMap, PSP2_INPUT, 2, pad.ry);
if (angles != GBA_KEY_NONE) {
activeKeys |= 1 << angles;
}
angles = GBAInputMapAxis(&context.inputMap, PSP2_INPUT, 3, pad.rx);
if (angles != GBA_KEY_NONE) {
activeKeys |= 1 << angles;
}
GBAContextFrame(&context, activeKeys);
MutexLock(&audioContext.mutex);
while (blip_samples_avail(context.gba->audio.left) >= PSP2_SAMPLES) {
if (CircleBufferSize(&audioContext.buffer) + PSP2_SAMPLES * sizeof(struct GBAStereoSample) > CircleBufferCapacity(&audioContext.buffer)) {
break;
}
struct GBAStereoSample samples[PSP2_SAMPLES];
blip_read_samples(context.gba->audio.left, &samples[0].left, PSP2_SAMPLES, true);
blip_read_samples(context.gba->audio.right, &samples[0].right, PSP2_SAMPLES, true);
int i;
for (i = 0; i < PSP2_SAMPLES; ++i) {
CircleBufferWrite16(&audioContext.buffer, samples[i].left);
CircleBufferWrite16(&audioContext.buffer, samples[i].right);
}
}
ConditionWake(&audioContext.cond);
MutexUnlock(&audioContext.mutex);
vita2d_start_drawing();
vita2d_clear_screen();
GBAPSP2Draw(0xFF);
vita2d_end_drawing();
vita2d_swap_buffers();
}
ConditionWake(&audioContext.cond);
MutexUnlock(&audioContext.mutex);
}
void GBAPSP2UnloadROM(void) {
if (context.gba->memory.hw.devices & (HW_TILT | HW_GYRO)) {
void GBAPSP2UnloadROM(struct GBAGUIRunner* runner) {
if (runner->context.gba->memory.hw.devices & (HW_TILT | HW_GYRO)) {
sceMotionStopSampling();
}
GBAContextStop(&context);
scePowerSetArmClockFrequency(80);
}
void GBAPSP2Teardown(void) {
GBAContextDeinit(&context);
void GBAPSP2Teardown(struct GBAGUIRunner* runner) {
UNUSED(runner);
vita2d_free_texture(tex);
vita2d_free_texture(backdrop);
}
void GBAPSP2Draw(uint8_t alpha) {
void GBAPSP2Draw(struct GBAGUIRunner* runner, bool faded) {
UNUSED(runner);
vita2d_start_drawing();
vita2d_clear_screen();
switch (screenMode) {
case SM_BACKDROP:
vita2d_draw_texture_tint(backdrop, 0, 0, (alpha << 24) | 0xFFFFFF);
vita2d_draw_texture_tint(backdrop, 0, 0, (faded ? 0 : 0xC0000000) | 0x3FFFFFFF);
// Fall through
case SM_PLAIN:
vita2d_draw_texture_tint_part_scale(tex, 120, 32, 0, 0, 240, 160, 3.0f, 3.0f, (alpha << 24) | 0xFFFFFF);
vita2d_draw_texture_tint_part_scale(tex, 120, 32, 0, 0, 240, 160, 3.0f, 3.0f, (faded ? 0 : 0xC0000000) | 0x3FFFFFFF);
break;
case SM_FULL:
vita2d_draw_texture_tint_scale(tex, 0, 0, 960.0f / 240.0f, 544.0f / 160.0f, (alpha << 24) | 0xFFFFFF);
vita2d_draw_texture_tint_scale(tex, 0, 0, 960.0f / 240.0f, 544.0f / 160.0f, (faded ? 0 : 0xC0000000) | 0x3FFFFFFF);
break;
}
vita2d_end_drawing();
vita2d_swap_buffers();
}
__attribute__((noreturn, weak)) void __assert_func(const char* file, int line, const char* func, const char* expr) {

View File

@ -8,13 +8,14 @@
#include "psp2-common.h"
void GBAPSP2Setup(void);
void GBAPSP2Teardown(void);
struct GBAGUIRunner;
void GBAPSP2Setup(struct GBAGUIRunner* runner);
void GBAPSP2Teardown(struct GBAGUIRunner* runner);
bool GBAPSP2LoadROM(const char* path);
void GBAPSP2Runloop(void);
void GBAPSP2UnloadROM(void);
void GBAPSP2Draw(uint8_t alpha);
void GBAPSP2LoadROM(struct GBAGUIRunner* runner);
void GBAPSP2UnloadROM(struct GBAGUIRunner* runner);
void GBAPSP2PrepareForFrame(struct GBAGUIRunner* runner);
void GBAPSP2Draw(struct GBAGUIRunner* runner, bool faded);
uint16_t GBAPSP2PollInput(struct GBAGUIRunner* runner);
#endif