git.y1.nz

gbdk-2020

GameBoy Development Kit
download: https://git.y1.nz/archives/gbdk.tar.gz
README | Files | Log | Refs | LICENSE

commit a460ac8c3299057c14801638bca6374f053d7150
parent dad4b9f2832963040652dc8c6f4f0b906523835e
Author: Toxa <untoxa@mail.ru>
Date:   Tue, 21 Sep 2021 11:48:16 +0300

simple rle decompressor and example

Diffstat:
Agbdk-lib/examples/cross-platform/rle_map/Makefile91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agbdk-lib/examples/cross-platform/rle_map/Makefile.targets38++++++++++++++++++++++++++++++++++++++
Agbdk-lib/examples/cross-platform/rle_map/res/level1_map.rle0
Agbdk-lib/examples/cross-platform/rle_map/res/level1_tiles.bin0
Agbdk-lib/examples/cross-platform/rle_map/src/main.c60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agbdk-lib/include/gbdk/rledecompress.h20++++++++++++++++++++
Mgbdk-lib/libc/targets/gbz80/ap/Makefile1+
Mgbdk-lib/libc/targets/gbz80/gb/Makefile1+
Agbdk-lib/libc/targets/gbz80/rle_decompress.s117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mgbdk-lib/libc/targets/z80/gg/Makefile1+
Agbdk-lib/libc/targets/z80/rle_decompress.s101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mgbdk-lib/libc/targets/z80/sms/Makefile1+
12 files changed, 431 insertions(+), 0 deletions(-)

