diff --git a/Frameworks/lazyusf2/lazyusf2.xcodeproj/project.pbxproj b/Frameworks/lazyusf2/lazyusf2.xcodeproj/project.pbxproj index 132b9846b..ed271c65d 100644 --- a/Frameworks/lazyusf2/lazyusf2.xcodeproj/project.pbxproj +++ b/Frameworks/lazyusf2/lazyusf2.xcodeproj/project.pbxproj @@ -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 = ""; }; 8379B5891AA4237E00F28A95 /* barray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = barray.h; sourceTree = ""; }; + 83AA660427B7CB490098D4B8 /* hvqm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hvqm.c; sourceTree = ""; }; + 83AA660527B7CB490098D4B8 /* re2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = re2.c; sourceTree = ""; }; 83C0787A1A9B544300ABBB67 /* resampler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resampler.c; sourceTree = ""; }; 83C0787B1A9B544300ABBB67 /* resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resampler.h; sourceTree = ""; }; 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 */, diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist.c b/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist.c index d3157155d..e509b3755 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist.c +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist.c @@ -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 #include #include #include @@ -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); } diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist.h b/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist.h index 99d765faf..2c2d40cfe 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist.h +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist.h @@ -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 -#include #include +#include 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, diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist_audio.c b/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist_audio.c index 3642cd44f..903268e94 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist_audio.c +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist_audio.c @@ -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); } diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist_naudio.c b/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist_naudio.c index 127ae9131..30891d23d 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist_naudio.c +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist_naudio.c @@ -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); } diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist_nead.c b/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist_nead.c index 5c0cbbc51..3a8fed8a6 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist_nead.c +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/alist_nead.c @@ -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); + } } diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/arithmetics.h b/Frameworks/lazyusf2/lazyusf2/rsp_hle/arithmetics.h index 529293d25..2250b248f 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/arithmetics.h +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/arithmetics.h @@ -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 * diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/audio.c b/Frameworks/lazyusf2/lazyusf2/rsp_hle/audio.c index e473d3460..fac2a101a 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/audio.c +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/audio.c @@ -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 #include -#include "common.h" - #include "arithmetics.h" const int16_t RESAMPLE_LUT[64 * 4] = { diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/audio.h b/Frameworks/lazyusf2/lazyusf2/rsp_hle/audio.h index 8524972ea..21c7a0916 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/audio.h +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/audio.h @@ -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 #include -#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; diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle.c b/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle.c index abb744d66..4e65113ab 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle.c +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle.c @@ -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 #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); } diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle.h b/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle.h index 3c705a939..a420b752d 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle.h +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle.h @@ -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 * diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle_external.h b/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle_external.h index 2f35a3c98..766cc51ea 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle_external.h +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle_external.h @@ -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 diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle_internal.h b/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle_internal.h index 352d956b5..efdca5c22 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle_internal.h +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/hle_internal.h @@ -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 diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/hvqm.c b/Frameworks/lazyusf2/lazyusf2/rsp_hle/hvqm.c new file mode 100644 index 000000000..8f8a943b6 --- /dev/null +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/hvqm.c @@ -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 +#include +#include +#include +#include + +#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); +} \ No newline at end of file diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/jpeg.c b/Frameworks/lazyusf2/lazyusf2/rsp_hle/jpeg.c index bde1d6b69..ff424c403 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/jpeg.c +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/jpeg.c @@ -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 #include -#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]]; diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/memory.c b/Frameworks/lazyusf2/lazyusf2/rsp_hle/memory.c index 0c1b82d51..7d5066bfa 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/memory.c +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/memory.c @@ -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 -#include "common.h" - #include "memory.h" /* Global functions */ diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/memory.h b/Frameworks/lazyusf2/lazyusf2/rsp_hle/memory.h index 91a747b16..9c8510483 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/memory.h +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/memory.h @@ -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 #include +#include "common.h" #include "hle_internal.h" #ifdef M64P_BIG_ENDIAN diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/mp3.c b/Frameworks/lazyusf2/lazyusf2/rsp_hle/mp3.c index 20a42c4d6..4e8ea14af 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/mp3.c +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/mp3.c @@ -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 #include - -#include "common.h" +#include #include "arithmetics.h" #include "hle_internal.h" diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/musyx.c b/Frameworks/lazyusf2/lazyusf2/rsp_hle/musyx.c index 36b7b7c5f..d5a630a03 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/musyx.c +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/musyx.c @@ -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 +#include #include #include -#include - -#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); } diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/plugin.c b/Frameworks/lazyusf2/lazyusf2/rsp_hle/plugin.c index 12d4d4c2e..0f767d5b9 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/plugin.c +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/plugin.c @@ -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 #include -#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 */ +} diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/re2.c b/Frameworks/lazyusf2/lazyusf2/rsp_hle/re2.c new file mode 100644 index 000000000..8ae178804 --- /dev/null +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/re2.c @@ -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 +#include +#include + +#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); +} diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/ucodes.h b/Frameworks/lazyusf2/lazyusf2/rsp_hle/ucodes.h index 1a12bf994..8d12bfb18 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/ucodes.h +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/ucodes.h @@ -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 +#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 diff --git a/Plugins/HighlyComplete/HighlyComplete.xcodeproj/project.pbxproj b/Plugins/HighlyComplete/HighlyComplete.xcodeproj/project.pbxproj index b0a6743e9..2ed67476f 100644 --- a/Plugins/HighlyComplete/HighlyComplete.xcodeproj/project.pbxproj +++ b/Plugins/HighlyComplete/HighlyComplete.xcodeproj/project.pbxproj @@ -199,6 +199,7 @@ 8360EEF117F92AC8005208A4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 8360EEF317F92AC8005208A4 /* HighlyComplete-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "HighlyComplete-Prefix.pch"; sourceTree = ""; }; 83848FE61807623F00E7332D /* SSEQPlayer.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SSEQPlayer.xcodeproj; path = ../../Frameworks/SSEQPlayer/SSEQPlayer.xcodeproj; sourceTree = ""; }; + 83AA660827B7CCB00098D4B8 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../../Utils/Logging.h; sourceTree = ""; }; 83CA241E1D7BC47C00F2EA53 /* mGBA.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = mGBA.xcodeproj; path = ../../Frameworks/mGBA/mGBA.xcodeproj; sourceTree = ""; }; 83DE0C34180A9BD400269051 /* vio2sf.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = vio2sf.xcodeproj; path = ../../Frameworks/vio2sf/vio2sf.xcodeproj; sourceTree = ""; }; 83E2F4C923566B0C006F7A41 /* lazyusf2.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = lazyusf2.xcodeproj; path = ../../Frameworks/lazyusf2/lazyusf2.xcodeproj; sourceTree = ""; }; @@ -308,6 +309,7 @@ 8360EEED17F92AC8005208A4 /* HighlyComplete */ = { isa = PBXGroup; children = ( + 83AA660827B7CCB00098D4B8 /* Logging.h */, 83FAF8A318ADD27F00057CAF /* PlaylistController.h */, 8324C584181513A10046F78F /* circular_buffer.h */, 834379A717F9818400584396 /* HCDecoder.mm */, diff --git a/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm b/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm index a62fde988..4ffa54aa8 100644 --- a/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm +++ b/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm @@ -8,6 +8,8 @@ #import "HCDecoder.h" +#import "Logging.h" + #import "hebios.h" #import @@ -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) {