add to sound loop
This commit is contained in:
parent
9a9a714da3
commit
9754df3fea
57
docs/config/the-house-of-the-dead-4-special.conf
Normal file
57
docs/config/the-house-of-the-dead-4-special.conf
Normal file
@ -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
|
@ -136,64 +136,34 @@ ALsizei FramesToBytes(ALsizei size, ALenum channels, ALenum type)
|
|||||||
return size;
|
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)
|
static void updateBufferData(SEGAContext *context, unsigned int offset, size_t length)
|
||||||
{
|
{
|
||||||
|
|
||||||
ALenum alFormat = -1;
|
ALenum alFormat = -1;
|
||||||
ALenum alChannels = -1;
|
|
||||||
ALenum alType;
|
|
||||||
|
|
||||||
switch (context->sampleFormat)
|
switch (context->sampleFormat)
|
||||||
{
|
{
|
||||||
case UNSIGNED_8PCM: /* Unsigned (offset 128) 8-bit PCM */
|
case UNSIGNED_8PCM: /* Unsigned (offset 128) 8-bit PCM */
|
||||||
alType = AL_BYTE_SOFT;
|
|
||||||
switch (context->channels)
|
switch (context->channels)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
alFormat = AL_MONO8_SOFT;
|
alFormat = AL_MONO8_SOFT;
|
||||||
alChannels = AL_MONO_SOFT;
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
alFormat = AL_STEREO8_SOFT;
|
alFormat = AL_STEREO8_SOFT;
|
||||||
alChannels = AL_STEREO_SOFT;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SIGNED_16PCM: /* Signed 16-bit PCM */
|
case SIGNED_16PCM: /* Signed 16-bit PCM */
|
||||||
alType = AL_SHORT_SOFT;
|
|
||||||
switch (context->channels)
|
switch (context->channels)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
alFormat = AL_MONO16_SOFT;
|
alFormat = AL_MONO16_SOFT;
|
||||||
alChannels = AL_MONO_SOFT;
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
alFormat = AL_STEREO16_SOFT;
|
alFormat = AL_STEREO16_SOFT;
|
||||||
alChannels = AL_STEREO_SOFT;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -208,40 +178,24 @@ static void updateBufferData(SEGAContext *context, unsigned int offset, size_t l
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset != -1)
|
if(context->loop) {
|
||||||
{
|
|
||||||
|
|
||||||
unsigned int sampleSize = bufferSampleSize(context);
|
|
||||||
|
|
||||||
ALint position;
|
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);
|
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, context->size, context->sampleRate);
|
||||||
alBufferData(context->alBuffer, alFormat, context->data, FramesToBytes(context->size / bufferSampleSize(context), alChannels, alType), context->sampleRate);
|
|
||||||
alSourcei(context->alSource, AL_BUFFER, context->alBuffer);
|
alSourcei(context->alSource, AL_BUFFER, context->alBuffer);
|
||||||
alSourcei(context->alSource, AL_SAMPLE_OFFSET, position);
|
alSourcei(context->alSource, AL_BYTE_OFFSET, position);
|
||||||
return;
|
alSourcePlay(context->alSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
alSourcei(context->alSource, AL_BUFFER, AL_NONE);
|
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);
|
alSourcei(context->alSource, AL_BUFFER, context->alBuffer);
|
||||||
|
|
||||||
// updateBufferLoop(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resetBuffer(SEGAContext *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->startLoop = 0;
|
||||||
context->endOffset = context->size;
|
context->endOffset = context->size;
|
||||||
@ -283,10 +237,13 @@ int SEGAAPI_Play(void *hHandle)
|
|||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
return SEGA_ERROR_BAD_PARAM;
|
return SEGA_ERROR_BAD_PARAM;
|
||||||
|
|
||||||
// alSourcei(context->alSource, AL_LOOPING, context->loop ? AL_TRUE : AL_FALSE);
|
alSourcei(context->alSource, AL_LOOPING, context->loop ? AL_TRUE : AL_FALSE);
|
||||||
alSourcei(context->alSource, AL_LOOPING, AL_FALSE);
|
//alSourcei(context->alSource, AL_LOOPING, AL_FALSE);
|
||||||
alSourcei(context->alSource, AL_BUFFER, context->alBuffer);
|
|
||||||
|
context->playing = true;
|
||||||
|
|
||||||
alSourcePlay(context->alSource);
|
alSourcePlay(context->alSource);
|
||||||
|
|
||||||
return SEGA_SUCCESS;
|
return SEGA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,6 +267,8 @@ int SEGAAPI_Stop(void *hHandle)
|
|||||||
|
|
||||||
alSourceStop(context->alSource);
|
alSourceStop(context->alSource);
|
||||||
|
|
||||||
|
context->playing = false;
|
||||||
|
|
||||||
return SEGA_SUCCESS;
|
return SEGA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,7 +469,6 @@ int SEGAAPI_SetStartLoopOffset(void *hHandle, unsigned int dwOffset)
|
|||||||
SEGAContext *context = hHandle;
|
SEGAContext *context = hHandle;
|
||||||
|
|
||||||
context->startLoop = dwOffset;
|
context->startLoop = dwOffset;
|
||||||
updateBufferLoop(context);
|
|
||||||
|
|
||||||
return SEGA_SUCCESS;
|
return SEGA_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -534,7 +492,6 @@ int SEGAAPI_SetEndLoopOffset(void *hHandle, unsigned int dwOffset)
|
|||||||
|
|
||||||
SEGAContext *context = hHandle;
|
SEGAContext *context = hHandle;
|
||||||
context->endLoop = dwOffset;
|
context->endLoop = dwOffset;
|
||||||
updateBufferLoop(context);
|
|
||||||
|
|
||||||
return SEGA_SUCCESS;
|
return SEGA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -48,10 +48,21 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr)
|
|||||||
|
|
||||||
switch (*code)
|
switch (*code)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
case 0xE4:
|
||||||
|
case 0xE5:
|
||||||
|
case 0xEC:
|
||||||
|
{
|
||||||
|
printf("UN IMPLELMENTED ASM IN CALL\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
case 0xED:
|
case 0xED:
|
||||||
{
|
{
|
||||||
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
|
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
|
// The first port called is usually random, but everything after that
|
||||||
// is a constant offset, so this is a hack to fix that.
|
// is a constant offset, so this is a hack to fix that.
|
||||||
// When run as sudo it works fine!?
|
// When run as sudo it works fine!?
|
||||||
@ -69,25 +80,50 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr)
|
|||||||
}
|
}
|
||||||
break;
|
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;
|
ctx->uc_mcontext.gregs[REG_EIP] += 2;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
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;
|
ctx->uc_mcontext.gregs[REG_EIP] += 2;
|
||||||
|
abort();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xEE: // OUT
|
case 0xEE: // OUT
|
||||||
{
|
{
|
||||||
|
|
||||||
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
|
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
|
||||||
uint8_t data = ctx->uc_mcontext.gregs[REG_EAX] & 0xFF;
|
uint8_t data = ctx->uc_mcontext.gregs[REG_EAX] & 0xFF;
|
||||||
|
|
||||||
|
|
||||||
|
printf("EE OUT %X, %X\n", port, data);
|
||||||
|
|
||||||
ctx->uc_mcontext.gregs[REG_EIP]++;
|
ctx->uc_mcontext.gregs[REG_EIP]++;
|
||||||
|
abort();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -95,7 +131,11 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr)
|
|||||||
case 0xEF: // OUT
|
case 0xEF: // OUT
|
||||||
{
|
{
|
||||||
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
|
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]++;
|
ctx->uc_mcontext.gregs[REG_EIP]++;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -103,8 +143,9 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr)
|
|||||||
default:
|
default:
|
||||||
printf("Warning: Skipping SEGFAULT %X\n", *code);
|
printf("Warning: Skipping SEGFAULT %X\n", *code);
|
||||||
ctx->uc_mcontext.gregs[REG_EIP]++;
|
ctx->uc_mcontext.gregs[REG_EIP]++;
|
||||||
// abort();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__((constructor)) hook_init()
|
void __attribute__((constructor)) hook_init()
|
||||||
|
@ -95,6 +95,7 @@ int securityBoardSetSwitch(JVSInput switchNumber, int value)
|
|||||||
|
|
||||||
int securityBoardOut(uint16_t port, uint32_t *data)
|
int securityBoardOut(uint16_t port, uint32_t *data)
|
||||||
{
|
{
|
||||||
|
printf("OUT(%X, %X%X)\n", port, *data >> 8 & 0XFF, *data & 0XFF);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +103,31 @@ int securityBoardIn(uint16_t port, uint32_t *data)
|
|||||||
{
|
{
|
||||||
switch (port)
|
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_NON_ROOT:
|
||||||
case SECURITY_BOARD_FRONT_PANEL:
|
case SECURITY_BOARD_FRONT_PANEL:
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user