diff --git a/gbdk-lib/examples/cross-platform/rle_map/Makefile b/gbdk-lib/examples/cross-platform/rle_map/Makefile @@ -0,0 +1,91 @@ +SHELL := /bin/bash + +# If you move this project you can change the directory +# to match your GBDK root directory (ex: GBDK_HOME = "C:/GBDK/" +GBDK_HOME = ../../../ +LCC = $(GBDK_HOME)bin/lcc + +# Set platforms to build here, spaced separated. (These are in the separate Makefile.targets) +# They can also be built/cleaned individually: "make gg" and "make gg-clean" +# Possible are: gb gbc pocket sms gg +#TARGETS=gb pocket sms gg +TARGETS=gb gg + +# Configure platform specific LCC flags here: +LCCFLAGS_gb = -Wl-yt0x19 -Wl-yo4 -Wm-yS -Wm-yn"$(PROJECTNAME)" +LCCFLAGS_pocket = -Wl-yt0x19 -Wl-yo4 -Wm-yS -Wm-yn"$(PROJECTNAME)" +LCCFLAGS_sms = -Wl-yo4 -Wm-yS +LCCFLAGS_gg = -Wl-yo4 -Wm-yS + +LCCFLAGS += $(LCCFLAGS_$(EXT)) # This adds the current platform specific LCC Flags + +# LCCFLAGS += -Wl-j -Wm-yoA -Wm-ya4 -autobank -Wb-ext=.rel -Wb-v # MBC + Autobanking related flags +LCCFLAGS += -Wl-j +# LCCFLAGS += -debug # Uncomment to enable debug output +# LCCFLAGS += -v # Uncomment for lcc verbose output + +CFLAGS = -Wf-Iinclude + +# You can set the name of the ROM file here +PROJECTNAME = rledecompress + +# EXT?=gb # Only sets extension to default (game boy .gb) if not populated +SRCDIR = src +SRCPLAT = src/$(PORT) +OBJDIR = obj/$(EXT) +RESDIR = res +BINDIR = build/$(EXT) +MKDIRS = $(OBJDIR) $(BINDIR) # See bottom of Makefile for directory auto-creation + +BINS = $(OBJDIR)/$(PROJECTNAME).$(EXT) +CSOURCES = $(foreach dir,$(SRCDIR),$(notdir $(wildcard $(dir)/*.c))) $(foreach dir,$(SRCPLAT),$(notdir $(wildcard $(dir)/*.c))) $(foreach dir,$(RESDIR),$(notdir $(wildcard $(dir)/*.c))) +ASMSOURCES = $(foreach dir,$(SRCDIR),$(notdir $(wildcard $(dir)/*.s))) $(foreach dir,$(SRCPLAT),$(notdir $(wildcard $(dir)/*.s))) +OBJS = $(CSOURCES:%.c=$(OBJDIR)/%.o) $(ASMSOURCES:%.s=$(OBJDIR)/%.o) + +# Builds all targets sequentially +all: $(TARGETS) + +# Compile .c files in "src/" to .o object files +$(OBJDIR)/%.o: $(SRCDIR)/%.c + $(LCC) $(CFLAGS) -c -o $@ $< + +# Compile .c files in "src/<target>/" to .o object files +$(OBJDIR)/%.o: $(SRCPLAT)/%.c + $(LCC) $(CFLAGS) -c -o $@ $< + +# Compile .c files in "res/" to .o object files +$(OBJDIR)/%.o: $(RESDIR)/%.c + $(LCC) $(CFLAGS) -c -o $@ $< + +# Compile .s assembly files in "src/<target>/" to .o object files +$(OBJDIR)/%.o: $(SRCPLAT)/%.s + $(LCC) $(CFLAGS) -c -o $@ $< + +# Compile .s assembly files in "src/" to .o object files +$(OBJDIR)/%.o: $(SRCDIR)/%.s + $(LCC) $(CFLAGS) -c -o $@ $< + +# If needed, compile .c files i n"src/" to .s assembly files +# (not required if .c is compiled directly to .o) +$(OBJDIR)/%.s: $(SRCDIR)/%.c + $(LCC) $(CFLAGS) -S -o $@ $< + +# Link the compiled object files into a .gb ROM file +$(BINS): $(OBJS) + $(LCC) $(LCCFLAGS) $(CFLAGS) -o $(BINDIR)/$(PROJECTNAME).$(EXT) $(OBJS) + +clean: + @echo Cleaning + @for target in $(TARGETS); do \ + $(MAKE) $$target-clean; \ + done + +# Include available build targets +include Makefile.targets + + +# create necessary directories after Makefile is parsed but before build +# info prevents the command from being pasted into the makefile +ifneq ($(strip $(EXT)),) # Only make the directories if EXT has been set by a target +$(info $(shell mkdir -p $(MKDIRS))) +endif diff --git a/gbdk-lib/examples/cross-platform/rle_map/Makefile.targets b/gbdk-lib/examples/cross-platform/rle_map/Makefile.targets @@ -0,0 +1,38 @@ + +# Platform specific flags for compiling (only populate if they're both present) +ifneq ($(strip $(PORT)),) +ifneq ($(strip $(PLAT)),) +CFLAGS += -m$(PORT):$(PLAT) +endif +endif + +# Called by the individual targets below to build a ROM +build-target: $(BINS) + +clean-target: + rm -rf $(OBJDIR) + rm -rf $(BINDIR) + +gb-clean: + ${MAKE} clean-target EXT=gb +gb: + ${MAKE} build-target PORT=gbz80 PLAT=gb EXT=gb + + +pocket-clean: + ${MAKE} clean-target EXT=pocket +pocket: + ${MAKE} build-target PORT=gbz80 PLAT=ap EXT=pocket + + +sms-clean: + ${MAKE} clean-target EXT=sms +sms: + ${MAKE} build-target PORT=z80 PLAT=sms EXT=sms + + +gg-clean: + ${MAKE} clean-target EXT=gg +gg: + ${MAKE} build-target PORT=z80 PLAT=gg EXT=gg + diff --git a/gbdk-lib/examples/cross-platform/rle_map/res/level1_map.rle b/gbdk-lib/examples/cross-platform/rle_map/res/level1_map.rle Binary files differ. diff --git a/gbdk-lib/examples/cross-platform/rle_map/res/level1_tiles.bin b/gbdk-lib/examples/cross-platform/rle_map/res/level1_tiles.bin Binary files differ. diff --git a/gbdk-lib/examples/cross-platform/rle_map/src/main.c b/gbdk-lib/examples/cross-platform/rle_map/src/main.c @@ -0,0 +1,60 @@ +#include <gbdk/platform.h> +#include <gbdk/incbin.h> + +#include <gbdk/rledecompress.h> + +INCBIN(level1_tiles, "res/level1_tiles.bin") +INCBIN_EXTERN(level1_tiles) + +INCBIN(level1_map, "res/level1_map.rle") +INCBIN_EXTERN(level1_map) + +extern uint8_t sample_rle_data[]; + +#define DATA_HEIGHT 16 + +uint8_t data[32][DATA_HEIGHT]; // collision map buffer +uint8_t scrollpos = 0; // scroll position in pixels +uint8_t datapos = 0; // x position in tiles inside the collision map + +void main() { + SHOW_BKG; + + set_bkg_data(0, INCBIN_SIZE(level1_tiles) >> 4, level1_tiles); + + rle_init(level1_map); // initialize decompressor + + // decompress and display whole screen + uint8_t * data_ptr = &data[0][0]; + for (uint8_t i = 0; (rle_decompress(data_ptr, DATA_HEIGHT)) && (i != DEVICE_SCREEN_WIDTH); i++) { + // pre-process column here + // ... + + // display column + set_bkg_tiles(i, 2, 1, DATA_HEIGHT, data_ptr); + } + + // main game loop + datapos = scrollpos = 0; + while(TRUE) { + if ((scrollpos & 7) == 0) { + datapos = (scrollpos >> 3); + uint8_t x_pos = (datapos + DEVICE_SCREEN_WIDTH) & 31; + // decompress and display column + data_ptr = &data[x_pos][0]; + if (rle_decompress(data_ptr, DATA_HEIGHT)) { + // pre-process column here + // ... + + // display column + set_bkg_tiles(x_pos, 2, 1, DATA_HEIGHT, data_ptr); + scrollpos++; + move_bkg(scrollpos, 0); + } + } else { + scrollpos++; + move_bkg(scrollpos, 0); + } + wait_vbl_done(); + } +} diff --git a/gbdk-lib/include/gbdk/rledecompress.h b/gbdk-lib/include/gbdk/rledecompress.h @@ -0,0 +1,19 @@ +#ifndef __RLEDECOMPRESS_H_INCLUDE +#define __RLEDECOMPRESS_H_INCLUDE + +#include <types.h> +#include <stdint.h> + +#define RLE_STOP 0 + +#if defined(__TARGET_gb) || defined(__TARGET_ap) +uint8_t rle_init(void * data) OLDCALL; +uint8_t rle_decompress(void * dest, uint8_t len) OLDCALL; +#elif defined(__TARGET_sms) || defined(__TARGET_gg) +uint8_t rle_init(void * data) __z88dk_fastcall; +uint8_t rle_decompress(void * dest, uint8_t len) __z88dk_callee; +#else + #error Unrecognized port +#endif + +#endif + diff --git a/gbdk-lib/libc/targets/gbz80/ap/Makefile b/gbdk-lib/libc/targets/gbz80/ap/Makefile @@ -33,6 +33,7 @@ ASSRC = cgb.s cgb_palettes.s cgb_compat.s \ metasprites.s metasprites_flip.s metasprites_hide.s metasprites_hide_spr.s \ set_tile_submap.s set_win_tile_submap.s \ gb_decompress.s gb_decompress_tiles.s \ + rle_decompress.s \ heap.s \ crt0.s diff --git a/gbdk-lib/libc/targets/gbz80/gb/Makefile b/gbdk-lib/libc/targets/gbz80/gb/Makefile @@ -33,6 +33,7 @@ ASSRC = cgb.s cgb_palettes.s cgb_compat.s \ metasprites.s metasprites_flip.s metasprites_hide.s metasprites_hide_spr.s \ set_tile_submap.s set_win_tile_submap.s \ gb_decompress.s gb_decompress_tiles.s \ + rle_decompress.s \ heap.s \ crt0.s diff --git a/gbdk-lib/libc/targets/gbz80/rle_decompress.s b/gbdk-lib/libc/targets/gbz80/rle_decompress.s @@ -0,0 +1,116 @@ + .include "global.s" + + .module RLE_DECOMPRESS + + .area _DATA + +rle_cursor: + .ds 0x02 +rle_counter: + .ds 0x01 +rle_current: + .ds 0x01 + + .area _CODE + +_rle_init:: + ldhl sp, #2 + ld a, (hl+) + ld e, (hl) + ld hl, #rle_cursor + ld (hl+), a + ld a, e + ld (hl+), a + xor a + ld (hl+), a + ld (hl), a + ld e, #1 + ret + +_rle_decompress:: + ;; Pop the return address + ldhl sp, #2 + ld a, (hl+) + ld c, a + ld a, (hl+) + ld d, a ; de == dest + ld b, (hl) ; b == count + + ld hl, #rle_cursor + ld a, (hl+) + ld h, (hl) + ld l, a ; hl == cursor + + or h + ld e, a + ret z + + ld e, c + + ld a, (rle_counter) + or a + ld c, a + jr z, 1$ + + ld a, (rle_current) + bit 7, c + jr nz, 10$ + jr 11$ +1$: + ;; Fetch the run + ld c, (hl) + inc hl + ;; Negative means a run +8$: + bit 7, c + jr z, 2$ + ;; Expanding a run + ld a, (hl+) +3$: + ld (de), a + inc de + + dec b + jr z, 6$ +10$: + inc c + jr NZ, 3$ + jr 1$ +2$: + ;; Zero means end of a block + inc c + dec c + jr z, 4$ + ;; Expanding a block +5$: + ld a, (hl+) + ld (de), a + inc de + + dec b + jr z, 6$ +11$: + dec c + jr NZ, 5$ + jr 1$ +4$: + ;; save state and exit + ld hl, #rle_cursor + xor a + ld (hl+), a + ld (hl), a + ld e, a + ret +6$: + ;; save state and exit + ld d, h + ld e, l + ld hl, #rle_current + ld (hl-), a + ld a, c + ld (hl-), a + ld a, d + ld (hl-), a + ld (hl), e + ld e, #1 + ret + diff --git a/gbdk-lib/libc/targets/z80/gg/Makefile b/gbdk-lib/libc/targets/z80/gg/Makefile @@ -29,6 +29,7 @@ ASSRC = set_interrupts.s \ memset_small.s \ far_ptr.s \ gb_decompress.s \ + rle_decompress.s \ heap.s \ __sdcc_bcall.s \ crt0.s diff --git a/gbdk-lib/libc/targets/z80/rle_decompress.s b/gbdk-lib/libc/targets/z80/rle_decompress.s @@ -0,0 +1,100 @@ + .include "global.s" + + .module RLE_DECOMPRESS + + .area _DATA + +rle_cursor: + .ds 0x02 +rle_counter: + .ds 0x01 +rle_current: + .ds 0x01 + + .area _CODE + +_rle_init:: + ld (rle_cursor), hl + xor a + ld hl, #rle_counter + ld (hl), a + inc hl + ld (hl), a + ld l, #1 + ret + +_rle_decompress:: + ;; Pop the return address + pop hl + pop de + dec sp + ex (sp), hl + ld b, h + + ld hl, (rle_cursor) + + ld a, l + or h + ret z + + ld a, (rle_counter) + or a + ld c, a + jr z, 1$ + + ld a, (rle_current) + bit 7, c + jr nz, 10$ + jr 11$ +1$: + ;; Fetch the run + ld c, (hl) + inc hl + ;; Negative means a run +8$: + bit 7, c + jr z, 2$ + ;; Expanding a run + ld a, (hl) + inc hl +3$: + ld (de), a + inc de + + dec b + jr z, 6$ +10$: + inc c + jr NZ, 3$ + jr 1$ +2$: + ;; Zero means end of a block + inc c + dec c + jr z, 4$ + ;; Expanding a block +5$: + ldi + inc bc + + dec b + jr z, 6$ +11$: + dec c + jr NZ, 5$ + jr 1$ +4$: + ;; save state and exit + ld hl, #0 + ld (rle_cursor), hl + ld (rle_counter), hl + ret +6$: + ;; save state and exit + ld (rle_cursor), hl + ld hl, #rle_counter + ld (hl), c + inc hl + ld (hl), a + ld l, #1 + ret + diff --git a/gbdk-lib/libc/targets/z80/sms/Makefile b/gbdk-lib/libc/targets/z80/sms/Makefile @@ -29,6 +29,7 @@ ASSRC = set_interrupts.s \ memset_small.s \ far_ptr.s \ gb_decompress.s \ + rle_decompress.s \ heap.s \ __sdcc_bcall.s \ crt0.s

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.