mirror of
https://github.com/mupen64plus/mupen64plus-rsp-hle.git
synced 2025-04-02 10:31:57 -04:00
Allow to pass a user-defined object to "external" functions.
This commit is contained in:
parent
9e482edcc9
commit
be21b61d9a
11 changed files with 151 additions and 121 deletions
12
src/alist.c
12
src/alist.c
|
@ -100,30 +100,30 @@ void alist_process(struct hle_t* hle, const acmd_callback_t abi[], unsigned int
|
||||||
if (acmd < abi_size)
|
if (acmd < abi_size)
|
||||||
(*abi[acmd])(hle, w1, w2);
|
(*abi[acmd])(hle, w1, w2);
|
||||||
else
|
else
|
||||||
WarnMessage("Invalid ABI command %u", acmd);
|
HleWarnMessage(hle->user_defined, "Invalid ABI command %u", acmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t alist_get_address(uint32_t so, const uint32_t *segments, size_t n)
|
uint32_t alist_get_address(struct hle_t* hle, uint32_t so, const uint32_t *segments, size_t n)
|
||||||
{
|
{
|
||||||
uint8_t segment = (so >> 24);
|
uint8_t segment = (so >> 24);
|
||||||
uint32_t offset = (so & 0xffffff);
|
uint32_t offset = (so & 0xffffff);
|
||||||
|
|
||||||
if (segment >= n) {
|
if (segment >= n) {
|
||||||
WarnMessage("Invalid segment %u", segment);
|
HleWarnMessage(hle->user_defined, "Invalid segment %u", segment);
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return segments[segment] + offset;
|
return segments[segment] + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_set_address(uint32_t so, uint32_t *segments, size_t n)
|
void alist_set_address(struct hle_t* hle, uint32_t so, uint32_t *segments, size_t n)
|
||||||
{
|
{
|
||||||
uint8_t segment = (so >> 24);
|
uint8_t segment = (so >> 24);
|
||||||
uint32_t offset = (so & 0xffffff);
|
uint32_t offset = (so & 0xffffff);
|
||||||
|
|
||||||
if (segment >= n) {
|
if (segment >= n) {
|
||||||
WarnMessage("Invalid segment %u", segment);
|
HleWarnMessage(hle->user_defined, "Invalid segment %u", segment);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,7 +563,7 @@ void alist_resample(
|
||||||
ipos -= 4;
|
ipos -= 4;
|
||||||
|
|
||||||
if (flag2)
|
if (flag2)
|
||||||
WarnMessage("alist_resample: flag2 is not implemented");
|
HleWarnMessage(hle->user_defined, "alist_resample: flag2 is not implemented");
|
||||||
|
|
||||||
if (init)
|
if (init)
|
||||||
alist_resample_reset(hle, ipos, &pitch_accu);
|
alist_resample_reset(hle, ipos, &pitch_accu);
|
||||||
|
|
|
@ -34,12 +34,12 @@ enum { DMEM_BASE = 0x5c0 };
|
||||||
/* helper functions */
|
/* helper functions */
|
||||||
static uint32_t get_address(struct hle_t* hle, uint32_t so)
|
static uint32_t get_address(struct hle_t* hle, uint32_t so)
|
||||||
{
|
{
|
||||||
return alist_get_address(so, hle->alist_audio.segments, N_SEGMENTS);
|
return alist_get_address(hle, so, hle->alist_audio.segments, N_SEGMENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_address(struct hle_t* hle, uint32_t so)
|
static void set_address(struct hle_t* hle, uint32_t so)
|
||||||
{
|
{
|
||||||
alist_set_address(so, hle->alist_audio.segments, N_SEGMENTS);
|
alist_set_address(hle, so, hle->alist_audio.segments, N_SEGMENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_segments(struct hle_t* hle)
|
static void clear_segments(struct hle_t* hle)
|
||||||
|
|
|
@ -31,8 +31,8 @@ struct hle_t;
|
||||||
typedef void (*acmd_callback_t)(struct hle_t* hle, uint32_t w1, uint32_t w2);
|
typedef void (*acmd_callback_t)(struct hle_t* hle, uint32_t w1, uint32_t w2);
|
||||||
|
|
||||||
void alist_process(struct hle_t* hle, const acmd_callback_t abi[], unsigned int abi_size);
|
void alist_process(struct hle_t* hle, const acmd_callback_t abi[], unsigned int abi_size);
|
||||||
uint32_t alist_get_address(uint32_t so, const uint32_t *segments, size_t n);
|
uint32_t alist_get_address(struct hle_t* hle, uint32_t so, const uint32_t *segments, size_t n);
|
||||||
void alist_set_address(uint32_t so, uint32_t *segments, size_t n);
|
void alist_set_address(struct hle_t* hle, uint32_t so, uint32_t *segments, size_t n);
|
||||||
void alist_clear(struct hle_t* hle, uint16_t dmem, uint16_t count);
|
void alist_clear(struct hle_t* hle, uint16_t dmem, uint16_t count);
|
||||||
void alist_load(struct hle_t* hle, uint16_t dmem, uint32_t address, uint16_t count);
|
void alist_load(struct hle_t* hle, uint16_t dmem, uint32_t address, uint16_t count);
|
||||||
void alist_save(struct hle_t* hle, uint16_t dmem, uint32_t address, uint16_t count);
|
void alist_save(struct hle_t* hle, uint16_t dmem, uint32_t address, uint16_t count);
|
||||||
|
|
|
@ -47,7 +47,8 @@ static void UNKNOWN(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t acmd = (w1 >> 24);
|
uint8_t acmd = (w1 >> 24);
|
||||||
|
|
||||||
WarnMessage("Unknown audio command %d: %08x %08x",
|
HleWarnMessage(hle->user_defined,
|
||||||
|
"Unknown audio command %d: %08x %08x",
|
||||||
acmd, w1, w2);
|
acmd, w1, w2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +91,8 @@ static void NAUDIO_14(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
address);
|
address);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
WarnMessage("NAUDIO_14: non null codebook[0-3] case not implemented.");
|
HleWarnMessage(hle->user_defined,
|
||||||
|
"NAUDIO_14: non null codebook[0-3] case not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SETVOL(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
static void SETVOL(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
|
|
|
@ -39,7 +39,8 @@ static void UNKNOWN(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t acmd = (w1 >> 24);
|
uint8_t acmd = (w1 >> 24);
|
||||||
|
|
||||||
WarnMessage("Unknown audio command %d: %08x %08x",
|
HleWarnMessage(hle->user_defined,
|
||||||
|
"Unknown audio command %d: %08x %08x",
|
||||||
acmd, w1, w2);
|
acmd, w1, w2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
src/jpeg.c
12
src/jpeg.c
|
@ -168,7 +168,8 @@ void jpeg_decode_OB(struct hle_t* hle)
|
||||||
const unsigned int macroblock_count = *dmem_u32(hle, TASK_DATA_SIZE);
|
const unsigned int macroblock_count = *dmem_u32(hle, TASK_DATA_SIZE);
|
||||||
const int qscale = *dmem_u32(hle, TASK_YIELD_DATA_SIZE);
|
const int qscale = *dmem_u32(hle, TASK_YIELD_DATA_SIZE);
|
||||||
|
|
||||||
VerboseMessage("jpeg_decode_OB: *buffer=%x, #MB=%d, qscale=%d",
|
HleVerboseMessage(hle->user_defined,
|
||||||
|
"jpeg_decode_OB: *buffer=%x, #MB=%d, qscale=%d",
|
||||||
address,
|
address,
|
||||||
macroblock_count,
|
macroblock_count,
|
||||||
qscale);
|
qscale);
|
||||||
|
@ -214,7 +215,8 @@ static void jpeg_decode_std(struct hle_t* hle,
|
||||||
uint32_t data_ptr;
|
uint32_t data_ptr;
|
||||||
|
|
||||||
if (*dmem_u32(hle, TASK_FLAGS) & 0x1) {
|
if (*dmem_u32(hle, TASK_FLAGS) & 0x1) {
|
||||||
WarnMessage("jpeg_decode_%s: task yielding not implemented", version);
|
HleWarnMessage(hle->user_defined,
|
||||||
|
"jpeg_decode_%s: task yielding not implemented", version);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,7 +228,8 @@ static void jpeg_decode_std(struct hle_t* hle,
|
||||||
qtableU_ptr = *dram_u32(hle, data_ptr + 16);
|
qtableU_ptr = *dram_u32(hle, data_ptr + 16);
|
||||||
qtableV_ptr = *dram_u32(hle, data_ptr + 20);
|
qtableV_ptr = *dram_u32(hle, data_ptr + 20);
|
||||||
|
|
||||||
VerboseMessage("jpeg_decode_%s: *buffer=%x, #MB=%d, mode=%d, *Qy=%x, *Qu=%x, *Qv=%x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
|
"jpeg_decode_%s: *buffer=%x, #MB=%d, mode=%d, *Qy=%x, *Qu=%x, *Qv=%x",
|
||||||
version,
|
version,
|
||||||
address,
|
address,
|
||||||
macroblock_count,
|
macroblock_count,
|
||||||
|
@ -236,7 +239,8 @@ static void jpeg_decode_std(struct hle_t* hle,
|
||||||
qtableV_ptr);
|
qtableV_ptr);
|
||||||
|
|
||||||
if (mode != 0 && mode != 2) {
|
if (mode != 0 && mode != 2) {
|
||||||
WarnMessage("jpeg_decode_%s: invalid mode %d", version, mode);
|
HleWarnMessage(hle->user_defined,
|
||||||
|
"jpeg_decode_%s: invalid mode %d", version, mode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
src/main.c
22
src/main.c
|
@ -119,13 +119,13 @@ static void rsp_break(struct hle_t* hle, unsigned int setbits)
|
||||||
|
|
||||||
if ((*hle->sp_status & SP_STATUS_INTR_ON_BREAK)) {
|
if ((*hle->sp_status & SP_STATUS_INTR_ON_BREAK)) {
|
||||||
*hle->mi_intr |= MI_INTR_SP;
|
*hle->mi_intr |= MI_INTR_SP;
|
||||||
CheckInterrupts();
|
HleCheckInterrupts(hle->user_defined);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void forward_gfx_task(struct hle_t* hle)
|
static void forward_gfx_task(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
ProcessDlistList();
|
HleProcessDlistList(hle->user_defined);
|
||||||
*hle->dpc_status &= ~DP_STATUS_FREEZE;
|
*hle->dpc_status &= ~DP_STATUS_FREEZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ static bool try_fast_audio_dispatching(struct hle_t* hle)
|
||||||
case 0x1e3c1390: /* BlastCorp, DiddyKongRacing */
|
case 0x1e3c1390: /* BlastCorp, DiddyKongRacing */
|
||||||
alist_process_audio_bc(hle); return true;
|
alist_process_audio_bc(hle); return true;
|
||||||
default:
|
default:
|
||||||
WarnMessage("ABI1 identification regression: v=%08x", v);
|
HleWarnMessage(hle->user_defined, "ABI1 identification regression: v=%08x", v);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
v = *dram_u32(hle, ucode_data + 0x10);
|
v = *dram_u32(hle, ucode_data + 0x10);
|
||||||
|
@ -179,7 +179,7 @@ static bool try_fast_audio_dispatching(struct hle_t* hle)
|
||||||
musyx_v2_task(hle); return true;
|
musyx_v2_task(hle); return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WarnMessage("ABI2 identification regression: v=%08x", v);
|
HleWarnMessage(hle->user_defined, "ABI2 identification regression: v=%08x", v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -203,7 +203,7 @@ static bool try_fast_audio_dispatching(struct hle_t* hle)
|
||||||
alist_process_naudio_cbfd(hle); return true;
|
alist_process_naudio_cbfd(hle); return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WarnMessage("ABI3 identification regression: v=%08x", v);
|
HleWarnMessage(hle->user_defined, "ABI3 identification regression: v=%08x", v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,14 +223,14 @@ static bool try_fast_task_dispatching(struct hle_t* hle)
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
if (FORWARD_AUDIO) {
|
if (FORWARD_AUDIO) {
|
||||||
ProcessAlistList();
|
HleProcessAlistList(hle->user_defined);
|
||||||
return true;
|
return true;
|
||||||
} else if (try_fast_audio_dispatching(hle))
|
} else if (try_fast_audio_dispatching(hle))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
ShowCFB();
|
HleShowCFB(hle->user_defined);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +273,7 @@ static void normal_task_dispatching(struct hle_t* hle)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WarnMessage("unknown OSTask: sum: %x PC:%x", sum, *hle->sp_pc);
|
HleWarnMessage(hle->user_defined, "unknown OSTask: sum: %x PC:%x", sum, *hle->sp_pc);
|
||||||
#ifdef ENABLE_TASK_DUMP
|
#ifdef ENABLE_TASK_DUMP
|
||||||
dump_unknown_task(hle, sum);
|
dump_unknown_task(hle, sum);
|
||||||
#endif
|
#endif
|
||||||
|
@ -291,7 +291,7 @@ static void non_task_dispatching(struct hle_t* hle)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WarnMessage("unknown RSP code: sum: %x PC:%x", sum, *hle->sp_pc);
|
HleWarnMessage(hle->user_defined, "unknown RSP code: sum: %x PC:%x", sum, *hle->sp_pc);
|
||||||
#ifdef ENABLE_TASK_DUMP
|
#ifdef ENABLE_TASK_DUMP
|
||||||
dump_unknown_non_task(hle, sum);
|
dump_unknown_non_task(hle, sum);
|
||||||
#endif
|
#endif
|
||||||
|
@ -356,10 +356,10 @@ static void dump_binary(const char *const filename, const unsigned char *const b
|
||||||
f = fopen(filename, "wb");
|
f = fopen(filename, "wb");
|
||||||
if (f != NULL) {
|
if (f != NULL) {
|
||||||
if (fwrite(bytes, 1, size, f) != size)
|
if (fwrite(bytes, 1, size, f) != size)
|
||||||
ErrorMessage("Writing error on %s", filename);
|
hleErrorMessage(hle->user_defined, "Writing error on %s", filename);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
} else
|
} else
|
||||||
ErrorMessage("Couldn't open %s for writing !", filename);
|
hleErrorMessage(hle->user_defined, "Couldn't open %s for writing !", filename);
|
||||||
} else
|
} else
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,9 @@ struct hle_t
|
||||||
uint32_t mp3_t6;
|
uint32_t mp3_t6;
|
||||||
uint32_t mp3_t5;
|
uint32_t mp3_t5;
|
||||||
uint32_t mp3_t4;
|
uint32_t mp3_t4;
|
||||||
|
|
||||||
|
/* for user convenience, ths will be passed to "external" functions */
|
||||||
|
void* user_defined;
|
||||||
};
|
};
|
||||||
|
|
||||||
void hle_execute(struct hle_t* hle);
|
void hle_execute(struct hle_t* hle);
|
||||||
|
|
75
src/musyx.c
75
src/musyx.c
|
@ -151,7 +151,8 @@ static void load_samples_PCM16(struct hle_t* hle, uint32_t voice_ptr, int16_t *s
|
||||||
static void load_samples_ADPCM(struct hle_t* hle, uint32_t voice_ptr, int16_t *samples,
|
static void load_samples_ADPCM(struct hle_t* hle, uint32_t voice_ptr, int16_t *samples,
|
||||||
unsigned *segbase, unsigned *offset);
|
unsigned *segbase, unsigned *offset);
|
||||||
|
|
||||||
static void adpcm_decode_frames(int16_t *dst, const uint8_t *src,
|
static void adpcm_decode_frames(struct hle_t* hle,
|
||||||
|
int16_t *dst, const uint8_t *src,
|
||||||
const int16_t *table, uint8_t count,
|
const int16_t *table, uint8_t count,
|
||||||
uint8_t skip_samples);
|
uint8_t skip_samples);
|
||||||
|
|
||||||
|
@ -205,7 +206,8 @@ void musyx_v1_task(struct hle_t* hle)
|
||||||
uint32_t state_ptr;
|
uint32_t state_ptr;
|
||||||
musyx_t musyx;
|
musyx_t musyx;
|
||||||
|
|
||||||
VerboseMessage("musyx_v1_task: *data=%x, #SF=%d",
|
HleVerboseMessage(hle->user_defined,
|
||||||
|
"musyx_v1_task: *data=%x, #SF=%d",
|
||||||
sfd_ptr,
|
sfd_ptr,
|
||||||
sfd_count);
|
sfd_count);
|
||||||
|
|
||||||
|
@ -264,7 +266,8 @@ void musyx_v2_task(struct hle_t* hle)
|
||||||
uint32_t sfd_count = *dmem_u32(hle, TASK_DATA_SIZE);
|
uint32_t sfd_count = *dmem_u32(hle, TASK_DATA_SIZE);
|
||||||
musyx_t musyx;
|
musyx_t musyx;
|
||||||
|
|
||||||
VerboseMessage("musyx_v2_task: *data=%x, #SF=%d",
|
HleVerboseMessage(hle->user_defined,
|
||||||
|
"musyx_v2_task: *data=%x, #SF=%d",
|
||||||
sfd_ptr,
|
sfd_ptr,
|
||||||
sfd_count);
|
sfd_count);
|
||||||
|
|
||||||
|
@ -299,7 +302,8 @@ void musyx_v2_task(struct hle_t* hle)
|
||||||
|
|
||||||
if (ptr_10) {
|
if (ptr_10) {
|
||||||
/* TODO */
|
/* TODO */
|
||||||
WarnMessage("ptr_10=%08x mask_14=%02x ptr_24=%08x",
|
HleWarnMessage(hle->user_defined,
|
||||||
|
"ptr_10=%08x mask_14=%02x ptr_24=%08x",
|
||||||
ptr_10, mask_14, ptr_24);
|
ptr_10, mask_14, ptr_24);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,8 +368,9 @@ static void update_base_vol(struct hle_t* hle, int32_t *base_vol,
|
||||||
unsigned i, k;
|
unsigned i, k;
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
|
|
||||||
VerboseMessage("base_vol voice_mask = %08x", voice_mask);
|
HleVerboseMessage(hle->user_defined, "base_vol voice_mask = %08x", voice_mask);
|
||||||
VerboseMessage("BEFORE: base_vol = %08x %08x %08x %08x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
|
"BEFORE: base_vol = %08x %08x %08x %08x",
|
||||||
base_vol[0], base_vol[1], base_vol[2], base_vol[3]);
|
base_vol[0], base_vol[1], base_vol[2], base_vol[3]);
|
||||||
|
|
||||||
/* optim: skip voices contributions entirely if voice_mask is empty */
|
/* optim: skip voices contributions entirely if voice_mask is empty */
|
||||||
|
@ -396,7 +401,8 @@ static void update_base_vol(struct hle_t* hle, int32_t *base_vol,
|
||||||
for (k = 0; k < 4; ++k)
|
for (k = 0; k < 4; ++k)
|
||||||
base_vol[k] = (base_vol[k] * 0x0000f850) >> 16;
|
base_vol[k] = (base_vol[k] * 0x0000f850) >> 16;
|
||||||
|
|
||||||
VerboseMessage("AFTER: base_vol = %08x %08x %08x %08x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
|
"AFTER: base_vol = %08x %08x %08x %08x",
|
||||||
base_vol[0], base_vol[1], base_vol[2], base_vol[3]);
|
base_vol[0], base_vol[1], base_vol[2], base_vol[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,7 +463,7 @@ static uint32_t voice_stage(struct hle_t* hle, musyx_t *musyx,
|
||||||
|
|
||||||
/* voice stage can be skipped if first voice has no samples */
|
/* voice stage can be skipped if first voice has no samples */
|
||||||
if (*dram_u16(hle, voice_ptr + VOICE_CATSRC_0 + CATSRC_SIZE1) == 0) {
|
if (*dram_u16(hle, voice_ptr + VOICE_CATSRC_0 + CATSRC_SIZE1) == 0) {
|
||||||
VerboseMessage("Skipping Voice stage");
|
HleVerboseMessage(hle->user_defined, "Skipping Voice stage");
|
||||||
output_ptr = *dram_u32(hle, voice_ptr + VOICE_INTERLEAVED_PTR);
|
output_ptr = *dram_u32(hle, voice_ptr + VOICE_INTERLEAVED_PTR);
|
||||||
} else {
|
} else {
|
||||||
/* otherwise process voices until a non null output_ptr is encountered */
|
/* otherwise process voices until a non null output_ptr is encountered */
|
||||||
|
@ -467,7 +473,7 @@ static uint32_t voice_stage(struct hle_t* hle, musyx_t *musyx,
|
||||||
unsigned segbase;
|
unsigned segbase;
|
||||||
unsigned offset;
|
unsigned offset;
|
||||||
|
|
||||||
VerboseMessage("Processing Voice #%d", i);
|
HleVerboseMessage(hle->user_defined, "Processing Voice #%d", i);
|
||||||
|
|
||||||
if (*dram_u8(hle, voice_ptr + VOICE_ADPCM_FRAMES) == 0)
|
if (*dram_u8(hle, voice_ptr + VOICE_ADPCM_FRAMES) == 0)
|
||||||
load_samples_PCM16(hle, voice_ptr, samples, &segbase, &offset);
|
load_samples_PCM16(hle, voice_ptr, samples, &segbase, &offset);
|
||||||
|
@ -502,7 +508,8 @@ static void dma_cat8(struct hle_t* hle, uint8_t *dst, uint32_t catsrc_ptr)
|
||||||
size_t count1 = size1;
|
size_t count1 = size1;
|
||||||
size_t count2 = size2;
|
size_t count2 = size2;
|
||||||
|
|
||||||
VerboseMessage("dma_cat: %08x %08x %04x %04x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
|
"dma_cat: %08x %08x %04x %04x",
|
||||||
ptr1,
|
ptr1,
|
||||||
ptr2,
|
ptr2,
|
||||||
size1,
|
size1,
|
||||||
|
@ -526,7 +533,8 @@ static void dma_cat16(struct hle_t* hle, uint16_t *dst, uint32_t catsrc_ptr)
|
||||||
size_t count1 = size1 >> 1;
|
size_t count1 = size1 >> 1;
|
||||||
size_t count2 = size2 >> 1;
|
size_t count2 = size2 >> 1;
|
||||||
|
|
||||||
VerboseMessage("dma_cat: %08x %08x %04x %04x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
|
"dma_cat: %08x %08x %04x %04x",
|
||||||
ptr1,
|
ptr1,
|
||||||
ptr2,
|
ptr2,
|
||||||
size1,
|
size1,
|
||||||
|
@ -550,7 +558,7 @@ static void load_samples_PCM16(struct hle_t* hle, uint32_t voice_ptr, int16_t *s
|
||||||
|
|
||||||
unsigned count = align(u16_40 + u8_3e, 4);
|
unsigned count = align(u16_40 + u8_3e, 4);
|
||||||
|
|
||||||
VerboseMessage("Format: PCM16");
|
HleVerboseMessage(hle->user_defined, "Format: PCM16");
|
||||||
|
|
||||||
*segbase = SAMPLE_BUFFER_SIZE - count;
|
*segbase = SAMPLE_BUFFER_SIZE - count;
|
||||||
*offset = u8_3e;
|
*offset = u8_3e;
|
||||||
|
@ -576,9 +584,9 @@ static void load_samples_ADPCM(struct hle_t* hle, uint32_t voice_ptr, int16_t *s
|
||||||
uint32_t adpcm_table_ptr = *dram_u32(hle, voice_ptr + VOICE_ADPCM_TABLE_PTR);
|
uint32_t adpcm_table_ptr = *dram_u32(hle, voice_ptr + VOICE_ADPCM_TABLE_PTR);
|
||||||
unsigned count;
|
unsigned count;
|
||||||
|
|
||||||
VerboseMessage("Format: ADPCM");
|
HleVerboseMessage(hle->user_defined, "Format: ADPCM");
|
||||||
|
|
||||||
VerboseMessage("Loading ADPCM table: %08x", adpcm_table_ptr);
|
HleVerboseMessage(hle->user_defined, "Loading ADPCM table: %08x", adpcm_table_ptr);
|
||||||
dram_load_u16(hle, (uint16_t *)adpcm_table, adpcm_table_ptr, 128);
|
dram_load_u16(hle, (uint16_t *)adpcm_table, adpcm_table_ptr, 128);
|
||||||
|
|
||||||
count = u8_3c << 5;
|
count = u8_3c << 5;
|
||||||
|
@ -587,15 +595,16 @@ static void load_samples_ADPCM(struct hle_t* hle, uint32_t voice_ptr, int16_t *s
|
||||||
*offset = u8_3e & 0x1f;
|
*offset = u8_3e & 0x1f;
|
||||||
|
|
||||||
dma_cat8(hle, buffer, voice_ptr + VOICE_CATSRC_0);
|
dma_cat8(hle, buffer, voice_ptr + VOICE_CATSRC_0);
|
||||||
adpcm_decode_frames(samples + *segbase, buffer, adpcm_table, u8_3c, u8_3e);
|
adpcm_decode_frames(hle, samples + *segbase, buffer, adpcm_table, u8_3c, u8_3e);
|
||||||
|
|
||||||
if (u8_3d != 0) {
|
if (u8_3d != 0) {
|
||||||
dma_cat8(hle, buffer, voice_ptr + VOICE_CATSRC_1);
|
dma_cat8(hle, buffer, voice_ptr + VOICE_CATSRC_1);
|
||||||
adpcm_decode_frames(samples, buffer, adpcm_table, u8_3d, u8_3f);
|
adpcm_decode_frames(hle, samples, buffer, adpcm_table, u8_3d, u8_3f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adpcm_decode_frames(int16_t *dst, const uint8_t *src,
|
static void adpcm_decode_frames(struct hle_t* hle,
|
||||||
|
int16_t *dst, const uint8_t *src,
|
||||||
const int16_t *table, uint8_t count,
|
const int16_t *table, uint8_t count,
|
||||||
uint8_t skip_samples)
|
uint8_t skip_samples)
|
||||||
{
|
{
|
||||||
|
@ -604,7 +613,9 @@ static void adpcm_decode_frames(int16_t *dst, const uint8_t *src,
|
||||||
unsigned i;
|
unsigned i;
|
||||||
bool jump_gap = false;
|
bool jump_gap = false;
|
||||||
|
|
||||||
VerboseMessage("ADPCM decode: count=%d, skip=%d", count, skip_samples);
|
HleVerboseMessage(hle->user_defined,
|
||||||
|
"ADPCM decode: count=%d, skip=%d",
|
||||||
|
count, skip_samples);
|
||||||
|
|
||||||
if (skip_samples >= 32) {
|
if (skip_samples >= 32) {
|
||||||
jump_gap = true;
|
jump_gap = true;
|
||||||
|
@ -693,7 +704,8 @@ static void mix_voice_samples(struct hle_t* hle, musyx_t *musyx,
|
||||||
v4_dst[2] = musyx->cc0;
|
v4_dst[2] = musyx->cc0;
|
||||||
v4_dst[3] = musyx->e50;
|
v4_dst[3] = musyx->e50;
|
||||||
|
|
||||||
VerboseMessage("Voice debug: segbase=%d"
|
HleVerboseMessage(hle->user_defined,
|
||||||
|
"Voice debug: segbase=%d"
|
||||||
"\tu16_4e=%04x\n"
|
"\tu16_4e=%04x\n"
|
||||||
"\tpitch: frac0=%04x shift=%04x\n"
|
"\tpitch: frac0=%04x shift=%04x\n"
|
||||||
"\tend_point=%04x restart_point=%04x\n"
|
"\tend_point=%04x restart_point=%04x\n"
|
||||||
|
@ -739,7 +751,8 @@ static void mix_voice_samples(struct hle_t* hle, musyx_t *musyx,
|
||||||
/* save last resampled sample */
|
/* save last resampled sample */
|
||||||
dram_store_u16(hle, (uint16_t *)v4, last_sample_ptr, 4);
|
dram_store_u16(hle, (uint16_t *)v4, last_sample_ptr, 4);
|
||||||
|
|
||||||
VerboseMessage("last_sample = %04x %04x %04x %04x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
|
"last_sample = %04x %04x %04x %04x",
|
||||||
v4[0], v4[1], v4[2], v4[3]);
|
v4[0], v4[1], v4[2], v4[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,7 +780,7 @@ static void sfx_stage(struct hle_t* hle, mix_sfx_with_main_subframes_t mix_sfx_w
|
||||||
int16_t fir4_hgain;
|
int16_t fir4_hgain;
|
||||||
uint16_t sfx_gains[2];
|
uint16_t sfx_gains[2];
|
||||||
|
|
||||||
VerboseMessage("SFX: %08x, idx=%d", sfx_ptr, idx);
|
HleVerboseMessage(hle->user_defined, "SFX: %08x, idx=%d", sfx_ptr, idx);
|
||||||
|
|
||||||
if (sfx_ptr == 0)
|
if (sfx_ptr == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -787,14 +800,17 @@ static void sfx_stage(struct hle_t* hle, mix_sfx_with_main_subframes_t mix_sfx_w
|
||||||
sfx_gains[0] = *dram_u16(hle, sfx_ptr + SFX_U16_3C);
|
sfx_gains[0] = *dram_u16(hle, sfx_ptr + SFX_U16_3C);
|
||||||
sfx_gains[1] = *dram_u16(hle, sfx_ptr + SFX_U16_3E);
|
sfx_gains[1] = *dram_u16(hle, sfx_ptr + SFX_U16_3E);
|
||||||
|
|
||||||
VerboseMessage("cbuffer: ptr=%08x length=%x", cbuffer_ptr,
|
HleVerboseMessage(hle->user_defined,
|
||||||
|
"cbuffer: ptr=%08x length=%x", cbuffer_ptr,
|
||||||
cbuffer_length);
|
cbuffer_length);
|
||||||
|
|
||||||
VerboseMessage("fir4: hgain=%04x hcoeff=%04x %04x %04x %04x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
fir4_hgain, fir4_hcoeffs[0], fir4_hcoeffs[1], fir4_hcoeffs[2],
|
"fir4: hgain=%04x hcoeff=%04x %04x %04x %04x",
|
||||||
fir4_hcoeffs[3]);
|
fir4_hgain,
|
||||||
|
fir4_hcoeffs[0], fir4_hcoeffs[1], fir4_hcoeffs[2], fir4_hcoeffs[3]);
|
||||||
|
|
||||||
VerboseMessage("tap count=%d\n"
|
HleVerboseMessage(hle->user_defined,
|
||||||
|
"tap count=%d\n"
|
||||||
"delays: %08x %08x %08x %08x %08x %08x %08x %08x\n"
|
"delays: %08x %08x %08x %08x %08x %08x %08x %08x\n"
|
||||||
"gains: %04x %04x %04x %04x %04x %04x %04x %04x",
|
"gains: %04x %04x %04x %04x %04x %04x %04x %04x",
|
||||||
tap_count,
|
tap_count,
|
||||||
|
@ -803,7 +819,7 @@ static void sfx_stage(struct hle_t* hle, mix_sfx_with_main_subframes_t mix_sfx_w
|
||||||
tap_gains[0], tap_gains[1], tap_gains[2], tap_gains[3],
|
tap_gains[0], tap_gains[1], tap_gains[2], tap_gains[3],
|
||||||
tap_gains[4], tap_gains[5], tap_gains[6], tap_gains[7]);
|
tap_gains[4], tap_gains[5], tap_gains[6], tap_gains[7]);
|
||||||
|
|
||||||
VerboseMessage("sfx_gains=%04x %04x", sfx_gains[0], sfx_gains[1]);
|
HleVerboseMessage(hle->user_defined, "sfx_gains=%04x %04x", sfx_gains[0], sfx_gains[1]);
|
||||||
|
|
||||||
/* mix up to 8 delayed subframes */
|
/* mix up to 8 delayed subframes */
|
||||||
memset(subframe, 0, SUBFRAME_SIZE * sizeof(subframe[0]));
|
memset(subframe, 0, SUBFRAME_SIZE * sizeof(subframe[0]));
|
||||||
|
@ -902,7 +918,7 @@ static void interleave_stage_v1(struct hle_t* hle, musyx_t *musyx, uint32_t outp
|
||||||
int16_t *right;
|
int16_t *right;
|
||||||
uint32_t *dst;
|
uint32_t *dst;
|
||||||
|
|
||||||
VerboseMessage("interleave: %08x", output_ptr);
|
HleVerboseMessage(hle->user_defined, "interleave: %08x", output_ptr);
|
||||||
|
|
||||||
base_left = clamp_s16(musyx->base_vol[0]);
|
base_left = clamp_s16(musyx->base_vol[0]);
|
||||||
base_right = clamp_s16(musyx->base_vol[1]);
|
base_right = clamp_s16(musyx->base_vol[1]);
|
||||||
|
@ -928,7 +944,8 @@ static void interleave_stage_v2(struct hle_t* hle, musyx_t *musyx,
|
||||||
uint32_t *dst;
|
uint32_t *dst;
|
||||||
uint16_t mask;
|
uint16_t mask;
|
||||||
|
|
||||||
VerboseMessage("mask_16=%04x ptr_18=%08x ptr_1c=%08x output_ptr=%08x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
|
"mask_16=%04x ptr_18=%08x ptr_1c=%08x output_ptr=%08x",
|
||||||
mask_16, ptr_18, ptr_1c, output_ptr);
|
mask_16, ptr_18, ptr_1c, output_ptr);
|
||||||
|
|
||||||
/* compute L_total, R_total and update subframe @ptr_1c */
|
/* compute L_total, R_total and update subframe @ptr_1c */
|
||||||
|
|
19
src/plugin.c
19
src/plugin.c
|
@ -59,7 +59,7 @@ static void DebugMessage(int level, const char *message, va_list args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Global functions needed by HLE core */
|
/* Global functions needed by HLE core */
|
||||||
void VerboseMessage(const char *message, ...)
|
void HleVerboseMessage(void* user_defined, const char *message, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, message);
|
va_start(args, message);
|
||||||
|
@ -67,7 +67,7 @@ void VerboseMessage(const char *message, ...)
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ErrorMessage(const char *message, ...)
|
void HleErrorMessage(void* user_defined, const char *message, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, message);
|
va_start(args, message);
|
||||||
|
@ -75,7 +75,7 @@ void ErrorMessage(const char *message, ...)
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WarnMessage(const char *message, ...)
|
void HleWarnMessage(void* user_defined, const char *message, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, message);
|
va_start(args, message);
|
||||||
|
@ -83,7 +83,7 @@ void WarnMessage(const char *message, ...)
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckInterrupts(void)
|
void HleCheckInterrupts(void* user_defined)
|
||||||
{
|
{
|
||||||
if (l_CheckInterrupts == NULL)
|
if (l_CheckInterrupts == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -91,7 +91,7 @@ void CheckInterrupts(void)
|
||||||
(*l_CheckInterrupts)();
|
(*l_CheckInterrupts)();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessDlistList(void)
|
void HleProcessDlistList(void* user_defined)
|
||||||
{
|
{
|
||||||
if (l_ProcessDlistList == NULL)
|
if (l_ProcessDlistList == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -99,7 +99,7 @@ void ProcessDlistList(void)
|
||||||
(*l_ProcessDlistList)();
|
(*l_ProcessDlistList)();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessAlistList(void)
|
void HleProcessAlistList(void* user_defined)
|
||||||
{
|
{
|
||||||
if (l_ProcessAlistList == NULL)
|
if (l_ProcessAlistList == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -107,7 +107,7 @@ void ProcessAlistList(void)
|
||||||
(*l_ProcessAlistList)();
|
(*l_ProcessAlistList)();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessRdpList(void)
|
void HleProcessRdpList(void* user_defined)
|
||||||
{
|
{
|
||||||
if (l_ProcessRdpList == NULL)
|
if (l_ProcessRdpList == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -115,7 +115,7 @@ void ProcessRdpList(void)
|
||||||
(*l_ProcessRdpList)();
|
(*l_ProcessRdpList)();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowCFB(void)
|
void HleShowCFB(void* user_defined)
|
||||||
{
|
{
|
||||||
if (l_ShowCFB == NULL)
|
if (l_ShowCFB == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -208,6 +208,9 @@ EXPORT void CALL InitiateRSP(RSP_INFO Rsp_Info, unsigned int *CycleCount)
|
||||||
g_hle.dpc_pipebusy = Rsp_Info.DPC_PIPEBUSY_REG;
|
g_hle.dpc_pipebusy = Rsp_Info.DPC_PIPEBUSY_REG;
|
||||||
g_hle.dpc_tmem = Rsp_Info.DPC_TMEM_REG;
|
g_hle.dpc_tmem = Rsp_Info.DPC_TMEM_REG;
|
||||||
|
|
||||||
|
/* not used in m64p */
|
||||||
|
g_hle.user_defined = NULL;
|
||||||
|
|
||||||
l_CheckInterrupts = Rsp_Info.CheckInterrupts;
|
l_CheckInterrupts = Rsp_Info.CheckInterrupts;
|
||||||
l_ProcessDlistList = Rsp_Info.ProcessDlistList;
|
l_ProcessDlistList = Rsp_Info.ProcessDlistList;
|
||||||
l_ProcessAlistList = Rsp_Info.ProcessAlistList;
|
l_ProcessAlistList = Rsp_Info.ProcessAlistList;
|
||||||
|
|
16
src/plugin.h
16
src/plugin.h
|
@ -22,15 +22,15 @@
|
||||||
#ifndef PLUGIN_H
|
#ifndef PLUGIN_H
|
||||||
#define PLUGIN_H
|
#define PLUGIN_H
|
||||||
|
|
||||||
void VerboseMessage(const char *message, ...);
|
void HleVerboseMessage(void* user_defined, const char *message, ...);
|
||||||
void ErrorMessage(const char *message, ...);
|
void HleErrorMessage(void* user_defined, const char *message, ...);
|
||||||
void WarnMessage(const char *message, ...);
|
void HleWarnMessage(void* user_defined, const char *message, ...);
|
||||||
|
|
||||||
void CheckInterrupts(void);
|
void HleCheckInterrupts(void* user_defined);
|
||||||
void ProcessDlistList(void);
|
void HleProcessDlistList(void* user_defined);
|
||||||
void ProcessAlistList(void);
|
void HleProcessAlistList(void* user_defined);
|
||||||
void ProcessRdpList(void);
|
void HleProcessRdpList(void* user_defined);
|
||||||
void ShowCFB(void);
|
void HleShowCFB(void* user_defined);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue