From 9754df3fea4e25bfc886a076dda0af02e855819f Mon Sep 17 00:00:00 2001 From: Bobby Dilley Date: Sun, 5 Feb 2023 21:50:23 +0000 Subject: [PATCH] add to sound loop --- .../the-house-of-the-dead-4-special.conf | 57 ++++++++++++++ src/libsegaapi/segaapi.c | 77 ++++--------------- src/lindbergh/hook.c | 47 ++++++++++- src/lindbergh/securityboard.c | 26 +++++++ 4 files changed, 144 insertions(+), 63 deletions(-) create mode 100644 docs/config/the-house-of-the-dead-4-special.conf diff --git a/docs/config/the-house-of-the-dead-4-special.conf b/docs/config/the-house-of-the-dead-4-special.conf new file mode 100644 index 0000000..79d33e2 --- /dev/null +++ b/docs/config/the-house-of-the-dead-4-special.conf @@ -0,0 +1,57 @@ +# SEGA Lindbergh Emulator Configuration File +# Written by Bobby Dilley + +# Set the colour of the lindbergh to change the Segaboot logo +# Possibly colours are: YELLOW and RED +LINDBERGH_COLOUR YELLOW + +# Choice of resolutions +# 640 x 480 +# 800 x 600 +# 1024 x 768 +# 1280 x 1024 +# 800 x 480 +# 1024 x 600 +# 1280 x 768 +# 1360 x 768 + +# Set the requested dip switch width here +WIDTH 1024 + +# Set the requested dip switch height here +HEIGHT 768 + +# Set if the emulator should emulate the rideboard used in the special games here +# If this is set to 0, then the emulator will route the traffic to the serial device +# defined in RIDEBOARD_PATH if it has been defined. +EMULATE_RIDEBOARD 1 + +# Set if the emulator should emulate the driveboard used in driving games here +# If this is set to 0, then the emulator will route the traffic to the serial device +# defined in DRIVEBOARD_PATH if it has been defined. +EMULATE_DRIVEBOARD 0 + +# Set if the emulator should emulate the motion board from Outrun 2 SP SDX here +# If this is set to 0, then the emulator will route the traffic to the serial device +# defined in MOTIONBOARD_PATH if it has been defined. +EMULATE_MOTIONBOARD 0 + +# Set if the emulator should emulate JVS and use the keyboard/mouse for controls. +# If this is set to 0, then the emulator will route the traffic to the serial device +# defined in RIDEBOARD_PATH if it has been defined. +EMULATE_JVS 1 + +# Define the path to pass the JVS packets to +# JVS_PATH /dev/ttyUSB0 + +# Define the path to pass the rideboard packets to +# RIDEBOARD_PATH /dev/ttyUSB0 + +# Define the path to pass the driveboard packets to +# DRIVEBOARD_PATH /dev/ttyUSB0 + +# Define the path to pass the motionboard packets to +# MOTIONBOARD_PATH /dev/ttyUSB0 + +# Set if the emulator should go full screen +FULLSCREEN 0 diff --git a/src/libsegaapi/segaapi.c b/src/libsegaapi/segaapi.c index 28b7dcf..edcbdf8 100644 --- a/src/libsegaapi/segaapi.c +++ b/src/libsegaapi/segaapi.c @@ -136,64 +136,34 @@ ALsizei FramesToBytes(ALsizei size, ALenum channels, ALenum type) return size; } -static unsigned int bufferSampleSize(SEGAContext *context) -{ - return context->channels * ((context->sampleFormat == SIGNED_16PCM) ? 2 : 1); -} - -static void updateBufferLoop(SEGAContext *context) -{ - return; - if (context == NULL) - return; - - unsigned int sampleSize = bufferSampleSize(context); - alSourcei(context->alSource, AL_BUFFER, AL_NONE); - - /* - FIXME: Re-enable, only crashed before - so fix this too.. - ALint loopPoints[] = { buffer->startLoop / sampleSize, buffer->endLoop / sampleSize }; - alBufferiv(buffer->alBuffer,AL_LOOP_POINTS_SOFT,loopPoints); - CHECK(); - */ -} - static void updateBufferData(SEGAContext *context, unsigned int offset, size_t length) { ALenum alFormat = -1; - ALenum alChannels = -1; - ALenum alType; - + switch (context->sampleFormat) { case UNSIGNED_8PCM: /* Unsigned (offset 128) 8-bit PCM */ - alType = AL_BYTE_SOFT; switch (context->channels) { case 1: alFormat = AL_MONO8_SOFT; - alChannels = AL_MONO_SOFT; break; case 2: alFormat = AL_STEREO8_SOFT; - alChannels = AL_STEREO_SOFT; break; default: break; } break; case SIGNED_16PCM: /* Signed 16-bit PCM */ - alType = AL_SHORT_SOFT; switch (context->channels) { case 1: alFormat = AL_MONO16_SOFT; - alChannels = AL_MONO_SOFT; break; case 2: alFormat = AL_STEREO16_SOFT; - alChannels = AL_STEREO_SOFT; break; default: break; @@ -208,40 +178,24 @@ static void updateBufferData(SEGAContext *context, unsigned int offset, size_t l abort(); } - if (offset != -1) - { - - unsigned int sampleSize = bufferSampleSize(context); - + if(context->loop) { ALint position; - alGetSourcei(context->alSource, AL_SAMPLE_OFFSET, &position); - + alGetSourcei(context->alSource, AL_BYTE_OFFSET, &position); + alSourceStop(context->alSource); alSourcei(context->alSource, AL_BUFFER, AL_NONE); - // alBufferData(context->alBuffer, alFormat, context->data + (offset / sampleSize), FramesToBytes(context->size / bufferSampleSize(context), alChannels, alType), context->sampleRate); - alBufferData(context->alBuffer, alFormat, context->data, FramesToBytes(context->size / bufferSampleSize(context), alChannels, alType), context->sampleRate); + alBufferData(context->alBuffer, alFormat, context->data, context->size, context->sampleRate); alSourcei(context->alSource, AL_BUFFER, context->alBuffer); - alSourcei(context->alSource, AL_SAMPLE_OFFSET, position); - return; + alSourcei(context->alSource, AL_BYTE_OFFSET, position); + alSourcePlay(context->alSource); } alSourcei(context->alSource, AL_BUFFER, AL_NONE); - alBufferData(context->alBuffer, alFormat, context->data, FramesToBytes(context->size / bufferSampleSize(context), alChannels, alType), context->sampleRate); + alBufferData(context->alBuffer, alFormat, context->data, context->size, context->sampleRate); alSourcei(context->alSource, AL_BUFFER, context->alBuffer); - - // updateBufferLoop(context); } static void resetBuffer(SEGAContext *context) -{ // printf("%s %d\n", __func__, __LINE__); - // * - Send Routing - // * - for 1 channel buffer, channel is routed to Front-Left and Front-Right. - // * - for 2 channel buffer, channel 0 is routed Front-Left, channel 1 is routed Front-Right - // * - Send Levels are set to 0 (infinite attenuation) - // * - Channel Volume is set to 0xFFFFFFFF (no attenuation) - // * - No notification. - // * - StartLoopOffset is set to 0. - // * - EndLoopOffset and EndOffset are set to pConfig->mapdata.dwSize. - // * - No loop. +{ context->startLoop = 0; context->endOffset = context->size; @@ -283,10 +237,13 @@ int SEGAAPI_Play(void *hHandle) if (context == NULL) return SEGA_ERROR_BAD_PARAM; - // alSourcei(context->alSource, AL_LOOPING, context->loop ? AL_TRUE : AL_FALSE); - alSourcei(context->alSource, AL_LOOPING, AL_FALSE); - alSourcei(context->alSource, AL_BUFFER, context->alBuffer); + alSourcei(context->alSource, AL_LOOPING, context->loop ? AL_TRUE : AL_FALSE); + //alSourcei(context->alSource, AL_LOOPING, AL_FALSE); + + context->playing = true; + alSourcePlay(context->alSource); + return SEGA_SUCCESS; } @@ -310,6 +267,8 @@ int SEGAAPI_Stop(void *hHandle) alSourceStop(context->alSource); + context->playing = false; + return SEGA_SUCCESS; } @@ -510,7 +469,6 @@ int SEGAAPI_SetStartLoopOffset(void *hHandle, unsigned int dwOffset) SEGAContext *context = hHandle; context->startLoop = dwOffset; - updateBufferLoop(context); return SEGA_SUCCESS; } @@ -534,7 +492,6 @@ int SEGAAPI_SetEndLoopOffset(void *hHandle, unsigned int dwOffset) SEGAContext *context = hHandle; context->endLoop = dwOffset; - updateBufferLoop(context); return SEGA_SUCCESS; } diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index e117423..6b814f5 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -48,10 +48,21 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr) switch (*code) { + + case 0xE4: + case 0xE5: + case 0xEC: + { + printf("UN IMPLELMENTED ASM IN CALL\n"); + abort(); + } + case 0xED: { uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF; + printf("ED IN %X\n", port); + // The first port called is usually random, but everything after that // is a constant offset, so this is a hack to fix that. // When run as sudo it works fine!? @@ -69,25 +80,50 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr) } break; - case 0xE7: // OUT IMMIDIATE + case 0xE6: // OUT IMMIDIATE { + uint8_t port = *((uint8_t *)ctx->uc_mcontext.gregs[REG_EIP] + 1); + uint8_t data = ctx->uc_mcontext.gregs[REG_EAX] & 0xFF; + + if(port != 0x80) { + printf("E6 OUT %X, %X\n", port, data); + + } + + ctx->uc_mcontext.gregs[REG_EIP] += 2; + return; } break; - case 0xE6: // OUT IMMIDIATE + case 0xE7: // OUT IMMIDIATE { + uint8_t port = *((uint8_t *)ctx->uc_mcontext.gregs[REG_EIP] + 1); + uint32_t data = ctx->uc_mcontext.gregs[REG_EAX]; + + printf("E7 OUT %X, %X\n", port, data); + + ctx->uc_mcontext.gregs[REG_EIP] += 2; + abort(); + return; } break; case 0xEE: // OUT { + uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF; uint8_t data = ctx->uc_mcontext.gregs[REG_EAX] & 0xFF; + + + printf("EE OUT %X, %X\n", port, data); + ctx->uc_mcontext.gregs[REG_EIP]++; + abort(); + return; } break; @@ -95,7 +131,11 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr) case 0xEF: // OUT { uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF; + uint8_t data = ctx->uc_mcontext.gregs[REG_EAX] & 0xFFFF; + + printf("EF OUT %X, %X\n", port, data); ctx->uc_mcontext.gregs[REG_EIP]++; + return; } break; @@ -103,8 +143,9 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr) default: printf("Warning: Skipping SEGFAULT %X\n", *code); ctx->uc_mcontext.gregs[REG_EIP]++; - // abort(); + return; } + } void __attribute__((constructor)) hook_init() diff --git a/src/lindbergh/securityboard.c b/src/lindbergh/securityboard.c index e2e4238..d5aa6bf 100644 --- a/src/lindbergh/securityboard.c +++ b/src/lindbergh/securityboard.c @@ -95,6 +95,7 @@ int securityBoardSetSwitch(JVSInput switchNumber, int value) int securityBoardOut(uint16_t port, uint32_t *data) { + printf("OUT(%X, %X%X)\n", port, *data >> 8 & 0XFF, *data & 0XFF); return 0; } @@ -102,6 +103,31 @@ int securityBoardIn(uint16_t port, uint32_t *data) { switch (port) { + case 0x28: + { + static int meme = 0; + static int n = 0; + + + if(meme == 0) { + meme++; + uint32_t result = 0xFFFFFFFF; + printf("flip\n"); + + *data = result; + } else { + meme = 0; + uint32_t result = 0x00000001 << n; + n++; + *data = result; + printf("flop return %d\n", result); + + } + + + + + } case SECURITY_BOARD_FRONT_PANEL_NON_ROOT: case SECURITY_BOARD_FRONT_PANEL: {