Update Makefile

This commit is contained in:
dannye 2021-10-15 12:43:42 -05:00
parent 02df79356b
commit 6e13f88d0e
11 changed files with 207 additions and 91 deletions

25
.gitignore vendored
View File

@ -4,34 +4,23 @@
# compiled object file
*.o
# no binaries
*.exe
# roms
*.gbc
*.gb
# rgbds extras
*.sym
*.map
*.sym
# swap files for vim
.*.swp
# for any of the poor souls with save game files in their working directory
# save game files
*.sgm
*.sav
*.sys
*.sn*
# for vim configuration
# url: http://www.vim.org/scripts/script.php?script_id=441
.lvimrc
# converted image data
# converted image/palette data
*.1bpp
*.2bpp
*.pal
# converted audio data
*.pcm
# shortcuts
*.lnk
# *disasm.py output file
*disasm_output.asm

127
Makefile
View File

@ -1,49 +1,104 @@
.PHONY: all tools compare clean tidy
rom := poketcg2.gbc
rom_obj := \
src/main.o \
src/wram.o
### Build tools
ifeq (,$(shell which sha1sum))
SHA1 := shasum
else
SHA1 := sha1sum
endif
RGBDS ?=
RGBASM ?= $(RGBDS)rgbasm
RGBFIX ?= $(RGBDS)rgbfix
RGBGFX ?= $(RGBDS)rgbgfx
RGBLINK ?= $(RGBDS)rgblink
### Build targets
.SUFFIXES:
.SECONDEXPANSION:
.PRECIOUS:
.SECONDARY:
.PHONY: all tcg2 clean tidy compare tools
ROM := TCG2.gbc
OBJS := src/main.o src/wram.o
MD5 := md5sum -c
all: $(ROM) compare
ifeq (,$(filter tools clean tidy,$(MAKECMDGOALS)))
Makefile: tools
endif
%.o: dep = $(shell tools/scan_includes -s -i src/ $(@D)/$*.asm)
%.o: %.asm $$(dep)
rgbasm -h -i src/ -o $@ $<
$(ROM): $(OBJS) src/tcg2.link
rgblink -n $(ROM:.gbc=.sym) -m $(ROM:.gbc=.map) -l src/tcg2.link -o $@ $(OBJS)
# rgbfix -jsvc -k 01 -l 0x33 -m 0x1e -p 0 -r 02 -t "POKEPINBALL" -i VPHE $@
# For contributors to make sure a change didn't affect the contents of the rom.
compare: $(ROM)
@$(MD5) rom.md5
tools:
$(MAKE) -C tools
tidy:
rm -f $(ROM) $(OBJS) $(ROM:.gbc=.sym) $(ROM:.gbc=.map)
$(MAKE) -C tools clean
all: $(rom) compare
tcg2: $(rom) compare
clean: tidy
find . \( -iname '*.1bpp' -o -iname '*.2bpp' -o -iname '*.pcm' \) -exec rm {} +
find src/gfx \( -iname '*.1bpp' -o -iname '*.2bpp' -o -iname '*.pal' \) -delete
%.interleave.2bpp: %.interleave.png
rgbgfx -o $@ $<
tools/gfx --interleave --png $< -o $@ $@
tidy:
rm -f $(rom) $(rom_obj) $(rom:.gbc=.map) $(rom:.gbc=.sym) src/rgbdscheck.o
$(MAKE) clean -C tools/
compare: $(rom)
@$(SHA1) -c rom.sha1
tools:
$(MAKE) -C tools/
RGBASMFLAGS = -h -i src/ -L -Weverything
# Create a sym/map for debug purposes if `make` run with `DEBUG=1`
ifeq ($(DEBUG),1)
RGBASMFLAGS += -E
endif
src/rgbdscheck.o: src/rgbdscheck.asm
$(RGBASM) -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.
define DEP
$1: $2 $$(shell tools/scan_includes -s -i src/ $2) | src/rgbdscheck.o
$$(RGBASM) $$(RGBASMFLAGS) -o $$@ $$<
endef
# Build tools when building the rom.
# This has to happen before the rules are processed, since that's when scan_includes is run.
ifeq (,$(filter clean tidy tools,$(MAKECMDGOALS)))
$(info $(shell $(MAKE) -C tools))
# Dependencies for objects
$(foreach obj, $(rom_obj), $(eval $(call DEP,$(obj),$(obj:.o=.asm))))
endif
%.asm: ;
opts = -Cv -k 2P -l 0x33 -m 0x1b -p 0xff -r 03 -t "POKEMON-CG2" -i BP7J
$(rom): $(rom_obj) src/layout.link
$(RGBLINK) -p 0x00 -m $(rom:.gbc=.map) -n $(rom:.gbc=.sym) -l src/layout.link -o $@ $(filter %.o,$^)
$(RGBFIX) $(opts) $@
### Misc file-specific graphics rules
### Catch-all graphics rules
%.png: ;
%.pal: ;
%.2bpp: %.png
rgbgfx -o $@ $<
$(RGBGFX) $(rgbgfx) -o $@ $<
$(if $(tools/gfx),\
tools/gfx $(tools/gfx) -o $@ $@)
%.1bpp: %.png
rgbgfx -d1 -o $@ $<
$(RGBGFX) $(rgbgfx) -d1 -o $@ $<
$(if $(tools/gfx),\
tools/gfx $(tools/gfx) -d1 -o $@ $@)

View File

@ -1 +0,0 @@
1134862E84110443190DF460351D4575 TCG2.gbc

1
rom.sha1 Normal file
View File

@ -0,0 +1 @@
a7e12bcc5f514e3aad8de570fd511aab0a308822 *poketcg2.gbc

View File

@ -259,8 +259,8 @@ Start: ; 0150 (0:0150)
ld sp, $fffe
push af
xor a
ld [rIF], a
ld [rIE], a
ldh [rIF], a
ldh [rIE], a
call $03e6
ld a, $1
call BankswitchROM
@ -310,16 +310,16 @@ VBlankHandler: ; 019b (0:019b)
.no_oam_copy
; flush scaling/windowing parameters
ldh a, [hSCX]
ld [rSCX], a
ldh [rSCX], a
ldh a, [hSCY]
ld [rSCY], a
ldh [rSCY], a
ldh a, [hWX]
ld [rWX], a
ldh [rWX], a
ldh a, [hWY]
ld [rWY], a
ldh [rWY], a
; flush LCDC
ldh a, [hLCDC]
ld [rLCDC], a
ldh [rLCDC], a
ei
call wVBlankFunctionTrampoline
call $0425
@ -329,7 +329,7 @@ VBlankHandler: ; 019b (0:019b)
res IN_VBLANK, [hl]
.done
pop af
ld [rSVBK], a
ldh [rSVBK], a
pop af
call BankswitchROM
pop hl
@ -345,10 +345,10 @@ TimerHandler: ; 01ef (0:01ef)
push bc
ei
call $0bb2
ld a, [rSVBK]
ldh a, [rSVBK]
push af
ld a, $1
ld [rSVBK], a
ldh [rSVBK], a
; only trigger every fourth interrupt <20> 60.24 Hz
ld hl, wTimerCounter
ld a, [hl]
@ -450,7 +450,7 @@ BankswitchVRAM0: ; 0795 (0:0795)
push af
xor a
ldh [hBankVRAM], a
ld [rVBK], a
ldh [rVBK], a
pop af
ret
; set current dest VRAM bank to 1
@ -459,14 +459,14 @@ BankswitchVRAM1: ; 079d (0:079d)
push af
ld a, $1
ldh [hBankVRAM], a
ld [rVBK], a
ldh [rVBK], a
pop af
ret
; set current dest VRAM bank to a
; Note: Exact match to TCG1
BankswitchVRAM: ; 07a6 (0:07a6)
ldh [hBankVRAM], a
ld [rVBK], a
ldh [rVBK], a
ret
; dummied out
; Note: Different from TCG1
@ -491,20 +491,20 @@ SwitchToCGBDoubleSpeed: ; 07b6 (0:07b6)
; switch between CGB Double Speed Mode and Normal Speed Mode
; Note: Exact match to TCG1
CGBSpeedSwitch: ; 07bc (0:07bc)
ld a, [rIE]
ldh a, [rIE]
push af
xor a
ld [rIE], a
ldh [rIE], a
set 0, [hl]
xor a
ld [rIF], a
ld [rIE], a
ldh [rIF], a
ldh [rIE], a
ld a, $30
ld [rJOYP], a
ldh [rJOYP], a
stop
call $0254
pop af
ld [rIE], a
ldh [rIE], a
ret
; validate the saved data in SRAM

12
src/rgbdscheck.asm Normal file
View File

