From a55e83161ed588cf0991d1a97ee5cc74fe1e0c2e Mon Sep 17 00:00:00 2001 From: jSTE0 <98854293+jSTE0@users.noreply.github.com> Date: Sat, 19 Feb 2022 19:44:26 +0000 Subject: [PATCH] Add Miyoo platform support (#405) * platform: Add miyoo support Add support for the miyoo platform, building upon the existing BittBoy support which is the first member of the miyoo family. Support shoulder buttons present in newer members like the PocketGO, Q90 and V90 (which has 2 more shoulder buttons). Remove hardcoded path to level data to allow auto-detection. * bittboy/miyoo: Add sound support Use the ALSA sound code from gcw0. --- src/core.h | 2 +- src/platform/bittboy/build_miyoo.sh | 1 + src/platform/bittboy/main.cpp | 122 +++++++++++++++++++++++++++- 3 files changed, 123 insertions(+), 2 deletions(-) create mode 100755 src/platform/bittboy/build_miyoo.sh diff --git a/src/core.h b/src/core.h index c485c1f..5de961b 100644 --- a/src/core.h +++ b/src/core.h @@ -96,7 +96,7 @@ #define DYNGEOM_NO_VBO #define INV_GAMEPAD_ONLY #define INV_STEREO -#elif __BITTBOY__ +#elif __BITTBOY__ || __MIYOO__ #define _OS_BITTBOY 1 #define _OS_LINUX 1 #define _GAPI_SW 1 diff --git a/src/platform/bittboy/build_miyoo.sh b/src/platform/bittboy/build_miyoo.sh new file mode 100755 index 0000000..7c66464 --- /dev/null +++ b/src/platform/bittboy/build_miyoo.sh @@ -0,0 +1 @@ +/opt/miyoo-toolchain/bin/arm-miyoo-linux-uclibcgnueabi-g++ -std=c++11 -O3 -s -fno-unroll-loops -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -Wl,--gc-sections -D__MIYOO__ -DNDEBUG -D_POSIX_THREADS -D_POSIX_READER_WRITER_LOCKS main.cpp ../../libs/stb_vorbis/stb_vorbis.c ../../libs/minimp3/minimp3.cpp ../../libs/tinf/tinflate.c -I../../ -o../../../bin/OpenLara -lm -lpthread -lSDL -lasound diff --git a/src/platform/bittboy/main.cpp b/src/platform/bittboy/main.cpp index c7172eb..fb2fe11 100644 --- a/src/platform/bittboy/main.cpp +++ b/src/platform/bittboy/main.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include "game.h" @@ -8,10 +9,21 @@ SDL_Surface *screen = NULL; #define SCREEN_WIDTH (SCREEN_HEIGHT/3)*4 #define SCREEN_HEIGHT 240 +#ifdef __MIYOO__ +#define BTN_A SDLK_LALT +#define BTN_B SDLK_LCTRL +#define BTN_X SDLK_LSHIFT +#define BTN_Y SDLK_SPACE +#define BTN_L1 SDLK_BACKSPACE +#define BTN_R1 SDLK_TAB +#define BTN_L2 SDLK_RSHIFT +#define BTN_R2 SDLK_RALT +#else #define BTN_B SDLK_SPACE #define BTN_A SDLK_LCTRL #define BTN_TA SDLK_LALT #define BTN_TB SDLK_LSHIFT +#endif #define BTN_START SDLK_RETURN #define BTN_SELECT SDLK_ESCAPE #define BTN_R SDLK_RCTRL @@ -29,6 +41,99 @@ int osGetTimeMS() { return int((t.tv_sec - startTime) * 1000 + t.tv_usec / 1000); } +// sound +snd_pcm_uframes_t SND_FRAMES = 512; +snd_pcm_t *sndOut; +Sound::Frame *sndData; +pthread_t sndThread; + +void* sndFill(void *arg) { + while (sndOut) { + Sound::fill(sndData, SND_FRAMES); + + int count = SND_FRAMES; + while (count > 0) { + int frames = snd_pcm_writei(sndOut, &sndData[SND_FRAMES - count], count); + if (frames < 0) { + frames = snd_pcm_recover(sndOut, frames, 0); + if (frames == -EAGAIN) { + LOG("snd_pcm_writei try again\n"); + sleep(1); + continue; + } + if (frames < 0) { + LOG("snd_pcm_writei failed: %s\n", snd_strerror(frames)); + sndOut = NULL; + return NULL; + } + } + count -= frames; + } + + snd_pcm_prepare(sndOut); + } + return NULL; +} + +bool sndInit() { + unsigned int freq = 44100; + + int err; + + for (int i = 0; i < 20; i++) { // 20 * 0.1 = 2 secs + sndOut = NULL; + if ((err = snd_pcm_open(&sndOut, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) { + LOG("sound: try to snd_pcm_open #%d...\n", i); + usleep(100000); // wait for 100 ms + continue; + } + break; + } + + // I've bad news for you + if (!sndOut) { + LOG("! sound: snd_pcm_open %s\n", snd_strerror(err)); + return false; + } + + snd_pcm_hw_params_t *params; + + snd_pcm_hw_params_alloca(¶ms); + snd_pcm_hw_params_any(sndOut, params); + snd_pcm_hw_params_set_access(sndOut, params, SND_PCM_ACCESS_RW_INTERLEAVED); + + snd_pcm_hw_params_set_channels(sndOut, params, 2); + snd_pcm_hw_params_set_format(sndOut, params, SND_PCM_FORMAT_S16_LE); + snd_pcm_hw_params_set_rate_near(sndOut, params, &freq, NULL); + + snd_pcm_hw_params_set_periods(sndOut, params, 4, 0); + snd_pcm_hw_params_set_period_size_near(sndOut, params, &SND_FRAMES, NULL); + snd_pcm_hw_params_get_period_size(params, &SND_FRAMES, 0); + + snd_pcm_hw_params(sndOut, params); + snd_pcm_prepare(sndOut); + + sndData = new Sound::Frame[SND_FRAMES]; + memset(sndData, 0, SND_FRAMES * sizeof(Sound::Frame)); + if ((err = snd_pcm_writei(sndOut, sndData, SND_FRAMES)) < 0) { + LOG("! sound: write %s\n", snd_strerror(err)); + sndOut = NULL; + } + + snd_pcm_start(sndOut); + pthread_create(&sndThread, NULL, sndFill, NULL); + + return true; +} + +void sndFree() { + pthread_cancel(sndThread); + snd_pcm_drop(sndOut); + snd_pcm_drain(sndOut); + snd_pcm_close(sndOut); + delete[] sndData; +} + // input bool osJoyReady(int index) { return index == 0; @@ -40,10 +145,21 @@ void osJoyVibrate(int index, float L, float R) { JoyKey getJoyKey(int key) { switch (key) { +#ifdef __MIYOO__ + case BTN_A : return jkA; + case BTN_B : return jkB; + case BTN_X : return jkX; + case BTN_Y : return jkY; + case BTN_L1 : return jkLB; + case BTN_R1 : return jkRB; + case BTN_L2 : return jkLT; + case BTN_R2 : return jkRT; +#else case BTN_B : return jkX; case BTN_A : return jkA; case BTN_TA : return jkRB; case BTN_TB : return jkY; +#endif case BTN_START : return jkStart; case BTN_SELECT : return jkSelect; case BTN_UP : return jkUp; @@ -68,11 +184,13 @@ int main() { Core::defLang = 0; - Game::init("/mnt/games/OpenLara/LEVEL2.PSX"); + Game::init((const char *)NULL); GAPI::resize(); GAPI::swColor = (uint16*)screen->pixels; + sndInit(); + bool isQuit = false; while (!isQuit) { @@ -98,5 +216,7 @@ int main() { Game::deinit(); + sndFree(); + return 0; }