Updated lazyusf2, and disabled RSP HLE warnings

The warn logging was preventing working USFs from playing due
to warnings occurring during the playback that didn't otherwise
affect the ability to play the files.
CQTexperiment
Christopher Snowhill 2022-02-12 03:29:43 -08:00
parent c39b7ee96a
commit 1df166b060
24 changed files with 983 additions and 215 deletions

View File

@ -10,6 +10,8 @@
8333B6721DCC498B004C140D /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8333B6711DCC498B004C140D /* libz.tbd */; };
8379B58A1AA4237E00F28A95 /* barray.c in Sources */ = {isa = PBXBuildFile; fileRef = 8379B5881AA4237E00F28A95 /* barray.c */; };
8379B58B1AA4237E00F28A95 /* barray.h in Headers */ = {isa = PBXBuildFile; fileRef = 8379B5891AA4237E00F28A95 /* barray.h */; };
83AA660627B7CB490098D4B8 /* hvqm.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AA660427B7CB490098D4B8 /* hvqm.c */; };
83AA660727B7CB490098D4B8 /* re2.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AA660527B7CB490098D4B8 /* re2.c */; };
83C0787C1A9B544300ABBB67 /* resampler.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C0787A1A9B544300ABBB67 /* resampler.c */; };
83C0787D1A9B544300ABBB67 /* resampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C0787B1A9B544300ABBB67 /* resampler.h */; };
83CA14741A987E91005E7ED4 /* preproc.h in Headers */ = {isa = PBXBuildFile; fileRef = 83CA146E1A987E91005E7ED4 /* preproc.h */; };
@ -205,6 +207,8 @@
8333B6711DCC498B004C140D /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
8379B5881AA4237E00F28A95 /* barray.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = barray.c; sourceTree = "<group>"; };
8379B5891AA4237E00F28A95 /* barray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = barray.h; sourceTree = "<group>"; };
83AA660427B7CB490098D4B8 /* hvqm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hvqm.c; sourceTree = "<group>"; };
83AA660527B7CB490098D4B8 /* re2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = re2.c; sourceTree = "<group>"; };
83C0787A1A9B544300ABBB67 /* resampler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resampler.c; sourceTree = "<group>"; };
83C0787B1A9B544300ABBB67 /* resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resampler.h; sourceTree = "<group>"; };
83C8B62218AF57770071B040 /* lazyusf2.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = lazyusf2.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@ -660,20 +664,21 @@
83CA14FF1A988138005E7ED4 /* rsp_hle */ = {
isa = PBXGroup;
children = (
83CA15001A988138005E7ED4 /* alist.c */,
83CA15011A988138005E7ED4 /* alist.h */,
83CA15021A988138005E7ED4 /* alist_audio.c */,
83CA15031A988138005E7ED4 /* alist_naudio.c */,
83CA15041A988138005E7ED4 /* alist_nead.c */,
83CA15001A988138005E7ED4 /* alist.c */,
83CA15011A988138005E7ED4 /* alist.h */,
83CA15051A988138005E7ED4 /* arithmetics.h */,
83CA15061A988138005E7ED4 /* audio.c */,
83CA15071A988138005E7ED4 /* audio.h */,
83CA15081A988138005E7ED4 /* cicx105.c */,
83CA15091A988138005E7ED4 /* common.h */,
83CA150A1A988138005E7ED4 /* hle.c */,
83CA150B1A988138005E7ED4 /* hle.h */,
83CA150C1A988138005E7ED4 /* hle_external.h */,
83CA150D1A988138005E7ED4 /* hle_internal.h */,
83CA150A1A988138005E7ED4 /* hle.c */,
83CA150B1A988138005E7ED4 /* hle.h */,
83AA660427B7CB490098D4B8 /* hvqm.c */,
83CA150E1A988138005E7ED4 /* jpeg.c */,
83CA150F1A988138005E7ED4 /* LICENSES */,
83CA15101A988138005E7ED4 /* memory.c */,
@ -681,6 +686,7 @@
83CA15121A988138005E7ED4 /* mp3.c */,
83CA15151A988138005E7ED4 /* musyx.c */,
83CA15161A988138005E7ED4 /* plugin.c */,
83AA660527B7CB490098D4B8 /* re2.c */,
83CA15171A988138005E7ED4 /* ucodes.h */,
);
path = rsp_hle;
@ -1020,6 +1026,7 @@
83CA15DE1A988138005E7ED4 /* alist_audio.c in Sources */,
83CA15D81A988138005E7ED4 /* ri_controller.c in Sources */,
83CA15861A988138005E7ED4 /* exception.c in Sources */,
83AA660627B7CB490098D4B8 /* hvqm.c in Sources */,
83CA15C61A988138005E7ED4 /* gcop1_d.c in Sources */,
83CA16291A988138005E7ED4 /* cic.c in Sources */,
83CA15A11A988138005E7ED4 /* pure_interp.c in Sources */,
@ -1059,6 +1066,7 @@
83CA15EC1A988138005E7ED4 /* memory.c in Sources */,
83CA15AC1A988138005E7ED4 /* tlb.c in Sources */,
83CA15DC1A988138005E7ED4 /* alist.c in Sources */,
83AA660727B7CB490098D4B8 /* re2.c in Sources */,
83CA15811A988138005E7ED4 /* cp0.c in Sources */,
83CA157A1A988138005E7ED4 /* cart_rom.c in Sources */,
83CA16331A988138005E7ED4 /* usf.c in Sources */,

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - alist.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* Copyright (C) 2009 Richard Goedeken *
* Copyright (C) 2002 Hacktarux *
@ -21,6 +21,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
@ -49,17 +50,17 @@ static void swap(int16_t **a, int16_t **b)
static int16_t* sample(struct hle_t* hle, unsigned pos)
{
return (int16_t*)hle->alist_buffer + (pos ^ S);
return (int16_t*)hle->alist_buffer + ((pos ^ S) & 0xfff);
}
static uint8_t* alist_u8(struct hle_t* hle, uint16_t dmem)
{
return u8(hle->alist_buffer, dmem);
return (uint8_t*)(hle->alist_buffer + ((dmem ^ S8) & 0xfff));
}
static int16_t* alist_s16(struct hle_t* hle, uint16_t dmem)
{
return (int16_t*)u16(hle->alist_buffer, dmem);
return (int16_t*)(hle->alist_buffer + ((dmem ^ S16) & 0xfff));
}
@ -1025,8 +1026,8 @@ void alist_iirf(
count -= 0x10;
} while (count > 0);
dram_store_u16(hle, (uint16_t*)&frame[6], address + 4, 4);
dram_store_u16(hle, (uint16_t*)&ibuf[(index-2)&3], address+8, 2);
dram_store_u16(hle, (uint16_t*)&ibuf[(index-1)&3], address+10, 2);
dram_store_u16(hle, (uint16_t*)&frame[6], address + 4, 2);
dram_store_u16(hle, (uint16_t*)&ibuf[(index-2)&3], address+8, 1);
dram_store_u16(hle, (uint16_t*)&ibuf[(index-1)&3], address+10, 1);
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - alist.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* *
* This program is free software; you can redistribute it and/or modify *
@ -23,8 +23,8 @@
#define ALIST_INTERNAL_H
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <stdint.h>
struct hle_t;
@ -114,7 +114,7 @@ void alist_adpcm(
uint32_t last_frame_address);
void alist_resample(
struct hle_t* hle,
struct hle_t* hle,
bool init,
bool flag2,
uint16_t dmemo, uint16_t dmemi, uint16_t count,

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - alist_audio.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* Copyright (C) 2009 Richard Goedeken *
* Copyright (C) 2002 Hacktarux *
@ -57,7 +57,7 @@ static void SPNOOP(struct hle_t* UNUSED(hle), uint32_t UNUSED(w1), uint32_t UNUS
static void CLEARBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2)
{
uint16_t dmem = w1 + DMEM_BASE;
uint16_t count = w2;
uint16_t count = w2 & 0xfff;
if (count == 0)
return;
@ -111,7 +111,7 @@ static void RESAMPLE(struct hle_t* hle, uint32_t w1, uint32_t w2)
alist_resample(
hle,
flags & 0x1,
flags & A_INIT,
flags & 0x2,
hle->alist_audio.out,
hle->alist_audio.in,
@ -152,8 +152,8 @@ static void ADPCM(struct hle_t* hle, uint32_t w1, uint32_t w2)
alist_adpcm(
hle,
flags & 0x1,
flags & 0x2,
flags & A_INIT,
flags & A_LOOP,
false, /* unsupported in this ucode */
hle->alist_audio.out,
hle->alist_audio.in,
@ -291,6 +291,7 @@ void alist_process_audio(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x10);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_audio_ge(struct hle_t* hle)
@ -317,6 +318,7 @@ void alist_process_audio_ge(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x10);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_audio_bc(struct hle_t* hle)
@ -343,4 +345,5 @@ void alist_process_audio_bc(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x10);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - alist_naudio.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* Copyright (C) 2009 Richard Goedeken *
* Copyright (C) 2002 Hacktarux *
@ -108,18 +108,18 @@ static void SETVOL(struct hle_t* hle, uint32_t w1, uint32_t w2)
{
uint8_t flags = (w1 >> 16);
if (flags & 0x4) {
if (flags & 0x2) {
if (flags & A_VOL) {
if (flags & A_LEFT) {
hle->alist_naudio.vol[0] = w1;
hle->alist_naudio.dry = (w2 >> 16);
hle->alist_naudio.wet = w2;
}
else {
else { /* A_RIGHT */
hle->alist_naudio.target[1] = w1;
hle->alist_naudio.rate[1] = w2;
}
}
else {
else { /* A_RATE */
hle->alist_naudio.target[0] = w1;
hle->alist_naudio.rate[0] = w2;
}
@ -134,7 +134,7 @@ static void ENVMIXER(struct hle_t* hle, uint32_t w1, uint32_t w2)
alist_envmix_lin(
hle,
flags & 0x1,
flags & A_INIT,
NAUDIO_DRY_LEFT,
NAUDIO_DRY_RIGHT,
NAUDIO_WET_LEFT,
@ -216,8 +216,8 @@ static void ADPCM(struct hle_t* hle, uint32_t w1, uint32_t w2)
alist_adpcm(
hle,
flags & 0x1,
flags & 0x2,
flags & A_INIT,
flags & A_LOOP,
false, /* unsuported by this ucode */
dmemo,
dmemi,
@ -237,7 +237,7 @@ static void RESAMPLE(struct hle_t* hle, uint32_t w1, uint32_t w2)
alist_resample(
hle,
flags & 0x1,
flags & A_INIT,
false, /* TODO: check which ABI supports it */
dmemo,
dmemi,
@ -285,6 +285,7 @@ void alist_process_naudio(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x10);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_naudio_bk(struct hle_t* hle)
@ -309,6 +310,7 @@ void alist_process_naudio_bk(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x10);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_naudio_dk(struct hle_t* hle)
@ -333,6 +335,7 @@ void alist_process_naudio_dk(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x10);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_naudio_mp3(struct hle_t* hle)
@ -356,6 +359,7 @@ void alist_process_naudio_mp3(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x10);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_naudio_cbfd(struct hle_t* hle)
@ -380,4 +384,5 @@ void alist_process_naudio_cbfd(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x10);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - alist_nead.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* Copyright (C) 2009 Richard Goedeken *
* Copyright (C) 2002 Hacktarux *
@ -300,7 +300,7 @@ static void ADDMIXER(struct hle_t* hle, uint32_t w1, uint32_t w2)
static void HILOGAIN(struct hle_t* hle, uint32_t w1, uint32_t w2)
{
int8_t gain = (w1 >> 16); /* Q4.4 signed */
uint16_t count = w1;
uint16_t count = w1 & 0xfff;
uint16_t dmem = (w2 >> 16);
alist_multQ44(hle, dmem, count, gain);
@ -386,6 +386,7 @@ void alist_process_nead_mk(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x20);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_nead_sf(struct hle_t* hle)
@ -416,6 +417,7 @@ void alist_process_nead_sf(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x20);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_nead_sfj(struct hle_t* hle)
@ -446,6 +448,7 @@ void alist_process_nead_sfj(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x20);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_nead_fz(struct hle_t* hle)
@ -476,6 +479,7 @@ void alist_process_nead_fz(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x20);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_nead_wrjb(struct hle_t* hle)
@ -506,6 +510,7 @@ void alist_process_nead_wrjb(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x20);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_nead_ys(struct hle_t* hle)
@ -532,6 +537,7 @@ void alist_process_nead_ys(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x18);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_nead_1080(struct hle_t* hle)
@ -558,6 +564,7 @@ void alist_process_nead_1080(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x18);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_nead_oot(struct hle_t* hle)
@ -584,6 +591,7 @@ void alist_process_nead_oot(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x18);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_nead_mm(struct hle_t* hle)
@ -610,6 +618,7 @@ void alist_process_nead_mm(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x18);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_nead_mmb(struct hle_t* hle)
@ -636,6 +645,7 @@ void alist_process_nead_mmb(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x18);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_nead_ac(struct hle_t* hle)
@ -662,4 +672,27 @@ void alist_process_nead_ac(struct hle_t* hle)
#else
alist_process(hle, ABI, 0x18);
#endif
rsp_break(hle, SP_STATUS_TASKDONE);
}
void alist_process_nead_mats(struct hle_t* hle)
{
/* FIXME: implement proper ucode
* Forward the task if possible,
* otherwise better to have no sound than garbage sound
*/
if (HleForwardTask(hle->user_defined) != 0) {
rsp_break(hle, SP_STATUS_TASKDONE);
}
}
void alist_process_nead_efz(struct hle_t* hle)
{
/* FIXME: implement proper ucode
* Forward the task if possible,
* otherwise use FZero ucode which should be very similar
*/
if (HleForwardTask(hle->user_defined) != 0) {
alist_process_nead_fz(hle);
}
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - arithmetics.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* *
* This program is free software; you can redistribute it and/or modify *

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - audio.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* *
* This program is free software; you can redistribute it and/or modify *
@ -23,8 +23,6 @@
#include <stddef.h>
#include <stdint.h>
#include "common.h"
#include "arithmetics.h"
const int16_t RESAMPLE_LUT[64 * 4] = {

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - audio.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* *
* This program is free software; you can redistribute it and/or modify *
@ -25,13 +25,13 @@
#include <stddef.h>
#include <stdint.h>
#include "osal/preproc.h"
#include "common.h"
extern const int16_t RESAMPLE_LUT[64 * 4];
int32_t rdot(size_t n, const int16_t *x, const int16_t *y);
static osal_inline int16_t adpcm_predict_sample(uint8_t byte, uint8_t mask,
static inline int16_t adpcm_predict_sample(uint8_t byte, uint8_t mask,
unsigned lshift, unsigned rshift)
{
int16_t sample = (uint16_t)(byte & mask) << lshift;

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - hle.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2012 Bobby Smiles *
* Copyright (C) 2009 Richard Goedeken *
* Copyright (C) 2002 Hacktarux *
@ -28,50 +28,35 @@
#include <stdio.h>
#endif
#include "common.h"
#include "hle_external.h"
#include "hle_internal.h"
#include "memory.h"
#include "ucodes.h"
#define min(a,b) (((a) < (b)) ? (a) : (b))
/* some rsp status flags */
#define SP_STATUS_HALT 0x1
#define SP_STATUS_BROKE 0x2
#define SP_STATUS_INTR_ON_BREAK 0x40
#define SP_STATUS_TASKDONE 0x200
/* some rdp status flags */
#define DP_STATUS_FREEZE 0x2
/* some mips interface interrupt flags */
#define MI_INTR_SP 0x1
/* helper functions prototypes */
static unsigned int sum_bytes(const unsigned char *bytes, unsigned int size);
static bool is_task(struct hle_t* hle);
static void rsp_break(struct hle_t* hle, unsigned int setbits);
static void forward_gfx_task(struct hle_t* hle);
static bool try_fast_audio_dispatching(struct hle_t* hle);
static bool try_fast_task_dispatching(struct hle_t* hle);
static void normal_task_dispatching(struct hle_t* hle);
static void non_task_dispatching(struct hle_t* hle);
static void send_dlist_to_gfx_plugin(struct hle_t* hle);
static ucode_func_t try_audio_task_detection(struct hle_t* hle);
static ucode_func_t try_normal_task_detection(struct hle_t* hle);
static ucode_func_t non_task_detection(struct hle_t* hle);
static ucode_func_t task_detection(struct hle_t* hle);
#ifdef ENABLE_TASK_DUMP
static void dump_binary(const char *const filename, const unsigned char *const bytes,
unsigned int size);
static void dump_binary(struct hle_t* hle, const char *const filename,
const unsigned char *const bytes, unsigned int size);
static void dump_task(struct hle_t* hle, const char *const filename);
static void dump_unknown_task(struct hle_t* hle, unsigned int sum);
static void dump_unknown_non_task(struct hle_t* hle, unsigned int sum);
static void dump_unknown_task(struct hle_t* hle, unsigned int uc_start);
static void dump_unknown_non_task(struct hle_t* hle, unsigned int uc_start);
#endif
/* local variables */
static const bool FORWARD_AUDIO = false, FORWARD_GFX = true;
/* Global functions */
void hle_init(struct hle_t* hle,
unsigned char* dram,
@ -123,14 +108,38 @@ void hle_init(struct hle_t* hle,
void hle_execute(struct hle_t* hle)
{
if (is_task(hle)) {
if (!try_fast_task_dispatching(hle))
normal_task_dispatching(hle);
rsp_break(hle, SP_STATUS_TASKDONE);
} else {
non_task_dispatching(hle);
rsp_break(hle, 0);
uint32_t uc_start = *dmem_u32(hle, TASK_UCODE);
uint32_t uc_dstart = *dmem_u32(hle, TASK_UCODE_DATA);
uint32_t uc_dsize = *dmem_u32(hle, TASK_UCODE_DATA_SIZE);
bool match = false;
struct cached_ucodes_t * cached_ucodes = &hle->cached_ucodes;
struct ucode_info_t *info = NULL;
if (cached_ucodes->count > 0)
info = &cached_ucodes->infos[cached_ucodes->count-1];
for (int i = 0; i < cached_ucodes->count; i++)
{
if (info->uc_start == uc_start && info->uc_dstart == uc_dstart && info->uc_dsize == uc_dsize)
{
match = true;
break;
}
info--;
}
if (!match)
{
info = &cached_ucodes->infos[cached_ucodes->count];
info->uc_start = uc_start;
info->uc_dstart = uc_dstart;
info->uc_dsize = uc_dsize;
info->uc_pfunc = task_detection(hle);
cached_ucodes->count++;
assert(cached_ucodes->count <= CACHED_UCODES_MAX_SIZE);
assert(info->uc_pfunc != NULL);
}
info->uc_pfunc(hle);
}
/* local functions */
@ -160,7 +169,7 @@ static bool is_task(struct hle_t* hle)
return (*dmem_u32(hle, TASK_UCODE_BOOT_SIZE) <= 0x1000);
}
static void rsp_break(struct hle_t* hle, unsigned int setbits)
void rsp_break(struct hle_t* hle, unsigned int setbits)
{
*hle->sp_status |= setbits | SP_STATUS_BROKE | SP_STATUS_HALT;
@ -170,13 +179,66 @@ static void rsp_break(struct hle_t* hle, unsigned int setbits)
}
}
static void forward_gfx_task(struct hle_t* hle)
static void send_alist_to_audio_plugin(struct hle_t* hle)
{
HleProcessDlistList(hle->user_defined);
*hle->dpc_status &= ~DP_STATUS_FREEZE;
HleProcessAlistList(hle->user_defined);
rsp_break(hle, SP_STATUS_TASKDONE);
}
static bool try_fast_audio_dispatching(struct hle_t* hle)
static void send_dlist_to_gfx_plugin(struct hle_t* hle)
{
/* Since GFX_INFO version 2, these bits are set before calling the ProcessDlistList function.
* And the GFX plugin is responsible to unset them if needed.
* For GFX_INFO version < 2, the GFX plugin didn't have access to sp_status so
* it doesn't matter if we set these bits before calling ProcessDlistList function.
*/
*hle->sp_status |= SP_STATUS_TASKDONE | SP_STATUS_BROKE | SP_STATUS_HALT;
HleProcessDlistList(hle->user_defined);
if ((*hle->sp_status & SP_STATUS_INTR_ON_BREAK) && (*hle->sp_status & (SP_STATUS_TASKDONE | SP_STATUS_BROKE | SP_STATUS_HALT))) {
*hle->mi_intr |= MI_INTR_SP;
HleCheckInterrupts(hle->user_defined);
}
}
static void task_done(struct hle_t* hle)
{
rsp_break(hle, SP_STATUS_TASKDONE);
}
static void unknown_ucode(struct hle_t* hle)
{
/* Forward task to RSP Fallback.
* If task is not forwarded, use the regular "unknown ucode" path */
if (HleForwardTask(hle->user_defined) != 0) {
uint32_t uc_start = *dmem_u32(hle, TASK_UCODE);
HleWarnMessage(hle->user_defined, "unknown RSP code: uc_start: %x PC:%x", uc_start, *hle->sp_pc);
#ifdef ENABLE_TASK_DUMP
dump_unknown_non_task(hle, uc_start);
#endif
}
}
static void unknown_task(struct hle_t* hle)
{
/* Forward task to RSP Fallback.
* If task is not forwarded, use the regular "unknown task" path */
if (HleForwardTask(hle->user_defined) != 0) {
/* Send task_done signal for unknown ucodes to allow further processings */
rsp_break(hle, SP_STATUS_TASKDONE);
uint32_t uc_start = *dmem_u32(hle, TASK_UCODE);
HleWarnMessage(hle->user_defined, "unknown OSTask: uc_start: %x PC:%x", uc_start, *hle->sp_pc);
#ifdef ENABLE_TASK_DUMP
dump_unknown_task(hle, uc_start);
#endif
}
}
static ucode_func_t try_audio_task_detection(struct hle_t* hle)
{
/* identify audio ucode by using the content of ucode_data */
uint32_t ucode_data = *dmem_u32(hle, TASK_UCODE_DATA);
@ -188,11 +250,11 @@ static bool try_fast_audio_dispatching(struct hle_t* hle)
switch(v)
{
case 0x1e24138c: /* audio ABI (most common) */
alist_process_audio(hle); return true;
return &alist_process_audio;
case 0x1dc8138c: /* GoldenEye */
alist_process_audio_ge(hle); return true;
return &alist_process_audio_ge;
case 0x1e3c1390: /* BlastCorp, DiddyKongRacing */
alist_process_audio_bc(hle); return true;
return &alist_process_audio_bc;
default:
HleWarnMessage(hle->user_defined, "ABI1 identification regression: v=%08x", v);
}
@ -201,30 +263,33 @@ static bool try_fast_audio_dispatching(struct hle_t* hle)
switch(v)
{
case 0x11181350: /* MarioKart, WaveRace (E) */
alist_process_nead_mk(hle); return true;
return &alist_process_nead_mk;
case 0x111812e0: /* StarFox (J) */
alist_process_nead_sfj(hle); return true;
return &alist_process_nead_sfj;
case 0x110412ac: /* WaveRace (J RevB) */
alist_process_nead_wrjb(hle); return true;
return &alist_process_nead_wrjb;
case 0x110412cc: /* StarFox/LylatWars (except J) */
alist_process_nead_sf(hle); return true;
return &alist_process_nead_sf;
case 0x1cd01250: /* FZeroX */
alist_process_nead_fz(hle); return true;
return &alist_process_nead_fz;
case 0x1f08122c: /* YoshisStory */
alist_process_nead_ys(hle); return true;
return &alist_process_nead_ys;
case 0x1f38122c: /* 1080° Snowboarding */
alist_process_nead_1080(hle); return true;
return &alist_process_nead_1080;
case 0x1f681230: /* Zelda OoT / Zelda MM (J, J RevA) */
alist_process_nead_oot(hle); return true;
return &alist_process_nead_oot;
case 0x1f801250: /* Zelda MM (except J, J RevA, E Beta), PokemonStadium 2 */
alist_process_nead_mm(hle); return true;
return &alist_process_nead_mm;
case 0x109411f8: /* Zelda MM (E Beta) */
alist_process_nead_mmb(hle); return true;
return &alist_process_nead_mmb;
case 0x1eac11b8: /* AnimalCrossing */
alist_process_nead_ac(hle); return true;
return &alist_process_nead_ac;
case 0x00010010: /* MusyX v2 (IndianaJones, BattleForNaboo) */
musyx_v2_task(hle); return true;
return &musyx_v2_task;
case 0x1f701238: /* Mario Artist Talent Studio */
return &alist_process_nead_mats;
case 0x1f4c1230: /* FZeroX Expansion */
return &alist_process_nead_efz;
default:
HleWarnMessage(hle->user_defined, "ABI2 identification regression: v=%08x", v);
}
@ -237,161 +302,177 @@ static bool try_fast_audio_dispatching(struct hle_t* hle)
RogueSquadron, ResidentEvil2, PolarisSnoCross,
TheWorldIsNotEnough, RugratsInParis, NBAShowTime,
HydroThunder, Tarzan, GauntletLegend, Rush2049 */
musyx_v1_task(hle); return true;
return &musyx_v1_task;
case 0x0000127c: /* naudio (many games) */
alist_process_naudio(hle); return true;
return &alist_process_naudio;
case 0x00001280: /* BanjoKazooie */
alist_process_naudio_bk(hle); return true;
return &alist_process_naudio_bk;
case 0x1c58126c: /* DonkeyKong */
alist_process_naudio_dk(hle); return true;
return &alist_process_naudio_dk;
case 0x1ae8143c: /* BanjoTooie, JetForceGemini, MickeySpeedWayUSA, PerfectDark */
alist_process_naudio_mp3(hle); return true;
return &alist_process_naudio_mp3;
case 0x1ab0140c: /* ConkerBadFurDay */
alist_process_naudio_cbfd(hle); return true;
return &alist_process_naudio_cbfd;
default:
HleWarnMessage(hle->user_defined, "ABI3 identification regression: v=%08x", v);
}
}
return false;
return NULL;
}
static bool try_fast_task_dispatching(struct hle_t* hle)
static ucode_func_t try_normal_task_detection(struct hle_t* hle)
{
/* identify task ucode by its type */
switch (*dmem_u32(hle, TASK_TYPE)) {
case 1:
if (FORWARD_GFX) {
forward_gfx_task(hle);
return true;
}
break;
case 2:
if (FORWARD_AUDIO) {
HleProcessAlistList(hle->user_defined);
return true;
} else if (try_fast_audio_dispatching(hle))
return true;
break;
case 7:
HleShowCFB(hle->user_defined);
return true;
}
return false;
}
static void normal_task_dispatching(struct hle_t* hle)
{
const unsigned int sum =
unsigned int sum =
sum_bytes((void*)dram_u32(hle, *dmem_u32(hle, TASK_UCODE)), min(*dmem_u32(hle, TASK_UCODE_SIZE), 0xf80) >> 1);
switch (sum) {
/* StoreVe12: found in Zelda Ocarina of Time [misleading task->type == 4] */
case 0x278:
/* Nothing to emulate */
return;
return &task_done;
/* GFX: Twintris [misleading task->type == 0] */
case 0x212ee:
if (FORWARD_GFX) {
forward_gfx_task(hle);
return;
if (hle->hle_gfx) {
return &send_dlist_to_gfx_plugin;
}
break;
return NULL;
/* JPEG: found in Pokemon Stadium J */
case 0x2c85a:
jpeg_decode_PS0(hle);
return;
return &jpeg_decode_PS0;
/* JPEG: found in Zelda Ocarina of Time, Pokemon Stadium 1, Pokemon Stadium 2 */
case 0x2caa6:
jpeg_decode_PS(hle);
return;
return &jpeg_decode_PS;
/* JPEG: found in Ogre Battle, Bottom of the 9th */
case 0x130de:
case 0x278b0:
jpeg_decode_OB(hle);
return;
return &jpeg_decode_OB;
}
HleWarnMessage(hle->user_defined, "unknown OSTask: sum: %x PC:%x", sum, *hle->sp_pc);
#ifdef ENABLE_TASK_DUMP
dump_unknown_task(hle, sum);
#endif
/* Resident Evil 2 */
sum = sum_bytes((void*)dram_u32(hle, *dmem_u32(hle, TASK_UCODE)), 256);
switch (sum) {
case 0x450f:
return &resize_bilinear_task;
case 0x3b44:
return &decode_video_frame_task;
case 0x3d84:
return &fill_video_double_buffer_task;
}
/* HVQM */
sum = sum_bytes((void*)dram_u32(hle, *dmem_u32(hle, TASK_UCODE)), 1488);
switch (sum) {
case 0x19495:
return &hvqm2_decode_sp1_task;
case 0x19728:
return &hvqm2_decode_sp2_task;
}
return NULL;
}
static void non_task_dispatching(struct hle_t* hle)
static ucode_func_t non_task_detection(struct hle_t* hle)
{
const unsigned int sum = sum_bytes(hle->imem, 44);
if (sum == 0x9e2)
{
/* CIC x105 ucode (used during boot of CIC x105 games) */
cicx105_ucode(hle);
return;
return &cicx105_ucode;
}
HleWarnMessage(hle->user_defined, "unknown RSP code: sum: %x PC:%x", sum, *hle->sp_pc);
#ifdef ENABLE_TASK_DUMP
dump_unknown_non_task(hle, sum);
#endif
return &unknown_ucode;
}
static ucode_func_t task_detection(struct hle_t* hle)
{
if (is_task(hle)) {
ucode_func_t uc_pfunc;
uint32_t type = *dmem_u32(hle, TASK_TYPE);
if (type == 2) {
if (hle->hle_aud) {
return &send_alist_to_audio_plugin;
}
uc_pfunc = try_audio_task_detection(hle);
if (uc_pfunc)
return uc_pfunc;
}
uc_pfunc = try_normal_task_detection(hle);
if (uc_pfunc)
return uc_pfunc;
if (type == 1) {
if (hle->hle_gfx) {
return &send_dlist_to_gfx_plugin;
}
}
return &unknown_task;
}
else {
return non_task_detection(hle);
}
}
#ifdef ENABLE_TASK_DUMP
static void dump_unknown_task(struct hle_t* hle, unsigned int sum)
static void dump_unknown_task(struct hle_t* hle, unsigned int uc_start)
{
char filename[256];
uint32_t ucode = *dmem_u32(hle, TASK_UCODE);
uint32_t ucode_data = *dmem_u32(hle, TASK_UCODE_DATA);
uint32_t data_ptr = *dmem_u32(hle, TASK_DATA_PTR);
sprintf(&filename[0], "task_%x.log", sum);
sprintf(&filename[0], "task_%x.log", uc_start);
dump_task(hle, filename);
/* dump ucode_boot */
sprintf(&filename[0], "ucode_boot_%x.bin", sum);
dump_binary(filename, (void*)dram_u32(hle, *dmem_u32(hle, TASK_UCODE_BOOT)), *dmem_u32(hle, TASK_UCODE_BOOT_SIZE));
sprintf(&filename[0], "ucode_boot_%x.bin", uc_start);
dump_binary(hle, filename, (void*)dram_u32(hle, *dmem_u32(hle, TASK_UCODE_BOOT)), *dmem_u32(hle, TASK_UCODE_BOOT_SIZE));
/* dump ucode */
if (ucode != 0) {
sprintf(&filename[0], "ucode_%x.bin", sum);
dump_binary(filename, (void*)dram_u32(hle, ucode), 0xf80);
sprintf(&filename[0], "ucode_%x.bin", uc_start);
dump_binary(hle, filename, (void*)dram_u32(hle, ucode), 0xf80);
}
/* dump ucode_data */
if (ucode_data != 0) {
sprintf(&filename[0], "ucode_data_%x.bin", sum);
dump_binary(filename, (void*)dram_u32(hle, ucode_data), *dmem_u32(hle, TASK_UCODE_DATA_SIZE));
sprintf(&filename[0], "ucode_data_%x.bin", uc_start);
dump_binary(hle, filename, (void*)dram_u32(hle, ucode_data), *dmem_u32(hle, TASK_UCODE_DATA_SIZE));
}
/* dump data */
if (data_ptr != 0) {
sprintf(&filename[0], "data_%x.bin", sum);
dump_binary(filename, (void*)dram_u32(hle, data_ptr), *dmem_u32(hle, TASK_DATA_SIZE));
sprintf(&filename[0], "data_%x.bin", uc_start);
dump_binary(hle, filename, (void*)dram_u32(hle, data_ptr), *dmem_u32(hle, TASK_DATA_SIZE));
}
}
static void dump_unknown_non_task(struct hle_t* hle, unsigned int sum)
static void dump_unknown_non_task(struct hle_t* hle, unsigned int uc_start)
{
char filename[256];
/* dump IMEM & DMEM for further analysis */
sprintf(&filename[0], "imem_%x.bin", sum);
dump_binary(filename, hle->imem, 0x1000);
sprintf(&filename[0], "imem_%x.bin", uc_start);
dump_binary(hle, filename, hle->imem, 0x1000);
sprintf(&filename[0], "dmem_%x.bin", sum);
dump_binary(filename, hle->dmem, 0x1000);
sprintf(&filename[0], "dmem_%x.bin", uc_start);
dump_binary(hle, filename, hle->dmem, 0x1000);
}
static void dump_binary(const char *const filename, const unsigned char *const bytes,
unsigned int size)
static void dump_binary(struct hle_t* hle, const char *const filename,
const unsigned char *const bytes, unsigned int size)
{
FILE *f;
@ -402,10 +483,10 @@ static void dump_binary(const char *const filename, const unsigned char *const b
f = fopen(filename, "wb");
if (f != NULL) {
if (fwrite(bytes, 1, size, f) != size)
hleErrorMessage(hle->user_defined, "Writing error on %s", filename);
HleErrorMessage(hle->user_defined, "Writing error on %s", filename);
fclose(f);
} else
hleErrorMessage(hle->user_defined, "Couldn't open %s for writing !", filename);
HleErrorMessage(hle->user_defined, "Couldn't open %s for writing !", filename);
} else
fclose(f);
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - hle.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* *
* This program is free software; you can redistribute it and/or modify *

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - hle_external.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* *
* This program is free software; you can redistribute it and/or modify *
@ -22,17 +22,25 @@
#ifndef HLE_EXTERNAL_H
#define HLE_EXTERNAL_H
#if defined(__GNUC__)
#define ATTR_FMT(fmtpos, attrpos) __attribute__ ((format (printf, fmtpos, attrpos)))
#else
#define ATTR_FMT(fmtpos, attrpos)
#endif
/* users of the hle core are expected to define these functions */
void HleVerboseMessage(void* user_defined, const char *message, ...);
void HleErrorMessage(void* user_defined, const char *message, ...);
void HleWarnMessage(void* user_defined, const char *message, ...);
void HleVerboseMessage(void* user_defined, const char *message, ...) ATTR_FMT(2, 3);
void HleInfoMessage(void* user_defined, const char *message, ...) ATTR_FMT(2, 3);
void HleErrorMessage(void* user_defined, const char *message, ...) ATTR_FMT(2, 3);
void HleWarnMessage(void* user_defined, const char *message, ...) ATTR_FMT(2, 3);
void HleCheckInterrupts(void* user_defined);
void HleProcessDlistList(void* user_defined);
void HleProcessAlistList(void* user_defined);
void HleProcessRdpList(void* user_defined);
void HleShowCFB(void* user_defined);
int HleForwardTask(void* user_defined);
#endif

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - hle_internal.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* *
* This program is free software; you can redistribute it and/or modify *
@ -57,6 +57,8 @@ struct hle_t
/* for user convenience, this will be passed to "external" functions */
void* user_defined;
int hle_gfx;
int hle_aud;
/* alist.c */
uint8_t alist_buffer[0x1000];
@ -72,7 +74,20 @@ struct hle_t
/* mp3.c */
uint8_t mp3_buffer[0x1000];
struct cached_ucodes_t cached_ucodes;
};
/* some mips interface interrupt flags */
#define MI_INTR_SP 0x1
/* some rsp status flags */
#define SP_STATUS_HALT 0x1
#define SP_STATUS_BROKE 0x2
#define SP_STATUS_INTR_ON_BREAK 0x40
#define SP_STATUS_TASKDONE 0x200
void rsp_break(struct hle_t* hle, unsigned int setbits);
#endif

View File

@ -0,0 +1,354 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - hvqm.c *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2020 Gilles Siberlin *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "hle_external.h"
#include "hle_internal.h"
#include "memory.h"
/* Nest size */
#define HVQM2_NESTSIZE_L 70 /* Number of elements on long side */
#define HVQM2_NESTSIZE_S 38 /* Number of elements on short side */
#define HVQM2_NESTSIZE (HVQM2_NESTSIZE_L * HVQM2_NESTSIZE_S)
struct HVQM2Block {
uint8_t nbase;
uint8_t dc;
uint8_t dc_l;
uint8_t dc_r;
uint8_t dc_u;
uint8_t dc_d;
};
struct HVQM2Basis {
uint8_t sx;
uint8_t sy;
int16_t scale;
uint16_t offset;
uint16_t lineskip;
};
struct HVQM2Arg {
uint32_t info;
uint32_t buf;
uint16_t buf_width;
uint8_t chroma_step_h;
uint8_t chroma_step_v;
uint16_t hmcus;
uint16_t vmcus;
uint8_t alpha;
uint32_t nest;
};
struct RGBA {
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a;
};
static struct HVQM2Arg arg;
static const int16_t constant[5][16] = {
{0x0006,0x0008,0x0008,0x0006,0x0008,0x000A,0x000A,0x0008,0x0008,0x000A,0x000A,0x0008,0x0006,0x0008,0x0008,0x0006},
{0x0002,0x0000,0xFFFF,0xFFFF,0x0002,0x0000,0xFFFF,0xFFFF,0x0002,0x0000,0xFFFF,0xFFFF,0x0002,0x0000,0xFFFF,0xFFFF},
{0xFFFF,0xFFFF,0x0000,0x0002,0xFFFF,0xFFFF,0x0000,0x0002,0xFFFF,0xFFFF,0x0000,0x0002,0xFFFF,0xFFFF,0x0000,0x0002},
{0x0002,0x0002,0x0002,0x0002,0x0000,0x0000,0x0000,0x0000,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF},
{0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x0000,0x0000,0x0000,0x0000,0x0002,0x0002,0x0002,0x0002}
};
static int process_info(struct hle_t* hle, uint8_t* base, int16_t* out)
{
struct HVQM2Block block;
uint8_t nbase = *base;
dram_load_u8(hle, (uint8_t*)&block, arg.info, sizeof(struct HVQM2Block));
arg.info += 8;
*base = block.nbase & 0x7;
if ((block.nbase & nbase) != 0)
return 0;
if (block.nbase == 0)
{
//LABEL8
for (int i = 0; i < 16; i++)
{
out[i] = constant[0][i] * block.dc;
out[i] += constant[1][i] * block.dc_l;
out[i] += constant[2][i] * block.dc_r;
out[i] += constant[3][i] * block.dc_u;
out[i] += constant[4][i] * block.dc_d;
out[i] += 4;
out[i] >>= 3;
}
}
else if ((block.nbase & 0xf) == 0)
{
//LABEL7
for (int i = 0; i < 16; i++)
{
out[i] = *dram_u8(hle, arg.info);
arg.info++;
}
}
else if (*base == 0)
{
//LABEL6
for (int i = 0; i < 16; i++)
{
out[i] = *(int8_t*)dram_u8(hle, arg.info) + block.dc;
arg.info++;
}
}
else
{
//LABEL5
struct HVQM2Basis basis;
for (int i = 0; i < 16; i++)
out[i] = block.dc;
for (; *base != 0; (*base)--)
{
basis.sx = *dram_u8(hle, arg.info);
arg.info++;
basis.sy = *dram_u8(hle, arg.info);
arg.info++;
basis.scale = *dram_u16(hle, arg.info);
arg.info += 2;
basis.offset = *dram_u16(hle, arg.info);
arg.info += 2;
basis.lineskip = *dram_u16(hle, arg.info);
arg.info += 2;
int16_t vec[16];
uint32_t addr = arg.nest + basis.offset;
int shift = (basis.sx != 0) ? 1 : 0;
//LABEL9
//LABEL10
for (int i = 0; i < 16; i += 4)
{
vec[i] = *dram_u8(hle, addr);
vec[i + 1] = *dram_u8(hle, addr + (1 << shift));
vec[i + 2] = *dram_u8(hle, addr + (2 << shift));
vec[i + 3] = *dram_u8(hle, addr + (3 << shift));
addr += basis.lineskip;
}
//LABEL11
int16_t sum = 0x8;
for (int i = 0; i < 16; i++)
sum += vec[i];
sum >>= 4;
int16_t max = 0;
for (int i = 0; i < 16; i++)
{
vec[i] -= sum;
max = (abs(vec[i]) > max) ? abs(vec[i]) : max;
}
double dmax = 0.0;
if (max > 0)
dmax = (double)(basis.scale << 2) / (double)max;
for (int i = 0; i < 16; i++)
out[i] += (vec[i] < 0) ? (int16_t)((double)vec[i] * dmax - 0.5) : (int16_t)((double)vec[i] * dmax + 0.5);
block.nbase &= 8;
}
assert(block.nbase == 0);
//if(block.nbase != 0)
// LABEL6
}
return 1;
}
#define SATURATE8(x) ((unsigned int) x <= 255 ? x : (x < 0 ? 0: 255))
static struct RGBA YCbCr_to_RGBA(int16_t Y, int16_t Cb, int16_t Cr, uint8_t alpha)
{
struct RGBA color;
//Format S10.6
int r = (int)(((double)Y + 0.5) + (1.765625 * (double)(Cr - 128)));
int g = (int)(((double)Y + 0.5) - (0.34375 * (double)(Cr - 128)) - (0.71875 * (double)(Cb - 128)));
int b = (int)(((double)Y + 0.5) + (1.40625 * (double)(Cb - 128)));
color.r = SATURATE8(r);
color.g = SATURATE8(g);
color.b = SATURATE8(b);
color.a = alpha;
return color;
}
void store_rgba5551(struct hle_t* hle, struct RGBA color, uint32_t * addr)
{
uint16_t pixel = ((color.b >> 3) << 11) | ((color.g >> 3) << 6) | ((color.r >> 3) << 1) | (color.a & 1);
dram_store_u16(hle, &pixel, *addr, 1);
*addr += 2;
}
void store_rgba8888(struct hle_t* hle, struct RGBA color, uint32_t * addr)
{
uint32_t pixel = (color.b << 24) | (color.g << 16) | (color.r << 8) | color.a;
dram_store_u32(hle, &pixel, *addr, 1);
*addr += 4;
}
typedef void(*store_pixel_t)(struct hle_t* hle, struct RGBA color, uint32_t * addr);
static void hvqm2_decode(struct hle_t* hle, int is32)
{
//uint32_t uc_data_ptr = *dmem_u32(hle, TASK_UCODE_DATA);
uint32_t data_ptr = *dmem_u32(hle, TASK_DATA_PTR);
assert((*dmem_u32(hle, TASK_FLAGS) & 0x1) == 0);
/* Fill HVQM2Arg struct */
arg.info = *dram_u32(hle, data_ptr);
data_ptr += 4;
arg.buf = *dram_u32(hle, data_ptr);
data_ptr += 4;
arg.buf_width = *dram_u16(hle, data_ptr);
data_ptr += 2;
arg.chroma_step_h = *dram_u8(hle, data_ptr);
data_ptr++;
arg.chroma_step_v = *dram_u8(hle, data_ptr);
data_ptr++;
arg.hmcus = *dram_u16(hle, data_ptr);
data_ptr += 2;
arg.vmcus = *dram_u16(hle, data_ptr);
data_ptr += 2;
arg.alpha = *dram_u8(hle, data_ptr);
arg.nest = data_ptr + 1;
assert(arg.chroma_step_h == 2);
assert((arg.chroma_step_v == 1) || (arg.chroma_step_v == 2));
assert((*hle->sp_status & 0x80) == 0); //SP_STATUS_YIELD
int length, skip;
store_pixel_t store_pixel;
if (is32)
{
length = 0x20;
skip = arg.buf_width << 2;
arg.buf_width <<= 4;
store_pixel = &store_rgba8888;
}
else
{
length = 0x10;
skip = arg.buf_width << 1;
arg.buf_width <<= 3;
store_pixel = &store_rgba5551;
}
if (arg.chroma_step_v == 2)
arg.buf_width += arg.buf_width;
for (int i = arg.vmcus; i != 0; i--)
{
uint32_t out;
int j;
for (j = arg.hmcus, out = arg.buf; j != 0; j--, out += length)
{
uint8_t base = 0x80;
int16_t Cb[16], Cr[16], Y1[32], Y2[32];
int16_t* pCb = Cb;
int16_t* pCr = Cr;
int16_t* pY1 = Y1;
int16_t* pY2 = Y2;
if (arg.chroma_step_v == 2)
{
if (process_info(hle, &base, pY1) == 0)
continue;
if (process_info(hle, &base, pY2) == 0)
continue;
pY1 = &Y1[16];
pY2 = &Y2[16];
}
if (process_info(hle, &base, pY1) == 0)
continue;
if (process_info(hle, &base, pY2) == 0)
continue;
if (process_info(hle, &base, Cr) == 0)
continue;
if (process_info(hle, &base, Cb) == 0)
continue;
pY1 = Y1;
pY2 = Y2;
uint32_t out_buf = out;
for (int k = 0; k < 4; k++)
{
for (int m = 0; m < arg.chroma_step_v; m++)
{
uint32_t addr = out_buf;
for (int l = 0; l < 4; l++)
{
struct RGBA color = YCbCr_to_RGBA(pY1[l], pCb[l >> 1], pCr[l >> 1], arg.alpha);
store_pixel(hle, color, &addr);
}
for (int l = 0; l < 4; l++)
{
struct RGBA color = YCbCr_to_RGBA(pY2[l], pCb[(l + 4) >> 1], pCr[(l + 4) >> 1], arg.alpha);
store_pixel(hle, color, &addr);
}
out_buf += skip;
pY1 += 4;
pY2 += 4;
}
pCr += 4;
pCb += 4;
}
}
arg.buf += arg.buf_width;
}
rsp_break(hle, SP_STATUS_TASKDONE);
}
void hvqm2_decode_sp1_task(struct hle_t* hle)
{
hvqm2_decode(hle, 0);
}
void hvqm2_decode_sp2_task(struct hle_t* hle)
{
hvqm2_decode(hle, 1);
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - jpeg.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2012 Bobby Smiles *
* Copyright (C) 2009 Richard Goedeken *
* Copyright (C) 2002 Hacktarux *
@ -25,8 +25,6 @@
#include <stdint.h>
#include <stdlib.h>
#include "common.h"
#include "arithmetics.h"
#include "hle_external.h"
#include "hle_internal.h"
@ -143,6 +141,7 @@ static const float IDCT_K[10] = {
void jpeg_decode_PS0(struct hle_t* hle)
{
jpeg_decode_std(hle, "PS0", RescaleYSubBlock, RescaleUVSubBlock, EmitYUVTileLine);
rsp_break(hle, SP_STATUS_TASKDONE);
}
/***************************************************************************
@ -152,6 +151,7 @@ void jpeg_decode_PS0(struct hle_t* hle)
void jpeg_decode_PS(struct hle_t* hle)
{
jpeg_decode_std(hle, "PS", NULL, NULL, EmitRGBATileLine);
rsp_break(hle, SP_STATUS_TASKDONE);
}
/***************************************************************************
@ -192,6 +192,7 @@ void jpeg_decode_OB(struct hle_t* hle)
address += (2 * 6 * SUBBLOCK_SIZE);
}
rsp_break(hle, SP_STATUS_TASKDONE);
}
@ -474,7 +475,7 @@ static void ReorderSubBlock(int16_t *dst, const int16_t *src, const unsigned int
unsigned int i;
/* source and destination sublocks cannot overlap */
assert(abs(dst - src) > SUBBLOCK_SIZE);
assert(labs(dst - src) > SUBBLOCK_SIZE);
for (i = 0; i < SUBBLOCK_SIZE; ++i)
dst[i] = src[table[i]];

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - memory.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* *
* This program is free software; you can redistribute it and/or modify *
@ -21,8 +21,6 @@
#include <string.h>
#include "common.h"
#include "memory.h"
/* Global functions */

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - memory.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* *
* This program is free software; you can redistribute it and/or modify *
@ -26,6 +26,7 @@
#include <stddef.h>
#include <stdint.h>
#include "common.h"
#include "hle_internal.h"
#ifdef M64P_BIG_ENDIAN

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - mp3.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* Copyright (C) 2009 Richard Goedeken *
* Copyright (C) 2002 Hacktarux *
@ -21,10 +21,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <string.h>
#include <stdint.h>
#include "common.h"
#include <string.h>
#include "arithmetics.h"
#include "hle_internal.h"

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - musyx.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2013 Bobby Smiles *
* *
* This program is free software; you can redistribute it and/or modify *
@ -20,14 +20,13 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stddef.h>
#include "common.h"
#include "arithmetics.h"
#include "audio.h"
#include "common.h"
#include "hle_external.h"
#include "hle_internal.h"
#include "memory.h"
@ -257,6 +256,8 @@ void musyx_v1_task(struct hle_t* hle)
dram_store_u16(hle, (uint16_t *)musyx.cc0, state_ptr + STATE_CC0, SUBFRAME_SIZE);
dram_store_u16(hle, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V1,
4);
rsp_break(hle, SP_STATUS_TASKDONE);
}
/**************************************************************************
@ -334,6 +335,8 @@ void musyx_v2_task(struct hle_t* hle)
sfd_ptr += SFD2_VOICES + MAX_VOICES * VOICE_SIZE;
}
rsp_break(hle, SP_STATUS_TASKDONE);
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - plugin.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* Copyright (C) 2009 Richard Goedeken *
* Copyright (C) 2002 Hacktarux *
@ -25,31 +25,32 @@
#include <string.h>
#include <stdio.h>
#include "../usf/usf.h"
#include "../main/main.h"
#include "../usf/usf_internal.h"
#include "usf/usf.h"
#include "usf/usf_internal.h"
#include "r4300/interupt.h"
#include "hle.h"
/* Global functions needed by HLE core */
void HleVerboseMessage(void* user_defined, const char *message, ...)
{
#ifdef DEBUG_INFO
usf_state_t* state;
va_list ap;
size_t len;
state = (usf_state_t*)user_defined;
if (state->debug_log)
{
va_start( ap, message );
vfprintf( state->debug_log, message, ap );
va_end( ap );
fputs( "\n", state->debug_log );
}
#endif
#ifdef DEBUG_INFO
usf_state_t* state;
va_list ap;
size_t len;
state = (usf_state_t*)user_defined;
if (state->debug_log)
{
va_start( ap, message );
vfprintf( state->debug_log, message, ap );
va_end( ap );
fputs( "\n", state->debug_log );
}
#endif
}
void HleErrorMessage(void* user_defined, const char *message, ...)
@ -74,6 +75,7 @@ void HleErrorMessage(void* user_defined, const char *message, ...)
void HleWarnMessage(void* user_defined, const char *message, ...)
{
#if 0
usf_state_t* state;
va_list ap;
size_t len;
@ -90,11 +92,12 @@ void HleWarnMessage(void* user_defined, const char *message, ...)
state->last_error = state->error_message;
state->stop = 1;
#endif
}
void HleCheckInterrupts(void* user_defined)
{
// check_interupt((usf_state_t*)user_defined);
check_interupt((usf_state_t*)user_defined);
}
void HleProcessDlistList(void* user_defined)
@ -117,3 +120,8 @@ void HleShowCFB(void* user_defined)
{
/* disabled */
}
int HleForwardTask(void* user_defined)
{
/* disabled */
}

View File

@ -0,0 +1,224 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - re2.c *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2016 Gilles Siberlin *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include "hle_external.h"
#include "hle_internal.h"
#include "memory.h"
#define SATURATE8(x) ((unsigned int) x <= 255 ? x : (x < 0 ? 0: 255))
/**************************************************************************
* Resident evil 2 ucodes
**************************************************************************/
void resize_bilinear_task(struct hle_t* hle)
{
int data_ptr = *dmem_u32(hle, TASK_UCODE_DATA);
int src_addr = *dram_u32(hle, data_ptr);
int dst_addr = *dram_u32(hle, data_ptr + 4);
int dst_width = *dram_u32(hle, data_ptr + 8);
int dst_height = *dram_u32(hle, data_ptr + 12);
int x_ratio = *dram_u32(hle, data_ptr + 16);
int y_ratio = *dram_u32(hle, data_ptr + 20);
#if 0 /* unused, but keep it for documentation purpose */
int dst_stride = *dram_u32(hle, data_ptr + 24);
#endif
int src_offset = *dram_u32(hle, data_ptr + 36);
int a, b, c ,d, index, y_index, xr, yr, blue, green, red, addr, i, j;
long long x, y, x_diff, y_diff, one_min_x_diff, one_min_y_diff;
unsigned short pixel;
src_addr += (src_offset >> 16) * (320 * 3);
x = y = 0;
for(i = 0; i < dst_height; i++)
{
yr = (int)(y >> 16);
y_diff = y - (yr << 16);
one_min_y_diff = 65536 - y_diff;
y_index = yr * 320;
x = 0;
for(j = 0; j < dst_width; j++)
{
xr = (int)(x >> 16);
x_diff = x - (xr << 16);
one_min_x_diff = 65536 - x_diff;
index = y_index + xr;
addr = src_addr + (index * 3);
dram_load_u8(hle, (uint8_t*)&a, addr, 3);
dram_load_u8(hle, (uint8_t*)&b, (addr + 3), 3);
dram_load_u8(hle, (uint8_t*)&c, (addr + (320 * 3)), 3);
dram_load_u8(hle, (uint8_t*)&d, (addr + (320 * 3) + 3), 3);
blue = (int)(((a&0xff)*one_min_x_diff*one_min_y_diff + (b&0xff)*x_diff*one_min_y_diff +
(c&0xff)*y_diff*one_min_x_diff + (d&0xff)*x_diff*y_diff) >> 32);
green = (int)((((a>>8)&0xff)*one_min_x_diff*one_min_y_diff + ((b>>8)&0xff)*x_diff*one_min_y_diff +
((c>>8)&0xff)*y_diff*one_min_x_diff + ((d>>8)&0xff)*x_diff*y_diff) >> 32);
red = (int)((((a>>16)&0xff)*one_min_x_diff*one_min_y_diff + ((b>>16)&0xff)*x_diff*one_min_y_diff +
((c>>16)&0xff)*y_diff*one_min_x_diff + ((d>>16)&0xff)*x_diff*y_diff) >> 32);
blue = (blue >> 3) & 0x001f;
green = (green >> 3) & 0x001f;
red = (red >> 3) & 0x001f;
pixel = (red << 11) | (green << 6) | (blue << 1) | 1;
dram_store_u16(hle, &pixel, dst_addr, 1);
dst_addr += 2;
x += x_ratio;
}
y += y_ratio;
}
rsp_break(hle, SP_STATUS_TASKDONE);
}
static uint32_t YCbCr_to_RGBA(uint8_t Y, uint8_t Cb, uint8_t Cr)
{
int r, g, b;
r = (int)(((double)Y * 0.582199097) + (0.701004028 * (double)(Cr - 128)));
g = (int)(((double)Y * 0.582199097) - (0.357070923 * (double)(Cr - 128)) - (0.172073364 * (double)(Cb - 128)));
b = (int)(((double)Y * 0.582199097) + (0.886001587 * (double)(Cb - 128)));
r = SATURATE8(r);
g = SATURATE8(g);
b = SATURATE8(b);
return (r << 24) | (g << 16) | (b << 8) | 0;
}
void decode_video_frame_task(struct hle_t* hle)
{
int data_ptr = *dmem_u32(hle, TASK_UCODE_DATA);
int pLuminance = *dram_u32(hle, data_ptr);
int pCb = *dram_u32(hle, data_ptr + 4);
int pCr = *dram_u32(hle, data_ptr + 8);
int pDestination = *dram_u32(hle, data_ptr + 12);
int nMovieWidth = *dram_u32(hle, data_ptr + 16);
int nMovieHeight = *dram_u32(hle, data_ptr + 20);
#if 0 /* unused, but keep it for documentation purpose */
int nRowsPerDMEM = *dram_u32(hle, data_ptr + 24);
int nDMEMPerFrame = *dram_u32(hle, data_ptr + 28);
int nLengthSkipCount = *dram_u32(hle, data_ptr + 32);
#endif
int nScreenDMAIncrement = *dram_u32(hle, data_ptr + 36);
int i, j;
uint8_t Y, Cb, Cr;
uint32_t pixel;
int pY_1st_row, pY_2nd_row, pDest_1st_row, pDest_2nd_row;
for (i = 0; i < nMovieHeight; i += 2)
{
pY_1st_row = pLuminance;
pY_2nd_row = pLuminance + nMovieWidth;
pDest_1st_row = pDestination;
pDest_2nd_row = pDestination + (nScreenDMAIncrement >> 1);
for (j = 0; j < nMovieWidth; j += 2)
{
dram_load_u8(hle, (uint8_t*)&Cb, pCb++, 1);
dram_load_u8(hle, (uint8_t*)&Cr, pCr++, 1);
/*1st row*/
dram_load_u8(hle, (uint8_t*)&Y, pY_1st_row++, 1);
pixel = YCbCr_to_RGBA(Y, Cb, Cr);
dram_store_u32(hle, &pixel, pDest_1st_row, 1);
pDest_1st_row += 4;
dram_load_u8(hle, (uint8_t*)&Y, pY_1st_row++, 1);
pixel = YCbCr_to_RGBA(Y, Cb, Cr);
dram_store_u32(hle, &pixel, pDest_1st_row, 1);
pDest_1st_row += 4;
/*2nd row*/
dram_load_u8(hle, (uint8_t*)&Y, pY_2nd_row++, 1);
pixel = YCbCr_to_RGBA(Y, Cb, Cr);
dram_store_u32(hle, &pixel, pDest_2nd_row, 1);
pDest_2nd_row += 4;
dram_load_u8(hle, (uint8_t*)&Y, pY_2nd_row++, 1);
pixel = YCbCr_to_RGBA(Y, Cb, Cr);
dram_store_u32(hle, &pixel, pDest_2nd_row, 1);
pDest_2nd_row += 4;
}
pLuminance += (nMovieWidth << 1);
pDestination += nScreenDMAIncrement;
}
rsp_break(hle, SP_STATUS_TASKDONE);
}
void fill_video_double_buffer_task(struct hle_t* hle)
{
int data_ptr = *dmem_u32(hle, TASK_UCODE_DATA);
int pSrc = *dram_u32(hle, data_ptr);
int pDest = *dram_u32(hle, data_ptr + 0x4);
int width = *dram_u32(hle, data_ptr + 0x8) >> 1;
int height = *dram_u32(hle, data_ptr + 0x10) << 1;
int stride = *dram_u32(hle, data_ptr + 0x1c) >> 1;
assert((*dram_u32(hle, data_ptr + 0x28) >> 16) == 0x8000);
#if 0 /* unused, but keep it for documentation purpose */
int arg3 = *dram_u32(hle, data_ptr + 0xc);
int arg5 = *dram_u32(hle, data_ptr + 0x14);
int arg6 = *dram_u32(hle, data_ptr + 0x18);
#endif
int i, j;
int r, g, b;
uint32_t pixel, pixel1, pixel2;
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j=j+4)
{
pixel1 = *dram_u32(hle, pSrc+j);
pixel2 = *dram_u32(hle, pDest+j);
r = (((pixel1 >> 24) & 0xff) + ((pixel2 >> 24) & 0xff)) >> 1;
g = (((pixel1 >> 16) & 0xff) + ((pixel2 >> 16) & 0xff)) >> 1;
b = (((pixel1 >> 8) & 0xff) + ((pixel2 >> 8) & 0xff)) >> 1;
pixel = (r << 24) | (g << 16) | (b << 8) | 0;
dram_store_u32(hle, &pixel, pDest+j, 1);
}
pSrc += stride;
pDest += stride;
}
rsp_break(hle, SP_STATUS_TASKDONE);
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-rsp-hle - ucodes.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Mupen64Plus homepage: https://mupen64plus.org/ *
* Copyright (C) 2014 Bobby Smiles *
* *
* This program is free software; you can redistribute it and/or modify *
@ -24,8 +24,23 @@
#include <stdint.h>
#define CACHED_UCODES_MAX_SIZE 16
struct hle_t;
typedef void(*ucode_func_t)(struct hle_t* hle);
struct ucode_info_t {
uint32_t uc_start;
uint32_t uc_dstart;
uint16_t uc_dsize;
ucode_func_t uc_pfunc;
};
struct cached_ucodes_t {
struct ucode_info_t infos[CACHED_UCODES_MAX_SIZE];
int count;
};
/* cic_x105 ucode */
void cicx105_ucode(struct hle_t* hle);
@ -126,7 +141,8 @@ void alist_process_nead_oot (struct hle_t* hle);
void alist_process_nead_mm (struct hle_t* hle);
void alist_process_nead_mmb (struct hle_t* hle);
void alist_process_nead_ac (struct hle_t* hle);
void alist_process_nead_mats(struct hle_t* hle);
void alist_process_nead_efz (struct hle_t* hle);
/* mp3 ucode */
void mp3_task(struct hle_t* hle, unsigned int index, uint32_t address);
@ -142,5 +158,14 @@ void jpeg_decode_PS0(struct hle_t* hle);
void jpeg_decode_PS(struct hle_t* hle);
void jpeg_decode_OB(struct hle_t* hle);
/* Resident evil 2 ucode */
void resize_bilinear_task(struct hle_t* hle);
void decode_video_frame_task(struct hle_t* hle);
void fill_video_double_buffer_task(struct hle_t* hle);
/* hvqm2 ucode */
void hvqm2_decode_sp1_task(struct hle_t* hle);
void hvqm2_decode_sp2_task(struct hle_t* hle);
#endif

View File

@ -199,6 +199,7 @@
8360EEF117F92AC8005208A4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
8360EEF317F92AC8005208A4 /* HighlyComplete-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "HighlyComplete-Prefix.pch"; sourceTree = "<group>"; };
83848FE61807623F00E7332D /* SSEQPlayer.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SSEQPlayer.xcodeproj; path = ../../Frameworks/SSEQPlayer/SSEQPlayer.xcodeproj; sourceTree = "<group>"; };
83AA660827B7CCB00098D4B8 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../../Utils/Logging.h; sourceTree = "<group>"; };
83CA241E1D7BC47C00F2EA53 /* mGBA.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = mGBA.xcodeproj; path = ../../Frameworks/mGBA/mGBA.xcodeproj; sourceTree = "<group>"; };
83DE0C34180A9BD400269051 /* vio2sf.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = vio2sf.xcodeproj; path = ../../Frameworks/vio2sf/vio2sf.xcodeproj; sourceTree = "<group>"; };
83E2F4C923566B0C006F7A41 /* lazyusf2.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = lazyusf2.xcodeproj; path = ../../Frameworks/lazyusf2/lazyusf2.xcodeproj; sourceTree = "<group>"; };
@ -308,6 +309,7 @@
8360EEED17F92AC8005208A4 /* HighlyComplete */ = {
isa = PBXGroup;
children = (
83AA660827B7CCB00098D4B8 /* Logging.h */,
83FAF8A318ADD27F00057CAF /* PlaylistController.h */,
8324C584181513A10046F78F /* circular_buffer.h */,
834379A717F9818400584396 /* HCDecoder.mm */,

View File

@ -8,6 +8,8 @@
#import "HCDecoder.h"
#import "Logging.h"
#import "hebios.h"
#import <psflib/psf2fs.h>
@ -931,7 +933,7 @@ static int usf_info(void *context, const char *name, const char *value) {
usf_clear(state.emu_state);
usf_set_hle_audio(state.emu_state, 0); // Sometimes buggy
usf_set_hle_audio(state.emu_state, 1);
emulatorCore = (uint8_t *)state.emu_state;
@ -1237,7 +1239,7 @@ static int usf_info(void *context, const char *name, const char *value) {
} else if(type == 0x21) {
const char *err;
if((err = usf_render_resampled(emulatorCore, (int16_t *)buf, frames, sampleRate)) != 0) {
fprintf(stderr, "%s\n", err);
DLog(@"USF Error: %s", err);
return 0;
}
} else if(type == 0x22) {