Fixed various audio bugs; DynOS can now detect texture duplicates to decrease generated bin files size (#110)

Fixed the following audio bugs:
    Bug: Rom-hacks sequences don't seem to be affected by volume scaling and
         muting
    Fix: Force the BGM sequences to follow the vanilla behavior:
        Volume can't go higher than default volume
        Volume is reduced to 31% when the game is paused
        Audio is stopped when the game is paused outside the Castle levels
    Bug: (Pointed out by Draco) Mario's voice clips are not replaced by the
         player's character's in the following instances: fall to death
         barrier, "here we go" in the ending cutscene, "let's a go"
         after selecting a star, "okey dokey" after starting the game.
    Fix: The first two ones now call
         play_character_sound(m, CHAR_SOUND_...) instead of
         play_sound(SOUND_MARIO_..., pos). The last two ones couldn't be
         fixed the same way for two reasons: First, the corresponding sounds
         were not referenced in the sound table, second, the sound played is
         always cut-off after a few frames (due to how sm64 resets the sound
         banks after loading a level).

Added SOUND_*_LETS_A_GO and SOUND_*_OKEY_DOKEY sounds for each playable
    character as Bass samples.
    Character Bass sounds work the same way as vanilla sounds (i.e. can be
    played with play_character_sound), but they cannot be prematurely stopped
    by sm64 sound banks shenanigans.
    This fixes the cut-off for both the star select and the castle grounds
    entry, plays the sound corresponding to the player's character, and doesn't
    need to extend or edit the sound table.

DynOS can detect texture duplicates when generating a bin or lvl file.
    When a duplicate is detected, the name of the original texture node is
    written instead of the whole PNG data, decreasing significantly the
    resulting file size.
This commit is contained in:
PeachyPeach 2022-05-20 01:40:45 +02:00 committed by GitHub
parent f63bffc64c
commit 4fbafc2708
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 255 additions and 36 deletions

View file

@ -1194,6 +1194,7 @@ ifeq ($(TARGET_N64),1)
$(BUILD_DIR)/lib/rsp.o: $(BUILD_DIR)/rsp/rspboot.bin $(BUILD_DIR)/rsp/fast3d.bin $(BUILD_DIR)/rsp/audio.bin
endif
$(BUILD_DIR)/src/game/characters.o: $(SOUND_SAMPLE_TABLES)
$(SOUND_BIN_DIR)/sound_data.o: $(SOUND_BIN_DIR)/sound_data.ctl.inc.c $(SOUND_BIN_DIR)/sound_data.tbl.inc.c $(SOUND_BIN_DIR)/sequences.bin.inc.c $(SOUND_BIN_DIR)/bank_sets.inc.c
$(BUILD_DIR)/levels/scripts.o: $(BUILD_DIR)/include/level_headers.h
@ -1321,6 +1322,9 @@ endif
$(BUILD_DIR)/%.table: %.aiff
$(call print,Extracting codebook:,$<,$@)
$(V)$(AIFF_EXTRACT_CODEBOOK) $< >$@
$(call print,Piping:,$<,$@.inc.c)
$(V)hexdump -v -e '1/1 "0x%X,"' $< > $@.inc.c
$(V)echo >> $@.inc.c
$(BUILD_DIR)/%.aifc: $(BUILD_DIR)/%.table %.aiff
$(call print,Encoding VADPCM:,$<,$@)

View file

@ -2615,7 +2615,13 @@ CHAR_SOUND_SO_LONGA_BOWSER = 40
CHAR_SOUND_IMA_TIRED = 41
--- @type CharacterSound
CHAR_SOUND_MAX = 42
CHAR_SOUND_LETS_A_GO = 42
--- @type CharacterSound
CHAR_SOUND_OKEY_DOKEY = 43
--- @type CharacterSound
CHAR_SOUND_MAX = 44
--- @class CharacterType

View file

@ -269,7 +269,9 @@
--- @field public soundHoohoo integer
--- @field public soundHrmm integer
--- @field public soundImaTired integer
--- @field public soundLetsAGo integer
--- @field public soundMamaMia integer
--- @field public soundOkeyDokey integer
--- @field public soundOnFire integer
--- @field public soundOoof integer
--- @field public soundOoof2 integer

View file

@ -11,6 +11,7 @@ extern "C" {
#define FUNCTION_CODE (u32) 0x434E5546
#define POINTER_CODE (u32) 0x52544E50
#define LUA_VAR_CODE (u32) 0x5641554C
#define TEX_REF_CODE (u32) 0x52584554
#define MOD_PACK_INDEX 99

View file

@ -159,6 +159,22 @@ void DynOS_Tex_Write(FILE* aFile, GfxData* aGfxData, DataNode<TexData> *aNode) {
aNode->mName.Write(aFile);
// Data
// Look for texture duplicates
// If that's the case, store the name of the texture node instead of the whole PNG data
// (Don't bother to look for duplicates if there is no data to write)
if (!aNode->mData->mPngData.Empty()) {
for (const auto& _Node : aGfxData->mTextures) {
if (_Node->mLoadIndex < aNode->mLoadIndex && // Check load order: duplicates should reference only an already loaded node
_Node->mData != NULL && // Check node data
aNode->mData->mPngData.Count() == _Node->mData->mPngData.Count() && // Check PNG data lengths
memcmp(aNode->mData->mPngData.begin(), _Node->mData->mPngData.begin(), aNode->mData->mPngData.Count()) == 0) // Check PNG data content
{
WriteBytes<u32>(aFile, TEX_REF_CODE);
_Node->mName.Write(aFile);
return;
}
}
}
aNode->mData->mPngData.Write(aFile);
}
@ -220,6 +236,27 @@ DataNode<TexData>* DynOS_Tex_Load(FILE *aFile, GfxData *aGfxData) {
// Data
_Node->mData = New<TexData>();
_Node->mData->mUploaded = false;
// Check for the texture ref magic
s32 _FileOffset = (s32) ftell(aFile);
u32 _TexRefCode = ReadBytes<u32>(aFile);
if (_TexRefCode == TEX_REF_CODE) {
// That's a duplicate, find the original node and copy its content
String _NodeName; _NodeName.Read(aFile);
for (const auto& _LoadedNode : aGfxData->mTextures) {
if (_LoadedNode->mName == _NodeName) {
_Node->mData->mPngData = _LoadedNode->mData->mPngData;
_Node->mData->mRawData = _LoadedNode->mData->mRawData;
_Node->mData->mRawWidth = _LoadedNode->mData->mRawWidth;
_Node->mData->mRawHeight = _LoadedNode->mData->mRawHeight;
_Node->mData->mRawFormat = _LoadedNode->mData->mRawFormat;
_Node->mData->mRawSize = _LoadedNode->mData->mRawSize;
break;
}
}
} else {
fseek(aFile, _FileOffset, SEEK_SET);
_Node->mData->mPngData.Read(aFile);
if (!_Node->mData->mPngData.Empty()) {
u8 *_RawData = stbi_load_from_memory(_Node->mData->mPngData.begin(), _Node->mData->mPngData.Count(), &_Node->mData->mRawWidth, &_Node->mData->mRawHeight, NULL, 4);
@ -234,6 +271,7 @@ DataNode<TexData>* DynOS_Tex_Load(FILE *aFile, GfxData *aGfxData) {
_Node->mData->mRawFormat = 0;
_Node->mData->mRawSize = 0;
}
}
// Append
if (aGfxData) {

View file

@ -836,7 +836,9 @@
| CHAR_SOUND_SNORING3 | 39 |
| CHAR_SOUND_SO_LONGA_BOWSER | 40 |
| CHAR_SOUND_IMA_TIRED | 41 |
| CHAR_SOUND_MAX | 42 |
| CHAR_SOUND_LETS_A_GO | 42 |
| CHAR_SOUND_OKEY_DOKEY | 43 |
| CHAR_SOUND_MAX | 44 |
### [enum CharacterType](#CharacterType)
| Identifier | Value |

View file

@ -436,7 +436,9 @@
| soundHoohoo | `integer` | read-only |
| soundHrmm | `integer` | read-only |
| soundImaTired | `integer` | read-only |
| soundLetsAGo | `integer` | read-only |
| soundMamaMia | `integer` | read-only |
| soundOkeyDokey | `integer` | read-only |
| soundOnFire | `integer` | read-only |
| soundOoof | `integer` | read-only |
| soundOoof2 | `integer` | read-only |

View file

@ -63,6 +63,16 @@ static void sequence_channel_process_sound(struct SequenceChannel *seqChannel) {
f32 panFromChannel;
s32 i;
// Rom-hacks audio fix
// Force the BGM sequence channels to follow the BGM sequence player mute behavior
// Make the audio completely silent if MUTE_BEHAVIOR_STOP_SCRIPT or MUTE_BEHAVIOR_STOP_NOTES is set
if (seqChannel->seqPlayer == &gSequencePlayers[0]) {
seqChannel->muteBehavior = seqChannel->seqPlayer->muteBehavior;
if (seqChannel->seqPlayer->muted && (seqChannel->muteBehavior & (MUTE_BEHAVIOR_STOP_SCRIPT | MUTE_BEHAVIOR_STOP_NOTES)) != 0) {
seqChannel->seqPlayer->muteVolumeScale = 0.f;
}
}
channelVolume = seqChannel->volume * seqChannel->volumeScale *
seqChannel->seqPlayer->fadeVolume * seqChannel->seqPlayer->volumeScale;
if (seqChannel->seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_SOFTEN) != 0) {

View file

@ -2356,6 +2356,21 @@ void play_dialog_sound(u8 dialogID) {
void set_sequence_player_volume(s32 player, f32 volume) {
gSequencePlayers[player].volumeScale = volume;
// Rom-hacks audio fix
// Custom sequences tend to ignore volume scaling and muting...
// Force the BGM sequence player to follow the Vanilla behavior:
// - Volume can't go higher than default volume
// - Volume is reduced to 31% when the game is paused
// - Audio is stopped when the game is paused outside the Castle levels
if (player == SEQ_PLAYER_LEVEL && sCurrentBackgroundMusicSeqId != 0xff) {
struct SequencePlayer *seqPlayer = &gSequencePlayers[player];
f32 maxVolume = get_current_background_music_default_volume() / 127.f;
seqPlayer->volume = MIN(seqPlayer->volume, maxVolume);
seqPlayer->fadeVolume = MIN(seqPlayer->fadeVolume, maxVolume);
seqPlayer->muteVolumeScale = 0.31f;
seqPlayer->muteBehavior = MUTE_BEHAVIOR_SOFTEN | ((gCurrCourseNum != 0) * (MUTE_BEHAVIOR_STOP_SCRIPT | MUTE_BEHAVIOR_STOP_NOTES));
}
}
/**
@ -2509,6 +2524,13 @@ u16 get_current_background_music(void) {
return -1;
}
u8 get_current_background_music_default_volume(void) {
if (sCurrentBackgroundMusicSeqId != 0xff) {
return sBackgroundMusicDefaultVolume[sCurrentBackgroundMusicSeqId];
}
return 0;
}
u8 get_current_background_music_target_volume(void) {
return sBackgroundMusicTargetVolume;
}

View file

@ -53,6 +53,7 @@ void stop_background_music(u16 seqId);
void fadeout_background_music(u16 arg0, u16 fadeOut);
void drop_queued_background_music(void);
u16 get_current_background_music(void);
u8 get_current_background_music_default_volume(void);
u8 get_current_background_music_target_volume(void);
u8 get_current_background_music_max_target_volume(void);
u8 is_current_background_music_volume_lowered(void);

View file

@ -10,7 +10,7 @@
#include "pc/configfile.h"
#include "audio/external.h"
#include "engine/graph_node.h"
#include "types.h"
#include "characters_bass_sounds.h"
extern Gfx mario_cap_seg3_dl_03022F48[];
extern Gfx luigi_cap_seg3_dl_03022F48[];
@ -87,6 +87,8 @@ struct Character gCharacters[CT_MAX] = {
.soundSnoring3 = SOUND_MARIO_SNORING3,
.soundSoLongaBowser = SOUND_MARIO_SO_LONGA_BOWSER,
.soundImaTired = SOUND_MARIO_IMA_TIRED,
.soundLetsAGo = CHAR_BASS_SOUND(SOUND_MARIO_LETS_A_GO),
.soundOkeyDokey = CHAR_BASS_SOUND(SOUND_MARIO_OKEY_DOKEY),
},
[CT_LUIGI] = {
@ -150,6 +152,8 @@ struct Character gCharacters[CT_MAX] = {
.soundSnoring3 = SOUND_LUIGI_SNORING3,
.soundSoLongaBowser = SOUND_LUIGI_SO_LONGA_BOWSER,
.soundImaTired = SOUND_LUIGI_IMA_TIRED,
.soundLetsAGo = CHAR_BASS_SOUND(SOUND_LUIGI_LETS_A_GO),
.soundOkeyDokey = CHAR_BASS_SOUND(SOUND_LUIGI_OKEY_DOKEY),
},
[CT_TOAD] = {
@ -213,6 +217,8 @@ struct Character gCharacters[CT_MAX] = {
.soundSnoring3 = SOUND_MARIO_SNORING3,
.soundSoLongaBowser = SOUND_MARIO_SO_LONGA_BOWSER,
.soundImaTired = SOUND_MARIO_IMA_TIRED,
.soundLetsAGo = CHAR_BASS_SOUND(SOUND_MARIO_LETS_A_GO),
.soundOkeyDokey = CHAR_BASS_SOUND(SOUND_MARIO_OKEY_DOKEY),
},
[CT_WALUIGI] = {
@ -279,6 +285,8 @@ struct Character gCharacters[CT_MAX] = {
.soundSnoring3 = SOUND_LUIGI_SNORING3,
.soundSoLongaBowser = SOUND_LUIGI_SO_LONGA_BOWSER,
.soundImaTired = SOUND_LUIGI_IMA_TIRED,
.soundLetsAGo = CHAR_BASS_SOUND(SOUND_LUIGI_LETS_A_GO),
.soundOkeyDokey = CHAR_BASS_SOUND(SOUND_LUIGI_OKEY_DOKEY),
},
[CT_WARIO] = {
@ -342,6 +350,8 @@ struct Character gCharacters[CT_MAX] = {
.soundSnoring3 = SOUND_WARIO_SNORING3,
.soundSoLongaBowser = SOUND_WARIO_SO_LONGA_BOWSER,
.soundImaTired = SOUND_WARIO_IMA_TIRED,
.soundLetsAGo = CHAR_BASS_SOUND(SOUND_WARIO_LETS_A_GO),
.soundOkeyDokey = CHAR_BASS_SOUND(SOUND_WARIO_OKEY_DOKEY),
},
};
@ -450,29 +460,41 @@ static s32 get_character_sound(struct MarioState* m, enum CharacterSound charact
case CHAR_SOUND_SNORING3: return character->soundSnoring3;
case CHAR_SOUND_SO_LONGA_BOWSER: return character->soundSoLongaBowser;
case CHAR_SOUND_IMA_TIRED: return character->soundImaTired;
case CHAR_SOUND_LETS_A_GO: return character->soundLetsAGo;
case CHAR_SOUND_OKEY_DOKEY: return character->soundOkeyDokey;
default: return 0;
}
}
void play_character_sound(struct MarioState* m, enum CharacterSound characterSound) {
static void play_character_sound_internal(struct MarioState *m, enum CharacterSound characterSound, u32 offset, u32 flags) {
if (m != NULL && (m->flags & flags) == 0) {
s32 sound = get_character_sound(m, characterSound);
if (sound == 0) { return; }
if (sound != 0) {
struct Character* character = get_character(m);
play_sound_with_freq_scale(sound, m->marioObj->header.gfx.cameraToObject, character->soundFreqScale);
f32 *pos = (m->marioObj != NULL ? m->marioObj->header.gfx.cameraToObject : gGlobalSoundSource);
if ((u32) (sound & CHAR_BASS_MAGIC) == CHAR_BASS_MAGIC) {
CharacterBassSound *cbs = get_character_bass_sound(sound);
if (cbs != NULL) {
play_character_bass_sound(cbs, pos, character->soundFreqScale);
}
} else {
play_sound_with_freq_scale(sound + offset, pos, character->soundFreqScale);
}
}
m->flags |= flags;
}
}
void play_character_sound(struct MarioState* m, enum CharacterSound characterSound) {
play_character_sound_internal(m, characterSound, 0, 0);
}
void play_character_sound_offset(struct MarioState* m, enum CharacterSound characterSound, u32 offset) {
s32 sound = get_character_sound(m, characterSound);
if (sound == 0) { return; }
struct Character* character = get_character(m);
play_sound_with_freq_scale(sound + offset, m->marioObj->header.gfx.cameraToObject, character->soundFreqScale);
play_character_sound_internal(m, characterSound, offset, 0);
}
void play_character_sound_if_no_flag(struct MarioState* m, enum CharacterSound characterSound, u32 flags) {
if ((m->flags & flags) == 0) {
play_character_sound(m, characterSound);
m->flags |= flags;
}
play_character_sound_internal(m, characterSound, 0, flags);
}
f32 get_character_anim_offset(struct MarioState* m) {

View file

@ -81,6 +81,8 @@ struct Character {
s32 soundSnoring3;
s32 soundSoLongaBowser;
s32 soundImaTired;
s32 soundLetsAGo;
s32 soundOkeyDokey;
};
enum CharacterSound {
@ -126,6 +128,8 @@ enum CharacterSound {
CHAR_SOUND_SNORING3,
CHAR_SOUND_SO_LONGA_BOWSER,
CHAR_SOUND_IMA_TIRED,
CHAR_SOUND_LETS_A_GO,
CHAR_SOUND_OKEY_DOKEY,
CHAR_SOUND_MAX // MUST BE LAST
};

View file

@ -0,0 +1,99 @@
#include "types.h"
#include "bass/bass.h"
#include "game/camera.h"
#undef min // Redefined in math_util.h, undef it to avoid compiler warnings
#undef max // Redefined in math_util.h, undef it to avoid compiler warnings
#include "engine/math_util.h"
#define H01(s, i, x) (x * 65599u + (u8) s[(i) < sizeof(s) ? (i) : sizeof(s)])
#define H04(s, i, x) H01(s, i, H01(s, i + 1, H01(s, i + 2, H01(s, i + 3, x))))
#define H16(s, i, x) H04(s, i, H04(s, i + 4, H04(s, i + 8, H04(s, i + 12, x))))
#define H64(s, i, x) H16(s, i, H16(s, i + 16, H16(s, i + 32, H16(s, i + 48, x))))
#define CHAR_BASS_MAGIC 0xFF000000u
#define CHAR_BASS_SOUND_ID(name) (H64(#name "________________________________________________________________", 0, 0) & ~CHAR_BASS_MAGIC)
#define CHAR_BASS_SOUND(name) (CHAR_BASS_MAGIC | CHAR_BASS_SOUND_ID(name))
#define CHAR_BASS_SOUND_NOT_LOADED 0xFFFFFFFFu
#define DECL_CHAR_BASS_SOUND_RAW(name, ...) static const u8 sCharacterBassSoundRaw_##name[] =
#define DECL_CHAR_BASS_SOUND(name) { CHAR_BASS_SOUND(name), (s32) sizeof(sCharacterBassSoundRaw_##name), sCharacterBassSoundRaw_##name, CHAR_BASS_SOUND_NOT_LOADED, 0.f }
// Undef these to avoid naming issues
#undef SOUND_MARIO_LETS_A_GO
#undef SOUND_LUIGI_LETS_A_GO
#undef SOUND_WARIO_LETS_A_GO
#undef SOUND_MARIO_OKEY_DOKEY
#undef SOUND_LUIGI_OKEY_DOKEY
#undef SOUND_WARIO_OKEY_DOKEY
/////////////////
// Bass sounds //
/////////////////
DECL_CHAR_BASS_SOUND_RAW(SOUND_MARIO_LETS_A_GO) {
#include "sound/samples/sfx_mario/1A_mario_lets_a_go.table.inc.c"
};
DECL_CHAR_BASS_SOUND_RAW(SOUND_LUIGI_LETS_A_GO) {
#include "sound/samples/sfx_custom_luigi/1A.table.inc.c"
};
DECL_CHAR_BASS_SOUND_RAW(SOUND_WARIO_LETS_A_GO) {
#include "sound/samples/sfx_custom_wario/1A.table.inc.c"
};
DECL_CHAR_BASS_SOUND_RAW(SOUND_MARIO_OKEY_DOKEY) {
#include "sound/samples/sfx_mario_peach/0B_mario_okey_dokey.table.inc.c"
};
DECL_CHAR_BASS_SOUND_RAW(SOUND_LUIGI_OKEY_DOKEY) {
#include "sound/samples/sfx_custom_luigi_peach/0B.table.inc.c"
};
DECL_CHAR_BASS_SOUND_RAW(SOUND_WARIO_OKEY_DOKEY) {
#include "sound/samples/sfx_custom_wario_peach/0B.table.inc.c"
};
///////////////////////
// Bass sounds table //
///////////////////////
typedef struct { s32 sound; s32 size; const u8 *raw; HSAMPLE sample; f32 freq; } CharacterBassSound;
static CharacterBassSound sCharacterBassSounds[] = {
DECL_CHAR_BASS_SOUND(SOUND_MARIO_LETS_A_GO),
DECL_CHAR_BASS_SOUND(SOUND_LUIGI_LETS_A_GO),
DECL_CHAR_BASS_SOUND(SOUND_WARIO_LETS_A_GO),
DECL_CHAR_BASS_SOUND(SOUND_MARIO_OKEY_DOKEY),
DECL_CHAR_BASS_SOUND(SOUND_LUIGI_OKEY_DOKEY),
DECL_CHAR_BASS_SOUND(SOUND_WARIO_OKEY_DOKEY),
{ 0, 0, NULL, CHAR_BASS_SOUND_NOT_LOADED, 0.f },
};
///////////////////////////
// Bass sounds functions //
///////////////////////////
static CharacterBassSound *get_character_bass_sound(s32 sound) {
for (CharacterBassSound *cbs = sCharacterBassSounds; cbs->raw != NULL; cbs++) {
if (cbs->sound == sound) {
return cbs;
}
}
return NULL;
}
static void play_character_bass_sound(CharacterBassSound *cbs, f32 *pos, f32 freqScale) {
if (cbs->sample == CHAR_BASS_SOUND_NOT_LOADED) {
cbs->sample = BASS_SampleLoad(TRUE, cbs->raw, 0, cbs->size, 32, BASS_SAMPLE_OVER_POS);
BASS_SAMPLE info; BASS_SampleGetInfo(cbs->sample, &info);
cbs->freq = info.freq;
}
DWORD handle = BASS_SampleGetChannel(cbs->sample, 0);
f32 dist = vec3f_length(pos);
f32 pan = (get_sound_pan(pos[0], pos[2]) - 0.5f) * 2.f;
f32 intensity = sound_get_level_intensity(dist);
f32 masterVolume = (f32) configMasterVolume / 127.f;
f32 sfxVolume = (f32) configSfxVolume / 127.f;
BASS_ChannelSetAttribute(handle, BASS_ATTRIB_VOL, masterVolume * sfxVolume * intensity * 0.75f);
BASS_ChannelSetAttribute(handle, BASS_ATTRIB_PAN, pan);
BASS_ChannelSetAttribute(handle, BASS_ATTRIB_FREQ, cbs->freq * freqScale);
BASS_ChannelPlay(handle, TRUE);
}

View file

@ -2237,7 +2237,7 @@ void check_death_barrier(struct MarioState *m) {
}
if (level_trigger_warp(m, WARP_OP_WARP_FLOOR) == 20 && !(m->flags & MARIO_UNKNOWN_18)) {
play_sound(SOUND_MARIO_WAAAOOOW, m->marioObj->header.gfx.cameraToObject);
play_character_sound(m, CHAR_SOUND_WAAAOOOW);
}
}
}

View file

@ -319,8 +319,7 @@ void play_sound_and_spawn_particles(struct MarioState *m, u32 soundBits, u32 wav
return;
}
if ((m->flags & MARIO_METAL_CAP) || soundBits == SOUND_ACTION_UNSTUCK_FROM_GROUND
|| soundBits == SOUND_MARIO_PUNCH_HOO || soundBits == SOUND_LUIGI_PUNCH_HOO) {
if ((m->flags & MARIO_METAL_CAP) || soundBits == SOUND_ACTION_UNSTUCK_FROM_GROUND) {
play_sound(soundBits, m->marioObj->header.gfx.cameraToObject);
} else {
play_sound(m->terrainSoundAddend + soundBits, m->marioObj->header.gfx.cameraToObject);

View file

@ -2643,7 +2643,7 @@ static void end_peach_cutscene_star_dance(struct MarioState *m) {
cutscene_put_cap_on(m);
}
if (animFrame == 88 && m->playerIndex == 0) {
play_sound(SOUND_MARIO_HERE_WE_GO, m->marioObj->header.gfx.cameraToObject);
play_character_sound(m, CHAR_SOUND_HERE_WE_GO);
}
if (!nonMario && animFrame >= 98) {
m->marioBodyState->handState = MARIO_HAND_PEACE_SIGN;

View file

@ -501,7 +501,9 @@ void star_select_finish_selection(void) {
#if defined(VERSION_JP)
play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource);
#else
play_sound(SOUND_MENU_STAR_SOUND_LETS_A_GO, gGlobalSoundSource);
if (gMarioState->marioObj) vec3f_copy(gMarioState->marioObj->header.gfx.cameraToObject, gGlobalSoundSource);
play_character_sound(gMarioState, CHAR_SOUND_LETS_A_GO);
play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource);
#endif
#ifdef VERSION_SH
queue_rumble_data(60, 70);

View file

@ -46,7 +46,8 @@ void djui_panel_host_message_do_host(UNUSED struct DjuiBase* caller) {
fake_lvl_init_from_save_file();
extern s16 gChangeLevelTransition;
gChangeLevelTransition = gLevelValues.entryLevel;
play_sound(SOUND_MENU_STAR_SOUND_OKEY_DOKEY, gGlobalSoundSource);
if (gMarioState->marioObj) vec3f_copy(gMarioState->marioObj->header.gfx.cameraToObject, gGlobalSoundSource);
play_character_sound(gMarioState, CHAR_SOUND_OKEY_DOKEY);
extern void play_transition(s16 transType, s16 time, u8 red, u8 green, u8 blue);
play_transition(0x09, 0x14, 0x00, 0x00, 0x00);
}

View file

@ -293,7 +293,7 @@ static struct LuaObjectField sChainSegmentFields[LUA_CHAIN_SEGMENT_FIELD_COUNT]
{ "yaw", LVT_S16, offsetof(struct ChainSegment, yaw), false, LOT_NONE },
};
#define LUA_CHARACTER_FIELD_COUNT 59
#define LUA_CHARACTER_FIELD_COUNT 61
static struct LuaObjectField sCharacterFields[LUA_CHARACTER_FIELD_COUNT] = {
{ "animOffsetEnabled", LVT_U8, offsetof(struct Character, animOffsetEnabled), true, LOT_NONE },
{ "animOffsetFeet", LVT_F32, offsetof(struct Character, animOffsetFeet), true, LOT_NONE },
@ -329,7 +329,9 @@ static struct LuaObjectField sCharacterFields[LUA_CHARACTER_FIELD_COUNT] = {
{ "soundHoohoo", LVT_S32, offsetof(struct Character, soundHoohoo), true, LOT_NONE },
{ "soundHrmm", LVT_S32, offsetof(struct Character, soundHrmm), true, LOT_NONE },
{ "soundImaTired", LVT_S32, offsetof(struct Character, soundImaTired), true, LOT_NONE },
{ "soundLetsAGo", LVT_S32, offsetof(struct Character, soundLetsAGo), true, LOT_NONE },
{ "soundMamaMia", LVT_S32, offsetof(struct Character, soundMamaMia), true, LOT_NONE },
{ "soundOkeyDokey", LVT_S32, offsetof(struct Character, soundOkeyDokey), true, LOT_NONE },
{ "soundOnFire", LVT_S32, offsetof(struct Character, soundOnFire), true, LOT_NONE },
{ "soundOoof", LVT_S32, offsetof(struct Character, soundOoof), true, LOT_NONE },
{ "soundOoof2", LVT_S32, offsetof(struct Character, soundOoof2), true, LOT_NONE },

View file

@ -1071,7 +1071,9 @@ char gSmluaConstants[] = ""
"CHAR_SOUND_SNORING3 = 39\n"
"CHAR_SOUND_SO_LONGA_BOWSER = 40\n"
"CHAR_SOUND_IMA_TIRED = 41\n"
"CHAR_SOUND_MAX = 42\n"
"CHAR_SOUND_LETS_A_GO = 42\n"
"CHAR_SOUND_OKEY_DOKEY = 43\n"
"CHAR_SOUND_MAX = 44\n"
"DIALOG_000 = 0\n"
"DIALOG_001 = 1\n"
"DIALOG_002 = 2\n"