@ -0,0 +1,12 @@
; poketcg requires rgbds 0.4.1 or newer.
MAJOR EQU 0
MINOR EQU 4
PATCH EQU 1
IF !DEF(__RGBDS_MAJOR__) || !DEF(__RGBDS_MINOR__) || !DEF(__RGBDS_PATCH__)
fail "poketcg requires rgbds {MAJOR}.{MINOR}.{PATCH} or newer."
ELIF (__RGBDS_MAJOR__ < MAJOR) || \
(__RGBDS_MAJOR__ == MAJOR && __RGBDS_MINOR__ < MINOR) || \
(__RGBDS_MAJOR__ == MAJOR && __RGBDS_MINOR__ == MINOR && __RGBDS_PATCH__ < PATCH)
fail "poketcg requires rgbds {MAJOR}.{MINOR}.{PATCH} or newer."
ENDC

4
tools/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
scan_includes
gfx
*.exe

View File

@ -1,11 +1,9 @@
.PHONY: all clean
CC := gcc
CFLAGS := -std=c99 -Wall -Wextra
CFLAGS := -O3 -std=c99 -Wall -Wextra -pedantic
tools := \
gfx \
scan_includes
tools := scan_includes gfx
all: $(tools)
@:
@ -13,5 +11,6 @@ all: $(tools)
clean:
rm -f $(tools)
gfx: common.h
%: %.c
$(CC) $(CFLAGS) -o $@ $<

View File

@ -21,7 +21,10 @@ uint8_t *read_u8(char *filename, int *size) {
*size = ftell(f);
rewind(f);
uint8_t *data = malloc(*size);
fread(data, 1, *size, f);
if (*size != (int)fread(data, 1, *size, f)) {
fprintf(stderr, "Could not read file: \"%s\"\n", filename);
exit(1);
}
fclose(f);
return data;
}

View File

