This commit is contained in:
luckytyphlosion 2026-03-21 08:18:25 -07:00 committed by GitHub
commit 4d24b2952e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 180 additions and 16 deletions

View File

@ -342,7 +342,7 @@ ifneq ($(NODEP),1)
endif
$(DATA_ASM_BUILDDIR)/%.o: $(DATA_ASM_SUBDIR)/%.s
$(PREPROC) $< charmap.txt | $(CPP) $(INCLUDE_SCANINC_ARGS) - | $(PREPROC) -ie $< charmap.txt | $(AS) $(ASFLAGS) -o $@
$(PREPROC) $< charmap.txt | $(CPP) $(INCLUDE_SCANINC_ARGS) - | $(PREPROC) -ieq $< charmap.txt | $(AS) $(ASFLAGS) -o $@
$(DATA_ASM_BUILDDIR)/%.d: $(DATA_ASM_SUBDIR)/%.s
$(SCANINC) -M $@ $(INCLUDE_SCANINC_ARGS) -I "" $<

View File

@ -2468,7 +2468,7 @@ Move_HORN_DRILL:
jumpifcontest HornDrillInContest
fadetobg BG_DRILL
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 5, -2304, 768, 1, -1
createvisualtask AnimTask_StartSlidingBg, 5, Q_8_8(-9.0), Q_8_8(3.0), TRUE, -1
HornDrillContinue:
waitbgfadein
setalpha 12, 8
@ -9060,7 +9060,7 @@ Move_COSMIC_POWER:
waitforvisualfinish
fadetobg BG_COSMIC
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 2, 0, 128, 0, -1
createvisualtask AnimTask_StartSlidingBg, 2, Q_8_8(0.0), Q_8_8(0.5), 0, -1
waitbgfadein
delay 70
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_MORNING_SUN, SOUND_PAN_ATTACKER

View File

