mirror of
https://github.com/rh-hideout/pokeemerald-expansion
synced 2025-10-05 23:42:46 +02:00
Low Health Beeps Configuration (#6328)
This commit is contained in:
@@ -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)
|
||||
|
@@ -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.
|
||||
|
@@ -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:
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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++;
|
||||
}
|
||||
|
Reference in New Issue
Block a user