@ -8,7 +8,7 @@
#include "common.h"
static void usage(void) {
fprintf(stderr, "Usage: gfx [--trim-whitespace] [--remove-whitespace] [--interleave] [--remove-duplicates [--keep-whitespace]] [--remove-xflip] [--remove-yflip] [--png filename] [-d depth] [-h] [-o outfile] infile\n");
fprintf(stderr, "Usage: gfx [--trim-whitespace] [--remove-whitespace] [--interleave] [--remove-duplicates [--keep-whitespace]] [--remove-xflip] [--remove-yflip] [--preserve indexes] [--png filename] [-d depth] [-h] [-o outfile] infile\n");
}
static void error(char *message) {
@ -27,6 +27,8 @@ struct Options {
int keep_whitespace;
int remove_xflip;
int remove_yflip;
int *preserved;
int num_preserved;
char *png_file;
};
@ -43,11 +45,13 @@ void get_args(int argc, char *argv[]) {
{"keep-whitespace", no_argument, &Options.keep_whitespace, 1},
{"remove-xflip", no_argument, &Options.remove_xflip, 1},
{"remove-yflip", no_argument, &Options.remove_yflip, 1},
{"preserve", required_argument, 0, 'r'},
{"png", required_argument, 0, 'p'},
{"depth", required_argument, 0, 'd'},
{"help", no_argument, 0, 'h'},
{0}
};
char *token;
for (int opt = 0; opt != -1;) {
switch (opt = getopt_long(argc, argv, "ho:d:p:", long_options)) {
case 'h':
@ -59,6 +63,15 @@ void get_args(int argc, char *argv[]) {
case 'd':
Options.depth = strtoul(optarg, NULL, 0);
break;
case 'r':
token = strtok(optarg, ",");
while (token) {
Options.num_preserved++;
Options.preserved = realloc(Options.preserved, Options.num_preserved * sizeof(int));
Options.preserved[Options.num_preserved-1] = strtoul(token, NULL, 0);
token = strtok(NULL, ",");
}
break;
case 'p':
Options.png_file = optarg;
break;
@ -73,6 +86,23 @@ void get_args(int argc, char *argv[]) {
}
}
bool is_preserved(int index) {
for (int i = 0; i < Options.num_preserved; i++) {
if (Options.preserved[i] == index) {
return true;
}
}
return false;
}
void shift_preserved(int removed_index) {
for (int i = 0; i < Options.num_preserved; i++) {
if (Options.preserved[i] >= removed_index) {
Options.preserved[i]--;
}
}
}
struct Graphic {
int size;
uint8_t *data;
@ -91,7 +121,7 @@ bool is_whitespace(uint8_t *tile, int tile_size) {
void trim_whitespace(struct Graphic *graphic) {
int tile_size = Options.depth * 8;
for (int i = graphic->size - tile_size; i > 0; i -= tile_size) {
if (is_whitespace(&graphic->data[i], tile_size)) {
if (is_whitespace(&graphic->data[i], tile_size) && !is_preserved(i / tile_size)) {
graphic->size = i;
} else {
break;
@ -102,9 +132,15 @@ void trim_whitespace(struct Graphic *graphic) {
void remove_whitespace(struct Graphic *graphic) {
int tile_size = Options.depth * 8;
if (Options.interleave) tile_size *= 2;
// Make sure we have a whole number of tiles, round down if required
graphic->size &= ~(tile_size - 1);
int i = 0;
for (int j = 0; i < graphic->size && j < graphic->size; i += tile_size, j += tile_size) {
while (is_whitespace(&graphic->data[j], tile_size)) {
for (int j = 0, d = 0; i < graphic->size && j < graphic->size; i += tile_size, j += tile_size) {
while (j < graphic->size && is_whitespace(&graphic->data[j], tile_size) && !is_preserved(j / tile_size - d)) {
shift_preserved(j / tile_size - d);
d++;
j += tile_size;
}
if (j >= graphic->size) {
@ -136,11 +172,17 @@ void remove_duplicates(struct Graphic *graphic) {
int tile_size = Options.depth * 8;
if (Options.interleave) tile_size *= 2;
int num_tiles = 0;
for (int i = 0, j = 0; i < graphic->size && j < graphic->size; i += tile_size, j += tile_size) {
while (tile_exists(&graphic->data[j], graphic->data, tile_size, num_tiles)) {
if (Options.keep_whitespace && is_whitespace(&graphic->data[j], tile_size)) {
// Make sure we have a whole number of tiles, round down if required
graphic->size &= ~(tile_size - 1);
for (int i = 0, j = 0, d = 0; i < graphic->size && j < graphic->size; i += tile_size, j += tile_size) {
while (j < graphic->size && tile_exists(&graphic->data[j], graphic->data, tile_size, num_tiles)) {
if ((Options.keep_whitespace && is_whitespace(&graphic->data[j], tile_size)) || is_preserved(j / tile_size - d)) {
break;
}
shift_preserved(j / tile_size - d);
d++;
j += tile_size;
}
if (j >= graphic->size) {
@ -155,7 +197,8 @@ void remove_duplicates(struct Graphic *graphic) {
}
bool flip_exists(uint8_t *tile, uint8_t *tiles, int tile_size, int num_tiles, bool xflip, bool yflip) {
uint8_t *flip = calloc(tile_size, 1);
uint8_t flip[tile_size];
memset(flip, 0, sizeof(flip));
int half_size = tile_size / 2;
for (int i = 0; i < tile_size; i++) {
int byte = i;
@ -183,11 +226,17 @@ void remove_flip(struct Graphic *graphic, bool xflip, bool yflip) {
int tile_size = Options.depth * 8;
if (Options.interleave) tile_size *= 2;
int num_tiles = 0;
for (int i = 0, j = 0; i < graphic->size && j < graphic->size; i += tile_size, j += tile_size) {
while (flip_exists(&graphic->data[j], graphic->data, tile_size, num_tiles, xflip, yflip)) {
if (Options.keep_whitespace && is_whitespace(&graphic->data[j], tile_size)) {
// Make sure we have a whole number of tiles, round down if required
graphic->size &= ~(tile_size - 1);
for (int i = 0, j = 0, d = 0; i < graphic->size && j < graphic->size; i += tile_size, j += tile_size) {
while (j < graphic->size && flip_exists(&graphic->data[j], graphic->data, tile_size, num_tiles, xflip, yflip)) {
if ((Options.keep_whitespace && is_whitespace(&graphic->data[j], tile_size)) || is_preserved(j / tile_size - d)) {
break;
}
shift_preserved(j / tile_size - d);
d++;
j += tile_size;
}
if (j >= graphic->size) {
@ -230,8 +279,13 @@ int png_get_width(char *filename) {
const int OFFSET_WIDTH = 16;
uint8_t bytes[4];
fseek(f, OFFSET_WIDTH, SEEK_SET);
fread(bytes, 1, 4, f);
size_t size = 4;
size_t result = fread(bytes, 1, size, f);
fclose(f);
if (result != size) {
fprintf(stderr, "Could not read file at offset 0x%x: \"%s\"\n", OFFSET_WIDTH, filename);
exit(1);
}
int width = 0;
for (int i = 0; i < 4; i++) {