Compare commits

..

6 Commits

Author SHA1 Message Date
Reonu
35e75ade73 Add VERTICAL_ROOMS define 2022-06-29 02:31:13 +01:00
Mr-Wiseguy
1166d7441d Merge branch 'master' into develop/2.1.0 2022-06-17 01:08:18 -04:00
Gregory Heskett
5ef0e8c9f6 Bugfix, refactor, and slightly improve BETTER_REVERB runtime (#391)
* Buxfix, refactor, and slightly improve BETTER_REVERB runtime

* Update BETTER_REVERB defaults and add some more customizability

* Improve BETTER_REVERB runtime even further

* Rename some reverb variables to make more sense in context
2022-06-17 00:05:40 -05:00
axollyon
25b421aaae Added buttonReleased member in the controller struct (#421) 2022-06-17 00:48:20 -04:00
Reonu
ad91c636ad Update name of lighting engine branch in readme
sorry for pushing to master :(((((((((((((
2022-01-22 11:11:51 +02:00
Mr-Wiseguy
475e039f8a Fixed hackersm64 using a ucode that never existed (#309) 2022-01-15 03:13:40 +00:00
15 changed files with 170 additions and 108 deletions

View File

@@ -25,7 +25,7 @@
"TARGET_N64=1",
"VERSION_US=1",
"F3DEX_GBI_2=1",
"F3DZEX_GBI_2=1",
"F3DZEX_NON_GBI_2=1",
"F3DEX_GBI_SHARED=1",
"NON_MATCHING=1",
"AVOID_UB=1"

View File

@@ -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_GBI_2=1 F3DEX_GBI_2=1 F3DEX_GBI_SHARED=1
DEFINES += F3DZEX_NON_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

View File

@@ -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-wip](https://github.com/Reonu/HackerSM64/tree/base/lighting-engine-wip)). Instructions on how to use it are in the readme of that branch.
- 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.
- 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**

View File

@@ -9,6 +9,11 @@
*/
#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).
*/
@@ -28,8 +33,3 @@
* 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

View File

@@ -17,6 +17,9 @@
// 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.

View File

@@ -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 F3DZEX_GBI_2 is defined).
// Use .rej microcode for certain objects (experimental - only should be used when F3DEX_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

View File

@@ -54,9 +54,9 @@
* config_graphics
*/
#ifndef F3DZEX_GBI_2
#undef OBJECTS_REJ // OBJECTS_REJ requires f3dzex.
#endif // !F3DZEX_GBI_2
#ifndef F3DEX_GBI_2
#undef OBJECTS_REJ // OBJECTS_REJ requires f3dex2.
#endif // !F3DEX_GBI_2
#ifndef F3DEX_GBI_SHARED
#undef OBJECTS_REJ // Non F3DEX-based ucodes do NOT support ucode switching.

View File

@@ -40,10 +40,11 @@ struct Controller {
/*0x0C*/ f32 stickMag; // distance from center [0, 64]
/*0x10*/ u16 buttonDown;
/*0x12*/ u16 buttonPressed;
/*0x14*/ OSContStatus *statusData;
/*0x18*/ OSContPad *controllerData;
/*0x14*/ u16 buttonReleased;
/*0x18*/ OSContStatus *statusData;
/*0x1C*/ OSContPad *controllerData;
#if ENABLE_RUMBLE
/*0x1C*/ s32 port;
/*0x20*/ s32 port;
#endif
};

View File

@@ -1059,7 +1059,6 @@ void init_reverb_us(s32 presetId) {
s32 i;
#ifdef BETTER_REVERB
s8 reverbConsole;
s32 bufOffset = 0;
#endif
s32 reverbWindowSize = gReverbSettings[presetId].windowSize;
@@ -1112,9 +1111,7 @@ void init_reverb_us(s32 presetId) {
gSynthesisReverb.items[1][i].toDownsampleRight = (mem + (DEFAULT_LEN_1CH / sizeof(s16)));
}
#ifdef BETTER_REVERB
delayBufsL = (s32**) soundAlloc(&gBetterReverbPool, BETTER_REVERB_PTR_SIZE);
delayBufsR = &delayBufsL[NUM_ALLPASS];
delayBufsL[0] = (s32*) soundAlloc(&gBetterReverbPool, BETTER_REVERB_SIZE - BETTER_REVERB_PTR_SIZE);
initialize_better_reverb_buffers();
#endif
} else {
bzero(gSynthesisReverb.ringBuffer.left, (REVERB_WINDOW_SIZE_MAX * 2 * sizeof(s16)));
@@ -1146,17 +1143,10 @@ void init_reverb_us(s32 presetId) {
#ifdef BETTER_REVERB
if (toggleBetterReverb) {
if (sAudioIsInitialized) {
bzero(delayBufsL[0], (BETTER_REVERB_SIZE - BETTER_REVERB_PTR_SIZE));
}
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];
clear_better_reverb_buffers();
}
set_better_reverb_buffers();
}
#endif
}

View File

@@ -93,6 +93,9 @@ 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

View File

@@ -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 = 3;
s8 betterReverbDownsampleConsole = 2;
// 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.
// Setting it to anything less than 3 will disable reverb outright.
// This value cannot be less than 3. Setting it to anything lower will act as if it was set to 3.
// This can be changed at any time, but is best set immediately before calling audio_reset_session.
u32 reverbFilterCountConsole = (NUM_ALLPASS - 6);
s32 reverbFilterCountConsole = (NUM_ALLPASS - 9);
// 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.
// Setting it to anything less than 3 will disable reverb outright.
// This value cannot be less than 3. Setting it to anything lower will act as if it was set to 3.
// This can be changed at any time, but is best set immediately before calling audio_reset_session.
u32 reverbFilterCountEmulator = NUM_ALLPASS;
s32 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 fullfilling reverb experience.
// 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.
// 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 fullfilling reverb experience.
// 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.
// 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 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_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_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,26 +136,25 @@ s32 delaysBaselineR[NUM_ALLPASS] = {
1200, 1432, 1232
};
// 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};
// 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};
/* -----------------------------------------------------------------------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;
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;
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;
#endif
@@ -193,72 +192,109 @@ u8 sAudioSynthesisPad[0x20];
#endif
#ifdef BETTER_REVERB
static inline void reverb_samples(s16 *outSampleL, s16 *outSampleR, s32 inSampleL, s32 inSampleR) {
static void reverb_samples(s16 *outSampleL, s16 *outSampleR, s32 inSampleL, s32 inSampleR) {
s32 *curDelaySampleL;
s32 *curDelaySampleR;
s32 historySampleL;
s32 historySampleR;
s32 i = 0;
s32 j = 0;
s32 k = 0;
s32 outTmpL = 0;
s32 outTmpR = 0;
s32 tmpCarryoverL = (((tmpBufL[reverbFilterCountm1] * REVERB_REV_INDEX) / 256) + inSampleL);
s32 tmpCarryoverR = (((tmpBufR[reverbFilterCountm1] * REVERB_REV_INDEX) / 256) + inSampleR);
s32 tmpCarryoverL = (((delayBufsL[reverbFilterCount][allpassIdxL[reverbFilterCount]] * REVERB_REV_INDEX) >> 8) + inSampleL);
s32 tmpCarryoverR = (((delayBufsR[reverbFilterCount][allpassIdxR[reverbFilterCount]] * REVERB_REV_INDEX) >> 8) + inSampleR);
for (; i != reverbFilterCount; ++i, ++j) {
tmpBufL[i] = delayBufsL[i][allpassIdxL[i]];
tmpBufR[i] = delayBufsR[i][allpassIdxR[i]];
for (; i <= reverbFilterCount; ++i, ++j) {
curDelaySampleL = &delayBufsL[i][allpassIdxL[i]];
curDelaySampleR = &delayBufsR[i][allpassIdxR[i]];
historySampleL = *curDelaySampleL;
historySampleR = *curDelaySampleR;
if (j == 2) {
j = -1;
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);
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);
}
} else {
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]);
*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);
}
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*/) / 256);
s32 outUnclamped = ((outTmpL * REVERB_WET_SIGNAL/* + inSampleL * REVERB_DRY_SIGNAL*/) >> 8);
*outSampleL = CLAMP_S16(outUnclamped);
outUnclamped = ((outTmpR * REVERB_WET_SIGNAL/* + inSampleL * REVERB_DRY_SIGNAL*/) / 256);
outUnclamped = ((outTmpR * REVERB_WET_SIGNAL/* + inSampleL * REVERB_DRY_SIGNAL*/) >> 8);
*outSampleR = CLAMP_S16(outUnclamped);
}
static inline void reverb_mono_sample(s16 *outSample, s32 inSample) {
static void reverb_mono_sample(s16 *outSample, s32 inSample) {
s32 *curDelaySample;
s32 historySample;
s32 i = 0;
s32 j = 0;
s32 k = 0;
s32 outTmp = 0;
s32 tmpCarryover = (((tmpBufL[reverbFilterCountm1] * REVERB_REV_INDEX) / 256) + inSample);
s32 tmpCarryover = (((delayBufsL[reverbFilterCount][allpassIdxL[reverbFilterCount]] * REVERB_REV_INDEX) >> 8) + inSample);
for (; i != reverbFilterCount; ++i, ++j) {
tmpBufL[i] = delayBufsL[i][allpassIdxL[i]];
for (; i <= reverbFilterCount; ++i, ++j) {
curDelaySample = &delayBufsL[i][allpassIdxL[i]];
historySample = *curDelaySample;
if (j == 2) {
j = -1;
outTmp += ((tmpBufL[i] * reverbMultsL[k++]) / 256);
delayBufsL[i][allpassIdxL[i]] = tmpCarryover;
if (i != reverbFilterCountm1)
tmpCarryover = ((tmpBufL[i] * REVERB_REV_INDEX) / 256);
outTmp += ((historySample * reverbMultsL[k++]) >> 8);
*curDelaySample = tmpCarryover;
if (i != reverbFilterCount)
tmpCarryover = ((historySample * REVERB_REV_INDEX) >> 8);
} else {
delayBufsL[i][allpassIdxL[i]] = (((tmpBufL[i] * (-REVERB_GAIN_INDEX)) / 256) + tmpCarryover);
tmpCarryover = (((delayBufsL[i][allpassIdxL[i]] * REVERB_GAIN_INDEX) / 256) + tmpBufL[i]);
*curDelaySample = (((historySample * (-REVERB_GAIN_INDEX)) >> 8) + tmpCarryover);
tmpCarryover = (((*curDelaySample * REVERB_GAIN_INDEX) >> 8) + historySample);
}
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*/) / 256);
s32 outUnclamped = ((outTmp * REVERB_WET_SIGNAL/* + inSample * REVERB_DRY_SIGNAL*/) >> 8);
*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
@@ -361,6 +397,7 @@ 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) {
@@ -397,6 +434,7 @@ 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];
@@ -556,18 +594,31 @@ u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) {
#ifdef BETTER_REVERB
if (gIsConsole) {
reverbFilterCount = (s32) reverbFilterCountConsole;
reverbFilterCount = reverbFilterCountConsole;
monoReverb = monoReverbConsole;
} else {
reverbFilterCount = (s32) reverbFilterCountEmulator;
reverbFilterCount = reverbFilterCountEmulator;
monoReverb = monoReverbEmulator;
}
if (reverbFilterCount > NUM_ALLPASS) {
reverbFilterCount = NUM_ALLPASS;
} else if (reverbFilterCount < 3) {
reverbFilterCount = 3;
}
reverbFilterCountm1 = (reverbFilterCount - 1);
if (reverbFilterCount < 3) {
reverbFilterCountm1 = 0;
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];
}
#endif

View File

@@ -33,20 +33,16 @@
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 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 s32 gReverbMultsL[NUM_ALLPASS / 3];
extern s32 gReverbMultsR[NUM_ALLPASS / 3];
extern u8 toggleBetterReverb;
#define REVERB_WINDOW_SIZE_MAX 0x2000
@@ -149,6 +145,12 @@ 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);

View File

@@ -294,6 +294,11 @@ 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;
@@ -611,8 +616,8 @@ void read_controller_inputs(s32 threadID) {
if (controller->controllerData != NULL) {
controller->rawStickX = controller->controllerData->stick_x;
controller->rawStickY = controller->controllerData->stick_y;
controller->buttonPressed = controller->controllerData->button
& (controller->controllerData->button ^ controller->buttonDown);
controller->buttonPressed = ~controller->buttonDown & controller->controllerData->button;
controller->buttonReleased = ~controller->controllerData->button & controller->buttonDown;
// 0.5x A presses are a good meme
controller->buttonDown = controller->controllerData->button;
adjust_analog_stick(controller);
@@ -620,6 +625,7 @@ 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;
@@ -636,6 +642,7 @@ 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;
}

View File

@@ -130,16 +130,21 @@ Gfx *geo_switch_area(s32 callContext, struct GraphNode *node, UNUSED void *conte
if (gMarioObject == NULL) {
switchCase->selectedCase = 0;
} else {
#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS
if (gCurrLevelNum == LEVEL_BBH) {
// In BBH, check for a floor manually, since there is an intangible floor. In custom hacks this can be removed.
#ifdef VERTICAL_ROOMS
// Checks for a floor manually, including intangible ones. This allows one to have vertical rooms.
find_room_floor(gMarioObject->oPosX, gMarioObject->oPosY, gMarioObject->oPosZ, &floor);
} else {
// Since no intangible floors are nearby, use Mario's floor instead.
floor = gMarioState->floor;
}
#else
floor = gMarioState->floor;
#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS
if (gCurrLevelNum == LEVEL_BBH) {
find_room_floor(gMarioObject->oPosX, gMarioObject->oPosY, gMarioObject->oPosZ, &floor);
} else {
floor = gMarioState->floor;
}
#else
// Use Mario's floor to determine the room.
// This saves processing time, but does not allow vertical rooms, since intangible floors will be skipped.
floor = gMarioState->floor;
#endif
#endif
if (floor) {
gMarioCurrentRoom = floor->room;

View File

@@ -367,7 +367,7 @@ void geo_process_master_list_sub(struct GraphNodeMasterList *node) {
gSPClearGeometryMode(gDisplayListHead++, G_ZBUFFER);
}
#ifdef OBJECTS_REJ
#if defined(F3DZEX_GBI_2) && defined(VISUAL_DEBUG)
#if defined(F3DEX_GBI_2) && defined(VISUAL_DEBUG)
if (hitboxView) render_debug_boxes(DEBUG_UCODE_REJ);
#endif
switch_ucode(GRAPH_NODE_UCODE_DEFAULT);
@@ -408,7 +408,7 @@ void geo_append_display_list(void *displayList, s32 layer) {
}
#endif // SILHOUETTE
}
#endif // F3DZEX_GBI_2 || SILHOUETTE
#endif // F3DEX_GBI_2 || SILHOUETTE
if (gCurGraphNodeMasterList != NULL) {
struct DisplayListNode *listNode =
alloc_only_pool_alloc(gDisplayListHeap, sizeof(struct DisplayListNode));