Low Health Beeps Configuration (#6328)

This commit is contained in:
khbsd
2025-03-16 00:02:48 -05:00
committed by GitHub
parent 5965c08326
commit 816ed0d963
6 changed files with 136 additions and 4 deletions

View File

@@ -6,12 +6,15 @@ MID_ASM_DIR := $(MID_SUBDIR)
CRY_BIN_DIR := $(CRY_SUBDIR)
SOUND_BIN_DIR := sound
# Needs to recompile for B_NUM_LOW_HEALTH_BEEPS in battle.h
EXPANSION_BATTLE_CONFIG := include/config/battle.h
SPECIAL_OUTDIRS := $(MID_ASM_DIR) $(CRY_BIN_DIR)
SPECIAL_OUTDIRS += $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/direct_sound_samples/phonemes $(SOUND_BIN_DIR)/direct_sound_samples/cries
$(shell mkdir -p $(SPECIAL_OUTDIRS) )
# Assembly song compilation
$(SONG_BUILDDIR)/%.o: $(SONG_SUBDIR)/%.s
$(SONG_BUILDDIR)/%.o: $(SONG_SUBDIR)/%.s $(EXPANSION_BATTLE_CONFIG)
$(AS) $(ASFLAGS) -I sound -o $@ $<
$(MID_BUILDDIR)/%.o: $(MID_ASM_DIR)/%.s
$(AS) $(ASFLAGS) -I sound -o $@ $<
@@ -34,7 +37,7 @@ MID_CFG_PATH := $(MID_SUBDIR)/midi.cfg
# $1: Source path no extension, $2 Options
define MID_RULE
$(MID_ASM_DIR)/$1.s: $(MID_SUBDIR)/$1.mid $(MID_CFG_PATH)
$(MID_ASM_DIR)/$1.s: $(MID_SUBDIR)/$1.mid $(MID_CFG_PATH) $(EXPANSION_BATTLE_CONFIG)
$(MID) $$< $$@ $2
endef
# source path, remaining text (options)

View File

@@ -283,6 +283,11 @@
#define B_TRY_CATCH_TRAINER_BALL GEN_LATEST // In Gen4+, trying to catch a Trainer's Pokémon does not consume the Poké Ball.
#define B_SLEEP_CLAUSE FALSE // Enables Sleep Clause all the time in every case, overriding B_FLAG_SLEEP_CLAUSE. Use that for modularity.
#define NUM_BEEPS_GEN_LATEST 4 // Loops 4 times
#define NUM_BEEPS_GEN_3 -1 // Loops infinitely
#define NUM_BEEPS_OFF 0 // Doesn't play at all
#define B_NUM_LOW_HEALTH_BEEPS NUM_BEEPS_GEN_LATEST // This controls the number of times the "low health" beep will loop. Setting this value to NUM_BEEPS_OFF will disable the beep, while NUM_BEEPS_GEN_3 will loop infinitely. You can set this to any number you want, the defines listed are just for ease of use.
// Animation Settings
#define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle.
#define B_NEW_LEECH_SEED_PARTICLE FALSE // If set to TRUE, it updates Leech Seed's animation particle.

View File

@@ -6,6 +6,9 @@ SRCS := agb.cpp error.cpp main.cpp midi.cpp tables.cpp
HEADERS := agb.h error.h main.h midi.h tables.h
# Needs to recompile for B_NUM_LOW_HEALTH_BEEPS in battle.h
EXPANSION_BATTLE_CONFIG := ../../include/config/battle.h
ifeq ($(OS),Windows_NT)
EXE := .exe
else
@@ -17,7 +20,7 @@ endif
all: mid2agb$(EXE)
@:
mid2agb$(EXE): $(SRCS) $(HEADERS)
mid2agb$(EXE): $(SRCS) $(HEADERS) $(EXPANSION_BATTLE_CONFIG)
$(CXX) $(CXXFLAGS) $(SRCS) -o $@ $(LDFLAGS)
clean:

View File

@@ -525,6 +525,117 @@ void PrintAgbTrack(std::vector<Event>& events)
PrintByte("FINE");
}
void PrintAgbTrackLoop(std::vector<Event>& events, int trackLoops)
{
std::fprintf(g_outputFile, "\n@**************** Track %u (Midi-Chn.%u) ****************@\n\n", g_agbTrack, g_midiChan + 1);
std::fprintf(g_outputFile, "%s_%u:\n", g_asmLabel.c_str(), g_agbTrack);
int wholeNoteCount = 0;
ResetTrackVars();
bool foundVolBeforeNote = false;
for (const Event& event : events)
{
if (event.type == EventType::Note)
break;
if (event.type == EventType::Controller && event.param1 == 0x07)
{
foundVolBeforeNote = true;
break;
}
}
if (!foundVolBeforeNote)
PrintByte("\tVOL , 127*%s_mvl/mxv", g_asmLabel.c_str());
PrintWait(g_initialWait);
if (trackLoops > 0)
PrintByte("KEYSH , %s_key%+d", g_asmLabel.c_str(), 0);
for (int k = 0; k < trackLoops; k++)
{
for (unsigned i = 0; events[i].type != EventType::EndOfTrack; i++)
{
const Event& event = events[i];
if (IsPatternBoundary(event.type))
{
if (s_inPattern)
PrintByte("PEND");
s_inPattern = false;
}
// added `&& (i % 2 == 0)` to cut down on excess comments created in the .s file
if ((event.type == EventType::WholeNoteMark || event.type == EventType::Pattern) && (i % 2 == 0))
std::fprintf(g_outputFile, "@ %03d ----------------------------------------\n", wholeNoteCount++);
switch (event.type)
{
case EventType::Note:
PrintNote(event);
break;
case EventType::EndOfTie:
PrintEndOfTieOp(event);
break;
case EventType::Label:
if (k == 0)
PrintSeqLoopLabel(event);
break;
case EventType::LoopEnd:
case EventType::LoopEndBegin:
break;
case EventType::LoopBegin:
if (k == 0)
PrintSeqLoopLabel(event);
break;
case EventType::WholeNoteMark:
if (event.param2 & 0x80000000)
{
std::fprintf(g_outputFile, "%s_%u_%03lu:\n", g_asmLabel.c_str(), g_agbTrack, (unsigned long)(event.param2 & 0x7FFFFFFF));
ResetTrackVars();
s_inPattern = true;
}
PrintWait(event.time);
break;
case EventType::Pattern:
PrintByte("PATT");
PrintWord("%s_%u_%03lu", g_asmLabel.c_str(), g_agbTrack, event.param2);
while (!IsPatternBoundary(events[i + 1].type))
i++;
ResetTrackVars();
break;
case EventType::Tempo:
if (k == 0)
{
PrintByte("TEMPO , %u*%s_tbs/2", static_cast<int>(round(60000000.0f / static_cast<float>(event.param2))), g_asmLabel.c_str());
PrintWait(event.time);
}
break;
case EventType::InstrumentChange:
if (k == 0)
PrintOp(event.time, "VOICE ", "%u", event.param1);
break;
case EventType::PitchBend:
PrintOp(event.time, "BEND ", "c_v%+d", event.param2 - 64);
break;
case EventType::Controller:
if (k == 0)
PrintControllerOp(event);
break;
default:
PrintWait(event.time);
break;
}
}
}
PrintByte("FINE");
}
void PrintAgbFooter()
{
int trackCount = g_agbTrack - 1;

View File

@@ -26,6 +26,7 @@
void PrintAgbHeader();
void PrintAgbTrack(std::vector<Event>& events);
void PrintAgbTrackLoop(std::vector<Event>& events, int trackLoops);
void PrintAgbFooter();
extern int g_agbTrack;

View File

@@ -21,6 +21,7 @@
#include <cstdio>
#include <cassert>
#include <string>
#include <cstring>
#include <vector>
#include <algorithm>
#include <memory>
@@ -30,6 +31,10 @@
#include "agb.h"
#include "tables.h"
// expansion headers
#include "../../include/config/battle.h"
#include "../../include/config/general.h"
enum class MidiEventCategory
{
Control,
@@ -916,6 +921,7 @@ void Compress(std::vector<Event>& events)
void ReadMidiTracks()
{
long trackHeaderStart = 14;
int trackLoops = B_NUM_LOW_HEALTH_BEEPS;
ReadMidiTrackHeader(trackHeaderStart);
ReadSeqEvents();
@@ -955,7 +961,10 @@ void ReadMidiTracks()
if (g_compressionEnabled)
Compress(*events);
PrintAgbTrack(*events);
if ((strcmp(g_asmLabel.c_str(), "se_low_health") == 0) && trackLoops >= 0)
PrintAgbTrackLoop(*events, trackLoops);
else
PrintAgbTrack(*events);
g_agbTrack++;
}