@ -21,6 +21,8 @@
#include <cstdio>
#include <cstdarg>
#include <stdexcept>
#include <sstream>
#include <cmath>
#include "preproc.h"
#include "asm_file.h"
#include "char_util.h"
@ -480,18 +482,172 @@ int AsmFile::ReadPadLength()
return n;
}
// Outputs the current line and moves to the next one.
void AsmFile::OutputLine()
bool AsmFile::CheckIdentifier(const std::string& ident)
{
while (m_buffer[m_pos] != '\n' && m_buffer[m_pos] != 0)
unsigned int i;
for (i = 0; i < ident.length() && m_pos + i < (unsigned)m_size; i++)
if (ident[i] != m_buffer[m_pos + i])
return false;
return (i == ident.length());
}
std::string fixedPointPseudoMacros[2] = { "Q_8_8", "UQ_8_8" };
bool AsmFile::TryConvertFixedPointPseudoMacro()
{
int incbinType = -1;
for (int i = 0; i < 2; i++)
{
if (CheckIdentifier(fixedPointPseudoMacros[i]))
{
incbinType = i;
break;
}
}
if (incbinType == -1) {
return false;
}
m_pos += fixedPointPseudoMacros[incbinType].length();
SkipWhitespace();
if (m_buffer[m_pos] != '(')
{
RaiseError("expected '(' after %s macro, got '%c'", fixedPointPseudoMacros[incbinType].c_str(), m_buffer[m_pos]);
}
m_pos++;
std::stringstream fixedPointNumStream;
bool foundDecimalPoint = false;
bool isFirstChar = true;
SkipWhitespace();
while (true)
{
char curChar;
curChar = m_buffer[m_pos];
if (curChar == 0) {
if (m_pos >= m_size)
RaiseError("unexpected EOF in fixed-point macro arg");
else
RaiseError("unexpected null character in fixed-point macro arg");
}
if (curChar == '\r' || curChar == '\n')
RaiseError("unexpected end of line character in path string");
if (isFirstChar && curChar == '-') {
fixedPointNumStream << curChar;
} else if (curChar == '.') {
if (foundDecimalPoint) {
RaiseError("Multiple decimal points found in fixed-point macro arg");
}
fixedPointNumStream << curChar;
} else if (std::isdigit(curChar)) {
fixedPointNumStream << curChar;
} else if (curChar == ')') {
m_pos++;
break;
} else {
RaiseError("unexpected character '%c' in fixed-point macro arg (note that only a single decimal number is currently supported, i.e. no expressions)", curChar);
}
m_pos++;
isFirstChar = false;
}
float fixedPointNum = 0.0;
bool parseError = false;
fixedPointNumStream >> fixedPointNum;
if (fixedPointNumStream.fail()) {
parseError = true;
} else {
fixedPointNum *= 256;
}
if (parseError || std::isnan(fixedPointNum) || std::isinf(fixedPointNum)) {
std::string fixedPointNumStr = fixedPointNumStream.str();
RaiseError("invalid fixed-point macro arg '%s' (note that only a single decimal number is currently supported, i.e. no expressions)", fixedPointNumStr.c_str());
}
//Q_8_8
if (incbinType == 0) {
// Q_8_8(-128.0) is the least value
// anything lesser results in underflow
if (fixedPointNum < -32768) {
std::string fixedPointNumStr = fixedPointNumStream.str();
RaiseError("fixed-point macro arg '%s' too small for Q_8_8 (must be in range [-128, 128).)", fixedPointNumStr.c_str());
} else if (fixedPointNum >= 32768) {
std::string fixedPointNumStr = fixedPointNumStream.str();
RaiseError("fixed-point macro arg '%s' too large for Q_8_8 (must be in range [-128, 128).)", fixedPointNumStr.c_str());
}
//UQ_8_8
} else {
// Q_8_8(-128.0) is the least value
// anything lesser results in underflow
if (fixedPointNum < 0) {
std::string fixedPointNumStr = fixedPointNumStream.str();
RaiseError("fixed-point macro arg '%s' cannot be negative for UQ_8_8", fixedPointNumStr.c_str());
} else if (fixedPointNum >= 65536) {
std::string fixedPointNumStr = fixedPointNumStream.str();
RaiseError("fixed-point macro arg '%s' too large for UQ_8_8 (must be in range [0,256).)", fixedPointNumStr.c_str());
}
}
int fixedPointNumAsInt = ((int)fixedPointNum) & 0xffff;
std::printf("%d", fixedPointNumAsInt);
return true;
}
// Outputs the current line and moves to the next one.
void AsmFile::OutputLine(bool doFixedPoint)
{
// have to restart to the current line because whitespace was skipped earlier in GetDirective
m_pos = m_lineStart;
if (doFixedPoint) {
while (true) {
char curChar = m_buffer[m_pos];
if (curChar == '\n' || curChar == 0) {
break;
}
// return true if fixed point macro happened
if (!TryConvertFixedPointPseudoMacro()) {
std::putchar(curChar);
m_pos++;
}
}
} else {
while (true) {
char curChar = m_buffer[m_pos];
if (curChar == '\n' || curChar == 0) {
break;
}
std::putchar(curChar);
m_pos++;
}
}
if (m_buffer[m_pos] == 0)
{
if (m_pos >= m_size)
{
RaiseWarning("file doesn't end with newline");
puts(&m_buffer[m_lineStart]);
std::putchar('\n');
}
else
{
@ -500,9 +656,8 @@ void AsmFile::OutputLine()
}
else
{
m_buffer[m_pos] = 0;
puts(&m_buffer[m_lineStart]);
m_buffer[m_pos] = '\n';
std::putchar('\n');
m_pos++;
m_lineStart = m_pos;
m_lineNum++;

View File

@ -48,7 +48,7 @@ public:
int ReadString(unsigned char* s);
int ReadBraille(unsigned char* s);
bool IsAtEnd();
void OutputLine();
void OutputLine(bool doFixedPoint);
void OutputLocation();
bool ParseEnum();
@ -63,6 +63,8 @@ private:
bool ConsumeComma();
int ReadPadLength();
bool CheckIdentifier(const std::string& ident);
bool TryConvertFixedPointPseudoMacro();
void RemoveComments();
bool CheckForDirective(std::string name);
void SkipWhitespace();

View File

@ -51,7 +51,7 @@ void PrintAsmBytes(unsigned char *s, int length)
}
}
void PreprocAsmFile(std::string filename, bool isStdin, bool doEnum)
void PreprocAsmFile(std::string filename, bool isStdin, bool doEnum, bool doFixedPoint)
{
std::stack<AsmFile> stack;
@ -95,7 +95,7 @@ void PreprocAsmFile(std::string filename, bool isStdin, bool doEnum)
case Directive::Enum:
{
if (!stack.top().ParseEnum())
stack.top().OutputLine();
stack.top().OutputLine(doFixedPoint);
break;
}
case Directive::Unknown:
@ -109,7 +109,7 @@ void PreprocAsmFile(std::string filename, bool isStdin, bool doEnum)
}
else
{
stack.top().OutputLine();
stack.top().OutputLine(doFixedPoint);
}
break;
@ -147,7 +147,7 @@ const char* GetFileExtension(const char* filename)
static void UsageAndExit(const char *program)
{
std::fprintf(stderr, "Usage: %s [-i] [-e] SRC_FILE CHARMAP_FILE\nwhere -i denotes if input is from stdin\n -e enables enum handling\n", program);
std::fprintf(stderr, "Usage: %s [-i] [-e] SRC_FILE CHARMAP_FILE\nwhere -i denotes if input is from stdin\n -e enables enum handling\n -q enables fixed-point macro (Q_8_8, UQ_8_8) handling\n", program);
std::exit(EXIT_FAILURE);
}
@ -158,9 +158,10 @@ int main(int argc, char **argv)
const char *charmap = NULL;
bool isStdin = false;
bool doEnum = false;
bool doFixedPoint = false;
/* preproc [-i] [-e] SRC_FILE CHARMAP_FILE */
while ((opt = getopt(argc, argv, "ie")) != -1)
while ((opt = getopt(argc, argv, "ieq")) != -1)
{
switch (opt)
{
@ -170,6 +171,9 @@ int main(int argc, char **argv)
case 'e':
doEnum = true;
break;
case 'q':
doFixedPoint = true;
break;
default:
UsageAndExit(argv[0]);
break;
@ -196,12 +200,15 @@ int main(int argc, char **argv)
if ((extension[0] == 's') && extension[1] == 0)
{
PreprocAsmFile(source, isStdin, doEnum);
PreprocAsmFile(source, isStdin, doEnum, doFixedPoint);
}
else if ((extension[0] == 'c' || extension[0] == 'i') && extension[1] == 0)
{
if (doEnum)
FATAL_ERROR("-e is invalid for C sources\n");
else if (doFixedPoint)
FATAL_ERROR("-q is invalid for C sources\n");
PreprocCFile(source, isStdin);
}
else