You've already forked HackerSM64
mirror of
https://github.com/HackerN64/HackerSM64.git
synced 2026-01-21 10:35:32 -08:00
Compare commits
8 Commits
develop/2.
...
develop/2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc3a4186c5 | ||
|
|
0028b33597 | ||
|
|
df0c4d11a3 | ||
|
|
77a3e81fc4 | ||
|
|
b3ca34cfa2 | ||
|
|
8be89acaf8 | ||
|
|
7de132ca34 | ||
|
|
dd9f0eeec1 |
2
.vscode/c_cpp_properties.json
vendored
2
.vscode/c_cpp_properties.json
vendored
@@ -25,7 +25,7 @@
|
||||
"TARGET_N64=1",
|
||||
"VERSION_US=1",
|
||||
"F3DEX_GBI_2=1",
|
||||
"F3DZEX_NON_GBI_2=1",
|
||||
"F3DZEX_GBI_2=1",
|
||||
"F3DEX_GBI_SHARED=1",
|
||||
"NON_MATCHING=1",
|
||||
"AVOID_UB=1"
|
||||
|
||||
2
Makefile
2
Makefile
@@ -108,7 +108,7 @@ else ifeq ($(GRUCODE),l3dex2) # Line3DEX2
|
||||
else ifeq ($(GRUCODE),f3dex2pl) # Fast3DEX2_PosLight
|
||||
DEFINES += F3DEX2PL_GBI=1 F3DEX_GBI_2=1 F3DEX_GBI_SHARED=1
|
||||
else ifeq ($(GRUCODE),f3dzex) # Fast3DZEX (2.08J / Animal Forest - DĹŤbutsu no Mori)
|
||||
DEFINES += F3DZEX_NON_GBI_2=1 F3DEX_GBI_2=1 F3DEX_GBI_SHARED=1
|
||||
DEFINES += F3DZEX_GBI_2=1 F3DEX_GBI_2=1 F3DEX_GBI_SHARED=1
|
||||
else ifeq ($(GRUCODE),super3d) # Super3D
|
||||
$(warning Super3D is experimental. Try at your own risk.)
|
||||
DEFINES += SUPER3D_GBI=1 F3D_NEW=1
|
||||
|
||||
@@ -33,7 +33,7 @@ This is a fork of the ultrasm64 repo by CrashOveride which includes the followin
|
||||
Thanks to Frame#5375 and AloXado320 for also helping with silhouette stuff
|
||||
|
||||
**Lighting Engine by Wiseguy**
|
||||
- Lighting Engine is available on a separate branch ([base/lighting-engine](https://github.com/Reonu/HackerSM64/tree/base/lighting-engine)). Instructions on how to use it are in the readme of that branch.
|
||||
- Lighting Engine is available on a separate branch ([base/lighting-engine-wip](https://github.com/Reonu/HackerSM64/tree/base/lighting-engine-wip)). Instructions on how to use it are in the readme of that branch.
|
||||
- Alternatively, the main repo has `Puppylights` available, which is a more lightweight, but limited lighting library intended to be used to modify existing light properties. You can look at `puppylights.c` to find out how to use it.
|
||||
|
||||
**Puppycam**
|
||||
|
||||
@@ -15,9 +15,14 @@
|
||||
.word 0x00000000 /* Unknown */
|
||||
.word 0x00000000 /* Unknown */
|
||||
.ascii INTERNAL_ROM_NAME /* Internal ROM name */
|
||||
#if defined(USE_GAMECUBE_CONTROLLER)
|
||||
/* Advanced homebrew ROM header bytes: https://n64brew.dev/wiki/ROM_Header#Advanced_Homebrew_ROM_Header */
|
||||
.word 0x82000000
|
||||
#else
|
||||
.word 0x00000000 /* Unknown */
|
||||
#endif
|
||||
.word 0x0000004E /* Cartridge */
|
||||
#if defined(EEP4K)
|
||||
#if defined(EEP4K) && !defined(USE_GAMECUBE_CONTROLLER)
|
||||
.ascii "SM" /* Cartridge ID */
|
||||
#else
|
||||
.ascii "ED" /* Cartridge ID */
|
||||
|
||||
@@ -9,11 +9,6 @@
|
||||
*/
|
||||
#define CASTLE_MUSIC_FIX
|
||||
|
||||
/**
|
||||
* Do not restart the music on cap grabs
|
||||
*/
|
||||
#define PERSISTENT_CAP_MUSIC
|
||||
|
||||
/**
|
||||
* Increase audio heap size to allow for larger/more custom sequences/banks/sfx to be imported without causing issues (not supported for SH).
|
||||
*/
|
||||
@@ -33,3 +28,8 @@
|
||||
* Reverb parameters can be configured in audio/synthesis.c to meet desired aesthetic/performance needs. Currently US/JP only. Hurts emulator and console performance.
|
||||
*/
|
||||
// #define BETTER_REVERB
|
||||
|
||||
/**
|
||||
* Do not restart the music on cap grabs
|
||||
*/
|
||||
#define PERSISTENT_CAP_MUSIC
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
// Number of walls that can push Mario at once. Vanilla is 4.
|
||||
#define MAX_REFERENCED_WALLS 4
|
||||
|
||||
// Allow vertical rooms to be a thing by using the SURFACE_INTANGIBLE floor type to separate the rooms. Note that this will add an extra floor check every frame.
|
||||
// #define VERTICAL_ROOMS
|
||||
|
||||
// Collision data is the type that the collision system uses. All data by default is stored as an s16, but you may change it to s32.
|
||||
// Naturally, that would double the size of all collision data, but would allow you to use 32 bit values instead of 16.
|
||||
// Rooms are s8 in vanilla, but if you somehow have more than 255 rooms, you may raise this number.
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
// Similar to the above, but 30 FPS (Textures by InTheBeef, cleaned up by Arceveti)
|
||||
#define IA8_30FPS_COINS
|
||||
|
||||
// Use .rej microcode for certain objects (experimental - only should be used when F3DEX_GBI_2 is defined).
|
||||
// Use .rej microcode for certain objects (experimental - only should be used when F3DZEX_GBI_2 is defined).
|
||||
// For advanced users only. Does not work perfectly out the box, best used when exported actor models are
|
||||
// using 64 vertex sizes, offered by Fast64 in the microcode menu.
|
||||
// #define OBJECTS_REJ
|
||||
|
||||
@@ -23,3 +23,6 @@
|
||||
// There is generally no reason to have a value other than 0 for emulator. As for console, it provides a (small) performance boost.
|
||||
#define BORDER_HEIGHT_CONSOLE 0
|
||||
#define BORDER_HEIGHT_EMULATOR 0
|
||||
|
||||
// Informs supported emulators to default to gamecube controller inputs
|
||||
// #define USE_GAMECUBE_CONTROLLER
|
||||
|
||||
@@ -54,9 +54,9 @@
|
||||
* config_graphics
|
||||
*/
|
||||
|
||||
#ifndef F3DEX_GBI_2
|
||||
#undef OBJECTS_REJ // OBJECTS_REJ requires f3dex2.
|
||||
#endif // !F3DEX_GBI_2
|
||||
#ifndef F3DZEX_GBI_2
|
||||
#undef OBJECTS_REJ // OBJECTS_REJ requires f3dzex.
|
||||
#endif // !F3DZEX_GBI_2
|
||||
|
||||
#ifndef F3DEX_GBI_SHARED
|
||||
#undef OBJECTS_REJ // Non F3DEX-based ucodes do NOT support ucode switching.
|
||||
|
||||
@@ -63,6 +63,18 @@ typedef struct {
|
||||
u8 error;
|
||||
} OSContPad;
|
||||
|
||||
// Custom extended controller pad struct that contains fields for gamecube controllers
|
||||
typedef struct {
|
||||
u16 button;
|
||||
s8 stick_x; /* -80 <= stick_x <= 80 */
|
||||
s8 stick_y; /* -80 <= stick_y <= 80 */
|
||||
s8 c_stick_x;
|
||||
s8 c_stick_y;
|
||||
u8 l_trig;
|
||||
u8 r_trig;
|
||||
u8 errno;
|
||||
} OSContPadEx;
|
||||
|
||||
typedef struct {
|
||||
void *address; /* Ram pad Address: 11 bits */
|
||||
u8 databuffer[32]; /* address of the data buffer */
|
||||
@@ -103,6 +115,7 @@ typedef struct {
|
||||
#define CONT_ABSOLUTE 0x0001
|
||||
#define CONT_RELATIVE 0x0002
|
||||
#define CONT_JOYPORT 0x0004
|
||||
#define CONT_GCN 0x0008
|
||||
#define CONT_EEPROM 0x8000
|
||||
#define CONT_EEP16K 0x4000
|
||||
#define CONT_TYPE_MASK 0x1f07
|
||||
@@ -150,6 +163,25 @@ typedef struct {
|
||||
#define L_CBUTTONS CONT_C
|
||||
#define R_CBUTTONS CONT_F
|
||||
#define D_CBUTTONS CONT_D
|
||||
#define GCN_X_BUTTON 0x0040
|
||||
#define GCN_Y_BUTTON 0x0080
|
||||
|
||||
/* Gamecube controller buttons */
|
||||
|
||||
#define CONT_GCN_GET_ORIGIN 0x2000
|
||||
#define CONT_GCN_START 0x1000
|
||||
#define CONT_GCN_Y 0x0800
|
||||
#define CONT_GCN_X 0x0400
|
||||
#define CONT_GCN_B 0x0200
|
||||
#define CONT_GCN_A 0x0100
|
||||
#define CONT_GCN_USE_ORIGIN 0x0080
|
||||
#define CONT_GCN_L 0x0040
|
||||
#define CONT_GCN_R 0x0020
|
||||
#define CONT_GCN_Z 0x0010
|
||||
#define CONT_GCN_UP 0x0008
|
||||
#define CONT_GCN_DOWN 0x0004
|
||||
#define CONT_GCN_RIGHT 0x0002
|
||||
#define CONT_GCN_LEFT 0x0001
|
||||
|
||||
/* Controller error number */
|
||||
|
||||
@@ -162,6 +194,9 @@ typedef struct {
|
||||
#define CONT_ERR_VOICE_WORD 14
|
||||
#define CONT_ERR_VOICE_NO_RESPONSE 15
|
||||
|
||||
#define CONT_TYPE_N64 0
|
||||
#define CONT_TYPE_GCN 1
|
||||
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
@@ -178,6 +213,7 @@ typedef struct {
|
||||
*
|
||||
*/
|
||||
|
||||
extern u8 __osControllerTypes[MAXCONTROLLERS];
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
@@ -191,11 +227,13 @@ extern s32 osContInit( OSMesgQueue *mq, u8 *bitpattern, OSContStatus *s
|
||||
extern s32 osContReset( OSMesgQueue *mq, OSContStatus *status);
|
||||
extern s32 osContStartQuery( OSMesgQueue *mq);
|
||||
extern s32 osContStartReadData(OSMesgQueue *mq);
|
||||
extern s32 osContStartReadDataEx(OSMesgQueue *mq);
|
||||
#ifndef _HW_VERSION_1
|
||||
extern s32 osContSetCh(u8 ch);
|
||||
#endif
|
||||
extern void osContGetQuery(OSContStatus *status);
|
||||
extern void osContGetReadData(OSContPad *pad);
|
||||
extern void osContGetReadDataEx(OSContPadEx *pad);
|
||||
|
||||
|
||||
#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */
|
||||
|
||||
@@ -62,12 +62,14 @@ extern "C" {
|
||||
/* Rumble PAK interface */
|
||||
|
||||
extern s32 osMotorInit(OSMesgQueue *mq, OSPfs *pfs, int controller_no);
|
||||
extern s32 osMotorInitEx(OSMesgQueue *mq, OSPfs *pfs, int controller_no);
|
||||
#if 1
|
||||
#define MOTOR_START 1
|
||||
#define MOTOR_STOP 0
|
||||
#define osMotorStart(x) __osMotorAccess((x), MOTOR_START)
|
||||
#define osMotorStop(x) __osMotorAccess((x), MOTOR_STOP)
|
||||
#define osMotorStart(x) __osMotorAccessEx((x), MOTOR_START)
|
||||
#define osMotorStop(x) __osMotorAccessEx((x), MOTOR_STOP)
|
||||
extern s32 __osMotorAccess(OSPfs *pfs, s32 flag);
|
||||
extern s32 __osMotorAccessEx(OSPfs *pfs, s32 flag);
|
||||
#else
|
||||
extern s32 osMotorStop( OSPfs *pfs);
|
||||
extern s32 osMotorStart(OSPfs *pfs);
|
||||
|
||||
@@ -715,7 +715,8 @@ enum MarioActionFlags {
|
||||
#define VALID_BUTTONS (A_BUTTON | B_BUTTON | Z_TRIG | START_BUTTON | \
|
||||
U_JPAD | D_JPAD | L_JPAD | R_JPAD | \
|
||||
L_TRIG | R_TRIG | \
|
||||
U_CBUTTONS | D_CBUTTONS | L_CBUTTONS | R_CBUTTONS )
|
||||
U_CBUTTONS | D_CBUTTONS | L_CBUTTONS | R_CBUTTONS | \
|
||||
GCN_X_BUTTON | GCN_Y_BUTTON)
|
||||
|
||||
#define C_BUTTONS (U_CBUTTONS | D_CBUTTONS | L_CBUTTONS | R_CBUTTONS )
|
||||
|
||||
|
||||
@@ -40,11 +40,10 @@ struct Controller {
|
||||
/*0x0C*/ f32 stickMag; // distance from center [0, 64]
|
||||
/*0x10*/ u16 buttonDown;
|
||||
/*0x12*/ u16 buttonPressed;
|
||||
/*0x14*/ u16 buttonReleased;
|
||||
/*0x18*/ OSContStatus *statusData;
|
||||
/*0x1C*/ OSContPad *controllerData;
|
||||
/*0x14*/ OSContStatus *statusData;
|
||||
/*0x18*/ OSContPadEx *controllerData;
|
||||
#if ENABLE_RUMBLE
|
||||
/*0x20*/ s32 port;
|
||||
/*0x1C*/ s32 port;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
2
sm64.ld
2
sm64.ld
@@ -186,6 +186,8 @@ SECTIONS
|
||||
lib/PR/audio/n_aspMain.o(.text*);
|
||||
lib/PR/hvqm/hvqm2sp1.o(.text*);
|
||||
_mainSegmentTextEnd = .;
|
||||
/* Overwrite a libultra function with its modified counterpart for GCN controller support */
|
||||
__osContGetInitData = __osContGetInitDataEx;
|
||||
|
||||
/* data */
|
||||
BUILD_DIR/asm/n64_assert.o(.*data*);
|
||||
|
||||
@@ -1059,6 +1059,7 @@ void init_reverb_us(s32 presetId) {
|
||||
s32 i;
|
||||
#ifdef BETTER_REVERB
|
||||
s8 reverbConsole;
|
||||
s32 bufOffset = 0;
|
||||
#endif
|
||||
|
||||
s32 reverbWindowSize = gReverbSettings[presetId].windowSize;
|
||||
@@ -1111,7 +1112,9 @@ void init_reverb_us(s32 presetId) {
|
||||
gSynthesisReverb.items[1][i].toDownsampleRight = (mem + (DEFAULT_LEN_1CH / sizeof(s16)));
|
||||
}
|
||||
#ifdef BETTER_REVERB
|
||||
initialize_better_reverb_buffers();
|
||||
delayBufsL = (s32**) soundAlloc(&gBetterReverbPool, BETTER_REVERB_PTR_SIZE);
|
||||
delayBufsR = &delayBufsL[NUM_ALLPASS];
|
||||
delayBufsL[0] = (s32*) soundAlloc(&gBetterReverbPool, BETTER_REVERB_SIZE - BETTER_REVERB_PTR_SIZE);
|
||||
#endif
|
||||
} else {
|
||||
bzero(gSynthesisReverb.ringBuffer.left, (REVERB_WINDOW_SIZE_MAX * 2 * sizeof(s16)));
|
||||
@@ -1143,10 +1146,17 @@ void init_reverb_us(s32 presetId) {
|
||||
#ifdef BETTER_REVERB
|
||||
if (toggleBetterReverb) {
|
||||
if (sAudioIsInitialized) {
|
||||
clear_better_reverb_buffers();
|
||||
}
|
||||
bzero(delayBufsL[0], (BETTER_REVERB_SIZE - BETTER_REVERB_PTR_SIZE));
|
||||
}
|
||||
|
||||
set_better_reverb_buffers();
|
||||
for (i = 0; i < NUM_ALLPASS; ++i) {
|
||||
delaysL[i] = (delaysBaselineL[i] / gReverbDownsampleRate);
|
||||
delaysR[i] = (delaysBaselineR[i] / gReverbDownsampleRate);
|
||||
delayBufsL[i] = (s32*) &delayBufsL[0][bufOffset];
|
||||
bufOffset += delaysL[i];
|
||||
delayBufsR[i] = (s32*) &delayBufsL[0][bufOffset]; // L and R buffers are interpolated adjacently in memory; not a bug
|
||||
bufOffset += delaysR[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -93,9 +93,6 @@ extern struct SoundAllocPool gAudioInitPool;
|
||||
extern struct SoundAllocPool gNotesAndBuffersPool;
|
||||
extern struct SoundAllocPool gPersistentCommonPool;
|
||||
extern struct SoundAllocPool gTemporaryCommonPool;
|
||||
#ifdef BETTER_REVERB
|
||||
extern struct SoundAllocPool gBetterReverbPool;
|
||||
#endif
|
||||
extern struct SoundMultiPool gSeqLoadedPool;
|
||||
extern struct SoundMultiPool gBankLoadedPool;
|
||||
#ifdef VERSION_SH
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
// You can change this value before audio_reset_session gets called if different levels can tolerate the demand better than others or just have different reverb goals.
|
||||
// A higher downsample value hits the game's frequency limit sooner, which can cause the reverb sometimes to be off pitch. This is a vanilla level issue (and also counter intuitive).
|
||||
// Higher downsample values also result in slightly shorter reverb decay times.
|
||||
s8 betterReverbDownsampleConsole = 2;
|
||||
s8 betterReverbDownsampleConsole = 3;
|
||||
|
||||
// Most emulators can handle a default value of 2, but 3 may be advisable in some cases if targeting older emulators (e.g. PJ64 1.6). Setting this to -1 also uses vanilla reverb.
|
||||
// Using a value of 1 is not recommended on emulator unless reducing other parameters to compensate. If you do decide to use 1 here, you must adjust BETTER_REVERB_SIZE appropriately.
|
||||
@@ -80,22 +80,22 @@ s8 betterReverbDownsampleEmulator = 2;
|
||||
|
||||
// This value represents the number of filters to use with the reverb. This can be decreased to improve performance, but at the cost of a lesser presence of reverb in the final audio.
|
||||
// Filter count should always be a multiple of 3. Never ever set this value to be greater than NUM_ALLPASS.
|
||||
// This value cannot be less than 3. Setting it to anything lower will act as if it was set to 3.
|
||||
// Setting it to anything less than 3 will disable reverb outright.
|
||||
// This can be changed at any time, but is best set immediately before calling audio_reset_session.
|
||||
s32 reverbFilterCountConsole = (NUM_ALLPASS - 9);
|
||||
u32 reverbFilterCountConsole = (NUM_ALLPASS - 6);
|
||||
|
||||
// This value represents the number of filters to use with the reverb. This can be decreased to improve performance, but at the cost of a lesser presence of reverb in the final audio.
|
||||
// Filter count should always be a multiple of 3. Never ever set this value to be greater than NUM_ALLPASS.
|
||||
// This value cannot be less than 3. Setting it to anything lower will act as if it was set to 3.
|
||||
// Setting it to anything less than 3 will disable reverb outright.
|
||||
// This can be changed at any time, but is best set immediately before calling audio_reset_session.
|
||||
s32 reverbFilterCountEmulator = NUM_ALLPASS;
|
||||
u32 reverbFilterCountEmulator = NUM_ALLPASS;
|
||||
|
||||
// Set this to TRUE to use mono over stereo for reverb. This should increase performance, but at the cost of a less fulfilling reverb experience.
|
||||
// Set this to TRUE to use mono over stereo for reverb. This should increase performance, but at the cost of a less fullfilling reverb experience.
|
||||
// If performance is desirable, it is recommended to change reverbFilterCountConsole or betterReverbDownsampleConsole first.
|
||||
// This can be changed at any time, but is best set immediately before calling audio_reset_session.
|
||||
u8 monoReverbConsole = FALSE;
|
||||
|
||||
// Set this to TRUE to use mono over stereo for reverb. This should increase performance, but at the cost of a less fulfilling reverb experience.
|
||||
// Set this to TRUE to use mono over stereo for reverb. This should increase performance, but at the cost of a less fullfilling reverb experience.
|
||||
// If performance is desirable, it is recommended to change reverbFilterCountEmulator or betterReverbDownsampleEmulator first.
|
||||
// This can be changed at any time, but is best set immediately before calling audio_reset_session.
|
||||
u8 monoReverbEmulator = FALSE;
|
||||
@@ -111,7 +111,7 @@ s32 betterReverbWindowsSize = -1;
|
||||
// Setting these to values larger than 0xFF (255) or less than 0 may cause issues and is not recommended.
|
||||
#define REVERB_REV_INDEX 0x60 // Affects decay time mostly (large values can cause terrible feedback!); can be messed with at any time
|
||||
#define REVERB_GAIN_INDEX 0xA0 // Affects signal immediately retransmitted back into buffers (mid-high values yield the strongest effect); can be messed with at any time
|
||||
#define REVERB_WET_SIGNAL 0xE0 // Amount of reverb specific output in final signal (also affects decay); can be messed with at any time, also very easy to control
|
||||
#define REVERB_WET_SIGNAL 0xE8 // Amount of reverb specific output in final signal (also affects decay); can be messed with at any time, also very easy to control
|
||||
|
||||
// #define REVERB_DRY_SIGNAL = 0x00; // Amount of original input in final signal (large values can cause terrible feedback!); declaration and uses commented out by default to improve compiler optimization
|
||||
|
||||
@@ -136,25 +136,26 @@ s32 delaysBaselineR[NUM_ALLPASS] = {
|
||||
1200, 1432, 1232
|
||||
};
|
||||
|
||||
// These values affect reverb decay depending on the filter index; can be messed with at any time, and will have effects updated in real time
|
||||
s32 gReverbMultsL[NUM_ALLPASS / 3] = {0xD7, 0x6F, 0x36, 0x22};
|
||||
s32 gReverbMultsR[NUM_ALLPASS / 3] = {0xCF, 0x73, 0x38, 0x1F};
|
||||
// These values affect reverb decay depending on the filter index; can be messed with at any time
|
||||
s32 reverbMultsL[NUM_ALLPASS / 3] = {0xD7, 0x6F, 0x36, 0x22};
|
||||
s32 reverbMultsR[NUM_ALLPASS / 3] = {0xCF, 0x73, 0x38, 0x1F};
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------END REVERB PARAMETERS----------------------------------------------------------------------- */
|
||||
|
||||
// Do not touch these values manually, unless you want potential for problems.
|
||||
s32 reverbFilterCount = NUM_ALLPASS;
|
||||
s32 reverbFilterCountm1 = (NUM_ALLPASS - 1);
|
||||
u8 monoReverb = FALSE;
|
||||
u8 toggleBetterReverb = TRUE;
|
||||
static u8 monoReverb = FALSE;
|
||||
static s32 reverbFilterCount = NUM_ALLPASS;
|
||||
static s32 allpassIdxL[NUM_ALLPASS] = {0};
|
||||
static s32 allpassIdxR[NUM_ALLPASS] = {0};
|
||||
static s32 delaysL[NUM_ALLPASS] = {0};
|
||||
static s32 delaysR[NUM_ALLPASS] = {0};
|
||||
static u8 reverbMultsL[NUM_ALLPASS / 3] = {0};
|
||||
static u8 reverbMultsR[NUM_ALLPASS / 3] = {0};
|
||||
static s32 **delayBufsL;
|
||||
static s32 **delayBufsR;
|
||||
s32 allpassIdxL[NUM_ALLPASS] = {0};
|
||||
s32 allpassIdxR[NUM_ALLPASS] = {0};
|
||||
s32 tmpBufL[NUM_ALLPASS] = {0};
|
||||
s32 tmpBufR[NUM_ALLPASS] = {0};
|
||||
s32 delaysL[NUM_ALLPASS] = {0};
|
||||
s32 delaysR[NUM_ALLPASS] = {0};
|
||||
s32 **delayBufsL;
|
||||
s32 **delayBufsR;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -192,109 +193,72 @@ u8 sAudioSynthesisPad[0x20];
|
||||
#endif
|
||||
|
||||
#ifdef BETTER_REVERB
|
||||
static void reverb_samples(s16 *outSampleL, s16 *outSampleR, s32 inSampleL, s32 inSampleR) {
|
||||
s32 *curDelaySampleL;
|
||||
s32 *curDelaySampleR;
|
||||
s32 historySampleL;
|
||||
s32 historySampleR;
|
||||
static inline void reverb_samples(s16 *outSampleL, s16 *outSampleR, s32 inSampleL, s32 inSampleR) {
|
||||
s32 i = 0;
|
||||
s32 j = 0;
|
||||
s32 k = 0;
|
||||
s32 outTmpL = 0;
|
||||
s32 outTmpR = 0;
|
||||
s32 tmpCarryoverL = (((delayBufsL[reverbFilterCount][allpassIdxL[reverbFilterCount]] * REVERB_REV_INDEX) >> 8) + inSampleL);
|
||||
s32 tmpCarryoverR = (((delayBufsR[reverbFilterCount][allpassIdxR[reverbFilterCount]] * REVERB_REV_INDEX) >> 8) + inSampleR);
|
||||
s32 tmpCarryoverL = (((tmpBufL[reverbFilterCountm1] * REVERB_REV_INDEX) / 256) + inSampleL);
|
||||
s32 tmpCarryoverR = (((tmpBufR[reverbFilterCountm1] * REVERB_REV_INDEX) / 256) + inSampleR);
|
||||
|
||||
for (; i <= reverbFilterCount; ++i, ++j) {
|
||||
curDelaySampleL = &delayBufsL[i][allpassIdxL[i]];
|
||||
curDelaySampleR = &delayBufsR[i][allpassIdxR[i]];
|
||||
historySampleL = *curDelaySampleL;
|
||||
historySampleR = *curDelaySampleR;
|
||||
for (; i != reverbFilterCount; ++i, ++j) {
|
||||
tmpBufL[i] = delayBufsL[i][allpassIdxL[i]];
|
||||
tmpBufR[i] = delayBufsR[i][allpassIdxR[i]];
|
||||
|
||||
if (j == 2) {
|
||||
j = -1;
|
||||
outTmpL += ((historySampleL * reverbMultsL[k ]) >> 8);
|
||||
outTmpR += ((historySampleR * reverbMultsR[k++]) >> 8);
|
||||
*curDelaySampleL = tmpCarryoverL;
|
||||
*curDelaySampleR = tmpCarryoverR;
|
||||
if (i != reverbFilterCount) {
|
||||
tmpCarryoverL = ((historySampleL * REVERB_REV_INDEX) >> 8);
|
||||
tmpCarryoverR = ((historySampleR * REVERB_REV_INDEX) >> 8);
|
||||
outTmpL += ((tmpBufL[i] * reverbMultsL[k ]) / 256);
|
||||
outTmpR += ((tmpBufR[i] * reverbMultsR[k++]) / 256);
|
||||
delayBufsL[i][allpassIdxL[i]] = tmpCarryoverL;
|
||||
delayBufsR[i][allpassIdxR[i]] = tmpCarryoverR;
|
||||
if (i != reverbFilterCountm1) {
|
||||
tmpCarryoverL = ((tmpBufL[i] * REVERB_REV_INDEX) / 256);
|
||||
tmpCarryoverR = ((tmpBufR[i] * REVERB_REV_INDEX) / 256);
|
||||
}
|
||||
} else {
|
||||
*curDelaySampleL = (((historySampleL * (-REVERB_GAIN_INDEX)) >> 8) + tmpCarryoverL);
|
||||
*curDelaySampleR = (((historySampleR * (-REVERB_GAIN_INDEX)) >> 8) + tmpCarryoverR);
|
||||
tmpCarryoverL = (((*curDelaySampleL * REVERB_GAIN_INDEX) >> 8) + historySampleL);
|
||||
tmpCarryoverR = (((*curDelaySampleR * REVERB_GAIN_INDEX) >> 8) + historySampleR);
|
||||
delayBufsL[i][allpassIdxL[i]] = (((tmpBufL[i] * (-REVERB_GAIN_INDEX)) / 256) + tmpCarryoverL);
|
||||
delayBufsR[i][allpassIdxR[i]] = (((tmpBufR[i] * (-REVERB_GAIN_INDEX)) / 256) + tmpCarryoverR);
|
||||
tmpCarryoverL = (((delayBufsL[i][allpassIdxL[i]] * REVERB_GAIN_INDEX) / 256) + tmpBufL[i]);
|
||||
tmpCarryoverR = (((delayBufsR[i][allpassIdxR[i]] * REVERB_GAIN_INDEX) / 256) + tmpBufR[i]);
|
||||
}
|
||||
|
||||
if (++allpassIdxL[i] == delaysL[i]) allpassIdxL[i] = 0;
|
||||
if (++allpassIdxR[i] == delaysR[i]) allpassIdxR[i] = 0;
|
||||
}
|
||||
|
||||
s32 outUnclamped = ((outTmpL * REVERB_WET_SIGNAL/* + inSampleL * REVERB_DRY_SIGNAL*/) >> 8);
|
||||
s32 outUnclamped = ((outTmpL * REVERB_WET_SIGNAL/* + inSampleL * REVERB_DRY_SIGNAL*/) / 256);
|
||||
*outSampleL = CLAMP_S16(outUnclamped);
|
||||
outUnclamped = ((outTmpR * REVERB_WET_SIGNAL/* + inSampleL * REVERB_DRY_SIGNAL*/) >> 8);
|
||||
outUnclamped = ((outTmpR * REVERB_WET_SIGNAL/* + inSampleL * REVERB_DRY_SIGNAL*/) / 256);
|
||||
*outSampleR = CLAMP_S16(outUnclamped);
|
||||
}
|
||||
|
||||
static void reverb_mono_sample(s16 *outSample, s32 inSample) {
|
||||
s32 *curDelaySample;
|
||||
s32 historySample;
|
||||
static inline void reverb_mono_sample(s16 *outSample, s32 inSample) {
|
||||
s32 i = 0;
|
||||
s32 j = 0;
|
||||
s32 k = 0;
|
||||
s32 outTmp = 0;
|
||||
s32 tmpCarryover = (((delayBufsL[reverbFilterCount][allpassIdxL[reverbFilterCount]] * REVERB_REV_INDEX) >> 8) + inSample);
|
||||
s32 tmpCarryover = (((tmpBufL[reverbFilterCountm1] * REVERB_REV_INDEX) / 256) + inSample);
|
||||
|
||||
for (; i <= reverbFilterCount; ++i, ++j) {
|
||||
curDelaySample = &delayBufsL[i][allpassIdxL[i]];
|
||||
historySample = *curDelaySample;
|
||||
for (; i != reverbFilterCount; ++i, ++j) {
|
||||
tmpBufL[i] = delayBufsL[i][allpassIdxL[i]];
|
||||
|
||||
if (j == 2) {
|
||||
j = -1;
|
||||
outTmp += ((historySample * reverbMultsL[k++]) >> 8);
|
||||
*curDelaySample = tmpCarryover;
|
||||
if (i != reverbFilterCount)
|
||||
tmpCarryover = ((historySample * REVERB_REV_INDEX) >> 8);
|
||||
outTmp += ((tmpBufL[i] * reverbMultsL[k++]) / 256);
|
||||
delayBufsL[i][allpassIdxL[i]] = tmpCarryover;
|
||||
if (i != reverbFilterCountm1)
|
||||
tmpCarryover = ((tmpBufL[i] * REVERB_REV_INDEX) / 256);
|
||||
} else {
|
||||
*curDelaySample = (((historySample * (-REVERB_GAIN_INDEX)) >> 8) + tmpCarryover);
|
||||
tmpCarryover = (((*curDelaySample * REVERB_GAIN_INDEX) >> 8) + historySample);
|
||||
delayBufsL[i][allpassIdxL[i]] = (((tmpBufL[i] * (-REVERB_GAIN_INDEX)) / 256) + tmpCarryover);
|
||||
tmpCarryover = (((delayBufsL[i][allpassIdxL[i]] * REVERB_GAIN_INDEX) / 256) + tmpBufL[i]);
|
||||
}
|
||||
|
||||
if (++allpassIdxL[i] == delaysL[i]) allpassIdxL[i] = 0;
|
||||
if (++allpassIdxL[i] == delaysL[i])
|
||||
allpassIdxL[i] = 0;
|
||||
}
|
||||
|
||||
s32 outUnclamped = ((outTmp * REVERB_WET_SIGNAL/* + inSample * REVERB_DRY_SIGNAL*/) >> 8);
|
||||
s32 outUnclamped = ((outTmp * REVERB_WET_SIGNAL/* + inSample * REVERB_DRY_SIGNAL*/) / 256);
|
||||
*outSample = CLAMP_S16(outUnclamped);
|
||||
}
|
||||
|
||||
void initialize_better_reverb_buffers(void) {
|
||||
delayBufsL = (s32**) soundAlloc(&gBetterReverbPool, BETTER_REVERB_PTR_SIZE);
|
||||
delayBufsR = &delayBufsL[NUM_ALLPASS];
|
||||
delayBufsL[0] = (s32*) soundAlloc(&gBetterReverbPool, BETTER_REVERB_SIZE - BETTER_REVERB_PTR_SIZE);
|
||||
}
|
||||
|
||||
void clear_better_reverb_buffers(void) {
|
||||
bzero(delayBufsL[0], (BETTER_REVERB_SIZE - BETTER_REVERB_PTR_SIZE));
|
||||
|
||||
bzero(allpassIdxL, sizeof(allpassIdxL));
|
||||
bzero(allpassIdxR, sizeof(allpassIdxR));
|
||||
}
|
||||
|
||||
void set_better_reverb_buffers(void) {
|
||||
s32 bufOffset = 0;
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < NUM_ALLPASS; ++i) {
|
||||
delaysL[i] = (delaysBaselineL[i] / gReverbDownsampleRate);
|
||||
delaysR[i] = (delaysBaselineR[i] / gReverbDownsampleRate);
|
||||
delayBufsL[i] = (s32*) &delayBufsL[0][bufOffset];
|
||||
bufOffset += delaysL[i];
|
||||
delayBufsR[i] = (s32*) &delayBufsL[0][bufOffset]; // L and R buffers are interpolated adjacently in memory; not a bug
|
||||
bufOffset += delaysR[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_EU
|
||||
@@ -397,7 +361,6 @@ void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex) {
|
||||
}
|
||||
#ifdef BETTER_REVERB
|
||||
else if (toggleBetterReverb) {
|
||||
reverbFilterCount--; // Temporarily lower filter count for optimized bulk processing
|
||||
item = &gSynthesisReverb.items[gSynthesisReverb.curFrame][updateIndex];
|
||||
if (gSoundMode == SOUND_MODE_MONO || monoReverb) {
|
||||
if (gReverbDownsampleRate != 1) {
|
||||
@@ -434,7 +397,6 @@ void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex) {
|
||||
reverb_samples(&gSynthesisReverb.ringBuffer.left[dstPos], &gSynthesisReverb.ringBuffer.right[dstPos], gSynthesisReverb.ringBuffer.left[dstPos], gSynthesisReverb.ringBuffer.right[dstPos]);
|
||||
}
|
||||
}
|
||||
reverbFilterCount++; // Reset filter count to accurate numbers
|
||||
}
|
||||
#endif
|
||||
item = &gSynthesisReverb.items[gSynthesisReverb.curFrame][updateIndex];
|
||||
@@ -594,31 +556,18 @@ u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) {
|
||||
|
||||
#ifdef BETTER_REVERB
|
||||
if (gIsConsole) {
|
||||
reverbFilterCount = reverbFilterCountConsole;
|
||||
reverbFilterCount = (s32) reverbFilterCountConsole;
|
||||
monoReverb = monoReverbConsole;
|
||||
} else {
|
||||
reverbFilterCount = reverbFilterCountEmulator;
|
||||
reverbFilterCount = (s32) reverbFilterCountEmulator;
|
||||
monoReverb = monoReverbEmulator;
|
||||
}
|
||||
if (reverbFilterCount > NUM_ALLPASS) {
|
||||
reverbFilterCount = NUM_ALLPASS;
|
||||
} else if (reverbFilterCount < 3) {
|
||||
reverbFilterCount = 3;
|
||||
}
|
||||
|
||||
s32 filterCountDiv3 = reverbFilterCount / 3;
|
||||
reverbFilterCount = filterCountDiv3 * 3; // reverbFilterCount should always be a multiple of 3.
|
||||
|
||||
// Update reverbMultsL every audio frame just in case gReverbMults is ever to change.
|
||||
for (i = 0; i < filterCountDiv3; ++i) {
|
||||
reverbMultsL[i] = gReverbMultsL[i];
|
||||
reverbMultsR[i] = gReverbMultsR[i];
|
||||
}
|
||||
|
||||
// If there's only one reverb multiplier set, adjust these to match so one channel doesn't end up potentially overpowering the other.
|
||||
if (filterCountDiv3 == 1) {
|
||||
reverbMultsL[0] = (reverbMultsR[0] + reverbMultsL[0]) / 2;
|
||||
reverbMultsR[0] = reverbMultsL[0];
|
||||
reverbFilterCountm1 = (reverbFilterCount - 1);
|
||||
if (reverbFilterCount < 3) {
|
||||
reverbFilterCountm1 = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -33,16 +33,20 @@
|
||||
|
||||
extern s8 betterReverbDownsampleConsole;
|
||||
extern s8 betterReverbDownsampleEmulator;
|
||||
extern u32 reverbFilterCountConsole;
|
||||
extern u32 reverbFilterCountEmulator;
|
||||
extern u8 monoReverbConsole;
|
||||
extern u8 monoReverbEmulator;
|
||||
extern s32 reverbFilterCountConsole;
|
||||
extern s32 reverbFilterCountEmulator;
|
||||
extern s32 betterReverbWindowsSize;
|
||||
|
||||
extern s32 delaysBaselineL[NUM_ALLPASS];
|
||||
extern s32 delaysBaselineR[NUM_ALLPASS];
|
||||
extern s32 gReverbMultsL[NUM_ALLPASS / 3];
|
||||
extern s32 gReverbMultsR[NUM_ALLPASS / 3];
|
||||
extern s32 delaysL[NUM_ALLPASS];
|
||||
extern s32 delaysR[NUM_ALLPASS];
|
||||
extern s32 reverbMultsL[NUM_ALLPASS / 3];
|
||||
extern s32 reverbMultsR[NUM_ALLPASS / 3];
|
||||
extern s32 **delayBufsL;
|
||||
extern s32 **delayBufsR;
|
||||
|
||||
extern u8 toggleBetterReverb;
|
||||
#define REVERB_WINDOW_SIZE_MAX 0x2000
|
||||
@@ -145,12 +149,6 @@ extern struct SynthesisReverb gSynthesisReverb;
|
||||
extern s16 D_SH_803479B4;
|
||||
#endif
|
||||
|
||||
#ifdef BETTER_REVERB
|
||||
void initialize_better_reverb_buffers(void);
|
||||
void clear_better_reverb_buffers(void);
|
||||
void set_better_reverb_buffers(void);
|
||||
#endif
|
||||
|
||||
u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen);
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
void note_init_volume(struct Note *note);
|
||||
|
||||
@@ -428,7 +428,7 @@ void thread2_crash_screen(UNUSED void *arg) {
|
||||
#if ENABLE_RUMBLE
|
||||
block_until_rumble_pak_free();
|
||||
#endif
|
||||
osContStartReadData(&gSIEventMesgQueue);
|
||||
osContStartReadDataEx(&gSIEventMesgQueue);
|
||||
}
|
||||
read_controller_inputs(THREAD_2_CRASH_SCREEN);
|
||||
draw_crash_screen(thread);
|
||||
|
||||
@@ -42,8 +42,9 @@ struct GfxPool *gGfxPool;
|
||||
|
||||
// OS Controllers
|
||||
OSContStatus gControllerStatuses[4];
|
||||
OSContPad gControllerPads[4];
|
||||
OSContPadEx gControllerPads[4];
|
||||
u8 gControllerBits;
|
||||
s8 gGamecubeControllerPort = -1; // HackerSM64: This is set to -1 if there's no GC controller, 0 if there's one in the first port and 1 if there's one in the second port.
|
||||
u8 gIsConsole = TRUE; // Needs to be initialized before audio_reset_session is called
|
||||
u8 gBorderHeight;
|
||||
#ifdef VANILLA_STYLE_CUSTOM_DEBUG
|
||||
@@ -294,11 +295,6 @@ void create_gfx_task_structure(void) {
|
||||
gGfxSPTask->task.t.ucode_data = gspF3DZEX2_PosLight_fifoDataStart;
|
||||
gGfxSPTask->task.t.ucode_size = ((u8 *) gspF3DZEX2_PosLight_fifoTextEnd - (u8 *) gspF3DZEX2_PosLight_fifoTextStart);
|
||||
gGfxSPTask->task.t.ucode_data_size = ((u8 *) gspF3DZEX2_PosLight_fifoDataEnd - (u8 *) gspF3DZEX2_PosLight_fifoDataStart);
|
||||
#elif F3DZEX_NON_GBI_2
|
||||
gGfxSPTask->task.t.ucode = gspF3DZEX2_NoN_PosLight_fifoTextStart;
|
||||
gGfxSPTask->task.t.ucode_data = gspF3DZEX2_NoN_PosLight_fifoDataStart;
|
||||
gGfxSPTask->task.t.ucode_size = ((u8 *) gspF3DZEX2_NoN_PosLight_fifoTextEnd - (u8 *) gspF3DZEX2_NoN_PosLight_fifoTextStart);
|
||||
gGfxSPTask->task.t.ucode_data_size = ((u8 *) gspF3DZEX2_NoN_PosLight_fifoDataEnd - (u8 *) gspF3DZEX2_NoN_PosLight_fifoDataStart);
|
||||
#elif F3DEX2PL_GBI
|
||||
gGfxSPTask->task.t.ucode = gspF3DEX2_PosLight_fifoTextStart;
|
||||
gGfxSPTask->task.t.ucode_data = gspF3DEX2_PosLight_fifoDataStart;
|
||||
@@ -600,7 +596,7 @@ void read_controller_inputs(s32 threadID) {
|
||||
if (threadID == THREAD_5_GAME_LOOP) {
|
||||
osRecvMesg(&gSIEventMesgQueue, &gMainReceivedMesg, OS_MESG_BLOCK);
|
||||
}
|
||||
osContGetReadData(&gControllerPads[0]);
|
||||
osContGetReadDataEx(&gControllerPads[0]);
|
||||
#if ENABLE_RUMBLE
|
||||
release_rumble_pak_control();
|
||||
#endif
|
||||
@@ -611,13 +607,24 @@ void read_controller_inputs(s32 threadID) {
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
struct Controller *controller = &gControllers[i];
|
||||
|
||||
// HackerSM64: Swaps Z and L, only on console, and only when playing with a GameCube controller.
|
||||
u32 oldButton = controller->controllerData->button;
|
||||
if (gIsConsole && (gGamecubeControllerPort >= 0)) {
|
||||
u32 newButton = oldButton & ~(Z_TRIG | L_TRIG);
|
||||
if (oldButton & Z_TRIG) {
|
||||
newButton |= L_TRIG;
|
||||
}
|
||||
if (controller->controllerData->l_trig > 85) { // How far the player has to press the L trigger for it to be considered a Z press. 64 is about 25%. 127 would be about 50%.
|
||||
newButton |= Z_TRIG;
|
||||
}
|
||||
controller->controllerData->button = newButton;
|
||||
}
|
||||
// if we're receiving inputs, update the controller struct with the new button info.
|
||||
if (controller->controllerData != NULL) {
|
||||
controller->rawStickX = controller->controllerData->stick_x;
|
||||
controller->rawStickY = controller->controllerData->stick_y;
|
||||
controller->buttonPressed = ~controller->buttonDown & controller->controllerData->button;
|
||||
controller->buttonReleased = ~controller->controllerData->button & controller->buttonDown;
|
||||
controller->buttonPressed = controller->controllerData->button
|
||||
& (controller->controllerData->button ^ controller->buttonDown);
|
||||
// 0.5x A presses are a good meme
|
||||
controller->buttonDown = controller->controllerData->button;
|
||||
adjust_analog_stick(controller);
|
||||
@@ -625,7 +632,6 @@ void read_controller_inputs(s32 threadID) {
|
||||
controller->rawStickX = 0;
|
||||
controller->rawStickY = 0;
|
||||
controller->buttonPressed = 0;
|
||||
controller->buttonReleased = 0;
|
||||
controller->buttonDown = 0;
|
||||
controller->stickX = 0;
|
||||
controller->stickY = 0;
|
||||
@@ -642,7 +648,6 @@ void read_controller_inputs(s32 threadID) {
|
||||
gPlayer3Controller->stickY = gPlayer1Controller->stickY;
|
||||
gPlayer3Controller->stickMag = gPlayer1Controller->stickMag;
|
||||
gPlayer3Controller->buttonPressed = gPlayer1Controller->buttonPressed;
|
||||
gPlayer3Controller->buttonReleased = gPlayer1Controller->buttonReleased;
|
||||
gPlayer3Controller->buttonDown = gPlayer1Controller->buttonDown;
|
||||
}
|
||||
|
||||
@@ -688,6 +693,15 @@ void init_controllers(void) {
|
||||
gControllers[cont++].controllerData = &gControllerPads[port];
|
||||
}
|
||||
}
|
||||
if (__osControllerTypes[1] == CONT_TYPE_GCN) {
|
||||
gGamecubeControllerPort = 1;
|
||||
gPlayer1Controller = &gControllers[1];
|
||||
} else {
|
||||
if (__osControllerTypes[0] == CONT_TYPE_GCN) {
|
||||
gGamecubeControllerPort = 0;
|
||||
}
|
||||
gPlayer1Controller = &gControllers[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Game thread core
|
||||
@@ -778,7 +792,7 @@ void thread5_game_loop(UNUSED void *arg) {
|
||||
#if ENABLE_RUMBLE
|
||||
block_until_rumble_pak_free();
|
||||
#endif
|
||||
osContStartReadData(&gSIEventMesgQueue);
|
||||
osContStartReadDataEx(&gSIEventMesgQueue);
|
||||
}
|
||||
|
||||
audio_game_loop_tick();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user