commit c78bc5e88bef99afba8959117d49c31b798369fb Author: Alvie Rahman Date: Mon Jun 6 22:19:34 2022 +0100 first commit - a kind of working thingy diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0c333d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +compile.bat +obj diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..6fdf0fc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "gbdk-2020"] + path = gbdk-2020 + url = https://github.com/gbdk-2020/gbdk-2020.git diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f172daa --- /dev/null +++ b/Makefile @@ -0,0 +1,60 @@ +# +# A Makefile that compiles all .c and .s files in "src" and "res" +# subdirectories and places the output in a "obj" subdirectory +# + +# If you move this project you can change the directory +# to match your GBDK root directory (ex: GBDK_HOME = "C:/GBDK/" +GBDK_HOME = ./gbdk-2020/ + +LCC = $(GBDK_HOME)bin/lcc + +# You can set flags for LCC here +# For example, you can uncomment the line below to turn on debug output +# LCCFLAGS = -debug + +# You can set the name of the .gb ROM file here +PROJECTNAME = untitled2dshooter + +SRCDIR = src +OBJDIR = obj +RESDIR = res +BINS = $(OBJDIR)/$(PROJECTNAME).gb +CSOURCES = $(foreach dir,$(SRCDIR),$(notdir $(wildcard $(dir)/*.c))) $(foreach dir,$(RESDIR),$(notdir $(wildcard $(dir)/*.c))) +ASMSOURCES = $(foreach dir,$(SRCDIR),$(notdir $(wildcard $(dir)/*.s))) +OBJS = $(CSOURCES:%.c=$(OBJDIR)/%.o) $(ASMSOURCES:%.s=$(OBJDIR)/%.o) + +all: prepare $(BINS) + +compile.bat: Makefile + @echo "REM Automatically generated from Makefile" > compile.bat + @make -sn | sed y/\\//\\\\/ | grep -v make >> compile.bat + +# Compile .c files in "src/" to .o object files +$(OBJDIR)/%.o: $(SRCDIR)/%.c + $(LCC) $(LCCFLAGS) -c -o $@ $< + +# Compile .c files in "res/" to .o object files +$(OBJDIR)/%.o: $(RESDIR)/%.c + $(LCC) $(LCCFLAGS) -c -o $@ $< + +# Compile .s assembly files in "src/" to .o object files +$(OBJDIR)/%.o: $(SRCDIR)/%.s + $(LCC) $(LCCFLAGS) -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) $(LCCFLAGS) -S -o $@ $< + +# Link the compiled object files into a .gb ROM file +$(BINS): $(OBJS) + $(LCC) $(LCCFLAGS) -o $(BINS) $(OBJS) + +prepare: + mkdir -p $(OBJDIR) + +clean: +# rm -f *.gb *.ihx *.cdb *.adb *.noi *.map + rm -f $(OBJDIR)/*.* + diff --git a/gbdk-2020 b/gbdk-2020 new file mode 160000 index 0000000..ebbc0b0 --- /dev/null +++ b/gbdk-2020 @@ -0,0 +1 @@ +Subproject commit ebbc0b0ed11267182c922fcbf87da915b9e90526 diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..d7527b1 --- /dev/null +++ b/readme.md @@ -0,0 +1,11 @@ +# untitled2dshooter + +an untitled 2d multiplayer shooter for the gameboy + +## compile + +``` +make all +``` + +the gameboy rom will be output to `obj/untitled2dshooter.gb` diff --git a/res/map.c b/res/map.c new file mode 100644 index 0000000..f4bbfbd --- /dev/null +++ b/res/map.c @@ -0,0 +1,65 @@ +/* + + MAP.C + + Map Source File. + + Info: + Section : + Bank : 0 + Map size : 20 x 18 + Tile set : Z:\home\alvie\d\p\wordboy\res\tiles.gbr + Plane count : 1 plane (8 bits) + Plane order : Tiles are continues + Tile offset : 0 + Split data : No + + This file was generated by GBMB v1.8 + +*/ + +#define mapWidth 20 +#define mapHeight 18 +#define mapBank 0 + +unsigned char map[] = +{ + 0x09,0x02,0x02,0x02,0x02,0x02,0x02,0x08,0x00,0x00, + 0x00,0x07,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x0A, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x04,0x00,0x00,0x0D,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x04,0x00,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x04,0x00,0x00,0x03,0x0F,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x04,0x00,0x00,0x11,0x00,0x00,0x0E,0x12,0x12,0x12, + 0x12,0x12,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x04,0x00,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x04,0x00,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x0E,0x12,0x12,0x0F,0x00,0x00,0x00,0x03, + 0x04,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,0x0B, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x13,0x13, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0B,0x13,0x13, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x05,0x0B,0x13,0x13,0x13, + 0x0C,0x01,0x01,0x01,0x01,0x01,0x01,0x06,0x00,0x00, + 0x00,0x05,0x01,0x01,0x01,0x0B,0x13,0x13,0x13,0x13 +}; + +/* End of MAP.C */ diff --git a/res/map.h b/res/map.h new file mode 100644 index 0000000..16f1362 --- /dev/null +++ b/res/map.h @@ -0,0 +1,27 @@ +/* + + MAP.H + + Map Include File. + + Info: + Section : + Bank : 0 + Map size : 20 x 18 + Tile set : Z:\home\alvie\d\p\wordboy\res\tiles.gbr + Plane count : 1 plane (8 bits) + Plane order : Tiles are continues + Tile offset : 0 + Split data : No + + This file was generated by GBMB v1.8 + +*/ + +#define mapWidth 20 +#define mapHeight 18 +#define mapBank 0 + +extern unsigned char map[]; + +/* End of MAP.H */ diff --git a/res/sprites.c b/res/sprites.c new file mode 100644 index 0000000..82adceb --- /dev/null +++ b/res/sprites.c @@ -0,0 +1,52 @@ +/* + + SPRITES.C + + Tile Source File. + + Info: + Form : All tiles as one unit. + Format : Gameboy 4 color. + Compression : None. + Counter : None. + Tile size : 8 x 8 + Tiles : 0 to 10 + + Palette colors : None. + SGB Palette : None. + CGB Palette : None. + + Convert to metatiles : No. + + This file was generated by GBTD v2.2 + +*/ + +/* Start of tile array. */ +unsigned char sprites[] = +{ + 0xF7,0x08,0xED,0x12,0xFE,0x11,0xFF,0x38, + 0xFE,0x39,0xFE,0x39,0xFF,0x7E,0xFF,0x6E, + 0xFF,0x00,0xC3,0x42,0x81,0x00,0x81,0x00, + 0x81,0x00,0x81,0x00,0xC3,0x42,0xFF,0x00, + 0xC3,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E, + 0x7E,0x7E,0x3C,0x3C,0xDB,0xDB,0xC3,0xC3, + 0x43,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E, + 0x7E,0x7E,0x3C,0x3C,0xDB,0xDB,0xC3,0xC3, + 0xC2,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E, + 0x7E,0x7E,0x3C,0x3C,0xDB,0xDB,0xC3,0xC3, + 0xC3,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E, + 0x7E,0x7E,0x3C,0x3C,0xDB,0xDB,0x43,0xC3, + 0xC3,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E, + 0x7E,0x7E,0x3C,0x3C,0xDB,0xDB,0xC2,0xC3, + 0x42,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E, + 0x7E,0x7E,0x3C,0x3C,0xDB,0xDB,0xC3,0xC3, + 0xC2,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E, + 0x7E,0x7E,0x3C,0x3C,0xDB,0xDB,0xC2,0xC3, + 0xC3,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E, + 0x7E,0x7E,0x3C,0x3C,0xDB,0xDB,0x42,0xC3, + 0x43,0xC3,0xDB,0xDB,0x3C,0x3C,0x7E,0x7E, + 0x7E,0x7E,0x3C,0x3C,0xDB,0xDB,0x43,0xC3 +}; + +/* End of SPRITES.C */ diff --git a/res/sprites.gbr b/res/sprites.gbr new file mode 100644 index 0000000..368fb5d Binary files /dev/null and b/res/sprites.gbr differ diff --git a/res/sprites.h b/res/sprites.h new file mode 100644 index 0000000..0fba763 --- /dev/null +++ b/res/sprites.h @@ -0,0 +1,31 @@ +/* + + SPRITES.H + + Include File. + + Info: + Form : All tiles as one unit. + Format : Gameboy 4 color. + Compression : None. + Counter : None. + Tile size : 8 x 8 + Tiles : 0 to 10 + + Palette colors : None. + SGB Palette : None. + CGB Palette : None. + + Convert to metatiles : No. + + This file was generated by GBTD v2.2 + +*/ + + +/* Bank of tiles. */ +#define spritesBank 0 +/* Start of tile array. */ +extern unsigned char sprites[]; + +/* End of SPRITES.H */ diff --git a/res/test.gbm b/res/test.gbm new file mode 100644 index 0000000..244f9ec Binary files /dev/null and b/res/test.gbm differ diff --git a/res/tilemap.gbm b/res/tilemap.gbm new file mode 100644 index 0000000..36a8e1b Binary files /dev/null and b/res/tilemap.gbm differ diff --git a/res/tiles.c b/res/tiles.c new file mode 100644 index 0000000..0404dab --- /dev/null +++ b/res/tiles.c @@ -0,0 +1,76 @@ +/* + + TILES.C + + Tile Source File. + + Info: + Form : All tiles as one unit. + Format : Gameboy 4 color. + Compression : None. + Counter : None. + Tile size : 8 x 8 + Tiles : 0 to 22 + + Palette colors : None. + SGB Palette : None. + CGB Palette : None. + + Convert to metatiles : No. + + This file was generated by GBTD v2.2 + +*/ + +/* Start of tile array. */ +unsigned char tiles[] = +{ + 0x10,0x00,0x00,0x00,0x08,0x00,0x10,0x00, + 0x30,0x00,0x20,0x00,0x60,0x00,0x50,0x20, + 0xFF,0xFF,0xFF,0xFF,0x00,0xFF,0x00,0xFF, + 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, + 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, + 0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF, + 0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF, + 0x03,0xFF,0x03,0xFF,0x03,0xFF,0x03,0xFF, + 0x03,0xFF,0x03,0xFF,0x03,0xFF,0x03,0xFF, + 0x7F,0x7F,0xFF,0xFF,0xF0,0xFF,0xE0,0xFF, + 0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF, + 0xFE,0xFE,0xFF,0xFF,0x0F,0xFF,0x07,0xFF, + 0x03,0xFF,0x03,0xFF,0x03,0xFF,0x03,0xFF, + 0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF, + 0xE0,0xFF,0xF0,0xFF,0xFF,0xFF,0x7F,0x7F, + 0x03,0xFF,0x03,0xFF,0x03,0xFF,0x03,0xFF, + 0x07,0xFF,0x0F,0xFF,0xFF,0xFF,0xFE,0xFE, + 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, + 0x00,0xFF,0x00,0xFF,0x01,0xFF,0x03,0xFF, + 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, + 0x00,0xFF,0x00,0xFF,0x80,0xFF,0xC0,0xFF, + 0xC0,0xFF,0x80,0xFF,0x00,0xFF,0x00,0xFF, + 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, + 0x03,0xFF,0x01,0xFF,0x00,0xFF,0x00,0xFF, + 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, + 0x7E,0x7E,0xFF,0xFF,0xE7,0xFF,0xC3,0xFF, + 0xC3,0xFF,0xC3,0xFF,0xC3,0xFF,0xC3,0xFF, + 0x7F,0x7F,0xFF,0xFF,0xE0,0xFF,0xC0,0xFF, + 0xC0,0xFF,0xE0,0xFF,0xFF,0xFF,0x7F,0x7F, + 0xFE,0xFE,0xFF,0xFF,0x07,0xFF,0x03,0xFF, + 0x03,0xFF,0x07,0xFF,0xFF,0xFF,0xFE,0xFE, + 0xC3,0xFF,0xC3,0xFF,0xC3,0xFF,0xC3,0xFF, + 0xC3,0xFF,0xE7,0xFF,0xFF,0xFF,0x7E,0x7E, + 0xC3,0xFF,0xC3,0xFF,0xC3,0xFF,0xC3,0xFF, + 0xC3,0xFF,0xC3,0xFF,0xC3,0xFF,0xC3,0xFF, + 0xFF,0xFF,0xFF,0xFF,0x00,0xFF,0x00,0xFF, + 0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, + 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + +/* End of TILES.C */ diff --git a/res/tiles.gbr b/res/tiles.gbr new file mode 100644 index 0000000..8ff2090 Binary files /dev/null and b/res/tiles.gbr differ diff --git a/res/tiles.h b/res/tiles.h new file mode 100644 index 0000000..ff45776 --- /dev/null +++ b/res/tiles.h @@ -0,0 +1,31 @@ +/* + + TILES.H + + Include File. + + Info: + Form : All tiles as one unit. + Format : Gameboy 4 color. + Compression : None. + Counter : None. + Tile size : 8 x 8 + Tiles : 0 to 22 + + Palette colors : None. + SGB Palette : None. + CGB Palette : None. + + Convert to metatiles : No. + + This file was generated by GBTD v2.2 + +*/ + + +/* Bank of tiles. */ +#define tilesBank 0 +/* Start of tile array. */ +extern unsigned char tiles[]; + +/* End of TILES.H */ diff --git a/src/constants.h b/src/constants.h new file mode 100644 index 0000000..08c62b3 --- /dev/null +++ b/src/constants.h @@ -0,0 +1,21 @@ +#ifndef CONSTANTS_LOADED +#define CONSTANTS_LOADED + +#define GRAV_ACC 1 +#define TERM_VELY 3 +#define TERM_VELX 2 +#define TERM_VELY_DIVISOR 3 +#define TERM_VELX_DIVISOR 3 + +#define JUMP_VEL 4 +#define JUMP_TIMEOUT_FRAMES 18 + +#define DASH_VELL 7 +#define DASH_VELD 5 +#define DASH_TIMEOUT_FRAMES 30 + +#define SPRITE_WIDTH 8 +#define SPRITE_HEIGHT 8 +#define PIXELS_PER_TILE 8 +#define TILES_PER_ROW 20 +#endif diff --git a/src/flags.h b/src/flags.h new file mode 100644 index 0000000..585ee16 --- /dev/null +++ b/src/flags.h @@ -0,0 +1,39 @@ +#define SPRITE_PROP_BEHIND 0b10000000 +#define SPRITE_PROP_VERTICAL_FLIP 0b01000000 +#define SPRITE_PROP_HORIZONTAL_FLIP 0b00100000 + +#define COLLISION_TOP_LEFT 0b10000000 +#define COLLISION_TOP_RIGHT 0b01000000 +#define COLLISION_BOTTOM_LEFT 0b00100000 +#define COLLISION_BOTTOM_RIGHT 0b00010000 + + +// Sprite Collision flags used by uint8_t collision(uint8_t, uint8_t, uint8_t, uint8_t) + +#define SC_TL 0b10000000 +#define SC_TR 0b01000000 +#define SC_BL 0b00100000 +#define SC_BR 0b00010000 +#define SC_LT 0b00001000 +#define SC_LB 0b00000100 +#define SC_RT 0b00000010 +#define SC_RB 0b00000001 + +#define SC_ITL 0b1000 +#define SC_ITR 0b0100 +#define SC_IBL 0b0010 +#define SC_IBR 0b0001 + +/* Sprite Collision point diagram: + * x TL LT x + * ------------ + * LT x|x ITL ITR x|x RT + * | | + * | | + * | | + * | | + * | | + * LB x|x IBL IBR x|x RB + * ------------ + * x TL LT x + */ diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..e5ca645 --- /dev/null +++ b/src/main.c @@ -0,0 +1,224 @@ +#include +#include +#include "../res/tiles.h" +#include "../res/map.h" +#include"../res/sprites.h" +#include "./flags.h" +#include "./constants.h" +#include "./vec.c" + +int getTileIndexByCoord(unsigned int x, unsigned int y) +{ + return ((y / PIXELS_PER_TILE) * 20) + (x / PIXELS_PER_TILE); +} + +// check for external collisions (if rectangle is at least touchign something) +unsigned int collision(unsigned char map[], struct UVec *sprite_pos, struct UVec *sprite_size) +{ + unsigned int rv = 0; + struct UVec itl, itr, ibl, ibr; + + itl.x = sprite_pos->x-8; itl.y = sprite_pos->y-16; + itr.x = sprite_pos->x-1; itr.y = sprite_pos->y-16; + ibl.x = sprite_pos->x-8; ibl.y = sprite_pos->y-9; + ibr.x = sprite_pos->x-1; ibr.y = sprite_pos->y-9; + + // check if corners are in a non 0 tile + if (map[getTileIndexByCoord(itl.x, itl.y-1)]) rv = rv | SC_TL; + if (map[getTileIndexByCoord(itr.x, itr.y-1)]) rv = rv | SC_TR; + + if (map[getTileIndexByCoord(ibl.x, ibl.y+1)]) rv = rv | SC_BL; + if (map[getTileIndexByCoord(ibr.x, ibr.y+1)]) rv = rv | SC_BR; + + if (map[getTileIndexByCoord(itl.x-1, itl.y)]) rv = rv | SC_LT; + if (map[getTileIndexByCoord(ibl.x-1, ibl.y)]) rv = rv | SC_LB; + + if (map[getTileIndexByCoord(itr.x+1, itr.y)]) rv = rv | SC_RT; + if (map[getTileIndexByCoord(ibr.x+1, ibr.y)]) rv = rv | SC_RB; + + return rv; +} + + +// calculate internal collisions from external collisions +unsigned int icollision(unsigned char map[], struct UVec *sprite_pos, struct UVec *sprite_size) +{ + unsigned int c, rv = 0; + struct UVec itl, itr, ibl, ibr; + + itl.x = sprite_pos->x-8; itl.y = sprite_pos->y-16; + itr.x = sprite_pos->x-1; itr.y = sprite_pos->y-16; + ibl.x = sprite_pos->x-8; ibl.y = sprite_pos->y-9; + ibr.x = sprite_pos->x-1; ibr.y = sprite_pos->y-9; + + if (map[getTileIndexByCoord(itl.x, itl.y)]) rv = rv | SC_ITL; + if (map[getTileIndexByCoord(itr.x, itr.y)]) rv = rv | SC_ITR; + if (map[getTileIndexByCoord(ibl.x, ibl.y)]) rv = rv | SC_IBL; + if (map[getTileIndexByCoord(ibr.x, ibr.y)]) rv = rv | SC_IBR; + + return rv; +} + + +void init_gfx() +{ + // Load Background tiles and then map + set_bkg_data(0, 23, tiles); + set_bkg_tiles(0, 0, mapWidth, mapHeight, map); + + set_sprite_data(0, 11, sprites); + set_sprite_tile(0, 2); + set_sprite_prop(0, 0); + + // Turn the background map on to make it visible + SHOW_BKG; + SHOW_SPRITES; +} + +void main(void) +{ + unsigned int c, search_found, frames_since_last_jump, frames_since_last_dash, fc = 0; + int xsearch, ysearch; + struct UVec sprite_pos, search_pos, sprite_size; + struct Vec velocity, acceleration; + + init_gfx(); + + sprite_pos.x = 72; + sprite_pos.y = 35; + sprite_size.x = 8; + sprite_size.y = 8; + frames_since_last_jump = JUMP_TIMEOUT_FRAMES; + frames_since_last_dash = DASH_TIMEOUT_FRAMES; + velocity.x = 0; + velocity.y = 0; + acceleration.x = 0; + acceleration.y = 0; + + move_sprite(0, sprite_pos.x, sprite_pos.y); + + // Loop forever + while(1) { + // the gameboy simulates physics too quickly to have good control over the speeds of things + // so draw them less often and move them more + if (frames_since_last_jump <= JUMP_TIMEOUT_FRAMES) frames_since_last_jump++; + if (frames_since_last_dash <= DASH_TIMEOUT_FRAMES) frames_since_last_dash++; + + if (++fc % 2 == 0) { + velocity.y += GRAV_ACC; + fc = 0; + } + + // player move left/right + if ((joypad() & J_RIGHT) && (velocity.x < TERM_VELX)) acceleration.x = 1; + else if ((joypad() & J_LEFT) && (velocity.x > -TERM_VELX)) acceleration.x = -1; + else acceleration.x = -velocity.x/abs(velocity.x); + velocity.x += acceleration.x; + + // player dash + if ((joypad() & J_B) && (frames_since_last_dash > DASH_TIMEOUT_FRAMES)) { + int frames_since_last_dash_copy = frames_since_last_dash; + frames_since_last_dash = 0; + + if ((joypad() & J_LEFT) && !(joypad() & (J_UP | J_RIGHT | J_DOWN))) { + velocity.x = -DASH_VELL; + } else if ((joypad() & J_RIGHT) && !(joypad() & (J_UP | J_LEFT | J_DOWN))) { + velocity.x = DASH_VELL; + } else if ((joypad() & J_UP) && !(joypad() & (J_RIGHT | J_LEFT | J_DOWN))) { + velocity.y = -DASH_VELL; + } else if ((joypad() & J_DOWN) && !(joypad() & (J_UP | J_LEFT | J_RIGHT))) { + velocity.y = DASH_VELL; + } else if ((joypad() & J_RIGHT) && (joypad() & J_UP)) { + velocity.x = DASH_VELD; + velocity.y = -DASH_VELD; + } else if ((joypad() & J_LEFT) && (joypad() & J_UP)) { + velocity.x = -DASH_VELD; + velocity.y = -DASH_VELD; + } else if ((joypad() & J_LEFT) && (joypad() & J_DOWN)) { + velocity.x = -DASH_VELD; + velocity.y = DASH_VELD; + } else if ((joypad() & J_RIGHT) && (joypad() & J_DOWN)) { + velocity.x = DASH_VELD; + velocity.y = DASH_VELD; + } else { + // if player doesn't hold the right buttons to dash, don't dash and set the + // frames_since_last_dash counter back to what it was before + frames_since_last_dash = frames_since_last_dash_copy; + } + } + + // slow down sprite in kind of realistic way + // (in real life i think it's drag is proportional to velocity square but not + // sure if that is worth the compute yet) + if (velocity.y > TERM_VELY) velocity.y -= (abs(velocity.y)-TERM_VELY)/TERM_VELY_DIVISOR; + if (velocity.y < -TERM_VELY) velocity.y += (abs(velocity.y)-TERM_VELY)/TERM_VELY_DIVISOR; + if (velocity.x > TERM_VELX) velocity.x -= (abs(velocity.x)-TERM_VELX)/TERM_VELX_DIVISOR; + if (velocity.x < -TERM_VELX) velocity.x += (abs(velocity.x)-TERM_VELX)/TERM_VELX_DIVISOR; + + // don't let player move in a direction which they are already touching something + if (((c & SC_TL) | (c & SC_TR)) && (velocity.y < 0)) { velocity.y = 0; } + if (((c & SC_BL) | (c & SC_BR)) && (velocity.y > 0)) { + // player jump + if ((joypad() & J_A) && (frames_since_last_jump > JUMP_TIMEOUT_FRAMES)) { + velocity.y = -JUMP_VEL; + frames_since_last_jump = 0; + } + else velocity.y = 0; + } + if (((c & SC_RT) | (c & SC_RB)) && (velocity.x > 0)) { velocity.x = 0; } + if (((c & SC_LT) | (c & SC_LB)) && (velocity.x < 0)) { velocity.x = 0; } + + sprite_pos.x += velocity.x; + sprite_pos.y += velocity.y; + + c = collision(map, &sprite_pos, &sprite_size); + + // move player out of tiles by brute force searching :eyes: + // TODO this is really stupid and bad and i think it will have to be changed when there + // are more players moving around + search_found = 0; + for (ysearch = 0; ysearch <= SPRITE_HEIGHT; ysearch++) { + for (xsearch = 0; xsearch <= SPRITE_WIDTH; xsearch++) { + search_pos.x = sprite_pos.x + xsearch; + search_pos.y = sprite_pos.y + ysearch; + if(icollision(map, &search_pos, &sprite_size) == 0) { + sprite_pos.x = search_pos.x; + sprite_pos.y = search_pos.y; + search_found = 1; + break; + } + search_pos.x = sprite_pos.x - xsearch; + search_pos.y = sprite_pos.y + ysearch; + if(icollision(map, &search_pos, &sprite_size) == 0) { + sprite_pos.x = search_pos.x; + sprite_pos.y = search_pos.y; + search_found = 1; + break; + } + search_pos.x = sprite_pos.x - xsearch; + search_pos.y = sprite_pos.y - ysearch; + if(icollision(map, &search_pos, &sprite_size) == 0) { + sprite_pos.x = search_pos.x; + sprite_pos.y = search_pos.y; + search_found = 1; + break; + } + search_pos.x = sprite_pos.x + xsearch; + search_pos.y = sprite_pos.y - ysearch; + if(icollision(map, &search_pos, &sprite_size) == 0) { + sprite_pos.x = search_pos.x; + sprite_pos.y = search_pos.y; + search_found = 1; + break; + } + } + if (search_found) break; + } + + // finally move the sprite + move_sprite(0, sprite_pos.x, sprite_pos.y); + + // Done processing, yield CPU and wait for start of next frame + wait_vbl_done(); + } +} diff --git a/src/vec.c b/src/vec.c new file mode 100644 index 0000000..ac662ce --- /dev/null +++ b/src/vec.c @@ -0,0 +1,9 @@ +struct UVec { + unsigned int x; + unsigned int y; +}; + +struct Vec { + int x; + int y; +};