summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml44
-rw-r--r--Makefile135
-rw-r--r--data/battle_anim_scripts.s30
-rw-r--r--data/maps/MagmaHideout_2F_2R/map.json2
-rw-r--r--data/maps/MagmaHideout_4F/map.json2
-rw-r--r--data/scripts/item_ball_scripts.inc4
-rw-r--r--include/battle_anim.h2
-rw-r--r--include/global.fieldmap.h16
-rw-r--r--include/strings.h4
-rw-r--r--make_tools.mk11
-rw-r--r--src/battle_anim_dark.c10
-rwxr-xr-xsrc/battle_anim_effects_2.c16
-rw-r--r--src/battle_anim_mons.c2
-rwxr-xr-xsrc/battle_anim_throw.c2
-rw-r--r--src/battle_interface.c4
-rw-r--r--src/battle_message.c6
-rw-r--r--src/bike.c2
-rw-r--r--src/contest.c2
-rw-r--r--src/contest_util.c2
-rwxr-xr-xsrc/item_use.c2
-rw-r--r--src/overworld.c6
-rw-r--r--src/region_map.c2
-rw-r--r--src/strings.c6
-rwxr-xr-xsrc/union_room_chat.c2
-rw-r--r--tools/preproc/c_file.cpp55
-rw-r--r--tools/preproc/c_file.h5
-rw-r--r--tools/preproc/preproc.cpp22
27 files changed, 271 insertions, 125 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 822b386ea..de3a35c40 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -7,11 +7,29 @@ on:
jobs:
build:
- runs-on: ubuntu-18.04
+ runs-on: ubuntu-latest
+ env:
+ GAME_VERSION: EMERALD
+ GAME_REVISION: 0
+ GAME_LANGUAGE: ENGLISH
+ MODERN: 0
+ COMPARE: 1
steps:
- name: Checkout
uses: actions/checkout@master
+ - name: Checkout syms
+ uses: actions/checkout@master
+ with:
+ path: symbols
+ ref: symbols
+
+ - name: Checkout agbcc
+ uses: actions/checkout@master
+ with:
+ path: agbcc
+ repository: pret/agbcc
+
- name: Install binutils
run: sudo apt install gcc-arm-none-eabi binutils-arm-none-eabi
# build-essential, git, and libpng-dev are already installed
@@ -20,16 +38,18 @@ jobs:
- name: Install agbcc
run: |
- git clone https://github.com/pret/agbcc.git
- cd agbcc
./build.sh
./install.sh ../
+ working-directory: agbcc
- name: Compare
- run: make -j${nproc} compare
+ run: make -j${nproc} all syms
- name: Modern
- run: make -j${nproc} modern
+ env:
+ MODERN: 1
+ COMPARE: 0
+ run: make -j${nproc} all
- name: Webhook
if: ${{ github.event_name == 'push' }}
@@ -38,3 +58,17 @@ jobs:
CALCROM_DISCORD_WEBHOOK_AVATAR_URL: https://i.imgur.com/38BQHdd.png
CALCROM_DISCORD_WEBHOOK_URL: ${{ secrets.CALCROM_DISCORD_WEBHOOK_URL }}
run: sh .github/calcrom/webhook.sh pokeemerald
+
+ - name: Move symfiles
+ if: ${{ github.event_name == 'push' }}
+ run: |
+ cp -v *.sym symbols/
+
+ - name: Update symfiles
+ if: ${{ github.event_name == 'push' }}
+ uses: EndBug/add-and-commit@v7
+ with:
+ branch: symbols
+ cwd: "./symbols"
+ add: "*.sym"
+ message: ${{ github.event.commits[0].message }}
diff --git a/Makefile b/Makefile
index a78949b3f..2e5afdf0c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,10 @@
TOOLCHAIN := $(DEVKITARM)
COMPARE ?= 0
+ifeq (compare,$(MAKECMDGOALS))
+ COMPARE := 1
+endif
+
# don't use dkP's base_tools anymore
# because the redefinition of $(CC) conflicts
# with when we want to use $(CC) to preprocess files
@@ -16,6 +20,7 @@ endif
PREFIX := arm-none-eabi-
OBJCOPY := $(PREFIX)objcopy
+OBJDUMP := $(PREFIX)objdump
AS := $(PREFIX)as
LD := $(PREFIX)ld
@@ -36,6 +41,10 @@ MAKER_CODE := 01
REVISION := 0
MODERN ?= 0
+ifeq (modern,$(MAKECMDGOALS))
+ MODERN := 1
+endif
+
# use arm-none-eabi-cpp for macOS
# as macOS's default compiler is clang
# and clang's preprocessor will warn on \u
@@ -67,6 +76,7 @@ SHELL := /bin/bash -o pipefail
ELF = $(ROM:.gba=.elf)
MAP = $(ROM:.gba=.map)
+SYM = $(ROM:.gba=.sym)
C_SUBDIR = src
GFLIB_SUBDIR = gflib
@@ -121,6 +131,8 @@ FIX := tools/gbafix/gbafix$(EXE)
MAPJSON := tools/mapjson/mapjson$(EXE)
JSONPROC := tools/jsonproc/jsonproc$(EXE)
+PERL := perl
+
TOOLDIRS := $(filter-out tools/agbcc tools/binutils,$(wildcard tools/*))
TOOLBASE = $(TOOLDIRS:tools/%=%)
TOOLS = $(foreach tool,$(TOOLBASE),tools/$(tool)/$(tool)$(EXE))
@@ -143,12 +155,28 @@ infoshell = $(foreach line, $(shell $1 | sed "s/ /__SPACE__/g"), $(info $(subst
# Build tools when building the rom
# Disable dependency scanning for clean/tidy/tools
-ifeq (,$(filter-out all rom compare modern berry_fix libagbsyscall,$(MAKECMDGOALS)))
-$(call infoshell, $(MAKE) tools)
+# Use a separate minimal makefile for speed
+# Since we don't need to reload most of this makefile
+ifeq (,$(filter-out all rom compare modern berry_fix libagbsyscall syms,$(MAKECMDGOALS)))
+$(call infoshell, $(MAKE) -f make_tools.mk)
+else
+NODEP ?= 1
+endif
+
+# check if we need to scan dependencies based on the rule
+ifeq (,$(MAKECMDGOALS))
+ SCAN_DEPS ?= 1
else
-NODEP := 1
+ # clean, tidy, tools, mostlyclean, clean-tools, $(TOOLDIRS), tidymodern, tidynonmodern don't even build the ROM
+ # berry_fix and libagbsyscall do their own thing
+ ifeq (,$(filter-out clean tidy tools mostlyclean clean-tools $(TOOLDIRS) tidymodern tidynonmodern berry_fix libagbsyscall,$(MAKECMDGOALS)))
+ SCAN_DEPS ?= 0
+ else
+ SCAN_DEPS ?= 1
+ endif
endif
+ifeq ($(SCAN_DEPS),1)
C_SRCS_IN := $(wildcard $(C_SUBDIR)/*.c $(C_SUBDIR)/*/*.c $(C_SUBDIR)/*/*/*.c)
C_SRCS := $(foreach src,$(C_SRCS_IN),$(if $(findstring .inc.c,$(src)),,$(src)))
C_OBJS := $(patsubst $(C_SUBDIR)/%.c,$(C_BUILDDIR)/%.o,$(C_SRCS))
@@ -178,15 +206,17 @@ OBJS := $(C_OBJS) $(GFLIB_OBJS) $(C_ASM_OBJS) $(ASM_OBJS) $(DATA_ASM_OBJS) $
OBJS_REL := $(patsubst $(OBJ_DIR)/%,%,$(OBJS))
SUBDIRS := $(sort $(dir $(OBJS)))
+$(shell mkdir -p $(SUBDIRS))
+endif
AUTO_GEN_TARGETS :=
-$(shell mkdir -p $(SUBDIRS))
-
all: rom
tools: $(TOOLDIRS)
+syms: $(SYM)
+
$(TOOLDIRS):
@$(MAKE) -C $@
@@ -196,7 +226,7 @@ ifeq ($(COMPARE),1)
endif
# For contributors to make sure a change didn't affect the contents of the ROM.
-compare: ; @$(MAKE) COMPARE=1
+compare: all
clean: mostlyclean clean-tools
@@ -270,48 +300,80 @@ else
$(C_BUILDDIR)/librfu_intr.o: CFLAGS := -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast
endif
-ifeq ($(NODEP),1)
-$(C_BUILDDIR)/%.o: c_dep :=
-else
-$(C_BUILDDIR)/%.o: c_dep = $(shell [[ -f $(C_SUBDIR)/$*.c ]] && $(SCANINC) -I include -I tools/agbcc/include -I gflib $(C_SUBDIR)/$*.c)
-endif
-
ifeq ($(DINFO),1)
override CFLAGS += -g
endif
-$(C_BUILDDIR)/%.o : $(C_SUBDIR)/%.c $$(c_dep)
+# The dep rules have to be explicit or else missing files won't be reported.
+# As a side effect, they're evaluated immediately instead of when the rule is invoked.
+# It doesn't look like $(shell) can be deferred so there might not be a better way.
+
+ifeq ($(SCAN_DEPS),1)
+ifeq ($(NODEP),1)
+$(C_BUILDDIR)/%.o: $(C_SUBDIR)/%.c
+ifeq (,$(KEEP_TEMPS))
+ @echo "$(CC1) <flags> -o $@ $<"
+ @$(CPP) $(CPPFLAGS) $< | $(PREPROC) $< charmap.txt -i | $(CC1) $(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $(AS) $(ASFLAGS) -o $@ -
+else
@$(CPP) $(CPPFLAGS) $< -o $(C_BUILDDIR)/$*.i
@$(PREPROC) $(C_BUILDDIR)/$*.i charmap.txt | $(CC1) $(CFLAGS) -o $(C_BUILDDIR)/$*.s
@echo -e ".text\n\t.align\t2, 0\n" >> $(C_BUILDDIR)/$*.s
$(AS) $(ASFLAGS) -o $@ $(C_BUILDDIR)/$*.s
-
-ifeq ($(NODEP),1)
-$(GFLIB_BUILDDIR)/%.o: c_dep :=
+endif
else
-$(GFLIB_BUILDDIR)/%.o: c_dep = $(shell [[ -f $(GFLIB_SUBDIR)/$*.c ]] && $(SCANINC) -I include -I tools/agbcc/include -I gflib $(GFLIB_SUBDIR)/$*.c)
+define C_DEP
+$1: $2 $$(shell $(SCANINC) -I include -I tools/agbcc/include -I gflib $2)
+ifeq (,$$(KEEP_TEMPS))
+ @echo "$$(CC1) <flags> -o $$@ $$<"
+ @$$(CPP) $$(CPPFLAGS) $$< | $$(PREPROC) $$< charmap.txt -i | $$(CC1) $$(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $$(AS) $$(ASFLAGS) -o $$@ -
+else
+ @$$(CPP) $$(CPPFLAGS) $$< -o $$(C_BUILDDIR)/$3.i
+ @$$(PREPROC) $$(C_BUILDDIR)/$3.i charmap.txt | $$(CC1) $$(CFLAGS) -o $$(C_BUILDDIR)/$3.s
+ @echo -e ".text\n\t.align\t2, 0\n" >> $$(C_BUILDDIR)/$3.s
+ $$(AS) $$(ASFLAGS) -o $$@ $$(C_BUILDDIR)/$3.s
+endif
+endef
+$(foreach src, $(C_SRCS), $(eval $(call C_DEP,$(patsubst $(C_SUBDIR)/%.c,$(C_BUILDDIR)/%.o,$(src)),$(src),$(patsubst $(C_SUBDIR)/%.c,%,$(src)))))
endif
-$(GFLIB_BUILDDIR)/%.o : $(GFLIB_SUBDIR)/%.c $$(c_dep)
+ifeq ($(NODEP),1)
+$(GFLIB_BUILDDIR)/%.o: $(GFLIB_SUBDIR)/%.c $$(c_dep)
+ifeq (,$(KEEP_TEMPS))
+ @echo "$(CC1) <flags> -o $@ $<"
+ @$(CPP) $(CPPFLAGS) $< | $(PREPROC) $< charmap.txt -i | $(CC1) $(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $(AS) $(ASFLAGS) -o $@ -
+else
@$(CPP) $(CPPFLAGS) $< -o $(GFLIB_BUILDDIR)/$*.i
@$(PREPROC) $(GFLIB_BUILDDIR)/$*.i charmap.txt | $(CC1) $(CFLAGS) -o $(GFLIB_BUILDDIR)/$*.s
@echo -e ".text\n\t.align\t2, 0\n" >> $(GFLIB_BUILDDIR)/$*.s
$(AS) $(ASFLAGS) -o $@ $(GFLIB_BUILDDIR)/$*.s
+endif
+else
+define GFLIB_DEP
+$1: $2 $$(shell $(SCANINC) -I include -I tools/agbcc/include -I gflib $2)
+ifeq (,$$(KEEP_TEMPS))
+ @echo "$$(CC1) <flags> -o $$@ $$<"
+ @$$(CPP) $$(CPPFLAGS) $$< | $$(PREPROC) $$< charmap.txt -i | $$(CC1) $$(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $$(AS) $$(ASFLAGS) -o $$@ -
+else
+ @$$(CPP) $$(CPPFLAGS) $$< -o $$(GFLIB_BUILDDIR)/$3.i
+ @$$(PREPROC) $$(GFLIB_BUILDDIR)/$3.i charmap.txt | $$(CC1) $$(CFLAGS) -o $$(GFLIB_BUILDDIR)/$3.s
+ @echo -e ".text\n\t.align\t2, 0\n" >> $$(GFLIB_BUILDDIR)/$3.s
+ $$(AS) $$(ASFLAGS) -o $$@ $$(GFLIB_BUILDDIR)/$3.s
+endif
+endef
+$(foreach src, $(GFLIB_SRCS), $(eval $(call GFLIB_DEP,$(patsubst $(GFLIB_SUBDIR)/%.c,$(GFLIB_BUILDDIR)/%.o, $(src)),$(src),$(patsubst $(GFLIB_SUBDIR)/%.c,%, $(src)))))
+endif
ifeq ($(NODEP),1)
-$(C_BUILDDIR)/%.o: c_asm_dep :=
+$(C_BUILDDIR)/%.o: $(C_SUBDIR)/%.s
+ $(PREPROC) $< charmap.txt | $(CPP) -I include - | $(AS) $(ASFLAGS) -o $@
else
-$(C_BUILDDIR)/%.o: c_asm_dep = $(shell [[ -f $(C_SUBDIR)/$*.s ]] && $(SCANINC) -I "" $(C_SUBDIR)/$*.s)
+define SRC_ASM_DATA_DEP
+$1: $2 $$(shell $(SCANINC) -I include -I "" $2)
+ $$(PREPROC) $$< charmap.txt | $$(CPP) -I include - | $$(AS) $$(ASFLAGS) -o $$@
+endef
+$(foreach src, $(C_ASM_SRCS), $(eval $(call SRC_ASM_DATA_DEP,$(patsubst $(C_SUBDIR)/%.s,$(C_BUILDDIR)/%.o, $(src)),$(src))))
endif
-$(C_BUILDDIR)/%.o: $(C_SUBDIR)/%.s $$(c_asm_dep)
- $(AS) $(ASFLAGS) -o $@ $<
-
-# The dep rules have to be explicit or else missing files won't be reported.
-# As a side effect, they're evaluated immediately instead of when the rule is invoked.
-# It doesn't look like $(shell) can be deferred so there might not be a better way.
-
-
ifeq ($(NODEP),1)
$(ASM_BUILDDIR)/%.o: $(ASM_SUBDIR)/%.s
$(AS) $(ASFLAGS) -o $@ $<
@@ -327,12 +389,8 @@ ifeq ($(NODEP),1)
$(DATA_ASM_BUILDDIR)/%.o: $(DATA_ASM_SUBDIR)/%.s
$(PREPROC) $< charmap.txt | $(CPP) -I include - | $(AS) $(ASFLAGS) -o $@
else
-define DATA_ASM_DEP
-$1: $2 $$(shell $(SCANINC) -I include -I "" $2)
- $$(PREPROC) $$< charmap.txt | $$(CPP) -I include - | $$(AS) $$(ASFLAGS) -o $$@
-endef
-$(foreach src, $(REGULAR_DATA_ASM_SRCS), $(eval $(call DATA_ASM_DEP,$(patsubst $(DATA_ASM_SUBDIR)/%.s,$(DATA_ASM_BUILDDIR)/%.o, $(src)),$(src))))
-$(foreach src, $(C_ASM_SRCS), $(eval $(call DATA_ASM_DEP,$(patsubst $(C_SUBDIR)/%.s,$(C_BUILDDIR)/%.o, $(src)),$(src))))
+$(foreach src, $(REGULAR_DATA_ASM_SRCS), $(eval $(call SRC_ASM_DATA_DEP,$(patsubst $(DATA_ASM_SUBDIR)/%.s,$(DATA_ASM_BUILDDIR)/%.o, $(src)),$(src))))
+endif
endif
$(SONG_BUILDDIR)/%.o: $(SONG_SUBDIR)/%.s
@@ -367,7 +425,7 @@ $(ROM): $(ELF)
$(OBJCOPY) -O binary $< $@
$(FIX) $@ -p --silent
-modern: ; @$(MAKE) MODERN=1
+modern: all
berry_fix/berry_fix.gba: berry_fix
@@ -376,3 +434,10 @@ berry_fix:
libagbsyscall:
@$(MAKE) -C libagbsyscall TOOLCHAIN=$(TOOLCHAIN) MODERN=$(MODERN)
+
+###################
+### Symbol file ###
+###################
+
+$(SYM): $(ELF)
+ $(OBJDUMP) -t $< | sort -u | grep -E "^0[2389]" | $(PERL) -p -e 's/^(\w{8}) (\w).{6} \S+\t(\w{8}) (\S+)$$/\1 \2 \3 \4/g' > $@
diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s
index d1c9bc78b..e7aad6a93 100644
--- a/data/battle_anim_scripts.s
+++ b/data/battle_anim_scripts.s
@@ -1656,12 +1656,12 @@ Explosion1:
Move_DEFENSE_CURL:
loadspritegfx ANIM_TAG_ECLIPSING_ORB
loopsewithpan SE_M_TRI_ATTACK, SOUND_PAN_ATTACKER, 18, 3
- createvisualtask AnimTask_SetGreyscaleOrOriginalPal, 5, ANIM_ATTACKER, 0
+ createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_ATTACKER, 0
createvisualtask AnimTask_DefenseCurlDeformMon, 5
waitforvisualfinish
createsprite gEclipsingOrbSpriteTemplate, ANIM_ATTACKER, 2, 0, 6, 0, 1
waitforvisualfinish
- createvisualtask AnimTask_SetGreyscaleOrOriginalPal, 5, ANIM_ATTACKER, 1
+ createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_ATTACKER, 1
waitforvisualfinish
end
@@ -7254,7 +7254,7 @@ Move_IRON_TAIL:
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
- createvisualtask AnimTask_SetGreyscaleOrOriginalPal, 5, ANIM_ATTACKER, 1
+ createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_ATTACKER, 1
clearmonbg ANIM_TARGET
blendoff
waitforvisualfinish
@@ -7274,7 +7274,7 @@ Move_POISON_TAIL:
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
- createvisualtask AnimTask_SetGreyscaleOrOriginalPal, 5, ANIM_ATTACKER, 1
+ createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_ATTACKER, 1
clearmonbg ANIM_TARGET
blendoff
call PoisonBubblesEffect
@@ -7551,7 +7551,7 @@ Move_DISABLE:
playsewithpan SE_M_DETECT, SOUND_PAN_ATTACKER
createsprite gSpinningSparkleSpriteTemplate, ANIM_ATTACKER, 13, 24, -16
waitforvisualfinish
- createvisualtask AnimTask_GrowAndGreyscale, 5
+ createvisualtask AnimTask_GrowAndGrayscale, 5
loopsewithpan SE_M_BIND, SOUND_PAN_TARGET, 15, 4
waitforvisualfinish
delay 1
@@ -7946,16 +7946,16 @@ Move_PERISH_SONG:
panse_1B SE_M_PERISH_SONG, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
delay 80
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 1, 3, 0, 16, RGB_BLACK
- createvisualtask AnimTask_SetGreyscaleOrOriginalPal, 5, 4, 0
- createvisualtask AnimTask_SetGreyscaleOrOriginalPal, 5, 5, 0
- createvisualtask AnimTask_SetGreyscaleOrOriginalPal, 5, 6, 0
- createvisualtask AnimTask_SetGreyscaleOrOriginalPal, 5, 7, 0
+ createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, 4, 0
+ createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, 5, 0
+ createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, 6, 0
+ createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, 7, 0
delay 100
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 1, 3, 16, 0, RGB_BLACK
- createvisualtask AnimTask_SetGreyscaleOrOriginalPal, 5, 4, 1
- createvisualtask AnimTask_SetGreyscaleOrOriginalPal, 5, 5, 1
- createvisualtask AnimTask_SetGreyscaleOrOriginalPal, 5, 6, 1
- createvisualtask AnimTask_SetGreyscaleOrOriginalPal, 5, 7, 1
+ createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, 4, 1
+ createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, 5, 1
+ createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, 6, 1
+ createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, 7, 1
waitforvisualfinish
end
@@ -9573,7 +9573,7 @@ Move_DOOM_DESIRE:
createvisualtask GetIsDoomDesireHitTurn, 2
delay 1
monbg ANIM_ATK_PARTNER
- createvisualtask AnimTask_SetGreyscaleOrOriginalPal, 5, ANIM_TARGET, FALSE
+ createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_TARGET, FALSE
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 1, 1, 0, 4, RGB_BLACK
waitforvisualfinish
setalpha 8, 8
@@ -9581,7 +9581,7 @@ Move_DOOM_DESIRE:
createvisualtask AnimTask_ScaleMonAndRestore, 5, -4, -4, 15, ANIM_ATTACKER, 1
waitforvisualfinish
delay 20
- createvisualtask AnimTask_SetGreyscaleOrOriginalPal, 5, ANIM_TARGET, TRUE
+ createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_TARGET, TRUE
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 1, 1, 4, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
diff --git a/data/maps/MagmaHideout_2F_2R/map.json b/data/maps/MagmaHideout_2F_2R/map.json
index 4aa6896f6..968c07fb7 100644
--- a/data/maps/MagmaHideout_2F_2R/map.json
+++ b/data/maps/MagmaHideout_2F_2R/map.json
@@ -50,7 +50,7 @@
"movement_range_y": 1,
"trainer_type": "TRAINER_TYPE_NONE",
"trainer_sight_or_berry_tree_id": "0",
- "script": "MagmaHideout_2F_2R_EventScript_MaxElixir",
+ "script": "MagmaHideout_2F_2R_EventScript_ItemMaxElixir",
"flag": "FLAG_ITEM_MAGMA_HIDEOUT_2F_2R_MAX_ELIXIR"
},
{
diff --git a/data/maps/MagmaHideout_4F/map.json b/data/maps/MagmaHideout_4F/map.json
index 94cf295e0..67c11481f 100644
--- a/data/maps/MagmaHideout_4F/map.json
+++ b/data/maps/MagmaHideout_4F/map.json
@@ -115,7 +115,7 @@
"movement_range_y": 1,
"trainer_type": "TRAINER_TYPE_NONE",
"trainer_sight_or_berry_tree_id": "0",
- "script": "MagmaHideout_4F_EventScript_MaxRevive",
+ "script": "MagmaHideout_4F_EventScript_ItemMaxRevive",
"flag": "FLAG_ITEM_MAGMA_HIDEOUT_4F_MAX_REVIVE"
}
],
diff --git a/data/scripts/item_ball_scripts.inc b/data/scripts/item_ball_scripts.inc
index 82633f77c..f9228134c 100644
--- a/data/scripts/item_ball_scripts.inc
+++ b/data/scripts/item_ball_scripts.inc
@@ -634,7 +634,7 @@ MagmaHideout_1F_EventScript_ItemRareCandy:: @ 82914DE
finditem ITEM_RARE_CANDY
end
-MagmaHideout_2F_2R_EventScript_MaxElixir:: @ 82914EB
+MagmaHideout_2F_2R_EventScript_ItemMaxElixir:: @ 82914EB
finditem ITEM_MAX_ELIXIR
end
@@ -650,7 +650,7 @@ MagmaHideout_3F_2R_EventScript_ItemPPMax:: @ 8291512
finditem ITEM_PP_MAX
end
-MagmaHideout_4F_EventScript_MaxRevive:: @ 829151F
+MagmaHideout_4F_EventScript_ItemMaxRevive:: @ 829151F
finditem ITEM_MAX_REVIVE
end
diff --git a/include/battle_anim.h b/include/battle_anim.h
index 476480489..ad160e74d 100644
--- a/include/battle_anim.h
+++ b/include/battle_anim.h
@@ -143,7 +143,7 @@ void TranslateSpriteLinear(struct Sprite *sprite);
void AnimSpriteOnMonPos(struct Sprite *sprite);
void InitAnimLinearTranslationWithSpeedAndPos(struct Sprite *sprite);
void TranslateSpriteInCircleOverDuration(struct Sprite *sprite);
-void SetGreyscaleOrOriginalPalette(u16 palNum, bool8 restoreOriginal);
+void SetGrayscaleOrOriginalPalette(u16 palNum, bool8 restoreOriginal);
void PrepareAffineAnimInTaskData(struct Task *task, u8 spriteId, const union AffineAnimCmd *affineAnimCmds);
bool8 RunAffineAnimFromTaskData(struct Task *task);
void AnimThrowProjectile(struct Sprite *sprite);
diff --git a/include/global.fieldmap.h b/include/global.fieldmap.h
index a3d99ee21..6bafa9747 100644
--- a/include/global.fieldmap.h
+++ b/include/global.fieldmap.h
@@ -142,19 +142,15 @@ struct MapHeader
/* 0x16 */ u8 weather;
/* 0x17 */ u8 mapType;
/* 0x18 */ u8 filler_18[2];
- /* 0x1A */ u8 flags;
+ // fields correspond to the arguments in the map_header_flags macro
+ /* 0x1A */ bool8 allowCycling:1;
+ bool8 allowEscaping:1; // Escape Rope and Dig
+ bool8 allowRunning:1;
+ bool8 showMapName:5; // the last 4 bits are unused
+ // but the 5 bit sized bitfield is required to match
/* 0x1B */ u8 battleType;
};
-// Flags for gMapHeader.flags, as defined in the map_header_flags macro
-#define MAP_ALLOW_CYCLING (1 << 0)
-#define MAP_ALLOW_ESCAPING (1 << 1) // Escape Rope and Dig
-#define MAP_ALLOW_RUNNING (1 << 2)
-#define MAP_SHOW_MAP_NAME (1 << 3)
-#define UNUSED_MAP_FLAGS (1 << 4 | 1 << 5 | 1 << 6 | 1 << 7)
-
-#define SHOW_MAP_NAME_ENABLED ((gMapHeader.flags & (MAP_SHOW_MAP_NAME | UNUSED_MAP_FLAGS)) == MAP_SHOW_MAP_NAME)
-
struct ObjectEvent
{
diff --git a/include/strings.h b/include/strings.h
index 04283db0e..9b3be0538 100644
--- a/include/strings.h
+++ b/include/strings.h
@@ -596,7 +596,7 @@ extern const u8 gText_TooImportantToToss[];
extern const u8 gText_ConfirmTossItems[];
extern const u8 gText_MoveVar1Where[];
-extern const u8 gText_ColorLightShadowDarkGrey[];
+extern const u8 gText_ColorLightShadowDarkGray[];
extern const u8 gText_ColorBlue[];
extern const u8 gText_Friend[];
extern const u8 gText_Tristan[];
@@ -2512,7 +2512,7 @@ extern const u8 gText_MatchCallMay_Intro1[];
extern const u8 gText_MatchCallMay_Intro2[];
// Contest Link
-extern const u8 gText_ColorDarkGrey[];
+extern const u8 gText_ColorDarkGray[];
extern const u8 gText_CommunicationStandby[];
extern const u8 gText_AnnouncingResults[];
extern const u8 gText_PreliminaryResults[];
diff --git a/make_tools.mk b/make_tools.mk
new file mode 100644
index 000000000..697897a69
--- /dev/null
+++ b/make_tools.mk
@@ -0,0 +1,11 @@
+
+MAKEFLAGS += --no-print-directory
+
+TOOLDIRS := $(filter-out tools/agbcc tools/binutils,$(wildcard tools/*))
+
+.PHONY: all $(TOOLDIRS)
+
+all: $(TOOLDIRS)
+
+$(TOOLDIRS):
+ @$(MAKE) -C $@
diff --git a/src/battle_anim_dark.c b/src/battle_anim_dark.c
index c2bfe269b..8000a648c 100644
--- a/src/battle_anim_dark.c
+++ b/src/battle_anim_dark.c
@@ -870,7 +870,7 @@ void AnimTask_MetallicShine(u8 taskId)
paletteNum = 16 + gSprites[spriteId].oam.paletteNum;
if (gBattleAnimArgs[1] == 0)
- SetGreyscaleOrOriginalPalette(paletteNum, FALSE);
+ SetGrayscaleOrOriginalPalette(paletteNum, FALSE);
else
BlendPalette(paletteNum * 16, 16, 11, gBattleAnimArgs[2]);
@@ -900,7 +900,7 @@ static void AnimTask_MetallicShine_Step(u8 taskId)
spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
paletteNum = 16 + gSprites[spriteId].oam.paletteNum;
if (gTasks[taskId].data[1] == 0)
- SetGreyscaleOrOriginalPalette(paletteNum, TRUE);
+ SetGrayscaleOrOriginalPalette(paletteNum, TRUE);
DestroySprite(&gSprites[gTasks[taskId].data[0]]);
GetBattleAnimBg1Data(&animBg);
@@ -925,10 +925,10 @@ static void AnimTask_MetallicShine_Step(u8 taskId)
}
}
-// Changes battler's palette to either greyscale or original.
+// Changes battler's palette to either grayscale or original.
// arg0: which battler
// arg1: FALSE grayscale, TRUE original
-void AnimTask_SetGreyscaleOrOriginalPal(u8 taskId)
+void AnimTask_SetGrayscaleOrOriginalPal(u8 taskId)
{
u8 spriteId;
u8 battler;
@@ -974,7 +974,7 @@ void AnimTask_SetGreyscaleOrOriginalPal(u8 taskId)
}
if (spriteId != SPRITE_NONE)
- SetGreyscaleOrOriginalPalette(gSprites[spriteId].oam.paletteNum + 16, gBattleAnimArgs[1]);
+ SetGrayscaleOrOriginalPalette(gSprites[spriteId].oam.paletteNum + 16, gBattleAnimArgs[1]);
DestroyAnimVisualTask(taskId);
}
diff --git a/src/battle_anim_effects_2.c b/src/battle_anim_effects_2.c
index 5dd584386..0ac5d384b 100755
--- a/src/battle_anim_effects_2.c
+++ b/src/battle_anim_effects_2.c
@@ -89,7 +89,7 @@ static void AnimPerishSongMusicNote_Step1(struct Sprite *);
static void AnimPerishSongMusicNote_Step2(struct Sprite *);
static void AnimGuardRing(struct Sprite *);
static void AnimTask_Withdraw_Step(u8);
-static void AnimTask_GrowAndGreyscale_Step(u8);
+static void AnimTask_GrowAndGrayscale_Step(u8);
static void AnimTask_Minimize_Step(u8);
static void CreateMinimizeSprite(struct Task *, u8);
static void ClonedMinizeSprite_Step(struct Sprite *);
@@ -1996,26 +1996,26 @@ static void AnimGuillotinePincer_Step3(struct Sprite *sprite)
DestroyAnimSprite(sprite);
}
-// Scales up the target mon sprite, and sets the palette to greyscale.
+// Scales up the target mon sprite, and sets the palette to grayscale.
// Used in MOVE_DISABLE.
// No args.
-void AnimTask_GrowAndGreyscale(u8 taskId)
+void AnimTask_GrowAndGrayscale(u8 taskId)
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_BLEND);
SetSpriteRotScale(spriteId, 0xD0, 0xD0, 0);
- SetGreyscaleOrOriginalPalette(gSprites[spriteId].oam.paletteNum + 16, FALSE);
+ SetGrayscaleOrOriginalPalette(gSprites[spriteId].oam.paletteNum + 16, FALSE);
gTasks[taskId].data[0] = 80;
- gTasks[taskId].func = AnimTask_GrowAndGreyscale_Step;
+ gTasks[taskId].func = AnimTask_GrowAndGrayscale_Step;
}
-static void AnimTask_GrowAndGreyscale_Step(u8 taskId)
+static void AnimTask_GrowAndGrayscale_Step(u8 taskId)
{
if (--gTasks[taskId].data[0] == -1)
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
ResetSpriteRotScale(spriteId);
- SetGreyscaleOrOriginalPalette(gSprites[spriteId].oam.paletteNum + 16, TRUE);
+ SetGrayscaleOrOriginalPalette(gSprites[spriteId].oam.paletteNum + 16, TRUE);
DestroyAnimVisualTask(taskId);
}
}
@@ -3710,7 +3710,7 @@ static void AnimPerishSongMusicNote2(struct Sprite *sprite)
}
if (++sprite->data[0] == sprite->data[1])
- SetGreyscaleOrOriginalPalette(sprite->oam.paletteNum + 16, 0);
+ SetGrayscaleOrOriginalPalette(sprite->oam.paletteNum + 16, 0);
if (sprite->data[0] == sprite->data[1] + 80)
DestroyAnimSprite(sprite);
diff --git a/src/battle_anim_mons.c b/src/battle_anim_mons.c
index 2082512ff..cf5ae6eb2 100644
--- a/src/battle_anim_mons.c
+++ b/src/battle_anim_mons.c
@@ -1310,7 +1310,7 @@ u16 ArcTan2Neg(s16 a, s16 b)
return -var;
}
-void SetGreyscaleOrOriginalPalette(u16 paletteNum, bool8 restoreOriginalColor)
+void SetGrayscaleOrOriginalPalette(u16 paletteNum, bool8 restoreOriginalColor)
{
int i;
struct PlttData *originalColor;
diff --git a/src/battle_anim_throw.c b/src/battle_anim_throw.c
index 83768b476..4064e250c 100755
--- a/src/battle_anim_throw.c
+++ b/src/battle_anim_throw.c
@@ -1420,7 +1420,7 @@ static void MakeCaptureStars(struct Sprite *sprite)
LoadBallParticleGfx(BALL_MASTER);
for (i = 0; i < ARRAY_COUNT(sCaptureStars); i++)
{
- u8 spriteId = CreateSprite(&sBallParticleSpriteTemplates[4], sprite->pos1.x, sprite->pos1.y, subpriority);
+ u8 spriteId = CreateSprite(&sBallParticleSpriteTemplates[BALL_MASTER], sprite->pos1.x, sprite->pos1.y, subpriority);
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].sDuration = 24;
diff --git a/src/battle_interface.c b/src/battle_interface.c
index ff376f6f1..50eb5373a 100644
--- a/src/battle_interface.c
+++ b/src/battle_interface.c
@@ -159,7 +159,7 @@ enum
// strings
extern const u8 gText_Slash[];
-extern const u8 gText_HighlightDarkGrey[];
+extern const u8 gText_HighlightDarkGray[];
extern const u8 gText_DynColor2[];
extern const u8 gText_DynColor2Male[];
extern const u8 gText_DynColor1Female[];
@@ -1895,7 +1895,7 @@ static void UpdateNickInHealthbox(u8 healthboxSpriteId, struct Pokemon *mon)
u16 species;
u8 gender;
- StringCopy(gDisplayedStringBattle, gText_HighlightDarkGrey);
+ StringCopy(gDisplayedStringBattle, gText_HighlightDarkGray);
GetMonData(mon, MON_DATA_NICKNAME, nickname);
StringGetEnd10(nickname);
ptr = StringAppend(gDisplayedStringBattle, nickname);
diff --git a/src/battle_message.c b/src/battle_message.c
index a30866410..ae30a2a62 100644
--- a/src/battle_message.c
+++ b/src/battle_message.c
@@ -383,7 +383,7 @@ static const u8 sText_ThrewPokeblockAtPkmn[] = _("{B_PLAYER_NAME} threw a {POKEB
static const u8 sText_OutOfSafariBalls[] = _("{PLAY_SE SE_DING_DONG}ANNOUNCER: You're out of\nSAFARI BALLS! Game over!\p");
static const u8 sText_OpponentMon1Appeared[] = _("{B_OPPONENT_MON1_NAME} appeared!\p");
static const u8 sText_WildPkmnAppeared[] = _("Wild {B_OPPONENT_MON1_NAME} appeared!\p");
-static const u8 sText_WildPkmnAppeared2[] = _("Wild {B_OPPONENT_MON1_NAME} appeared!\p");
+static const u8 sText_LegendaryPkmnAppeared[] = _("Wild {B_OPPONENT_MON1_NAME} appeared!\p");
static const u8 sText_WildPkmnAppearedPause[] = _("Wild {B_OPPONENT_MON1_NAME} appeared!{PAUSE 127}");
static const u8 sText_TwoWildPkmnAppeared[] = _("Wild {B_OPPONENT_MON1_NAME} and\n{B_OPPONENT_MON2_NAME} appeared!\p");
static const u8 sText_Trainer1WantsToBattle[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME}\nwould like to battle!\p");
@@ -1328,7 +1328,7 @@ static const u8 sText_SpaceIs[] = _(" is");
static const u8 sText_ApostropheS[] = _("'s");
// For displaying names of invalid moves
-static const u8 sATypeMove_Table[][NUMBER_OF_MON_TYPES - 1] =
+static const u8 sATypeMove_Table[NUMBER_OF_MON_TYPES][17] =
{
[TYPE_NORMAL] = _("a NORMAL move"),
[TYPE_FIGHTING] = _("a FIGHTING move"),
@@ -2125,7 +2125,7 @@ void BufferStringBattle(u16 stringID)
else
{
if (gBattleTypeFlags & BATTLE_TYPE_LEGENDARY)
- stringPtr = sText_WildPkmnAppeared2;
+ stringPtr = sText_LegendaryPkmnAppeared;
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) // interesting, looks like they had something planned for wild double battles
stringPtr = sText_TwoWildPkmnAppeared;
else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL)
diff --git a/src/bike.c b/src/bike.c
index 62ce3cd44..e97a5e04e 100644
--- a/src/bike.c
+++ b/src/bike.c
@@ -1053,7 +1053,7 @@ void Bike_HandleBumpySlopeJump(void)
bool32 IsRunningDisallowed(u8 metatile)
{
- if (!(gMapHeader.flags & MAP_ALLOW_RUNNING) || IsRunningDisallowedByMetatile(metatile) == TRUE)
+ if (!gMapHeader.allowRunning || IsRunningDisallowedByMetatile(metatile) == TRUE)
return TRUE;
else
return FALSE;
diff --git a/src/contest.c b/src/contest.c
index 920c3bdd7..84d00d8ee 100644
--- a/src/contest.c
+++ b/src/contest.c
@@ -1531,7 +1531,7 @@ static void Task_ShowMoveSelectScreen(u8 taskId)
&& eContestantStatus[gContestPlayerMonIndex].hasJudgesAttention)
{
// Highlight the text because it's a combo move
- moveNameBuffer = StringCopy(moveName, gText_ColorLightShadowDarkGrey);
+ moveNameBuffer = StringCopy(moveName, gText_ColorLightShadowDarkGray);
}
else if (move != MOVE_NONE
&& eContestantStatus[gContestPlayerMonIndex].prevMove == move
diff --git a/src/contest_util.c b/src/contest_util.c
index decbded2c..88ab4a7d2 100644
--- a/src/contest_util.c
+++ b/src/contest_util.c
@@ -497,7 +497,7 @@ static void LoadContestMonName(u8 monIndex)
struct ContestPokemon *mon = &gContestMons[monIndex];
u8 *str = gDisplayedStringBattle;
if (monIndex == gContestPlayerMonIndex)
- str = StringCopy(gDisplayedStringBattle, gText_ColorDarkGrey);
+ str = StringCopy(gDisplayedStringBattle, gText_ColorDarkGray);
StringCopy(str, mon->nickname);
AddContestTextPrinter(monIndex, gDisplayedStringBattle, 0);
diff --git a/src/item_use.c b/src/item_use.c
index 19f50549e..c9087e929 100755
--- a/src/item_use.c
+++ b/src/item_use.c
@@ -910,7 +910,7 @@ static void ItemUseOnFieldCB_EscapeRope(u8 taskId)
bool8 CanUseDigOrEscapeRopeOnCurMap(void)
{
- if (gMapHeader.flags & MAP_ALLOW_ESCAPING)
+ if (gMapHeader.allowEscaping)
return TRUE;
else
return FALSE;
diff --git a/src/overworld.c b/src/overworld.c
index 600333a47..979ebb74c 100644
--- a/src/overworld.c
+++ b/src/overworld.c
@@ -962,7 +962,7 @@ static u16 GetCenterScreenMetatileBehavior(void)
bool32 Overworld_IsBikingAllowed(void)
{
- if (!(gMapHeader.flags & MAP_ALLOW_CYCLING))
+ if (!gMapHeader.allowCycling)
return FALSE;
else
return TRUE;
@@ -1687,7 +1687,7 @@ void CB2_ReturnToFieldFadeFromBlack(void)
static void FieldCB_FadeTryShowMapPopup(void)
{
- if (SHOW_MAP_NAME_ENABLED && SecretBaseMapPopupEnabled() == TRUE)
+ if (gMapHeader.showMapName == TRUE && SecretBaseMapPopupEnabled() == TRUE)
ShowMapNamePopup();
FieldCB_WarpExitFadeFromBlack();
}
@@ -1933,7 +1933,7 @@ static bool32 LoadMapInStepsLocal(u8 *state, bool32 a2)
(*state)++;
break;
case 11:
- if (SHOW_MAP_NAME_ENABLED && SecretBaseMapPopupEnabled() == TRUE)
+ if (gMapHeader.showMapName == TRUE && SecretBaseMapPopupEnabled() == TRUE)
ShowMapNamePopup();
(*state)++;
break;
diff --git a/src/region_map.c b/src/region_map.c
index bec51ebf0..27e035199 100644
--- a/src/region_map.c
+++ b/src/region_map.c
@@ -1007,7 +1007,7 @@ static void InitMapBasedOnPlayerLocation(void)
break;
case MAP_TYPE_UNDERGROUND:
case MAP_TYPE_UNKNOWN:
- if (gMapHeader.flags & MAP_ALLOW_ESCAPING)
+ if (gMapHeader.allowEscaping)
{
mapHeader = Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->escapeWarp.mapGroup, gSaveBlock1Ptr->escapeWarp.mapNum);
gRegionMap->mapSecId = mapHeader->regionMapSectionId;
diff --git a/src/strings.c b/src/strings.c
index 18cf31fb7..4987e32d2 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -1229,7 +1229,7 @@ ALIGNED(4) const u8 gText_Facility[] = _("{STR_VAR_1}");
const u8 gText_Give[] = _("Give");
const u8 gText_NoNeed[] = _("No need");
-const u8 gText_ColorLightShadowDarkGrey[] = _("{COLOR LIGHT_GRAY}{SHADOW DARK_GRAY}");
+const u8 gText_ColorLightShadowDarkGray[] = _("{COLOR LIGHT_GRAY}{SHADOW DARK_GRAY}");
const u8 gText_ColorBlue[] = _("{COLOR BLUE}");
const u8 gText_ColorTransparent[] = _("{HIGHLIGHT TRANSPARENT}{COLOR TRANSPARENT}");
const u8 gText_CDot[] = _("C.");
@@ -1239,9 +1239,9 @@ const u8 gText_PreliminaryResults[] = _("The preliminary results!");
const u8 gText_Round2Results[] = _("Round 2 results!");
const u8 gText_ContestantsMonWon[] = _("{STR_VAR_1}'s {STR_VAR_2} won!");
const u8 gText_CommunicationStandby[] = _("Communication standby…");
-const u8 gText_ColorDarkGrey[] = _("{COLOR DARK_GRAY}");
+const u8 gText_ColorDarkGray[] = _("{COLOR DARK_GRAY}");
const u8 gText_ColorDynamic6WhiteDynamic5[] = _("{COLOR_HIGHLIGHT_SHADOW DYNAMIC_COLOR6 WHITE DYNAMIC_COLOR5}"); // Unused
-const u8 gText_HighlightDarkGrey[] = _("{HIGHLIGHT DARK_GRAY}");
+const u8 gText_HighlightDarkGray[] = _("{HIGHLIGHT DARK_GRAY}");
const u8 gText_EmptySpace2[] = _(" "); // Unused
const u8 gText_DynColor2Male[] = _("{COLOR DYNAMIC_COLOR2}♂");
const u8 gText_DynColor1Female[] = _("{COLOR DYNAMIC_COLOR1}♀");
diff --git a/src/union_room_chat.c b/src/union_room_chat.c
index fb875bbb4..8e9f78280 100755
--- a/src/union_room_chat.c
+++ b/src/union_room_chat.c
@@ -2984,7 +2984,7 @@ static void HideKeyboardSwapMenu(void)
static void PrintChatMessage(u16 row, u8 *str, u8 colorIdx)
{
- // colorIdx: 0 = grey, 1 = red, 2 = green, 3 = blue
+ // colorIdx: 0 = gray, 1 = red, 2 = green, 3 = blue
u8 color[3];
color[0] = TEXT_COLOR_WHITE;
color[1] = colorIdx * 2 + 2;
diff --git a/tools/preproc/c_file.cpp b/tools/preproc/c_file.cpp
index b996a048c..17a08cc9f 100644
--- a/tools/preproc/c_file.cpp
+++ b/tools/preproc/c_file.cpp
@@ -23,32 +23,59 @@
#include <stdexcept>
#include <string>
#include <memory>
+#include <cstring>
+#include <cerrno>
#include "preproc.h"
#include "c_file.h"
#include "char_util.h"
#include "utf8.h"
#include "string_parser.h"
-CFile::CFile(std::string filename) : m_filename(filename)
+CFile::CFile(const char * filenameCStr, bool isStdin)
{
- FILE *fp = std::fopen(filename.c_str(), "rb");
+ FILE *fp;
+
+ if (isStdin) {
+ fp = stdin;
+ m_filename = std::string{"<stdin>/"}.append(filenameCStr);
+ } else {
+ fp = std::fopen(filenameCStr, "rb");
+ m_filename = std::string(filenameCStr);
+ }
+
+ std::string& filename = m_filename;
if (fp == NULL)
FATAL_ERROR("Failed to open \"%s\" for reading.\n", filename.c_str());
- std::fseek(fp, 0, SEEK_END);
-
- m_size = std::ftell(fp);
+ m_size = 0;
+ m_buffer = (char *)malloc(CHUNK_SIZE + 1);
+ if (m_buffer == NULL) {
+ FATAL_ERROR("Failed to allocate memory to process file \"%s\"!", filename.c_str());
+ }
- if (m_size < 0)
- FATAL_ERROR("File size of \"%s\" is less than zero.\n", filename.c_str());
+ std::size_t numAllocatedBytes = CHUNK_SIZE + 1;
+ std::size_t bufferOffset = 0;
+ std::size_t count;
- m_buffer = new char[m_size + 1];
+ while ((count = std::fread(m_buffer + bufferOffset, 1, CHUNK_SIZE, fp)) != 0) {
+ if (!std::ferror(fp)) {
+ m_size += count;
- std::rewind(fp);
+ if (std::feof(fp)) {
+ break;
+ }
- if (std::fread(m_buffer, m_size, 1, fp) != 1)
- FATAL_ERROR("Failed to read \"%s\".\n", filename.c_str());
+ numAllocatedBytes += CHUNK_SIZE;
+ bufferOffset += CHUNK_SIZE;
+ m_buffer = (char *)realloc(m_buffer, numAllocatedBytes);
+ if (m_buffer == NULL) {
+ FATAL_ERROR("Failed to allocate memory to process file \"%s\"!", filename.c_str());
+ }
+ } else {
+ FATAL_ERROR("Failed to read \"%s\". (error: %s)", filename.c_str(), std::strerror(errno));
+ }
+ }
m_buffer[m_size] = 0;
@@ -56,6 +83,7 @@ CFile::CFile(std::string filename) : m_filename(filename)
m_pos = 0;
m_lineNum = 1;
+ m_isStdin = isStdin;
}
CFile::CFile(CFile&& other) : m_filename(std::move(other.m_filename))
@@ -64,13 +92,14 @@ CFile::CFile(CFile&& other) : m_filename(std::move(other.m_filename))
m_pos = other.m_pos;
m_size = other.m_size;
m_lineNum = other.m_lineNum;
+ m_isStdin = other.m_isStdin;
- other.m_buffer = nullptr;
+ other.m_buffer = NULL;
}
CFile::~CFile()
{
- delete[] m_buffer;
+ free(m_buffer);
}
void CFile::Preproc()
diff --git a/tools/preproc/c_file.h b/tools/preproc/c_file.h
index 7369aba85..49e633a18 100644
--- a/tools/preproc/c_file.h
+++ b/tools/preproc/c_file.h
@@ -30,7 +30,7 @@
class CFile
{
public:
- CFile(std::string filename);
+ CFile(const char * filenameCStr, bool isStdin);
CFile(CFile&& other);
CFile(const CFile&) = delete;
~CFile();
@@ -42,6 +42,7 @@ private:
long m_size;
long m_lineNum;
std::string m_filename;
+ bool m_isStdin;
bool ConsumeHorizontalWhitespace();
bool ConsumeNewline();
@@ -55,4 +56,6 @@ private:
void RaiseWarning(const char* format, ...);
};
+#define CHUNK_SIZE 4096
+
#endif // C_FILE_H
diff --git a/tools/preproc/preproc.cpp b/tools/preproc/preproc.cpp
index c9c6042df..eb2d4c8a2 100644
--- a/tools/preproc/preproc.cpp
+++ b/tools/preproc/preproc.cpp
@@ -103,9 +103,9 @@ void PreprocAsmFile(std::string filename)
}
}
-void PreprocCFile(std::string filename)
+void PreprocCFile(const char * filename, bool isStdin)
{
- CFile cFile(filename);
+ CFile cFile(filename, isStdin);
cFile.Preproc();
}
@@ -132,9 +132,9 @@ char* GetFileExtension(char* filename)
int main(int argc, char **argv)
{
- if (argc != 3)
+ if (argc < 3 || argc > 4)
{
- std::fprintf(stderr, "Usage: %s SRC_FILE CHARMAP_FILE", argv[0]);
+ std::fprintf(stderr, "Usage: %s SRC_FILE CHARMAP_FILE [-i]\nwhere -i denotes if input is from stdin\n", argv[0]);
return 1;
}
@@ -147,9 +147,17 @@ int main(int argc, char **argv)
if ((extension[0] == 's') && extension[1] == 0)
PreprocAsmFile(argv[1]);
- else if ((extension[0] == 'c' || extension[0] == 'i') && extension[1] == 0)
- PreprocCFile(argv[1]);
- else
+ else if ((extension[0] == 'c' || extension[0] == 'i') && extension[1] == 0) {
+ if (argc == 4) {
+ if (argv[3][0] == '-' && argv[3][1] == 'i' && argv[3][2] == '\0') {
+ PreprocCFile(argv[1], true);
+ } else {
+ FATAL_ERROR("unknown argument flag \"%s\".\n", argv[3]);
+ }
+ } else {
+ PreprocCFile(argv[1], false);
+ }
+ } else
FATAL_ERROR("\"%s\" has an unknown file extension of \"%s\".\n", argv[1], extension);
return 0;