From c17a0db190dd7b991965635a3c41eeee79bf77ff Mon Sep 17 00:00:00 2001 From: Matt Kubilus Date: Sun, 9 Feb 2020 11:37:59 -0500 Subject: [PATCH] Updates to collision, tiled conversion, sgdk compat --- Makefile | 10 +- examples/coll_test1/Makefile | 7 +- examples/physics_test1/main.c | 47 +-- incs/blast.h | 14 +- incs/math_tables.h | 9 + incs/sprite.h | 38 ++- incs/stack.h | 68 +++++ incs/tilemap.h | 10 +- incs/u8_stack.h | 19 ++ libs/blast.c | 33 +- libs/gfx.c | 24 +- libs/math_tables.c | 67 +++++ libs/sprite.c | 552 +++++++++++++++++++++++----------- libs/stack.c | 106 +++++++ libs/tilemap.c | 137 ++++++--- libs/u8_stack.c | 2 + tools/gen_tables.py | 15 + tools/png2bmp.sh | 8 +- tools/tiled2c.py | 121 ++++++-- 19 files changed, 984 insertions(+), 303 deletions(-) create mode 100644 incs/math_tables.h create mode 100644 incs/stack.h create mode 100644 incs/u8_stack.h create mode 100644 libs/math_tables.c create mode 100644 libs/stack.c create mode 100644 libs/u8_stack.c mode change 100644 => 100755 tools/png2bmp.sh diff --git a/Makefile b/Makefile index 0809671..e981327 100644 --- a/Makefile +++ b/Makefile @@ -12,8 +12,9 @@ RM = rm -f ASMZ80 = $(GENBIN)/sjasm BINTOS = $(GENBIN)/bintos -#OPTION= -Dnologo_ --save-temps -fverbose-asm -g -OPTION= -Dnologo_ -fverbose-asm -g +OPTION= -Dnologo_ --save-temps -fverbose-asm -g +#OPTION= -Dnologo_ -fverbose-asm -g +#OPTION= -Dnologo_ CS=$(wildcard libs/*.c) SS=$(wildcard libs/*.s) @@ -25,9 +26,12 @@ RESOURCES+=$(S80S:.s80=.o) blast.a_OBJS=$(RESOURCES) INCS = -Iincs -I$(GENDEV)/m68k-elf/include -I$(GENDEV)/sgdk/inc -I$(GENDEV)/sgdk/res -FLAGS = $(OPTION) -m68000 -Wall -O1 -c -fomit-frame-pointer $(INCS) +FLAGS = $(OPTION) -m68000 -Wall -O2 -c -fomit-frame-pointer -fuse-linker-plugin -fno-web -fno-gcse -fno-unit-at-a-time $(INCS) +#FLAGS = $(OPTION) -m68000 -Wall -c -fomit-frame-pointer $(INCS) -O3 -flto -fuse-linker-plugin -fno-web -fno-gcse -fno-unit-at-a-time +#FLAGS = $(OPTION) -m68000 -Wall -c -fomit-frame-pointer $(INCS) -O3 -flto -fuse-linker-plugin -fno-web -fno-gcse -fno-unit-at-a-time -fomit-frame-pointer FLAGSZ80 = -isrc -iincs -I$(GENDEV)/m68k-elf/include + all: libblast.a %.a: $(blast.a_OBJS) diff --git a/examples/coll_test1/Makefile b/examples/coll_test1/Makefile index e152945..671750f 100644 --- a/examples/coll_test1/Makefile +++ b/examples/coll_test1/Makefile @@ -5,6 +5,7 @@ MAKE?=make LIB?=lib GENGCC_BIN=$(GENDEV)/bin GENBIN=$(GENDEV)/bin +SGDK_VER=1.34 CC = $(GENGCC_BIN)/m68k-elf-gcc AS = $(GENGCC_BIN)/m68k-elf-as @@ -30,16 +31,16 @@ SCD_LOADER = scd/LukeProjectCD OPTION = #OPTION = --save-temps #INCS = -I. -I$(GENDEV)/m68k-elf/include -I$(GENDEV)/m68k-elf/include -Isrc -Ires -INCS = -I$(GENDEV)/include/blast -I. -I $(GENDEV)/sgdk/res -I $(GENDEV)/sgdk/inc -I$(GENDEV)/m68k-elf/include -I$(GENDEV)/m68k-elf/m68k-elf/include -I$(GENDEV)/include/blast -Isrc -Ires +INCS = -I$(GENDEV)/include/blast -I. -I $(GENDEV)/sgdk$(SGDK_VER)/res -I $(GENDEV)/sgdk$(SGDK_VER)/inc -I$(GENDEV)/m68k-elf/include -I$(GENDEV)/m68k-elf/m68k-elf/include -I$(GENDEV)/include/blast -Isrc -Ires CCFLAGS = $(OPTION) -m68000 -Wall -O2 -c -fomit-frame-pointer HWCCFLAGS = $(OPTION) -m68000 -Wall -O1 -c -fomit-frame-pointer Z80FLAGS = -vb2 ASFLAGS = -m68000 --register-prefix-optional #LIBS = -L$(GENDEV)/m68k-elf/lib -L$(GENDEV)/m68k-elf/lib/gcc/m68k-elf/4.8.2 -L$(GENDEV)/m68k-elf/m68k-elf/lib -lmd -lc -lgcc -lnosys -lm -LIBS = -L$(GENDEV)/m68k-elf/lib -L$(GENDEV)/sgdk/lib -lmd -lnosys -lblast +LIBS = -L$(GENDEV)/m68k-elf/lib -L$(GENDEV)/sgdk$(SGDK_VER)/lib -lmd -lnosys -lblast LINKFLAGS = -T $(GENDEV)/ldscripts/sgdk.ld -Map=output.map -nostdlib SCDLINKFLAGS = -T scd/mdcd.ld -nostdlib -ARCHIVES = $(GENDEV)/sgdk/lib/libmd.a +ARCHIVES = $(GENDEV)/sgdk$(SGDK_VER)/lib/libmd.a # Are we AMD64? diff --git a/examples/physics_test1/main.c b/examples/physics_test1/main.c index 8d8cdfd..4a986f1 100644 --- a/examples/physics_test1/main.c +++ b/examples/physics_test1/main.c @@ -36,15 +36,15 @@ void myJoyHandler(u16 joy, u16 changed, u16 state) { //VDP_drawTextBG(VDP_PLAN_A,"JOY ",0x8000,1,1); if (joy == JOY_1) { if((state & BUTTON_UP)) { - asprite.velocity.y += -64; + asprite.velocity.y += -16; } else if ((state & BUTTON_DOWN)) { - asprite.velocity.y += 64; + asprite.velocity.y += 16; } if ((state & BUTTON_RIGHT)) { - asprite.velocity.x += 64; + asprite.velocity.x += 16; } else if ((state & BUTTON_LEFT)) { - asprite.velocity.x += -64; + asprite.velocity.x += -16; } } asprite.velocity.x = min(asprite.velocity.x, 256); @@ -85,7 +85,6 @@ void terrain_coll(spritedef* sprt, u8 coll_dir) { //sprt->direction += 128; //sprt->force = 2; - } void (*coll_callback)(spritedef* sprta, spritedef* sprtb) = &do_coll; @@ -93,6 +92,7 @@ void (*t_coll_callback)(spritedef* sprt, u8 coll) = &terrain_coll; int main() { + int i; /* * * Init Blast @@ -140,15 +140,14 @@ int main() { asprite_idx = sprite_init(&asprite,terrain_tile_offset+7,1,256,256,1,1,PAL0); lista[0] = asprite_idx; - bsprite_idx = sprite_init(&bsprite,terrain_tile_offset+7,1,256,220,1,1,PAL1); /* pow_idx = sprite_init(&pow,shot_offset,1,276,265,1,1,PAL0); pow1_idx = sprite_init(&pow1,shot_offset,1,226,285,1,1,PAL0); pow2_idx = sprite_init(&pow2,shot_offset,1,270,265,1,1,PAL0); */ - asprite.inv_mass = FIX16(0.05); - bsprite.inv_mass = FIX16(0.25); + asprite.inv_mass = FIX16(0.5); + bsprite.inv_mass = FIX16(0.5); //pow.inv_mass = FIX16(0.5); //pow1.inv_mass = FIX16(0.2); //pow2.inv_mass = FIX16(0.25); @@ -159,40 +158,32 @@ int main() { listc[0] = asprite_idx; listc[1] = bsprite_idx; - listc[2] = pow_idx; - listc[3] = pow1_idx; - listc[4] = pow2_idx; + //listc[2] = pow_idx; + //listc[3] = pow1_idx; + //listc[4] = pow2_idx; coly_idx = sprite_init(&coly,shot_offset,1,5,5,1,1,PAL0); - int i; for(i=0;i<25;i++){ u8 x = sprite_init( &spr_list[i], shot_offset, + //terrain_tile_offset+7, 1, random() % 64 + 200, random() % 64 + 200, - 1,1,PAL0); + 1,1,PAL2); listd[i] = spr_list[i].idx; spr_list[i].velocity.x = random()>>8; spr_list[i].velocity.y = random()>>8; + spr_list[i].inv_mass = FIX16(0.5); } listd[25] = asprite_idx; listd[26] = bsprite_idx; - for(i=0;i<32;i++){ - VDP_showFPS(0); - center_screen(&arena_map, asprite_idx, &hs, &vs); - center_screen(&arena_map, asprite_idx, &hs, &vs); - center_screen(&arena_map, asprite_idx, &hs, &vs); - center_screen(&arena_map, asprite_idx, &hs, &vs); - //BLAST_updateSprites(); - VDP_waitVSync(); - } //bsprite.direction = 160; //bsprite.force = 16; @@ -213,7 +204,17 @@ int main() { pow2.velocity.y = -132; */ + for(i=0;i<32;i++){ + center_screen(&arena_map, asprite_idx, &hs, &vs); + center_screen(&arena_map, asprite_idx, &hs, &vs); + center_screen(&arena_map, asprite_idx, &hs, &vs); + center_screen(&arena_map, asprite_idx, &hs, &vs); + //BLAST_updateSprites(); + VDP_waitVSync(); + } + while(1) { + //center_screen(&arena_map, asprite_idx, &hs, &vs); // Move player myJoyHandler(JOY_1,0,JOY_readJoypad(JOY_1)); @@ -239,7 +240,7 @@ int main() { //check_t_collision(listb, 1, &arena_map, t_coll_callback); move_sprites(&arena_map, t_coll_callback); - //drag_sprites(); + // drag_sprites(); //VDP_showFPS(0); uintToStr(getFPS(), str, 1); diff --git a/incs/blast.h b/incs/blast.h index 6e3b1ec..ca7970d 100644 --- a/incs/blast.h +++ b/incs/blast.h @@ -2,12 +2,17 @@ #include "gfx.h" #include "tilemap.h" #include "sprite.h" - +#include "u8_stack.h" +#include "math_tables.h" #ifndef _BLAST #define _BLAST -typedef int bool; +#undef DEBUG +#undef ROWCHECK +#undef COLCHECK + +//typedef int bool; #define true 1 #define false 0 @@ -19,6 +24,7 @@ void wait_vsync(); u8 coll_col [40]; u8 coll_row [28]; u8 spr_coll; -u16 coll_vcnt; -u32 coll_row_mask; +blastmap* fore_map; +//u16 coll_vcnt; +//u32 coll_row_mask; #endif diff --git a/incs/math_tables.h b/incs/math_tables.h new file mode 100644 index 0000000..600e3b7 --- /dev/null +++ b/incs/math_tables.h @@ -0,0 +1,9 @@ +#ifndef _MATH_TABLES +#define _MATH_TABLES + +const s8 sin_table[256]; +const s8 cos_table[256]; +const u8 atan_table[17]; +const u8 sqrt_table[256]; + +#endif diff --git a/incs/sprite.h b/incs/sprite.h index 07c67a9..5ff9590 100644 --- a/incs/sprite.h +++ b/incs/sprite.h @@ -1,6 +1,6 @@ #ifndef _SPRITE #define _SPRITE - +//#include "math_tables.h" //#include "genesis.h" //#include "blast.h" //#include "tilemap.h" @@ -10,7 +10,7 @@ #define MAX_SPRITE_COL 2 #define MAX_SPRITE_ROW 2 -typedef int bool; +//typedef int bool; typedef struct _vec2 { s16 x; @@ -23,6 +23,12 @@ typedef struct _AABB { vec2 max; } AABB; + +typedef struct _BLAST_Circle { + u8 radius; + vec2 position; +} BLAST_Circle; + typedef struct _spritedef { // Position on plane? @@ -52,12 +58,15 @@ typedef struct _spritedef // Tile width & height u8 tile_height; u8 tile_width; - // virtual position + // virtual position in map u16 vposx; u16 vposy; // VDP sprite list index u8 idx; + // horizontal and vertical attrs + u8 h_attr; + u8 v_attr; // Direction of motion // 0 up @@ -71,21 +80,32 @@ typedef struct _spritedef //u8 col_group; - s8 x_vec; - s8 y_vec; - + //s8 x_vec; + //s8 y_vec; +#ifdef COLCHECK u8 columns[MAX_SPRITE_COL]; u32 column_mask; +#endif + +#ifdef ROWCHECK u32 row_mask; u8 rows[MAX_SPRITE_ROW]; +#endif // Sprites axis aligned bounding box AABB aabb; fix16 inv_mass; vec2 velocity; + // Remainder velocity:w + vec2 r_vel; + + BLAST_Circle circle; //u8* coll_list; + + // Extra properties + void* properties; } spritedef; typedef struct _manifold { @@ -136,9 +156,11 @@ void check_collision(u8* lista, u8 lista_len, u8* listb, u8 listb_len, void (*ca void BLAST_updateSprites(); void BLAST_setSpriteP(u16 index, const spritedef *sprite); void sprite_bounce(spritedef* sprt_a, spritedef* sprt_b, manifold* m); -bool get_manifold(spritedef* a, spritedef* b, manifold *m); +bool get_box_manifold(spritedef* a, spritedef* b, manifold *m); +bool get_circle_manifold(spritedef* a, spritedef* b, manifold *m); void move_sprite(spritedef* sprt, blastmap* map, void (*callback)(spritedef* insprt, u8 coll)); void move_sprites(blastmap* map, void (*callback)(spritedef* sprt, u8 coll)); -void drag_sprites(); +void drag_sprites(u8 drag); +void flip_sprite(spritedef* sprt, u8 h, u8 v); #endif diff --git a/incs/stack.h b/incs/stack.h new file mode 100644 index 0000000..a4131b8 --- /dev/null +++ b/incs/stack.h @@ -0,0 +1,68 @@ +/** + * generic-stack.h + * Declarations for a simple generic implementation of stacks. + * + * + */ + +#ifdef TYPE + +// +--------+-------------------------------------------------------- +// | Macros | +// +--------+ + +/** + * By default, we do not rename procedures and structs. + */ +#ifndef TYPED +#define TYPED(THING) THING +#endif + +#ifndef NULL +#define NULL 0 +#endif +// +-------+--------------------------------------------------------- +// | Types | +// +-------+ + +typedef struct TYPED(Stack) TYPED(Stack); + +// +------------+---------------------------------------------------- +// | Procedures | +// +------------+ + +/** + * Create a new stack. + */ +TYPED(Stack)* TYPED(stack_new) (void); + +/** + * Free the space allocated to a stack. + */ +void TYPED(stack_free) (TYPED(Stack) *stack); + +void TYPED(stack_to_list) (TYPED(Stack) *stack, TYPE* thislist); + +/** + * Determine the number of elements in the stack. + */ +int TYPED(stack_size) (TYPED(Stack) *stack); + +/** + * Look at the top element of the stack. Requires that the + * stack have at least one element. + */ +TYPE TYPED(stack_top) (TYPED(Stack) *stack); + +/** + * Remove and return the top element of the stack. Requires that + * the stack have at least one element. + */ +TYPE TYPED(stack_pop) (TYPED(Stack) *stack); + +/** + * Add an element to the stack. + */ +void TYPED(stack_push) (TYPED(Stack) *stack, TYPE val); + +#endif // TYPE diff --git a/incs/tilemap.h b/incs/tilemap.h index d8130f0..0260cd7 100644 --- a/incs/tilemap.h +++ b/incs/tilemap.h @@ -7,8 +7,10 @@ #define winH 28 #define winW 40 -#define GET_TILE_XY(BMAP, X, Y) BMAP->tiles->data[(Y * (BMAP->mapw)) + X] + BMAP->tileoffset - 1 +//#define GET_TILE_XY(BMAP, X, Y) (BMAP->tiles->data[(Y * (BMAP->mapw)) + X] + BMAP->tileoffset - 1) +#define GET_COLL_XY(BMAP, X, Y) (((BMAP->tiles->data[(Y * (BMAP->mapw)) + X]) - 1) + BMAP->tileoffset) +#define GET_TILE_XY(BMAP, X, Y) (BMAP->tlookup[((BMAP->tiles->data[(Y * (BMAP->mapw)) + X]) - 1)] + BMAP->tileoffset) #define NOCOLL 0 #define COLL 1 #define COLL_LEFT 2 @@ -55,9 +57,13 @@ typedef struct d_map{ // tiles -> map of tiles tilemap* tiles; + + // + u16* tlookup; + } blastmap; -void blastmap_init(blastmap* bmap, tilemap* tmap, u16 tileoffset, VDPPlan plane); +void blastmap_init(blastmap* bmap, tilemap* tmap, u16* tlookup, u16 tileoffset, VDPPlan plane); void load_map(blastmap* bmap, int xoffset, int yoffset); void load_visible_map(blastmap* bmap, int xoffset, int yoffset); void load_map_row(blastmap* bmap, u8 row); diff --git a/incs/u8_stack.h b/incs/u8_stack.h new file mode 100644 index 0000000..cfd3ff5 --- /dev/null +++ b/incs/u8_stack.h @@ -0,0 +1,19 @@ +#ifndef _U8_STACK_H_ +#define _U8_STACK_H_ +#include "blast.h" +/** + * double-stack.h + * Stacks of doubles. + * + * + */ + +#undef TYPE +#undef TYPED + +#define TYPE u8 +#define TYPED(THING) u8_ ## THING + +#include "stack.h" + +#endif // _U8_STACK_H_ diff --git a/libs/blast.c b/libs/blast.c index 452ff13..5966cf3 100644 --- a/libs/blast.c +++ b/libs/blast.c @@ -1,5 +1,6 @@ #include "genesis.h" #include "blast.h" +//#include "math_tables.h" char str[10]; void vblank() { @@ -13,16 +14,17 @@ void vblank() { //check_collision(); } -void hblank() { +void _hblank() { //check_collision(); +#ifdef FOOBAR if(GET_VDPSTATUS(VDP_SPRCOLLISION_FLAG)) { //int i; //VDP_drawText(" COL ", 22, 20); //VDP_drawText(" COL ", 22, 20); //const u16 vcnt = GET_VCOUNTER; - - coll_row_mask |= 1U << (GET_VCOUNTER/8); - +#ifdef ROWCHECK + coll_row_mask |= 1U << (GET_VCOUNTER >> 3); +#endif //coll_vcnt = GET_VCOUNTER; //coll_row[ vcnt/8 ] = 1; spr_coll = 1; @@ -33,16 +35,18 @@ void hblank() { //VDP_drawText(str, 24, 25); } +#endif } void blast_init() { SYS_disableInts(); VDP_init(); VDP_resetSprites(); - //VDP_setScreenWidth256(); - VDP_setHIntCounter(2); - VDP_setHInterrupt(1); - VDP_setPlanSize(64,64); + VDP_setScreenWidth256(); + //VDP_setScreenWidth320(); + //VDP_setHIntCounter(2); + //VDP_setHInterrupt(1); + VDP_setPlanSize(64,32); VDP_setScrollingMode(HSCROLL_PLANE, VSCROLL_PLANE); //VDP_setTextPalette(1); //VDP_clearPlan(VDP_PLAN_A, 0); @@ -50,12 +54,19 @@ void blast_init() { //VDP_clearPlan(VDP_PLAN_B, 0); VDP_clearPlan(PLAN_B, 0); SYS_setVIntCallback(vblank); - SYS_setHIntCallback(hblank); - memset(coll_row, 0, sizeof(coll_row)); + //SYS_setHIntCallback(hblank); + //memset(coll_row, 0, sizeof(coll_row)); spr_coll = 0; - coll_row_mask = 0; + //coll_row_mask = 0; SYS_enableInts(); + + //wait_vsync(); + VDP_waitVSync(); + VDP_waitVSync(); + VDP_waitVSync(); + VDP_waitVSync(); + VDP_waitVSync(); } void wait_vsync() diff --git a/libs/gfx.c b/libs/gfx.c index 315632c..d36ec46 100644 --- a/libs/gfx.c +++ b/libs/gfx.c @@ -1,9 +1,25 @@ #include "gfx.h" -static u16 vdp_offset = 1; +static u16 vdp_offset = TILE_USERINDEX; +//static u16 vdp_offset = 1; +u16 draw_img(Image *img) { + u16 tmp_offset = vdp_offset; + VDP_drawImageEx(PLAN_B, img, TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, vdp_offset), 0, 0, FALSE, TRUE); + vdp_offset += img->tileset->numTile; + return tmp_offset; +} -u16 load_bmp(u32 *data, u16 w, u16 h) { +u16 load_img(Image* img) { + u16 tmp_offset = vdp_offset; + + VDP_loadTileSet(img->tileset, TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, vdp_offset) & TILE_INDEX_MASK, 1); + //VDP_loadTileData(img->tileset->tiles, vdp_offset, img->tileset->numTile, TRUE); + vdp_offset += img->tileset->numTile; + return tmp_offset; +} + +u16 load_bmp(u32* data, u16 w, u16 h) { u16 tmp_offset = vdp_offset; VDP_loadBMPTileData( @@ -25,8 +41,8 @@ u16 load_tile(u32 *data, u16 w, u16 h) { VDP_loadTileData( data, vdp_offset, - w/8, - h/8 + ((w/8) * (h/8)), + 1 ); vdp_offset += ((w/8) * (h/8)); diff --git a/libs/math_tables.c b/libs/math_tables.c new file mode 100644 index 0000000..516fb94 --- /dev/null +++ b/libs/math_tables.c @@ -0,0 +1,67 @@ +#include "blast.h" +const s8 sin_table[256] = { + 0,2,3,5,6,8,9,11,12,14,16,17,19,20,22,23, + 24,26,27,29,30,32,33,34,36,37,38,39,41,42,43,44, + 45,46,47,48,49,50,51,52,53,54,55,56,56,57,58,59, + 59,60,60,61,61,62,62,62,63,63,63,64,64,64,64,64, + 64,64,64,64,64,64,63,63,63,62,62,62,61,61,60,60, + 59,59,58,57,56,56,55,54,53,52,51,50,49,48,47,46, + 45,44,43,42,41,39,38,37,36,34,33,32,30,29,27,26, + 24,23,22,20,19,17,16,14,12,11,9,8,6,5,3,2, + 0,-2,-3,-5,-6,-8,-9,-11,-12,-14,-16,-17,-19,-20,-22,-23, + -24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,-43,-44, + -45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-56,-57,-58,-59, + -59,-60,-60,-61,-61,-62,-62,-62,-63,-63,-63,-64,-64,-64,-64,-64, + -64,-64,-64,-64,-64,-64,-63,-63,-63,-62,-62,-62,-61,-61,-60,-60, + -59,-59,-58,-57,-56,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46, + -45,-44,-43,-42,-41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26, + -24,-23,-22,-20,-19,-17,-16,-14,-12,-11,-9,-8,-6,-5,-3,-2, +}; + + +const s8 cos_table[256] = { + 64,64,64,64,64,64,63,63,63,62,62,62,61,61,60,60, + 59,59,58,57,56,56,55,54,53,52,51,50,49,48,47,46, + 45,44,43,42,41,39,38,37,36,34,33,32,30,29,27,26, + 24,23,22,20,19,17,16,14,12,11,9,8,6,5,3,2, + 0,-2,-3,-5,-6,-8,-9,-11,-12,-14,-16,-17,-19,-20,-22,-23, + -24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,-43,-44, + -45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-56,-57,-58,-59, + -59,-60,-60,-61,-61,-62,-62,-62,-63,-63,-63,-64,-64,-64,-64,-64, + -64,-64,-64,-64,-64,-64,-63,-63,-63,-62,-62,-62,-61,-61,-60,-60, + -59,-59,-58,-57,-56,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46, + -45,-44,-43,-42,-41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26, + -24,-23,-22,-20,-19,-17,-16,-14,-12,-11,-9,-8,-6,-5,-3,-2, + 0,2,3,5,6,8,9,11,12,14,16,17,19,20,22,23, + 24,26,27,29,30,32,33,34,36,37,38,39,41,42,43,44, + 45,46,47,48,49,50,51,52,53,54,55,56,56,57,58,59, + 59,60,60,61,61,62,62,62,63,63,63,64,64,64,64,64, +}; + + +const u8 atan_table[17] = { + 0,2,5,7,9,12,14,16,18,20,22,24,26,27,29,30, + 32, +}; + + +const u8 sqrt_table[256] = { + 0,16,23,28,32,36,39,42,45,48,51,53,55,58,60,62, + 64,66,68,70,72,73,75,77,78,80,82,83,85,86,88,89, + 91,92,93,95,96,97,99,100,101,102,104,105,106,107,109,110, + 111,112,113,114,115,116,118,119,120,121,122,123,124,125,126,127, + 128,129,130,131,132,133,134,135,136,137,138,139,139,140,141,142, + 143,144,145,146,147,148,148,149,150,151,152,153,153,154,155,156, + 157,158,158,159,160,161,162,162,163,164,165,166,166,167,168,169, + 169,170,171,172,172,173,174,175,175,176,177,177,178,179,180,180, + 181,182,182,183,184,185,185,186,187,187,188,189,189,190,191,191, + 192,193,193,194,195,195,196,197,197,198,199,199,200,200,201,202, + 202,203,204,204,205,206,206,207,207,208,209,209,210,210,211,212, + 212,213,213,214,215,215,216,216,217,218,218,219,219,220,221,221, + 222,222,223,223,224,225,225,226,226,227,227,228,229,229,230,230, + 231,231,232,232,233,234,234,235,235,236,236,237,237,238,238,239, + 239,240,241,241,242,242,243,243,244,244,245,245,246,246,247,247, + 248,248,249,249,250,250,251,251,252,252,253,253,254,254,255,255, +}; + + diff --git a/libs/sprite.c b/libs/sprite.c index da01ef1..24767ad 100644 --- a/libs/sprite.c +++ b/libs/sprite.c @@ -1,13 +1,20 @@ #include "genesis.h" #include "blast.h" +#include "math_tables.h" +//#define TESTCOLL 1 +//#define DEBUG 1 +//#define MATH_BIG_TABLES 1 +//#define OVERLAP 1 +#undef OVERLAP char abuf[50]; // Serve as the sprite counter u8 _sprite_count = 0; u16 spriteNum; -//SpriteDef vdpSpriteCache[MAX_SPRITE]; +u8 move_count = 1; +//SpriteDef vdpSpriteCache[MAX_SPRITE]; void BLAST_setSpriteP(u16 index, const spritedef *sprite) { } @@ -16,9 +23,10 @@ void BLAST_updateSprites() { vu32 *plctrl; vu16 *pwdata; + u32 addr; //SpriteDef *sprite; spritedef *sprite; - u16 i; + u16 i = 0; int cur_idx = 0; int next_idx = 0; @@ -31,23 +39,31 @@ void BLAST_updateSprites() plctrl = (u32 *) GFX_CTRL_PORT; pwdata = (u16 *) GFX_DATA_PORT; - *plctrl = GFX_WRITE_VRAM_ADDR(SLIST); - - - while(1) { sprite = _sprite_all[cur_idx]; - // y position - *pwdata = 0x80 + sprite->posy; - // size & link - *pwdata = (sprite->size << 8) | sprite->link; - // tile attribut - *pwdata = sprite->tile_attr; - // x position - *pwdata = 0X80 + sprite->posx; + + // if(sprite->posx < 320 && sprite->posx > -50 && sprite->posy < 240 && sprite->posy > -50) { + // Make sure we are updating the correct index + addr = SLIST + (cur_idx * 8); + *plctrl = GFX_WRITE_VRAM_ADDR(addr); + + //i++; + // y position + *pwdata = 0x80 + sprite->posy; + // size & link + *pwdata = (sprite->size << 8) | sprite->link; + // tile attribut + *pwdata = sprite->tile_attr; + // x position + *pwdata = 0X80 + sprite->posx; + // } next_idx = sprite->link; + + //uintToStr(sprite->link, abuf, 3); + //VDP_drawText(abuf, 5, 7+i); + if(next_idx == 0) { break; @@ -55,6 +71,8 @@ void BLAST_updateSprites() cur_idx = next_idx; } + //uintToStr(i, abuf, 3); + //VDP_drawText(abuf, 5, 6); /* sprite = &vdpSpriteCache[0]; @@ -80,15 +98,22 @@ void BLAST_updateSprites() } void sprite_setrowcol(spritedef* sprite) { - + return; +#ifdef COLCHECK sprite->columns[0] = sprite->posx/8; sprite->columns[1] = (sprite->posx + sprite->width)/8; +#endif //sprite->rows[0] = sprite->posy/8; //sprite->rows[1] = (sprite->posy + sprite->height)/8; - +#ifdef ROWCHECK sprite->row_mask = 0; - sprite->row_mask |= 1U << (sprite->posy/8); - sprite->row_mask |= 1U << ((sprite->posy + sprite->height)/8); + + //sprite->row_mask |= 1U << (sprite->posy/8); + //sprite->row_mask |= 1U << ((sprite->posy + sprite->height)/8); + + sprite->row_mask |= 1U << ((sprite->aabb.min.y)/8); + sprite->row_mask |= 1U << ((sprite->aabb.max.y)/8); +#endif /* VDP_drawText(" ", 18, 16); VDP_drawText(" ", 18, 17); @@ -102,6 +127,7 @@ void sprite_setrowcol(spritedef* sprite) { } u16 sprite_init(spritedef* sprite, u16 addr, u16 steps, s16 x, s16 y, u8 w, u8 h, u8 pal) { + // Position in the plane sprite->posx = x; sprite->posy = y; sprite->size = SPRITE_SIZE(w,h); @@ -120,16 +146,22 @@ u16 sprite_init(spritedef* sprite, u16 addr, u16 steps, s16 x, s16 y, u8 w, u8 h // This doesn't appear to be correct after moving screen + // vpos: position in the map coordinates sprite->vposx = x + hs; sprite->vposy = y + vs; sprite->idx = add_sprite(sprite); //sprite->coll_list = coll_list; - + + sprite->h_attr = 0; + sprite->v_attr = 0; + sprite->direction=0; sprite->force=0; +#ifdef COLCHECK sprite->column_mask = 0; +#endif /* sprite->minx = x; @@ -139,7 +171,6 @@ u16 sprite_init(spritedef* sprite, u16 addr, u16 steps, s16 x, s16 y, u8 w, u8 h */ - sprite_setrowcol(sprite); /* u16 i; @@ -162,26 +193,126 @@ u16 sprite_init(spritedef* sprite, u16 addr, u16 steps, s16 x, s16 y, u8 w, u8 h sprite->aabb.max.x = (w*8)+x; sprite->aabb.max.y = (h*8)+y; + sprite->circle.radius = 4; + sprite->circle.position.x = x + 4; + sprite->circle.position.y = y + 4; + sprite->inv_mass = FIX16(0.1); + sprite->velocity.x = 0; sprite->velocity.y = 0; + sprite->r_vel.x = 0; + sprite->r_vel.y = 0; - + sprite_setrowcol(sprite); return sprite->idx; } +bool check_circle(BLAST_Circle a, BLAST_Circle b) { + u16 r = a.radius + b.radius; + r *= r; + + s16 x = (a.position.x - b.position.x); + x *= x; + + s16 y = (a.position.y - b.position.y); + y *= y; + + if (r > (x + y) ) { +#ifdef DEBUG + VDP_drawText("check_c", 36, 15); + intToStr(r,abuf,3); + VDP_drawText(abuf, 36,16); + intToStr(a.position.x,abuf,6); + VDP_drawText(abuf, 36, 17); + intToStr(b.position.x,abuf,6); + VDP_drawText(abuf, 36, 18); + intToStr(x,abuf,6); + VDP_drawText(abuf, 36, 19); + intToStr(y,abuf,6); + VDP_drawText(abuf, 36, 20); +#endif + + return true; + } + + return false; +} bool check_aabb(AABB a, AABB b) { + if(a.max.x < b.min.x) + return false; + + if(a.min.x > b.max.x) + return false; + + if(a.max.y < b.min.y) + return false; + + if(a.min.y > b.max.y) + return false; // Exit with no intersection if found separated along an axis - if(a.max.x < b.min.x || a.min.x > b.max.x) return false; - if(a.max.y < b.min.y || a.min.y > b.max.y) return false; + //if(a.max.x < b.min.x || a.min.x > b.max.x) return false; + //if(a.max.y < b.min.y || a.min.y > b.max.y) return false; // No separating axis found, therefor there is at least one overlapping axis return true; } -bool get_manifold(spritedef* a, spritedef* b, manifold *m) { + +bool get_circle_manifold(spritedef* a, spritedef* b, manifold* m) { + vec2 n; + n.x = b->circle.position.x - a->circle.position.x; + n.y = b->circle.position.y - a->circle.position.y; + + u16 r = (a->circle.radius + b->circle.radius); + //r *= r; + + s16 n_length = (n.x * n.x) + (n.y * n.y); + +#ifdef DEBUG + VDP_drawText("get_circle_m", 30, 15); + intToStr(n_length,abuf,3); + VDP_drawText(abuf, 30,16); + intToStr(r,abuf,3); + VDP_drawText(abuf, 30, 17); + intToStr(n.x,abuf,3); + VDP_drawText(abuf, 30, 18); + intToStr(n.y,abuf,3); + VDP_drawText(abuf, 30, 19); +#endif + + if(n_length > (r * r)) { + //VDP_drawText("reject", 30, 14); + return false; + } + + + u8 d = (sqrt_table[n_length]>>4); +#ifdef DEBUG + intToStr(d,abuf,3); + VDP_drawText(abuf, 30, 20); +#endif + /* + while(1) { + VDP_waitVSync(); + } + */ + if(d != 0) { + m->penetration = r - d; + m->normal.x = ((n.x) / d)<<4; + m->normal.y = ((n.y) / d)<<4; + return true; + } else { + m->penetration = a->circle.radius; + m->normal.x = 16; + m->normal.y = 0; + return true; + } +} + +bool get_box_manifold(spritedef* a, spritedef* b, manifold *m) { vec2 n; n.x = b->posx - a->posx; n.y = b->posy - a->posy; @@ -201,13 +332,16 @@ bool get_manifold(spritedef* a, spritedef* b, manifold *m) { u16 y_overlap = a_extent + b_extent - abs(n.y); if(y_overlap > 0) { + + + if(x_overlap < y_overlap) { //VDP_drawText(" X min ", 14, 19); if(n.x < 0){ - m->normal.x = -1; + m->normal.x = -16; m->normal.y = 0; } else { - m->normal.x = 1; + m->normal.x = 16; m->normal.y = 0; } m->penetration = x_overlap; @@ -216,11 +350,11 @@ bool get_manifold(spritedef* a, spritedef* b, manifold *m) { if(n.y < 0) { //VDP_drawText(" y>0 ", 19, 18); m->normal.x = 0; - m->normal.y = -1; + m->normal.y = -16; } else { //VDP_drawText(" y>0 ", 19, 18); m->normal.x = 0; - m->normal.y = 1; + m->normal.y = 16; } m->penetration = y_overlap; } @@ -231,27 +365,21 @@ bool get_manifold(spritedef* a, spritedef* b, manifold *m) { return false; } -//#define TESTCOLL 1 - void sprite_bounce(spritedef* sprt_a, spritedef* sprt_b, manifold* m) { -#ifdef TESTCOLL - if ( sprt_a->velocity.y == 0 ){ - return; - } -#endif vec2 rv; rv.x = sprt_b->velocity.x - sprt_a->velocity.x; rv.y = sprt_b->velocity.y - sprt_a->velocity.y; -#ifdef DEBUG +#ifdef DEBUG + //VDP_drawText("line 15", 30, 15); intToStr(rv.x,abuf,3); VDP_drawText(abuf, 14,15); intToStr(rv.y,abuf,3); VDP_drawText(abuf, 14,16); #endif - s16 vel_normal = ((rv.x * m->normal.x) + (rv.y * m->normal.y)); + s16 vel_normal = ((rv.x * (m->normal.x>>4)) + (rv.y * (m->normal.y>>4))); #ifdef DEBUG intToStr(vel_normal,abuf,3); @@ -262,21 +390,6 @@ void sprite_bounce(spritedef* sprt_a, spritedef* sprt_b, manifold* m) { #ifdef DEBUG VDP_drawText(" SKIP ", 19, 16); #endif -#ifdef TESTCOLL - intToStr(sprt_a->velocity.x,abuf,3); - VDP_drawText(abuf, 14,21); - intToStr(sprt_a->velocity.y,abuf,3); - VDP_drawText(abuf, 14,22); - - intToStr(sprt_b->velocity.x,abuf,3); - VDP_drawText(abuf, 14,23); - intToStr(sprt_b->velocity.y,abuf,3); - VDP_drawText(abuf, 14,24); - sprt_a->velocity.x = 0; - sprt_a->velocity.y = 0; - sprt_b->velocity.x = 0; - sprt_b->velocity.y = 0; -#endif //VDP_drawText(" SKIP ", 19, 17); return; } @@ -308,15 +421,18 @@ void sprite_bounce(spritedef* sprt_a, spritedef* sprt_b, manifold* m) { //u16 mass_sum = sprt_a->mass + sprt_b->mass; vec2 impulse; - impulse.x = fix16ToInt(fix16Mul(j, intToFix16(m->normal.x))); - impulse.y = fix16ToInt(fix16Mul(j, intToFix16(m->normal.y))); - + impulse.x = fix16ToInt(fix16Mul(j, intToFix16(m->normal.x>>4))); + impulse.y = fix16ToInt(fix16Mul(j, intToFix16(m->normal.y>>4))); + +#ifdef BOUNDS /* Max impulse */ impulse.x = min(impulse.x, 256); impulse.x = max(impulse.x, -256); impulse.y = min(impulse.y, 256); impulse.y = max(impulse.y, -256); +#endif /* + * if (impulse.x > 256 || impulse.y > 256) { VDP_drawText("BOUNDS EXCEEDED", 14, 17); } @@ -348,13 +464,25 @@ void sprite_bounce(spritedef* sprt_a, spritedef* sprt_b, manifold* m) { intToStr(sprt_b->velocity.y,abuf,3); VDP_drawText(abuf, 14,24); #endif -#ifdef TESTCOLL - sprt_a->velocity.x = 0; - sprt_a->velocity.y = 0; - sprt_b->velocity.x = 0; - sprt_b->velocity.y = 0; -#endif +#ifdef OVERLAP + u16 p_amnt = abs(m->penetration) >> 1; + if(m->normal.x < 0) { + sprite_left(sprt_b, p_amnt, 512); + sprite_right(sprt_a, p_amnt, 512); + } else if (m->normal.x > 0) { + sprite_right(sprt_b, p_amnt, 512); + sprite_left(sprt_a, p_amnt, 512); + } + if(m->normal.y < 0) { + sprite_up(sprt_b, p_amnt, 512); + sprite_down(sprt_a, p_amnt, 512); + } else if (m->normal.y > 0) { + sprite_down(sprt_b, p_amnt, 512); + sprite_up(sprt_a, p_amnt, 512); + } +#endif + //return; sprt_a->velocity.x = min(sprt_a->velocity.x, 256); sprt_a->velocity.x = max(sprt_a->velocity.x, -256); @@ -380,6 +508,9 @@ void sprite_left(spritedef *sprt, u8 amnt, u16 max) { sprt->posx-=amnt; sprt->aabb.min.x-=amnt; sprt->aabb.max.x-=amnt; + sprt->circle.position.x-=amnt; + + sprite_setrowcol(sprt); //sprt->direction=192; /* @@ -409,7 +540,6 @@ void sprite_left(spritedef *sprt, u8 amnt, u16 max) { } } */ - sprite_setrowcol(sprt); if(sprt->vposx <= amnt) { //sprt->vposx = (sprt->vposx - amnt) + 65536; sprt->vposx = max - (amnt - 1); @@ -424,6 +554,7 @@ void sprite_right(spritedef *sprt, u8 amnt, u16 max) { sprt->posx+=amnt; sprt->aabb.min.x+=amnt; sprt->aabb.max.x+=amnt; + sprt->circle.position.x+=amnt; //sprt->direction=64; sprite_setrowcol(sprt); @@ -462,6 +593,7 @@ void sprite_up(spritedef *sprt, u8 amnt, u16 max) { sprt->posy-=amnt; sprt->aabb.min.y-=amnt; sprt->aabb.max.y-=amnt; + sprt->circle.position.y-=amnt; //sprt->direction=0; sprite_setrowcol(sprt); //uintToStr((sprt->posy),abuf,3); @@ -484,6 +616,7 @@ void sprite_down(spritedef *sprt, u8 amnt, u16 max) { sprt->posy+=amnt; sprt->aabb.min.y+=amnt; sprt->aabb.max.y+=amnt; + sprt->circle.position.y+=amnt; //sprt->direction=128; sprite_setrowcol(sprt); //uintToStr((sprt->posy),abuf,3); @@ -507,7 +640,7 @@ void animate_sprite(spritedef *sprt) { sprt->tile_attr = TILE_ATTR_FULL( sprt->pal, - 1,0,0, + 1,sprt->v_attr,sprt->h_attr, sprt->startaddr+(sprt->tilesize*(sprt->curstep % sprt->steps))); sprt->curstep++; } @@ -577,6 +710,8 @@ u8 add_sprite(spritedef* sprite) // Update link of last_idx _sprite_all[last_idx]->link = cur_idx; + //uintToStr(_sprite_count, abuf, 3); + //VDP_drawText(abuf, 5, 5); return cur_idx; } @@ -599,26 +734,103 @@ int drop_sprite(u8 del_idx) { //Found the item to delete _sprite_all[last_idx]->link = _sprite_all[idx]->link; + _sprite_count--; break; } } - _sprite_count--; + //uintToStr(_sprite_count, abuf, 3); + //VDP_drawText(abuf, 5, 5); return 0; } +void set_sprite_x(spritedef* sprite, u16 map_max_x) { + + if(sprite->circle.position.x < 0) { + sprite->circle.position.x = ((map_max_x) + sprite->circle.position.x + 1); + } else if (sprite->circle.position.x > map_max_x) { + sprite->circle.position.x = (sprite->circle.position.x - (map_max_x) - 1); + } + + if(sprite->aabb.min.x < 0) { + sprite->aabb.min.x = (map_max_x + sprite->aabb.min.x + 1); + } else if (sprite->aabb.min.x > map_max_x) { + sprite->aabb.min.x = (sprite->aabb.min.x - map_max_x - 1); + } + + if(sprite->aabb.max.x < 0) { + sprite->aabb.max.x = (map_max_x + sprite->aabb.max.x + 1); + } else if (sprite->aabb.max.x > map_max_x) { + sprite->aabb.max.x = (sprite->aabb.max.x - map_max_x - 1); + } +} + +void set_sprite_y(spritedef* sprite, u16 map_max_y) { + + if(sprite->circle.position.y < 0) { + sprite->circle.position.y = ((map_max_y) + sprite->circle.position.y + 1); + } else if (sprite->circle.position.y > map_max_y) { + sprite->circle.position.y = (sprite->circle.position.y - (map_max_y) - 1); + } + + if(sprite->aabb.min.y < 0) { + sprite->aabb.min.y = (map_max_y + sprite->aabb.min.y + 1); + } else if (sprite->aabb.min.y > map_max_y) { + sprite->aabb.min.y = (sprite->aabb.min.y - map_max_y - 1); + } + + if(sprite->aabb.max.y < 0) { + sprite->aabb.max.y = (map_max_y + sprite->aabb.max.y + 1); + } else if (sprite->aabb.max.y > map_max_y) { + sprite->aabb.max.y = (sprite->aabb.max.y - map_max_y) - 1; + } +} + void hscroll_sprites(s8 hscroll) { int cur_idx = 0; int next_idx = 0; + int y = 10; spritedef* tsprite; + u16 map_max_x = (fore_map->mapw * 8) - 1; + while(1) { // If the next link is 0, we are at the end tsprite = _sprite_all[cur_idx]; + + /* + if(hscroll > 0) { + sprite_right(tsprite, hscroll, 512); + } else { + sprite_left(tsprite, hscroll, 512); + }*/ + + + tsprite->posx += hscroll; + tsprite->aabb.min.x += hscroll; + tsprite->aabb.max.x += hscroll; + tsprite->circle.position.x += hscroll; sprite_setrowcol(tsprite); + set_sprite_x(tsprite, map_max_x); + + /* + VDP_drawText(" ", 20, y); + uintToStr(tsprite->circle.position.x, abuf, 5); + VDP_drawText(abuf, 20, y); + y+=1; + */ + + /* + if(hscroll > 0){ + sprite_right(tsprite, abs(hscroll), 512); + } else { + sprite_left(tsprite, hscroll, 512); + } + */ + //BLAST_setSpriteP( // cur_idx, // _sprite_all[cur_idx]); @@ -641,14 +853,28 @@ void vscroll_sprites(s8 vscroll) int cur_idx = 0; int next_idx = 0; spritedef* tsprite; + u16 map_max_y = (fore_map->maph * 8) - 1; while(1) { //VDP_drawTextBG(VDP_PLAN_A, "SCROLL", 0x8000, 4,4); // If the next link is 0, we are at the end tsprite = _sprite_all[cur_idx]; + + /* + if(vscroll > 0) { + sprite_down(tsprite, vscroll, 512); + } else { + sprite_up(tsprite, vscroll, 512); + } + */ tsprite->posy += vscroll; + tsprite->aabb.min.y += vscroll; + tsprite->aabb.max.y += vscroll; + tsprite->circle.position.y += vscroll; + set_sprite_y(tsprite, map_max_y); sprite_setrowcol(tsprite); + //BLAST_setSpriteP( // cur_idx, // _sprite_all[cur_idx]); @@ -662,96 +888,20 @@ void vscroll_sprites(s8 vscroll) next_idx = _sprite_all[cur_idx]->link; if(next_idx == 0) { + //uintToStr(cur_idx, abuf, 3); + //VDP_drawText(abuf, 12,12); break; } cur_idx = next_idx; } } - -void check_t_collision(u8* slist, u8 list_len, blastmap* map, void (*callback)(spritedef* sprt, u8 coll)) { - u8 i; - spritedef* sprt; - u8 coll = 0; - for(i=0;idirection) { - case 32: - if(check_up(map, sprt)) - sprt->direction = 64; - break; - case 96: - if(check_right(map, sprt)) - sprt->direction = 128; - break; - case 160: - if(check_down(map, sprt)) - sprt->direction = 192; - break; - case 224: - if(check_left(map, sprt)) - sprt->direction = 0; - break; - } - - switch(sprt->direction) { - case 224: - case 0: - coll |= check_up(map, sprt); - if(coll && sprt->direction == 224){ - sprt->direction = 192; - coll = 0; - } - break; - case 32: - // Already checked - //coll = check_up(map, sprt); - case 64: - coll |= check_right(map, sprt); - if(coll && sprt->direction == 32){ - sprt->direction = 0; - coll = 0; - } - break; - case 96: - //coll = check_right(map, sprt); - case 128: - coll |= check_down(map, sprt); - if(coll && sprt->direction == 96){ - sprt->direction = 64; - coll = 0; - } - break; - case 160: - //coll = check_down(map, sprt); - case 192: - coll |= check_left(map, sprt); - if(coll && sprt->direction == 160){ - sprt->direction = 128; - coll = 0; - } - break; - } - if(coll != 0) { - (*callback) (sprt, coll); - }*/ - } - -} - void do_noop(){ u8 dummy = 0; return; } void check_collision(u8* lista, u8 lista_len, u8* listb, u8 listb_len, void (*callback)(spritedef* sprta, spritedef* sprtb)){ - /* for sprite_a in lista: for sprite_b in listb: @@ -768,32 +918,38 @@ void check_collision(u8* lista, u8 lista_len, u8* listb, u8 listb_len, void (*ca u8 a_idx; u8 b_idx; - u8 a_row_idx; + +#ifdef COLCHECK u8 a_col_idx; u8 b_col_idx; - - u32 column_collision = 0; - u32 row_collision; +#endif + //u32 column_collision = 0; +#ifdef ROWCHECK + //u8 a_row_idx; + //u32 row_collision; +#endif spritedef* sprite_a; spritedef* sprite_b; - manifold* coll_manifold; #ifdef DEBUG - VDP_drawText(" ", 20,20); - VDP_drawText(" ", 20,21); + VDP_drawText(" ", 20,20); + VDP_drawText(" ", 20,21); #endif for(a_idx=0; a_idx < lista_len; a_idx++) { // For each sprite_a in lista sprite_a = _sprite_all[lista[a_idx]]; - +#ifdef ROWCHECK + /* if((sprite_a->row_mask & coll_row_mask) == 0) { // If not on a row with a collision, skip continue; } + */ +#endif #ifdef DEBUG // Row collision - VDP_drawText("Row Coll ", 20,20); + VDP_drawText("Row Coll", 20,20); #endif for(b_idx=0; b_idx < listb_len; b_idx++) { // For each sprite_b in listb @@ -803,12 +959,16 @@ void check_collision(u8* lista, u8 lista_len, u8* listb, u8 listb_len, void (*ca // Don't check sprite against itself! continue; } +#ifdef ROWCHECK + /* if((sprite_b->row_mask & coll_row_mask) == 0) { // If not on a row with a collision, skip continue; } - + */ +#endif +#ifdef COLCHECK for(a_col_idx=0; a_col_idx < MAX_SPRITE_COL; a_col_idx++) { // For each column of sprite_a // @@ -816,65 +976,93 @@ void check_collision(u8* lista, u8 lista_len, u8* listb, u8 listb_len, void (*ca // For each colum of spriteb if(sprite_a->columns[a_col_idx] == sprite_b->columns[b_col_idx]) { +#endif +#ifdef ROWCHECK + if(sprite_a->row_mask & sprite_b->row_mask == 0) { + continue; + } +#endif if(check_aabb(sprite_a->aabb, sprite_b->aabb)) { + //if(check_circle(sprite_a->circle, sprite_b->circle)) { // Collision! // Do a callback //column_collision += 1; //do_noop(); (*callback) (sprite_a, sprite_b); - //if(get_manifold(sprite_a, sprite_b, coll_manifold)) { - //sprite_bounce(sprite_a, sprite_b, coll_manifold); - //} + /*if(get_manifold(sprite_a, sprite_b, coll_manifold)) { + sprite_bounce(sprite_a, sprite_b, coll_manifold); + }*/ } +#ifdef COLCHECK } } } +#endif } } +#ifdef ROWCHECK // Clear collision mask - coll_row_mask = 0; + //coll_row_mask = 0; +#endif } void move_sprite(spritedef* sprt, blastmap* map, void (*callback)(spritedef* insprt, u8 coll)){ - if((sprt->velocity.x == 0) && (sprt->velocity.y == 0)) + s16 x; + s16 y; + u8 coll = 0; + + if(abs(sprt->velocity.x) < 64) { + sprt->r_vel.x += sprt->velocity.x; + x = abs(sprt->r_vel.x)>>6; + } else { + x = abs(sprt->velocity.x)>>6; + } + + if(abs(sprt->velocity.y) < 64) { + sprt->r_vel.y += sprt->velocity.y; + y = abs(sprt->r_vel.y)>>6; + } else { + y = abs(sprt->velocity.y)>>6; + } + + if((x == 0) & (y == 0)) return; - u8 coll = 0; - if(sprt->velocity.x>0) { + if((sprt->velocity.x > 0) || (sprt->r_vel.x > 0)) { + sprt->r_vel.x = 0; coll = check_right(map, sprt); if(coll == NOCOLL || coll == COLL_RIGHT) { - sprite_right(sprt, (sprt->velocity.x>>6), 512); - //sprt->velocity.x -= 1; + sprite_right(sprt, x, 512); } else { sprt->velocity.x *= -1; (*callback)(sprt, coll); } - } else if (sprt->velocity.x<0) { + } else { + sprt->r_vel.x = 0; coll = check_left(map, sprt); if(coll == NOCOLL || coll == COLL_LEFT) { - sprite_left(sprt, ((sprt->velocity.x*-1)>>6), 512); - //sprt->velocity.x += 1; + sprite_left(sprt, x, 512); } else { sprt->velocity.x *= -1; (*callback)(sprt, coll); } } - if(sprt->velocity.y<0) { + if((sprt->velocity.y < 0) || (sprt->r_vel.y < 0)) { + sprt->r_vel.y = 0; coll = check_up(map, sprt); if(coll == NOCOLL || coll == COLL_UP) { - sprite_up(sprt, (abs(sprt->velocity.y)>>6), 512); - //sprt->velocity.y -= 1; + sprite_up(sprt, y, 512); } else { sprt->velocity.y *= -1; (*callback)(sprt, coll); } - } else if (sprt->velocity.y>0) { + } else { + sprt->r_vel.y = 0; coll = check_down(map, sprt); if(coll == NOCOLL || coll == COLL_DOWN) { - sprite_down(sprt, (sprt->velocity.y>>6), 512); - sprt->velocity.y += 1; + sprite_down(sprt, y, 512); } else { sprt->velocity.y *= -1; (*callback)(sprt, coll); @@ -904,26 +1092,24 @@ void move_sprites(blastmap* map, void (*callback)(spritedef* sprt, u8 coll)) { } -void drag_sprites() { +void drag_sprites(u8 drag) { u8 cur_idx = 0; u8 next_idx = 0; spritedef* tsprite; - u8 drag = 1; - while(1) { tsprite = _sprite_all[cur_idx]; if(tsprite->velocity.x > 0) { - tsprite->velocity.x -= drag; + tsprite->velocity.x = max((tsprite->velocity.x - drag), 0); } else if (tsprite->velocity.x < 0) { - tsprite->velocity.x += drag; + tsprite->velocity.x = min((tsprite->velocity.x + drag), 0); } if(tsprite->velocity.y > 0) { - tsprite->velocity.y -= drag; + tsprite->velocity.y = max((tsprite->velocity.y - drag), 0); } else if (tsprite->velocity.y < 0) { - tsprite->velocity.y += drag; + tsprite->velocity.y = min((tsprite->velocity.y + drag), 0); } next_idx = tsprite->link; @@ -933,3 +1119,15 @@ void drag_sprites() { cur_idx = next_idx; } } + +void flip_sprite(spritedef* sprt, u8 h, u8 v) { + sprt->tile_attr = TILE_ATTR_FULL( + sprt->pal, + 1, + v, + h, + sprt->startaddr+(sprt->tilesize*(sprt->curstep % sprt->steps)) + ); + sprt->v_attr = v; + sprt->h_attr = h; +} diff --git a/libs/stack.c b/libs/stack.c new file mode 100644 index 0000000..29debbb --- /dev/null +++ b/libs/stack.c @@ -0,0 +1,106 @@ + +#ifdef TYPE + +#ifndef TYPED +#define TYPED(THING) THING +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/** + * The nodes in our stack. + */ +struct StackNode + { + TYPE val; // The value at the top of the stack + struct StackNode *next; // The rest of the values in the stack. + }; + +/** + * The stack itself. + */ +struct TYPED(Stack) + { + int size; // How many elements are in the stack? + struct StackNode *top; // What's at the top of the stack? + }; + +//Stack * +//stack_new (void) +TYPED(Stack)* TYPED(stack_new) (void) +{ + struct TYPED(Stack) *new_stack = (struct TYPED(Stack) *) MEM_alloc (sizeof (struct TYPED(Stack))); + new_stack->size = 0; + new_stack->top = NULL; + return new_stack; +} // stack_new + +//void +//stack_free (Stack *stack) +void TYPED(stack_free) (TYPED(Stack) *stack) +{ + // Free all the nodes in the stack + struct StackNode *tmp; + while ((tmp = stack->top) != NULL) + { + stack->top = tmp->next; + MEM_free (tmp); + } // while + // Free the stack itself + MEM_free (stack); +} // stack_free + +void TYPED(stack_to_list) (TYPED(Stack) *stack, TYPE* thislist) { + struct StackNode *tmp; + int i = 0; + while ((tmp = stack->top) != NULL) { + stack->top = tmp->next; + thislist[i] = tmp->val; + } // while +} + +//int +//stack_size (Stack *stack) +int TYPED(stack_size) (TYPED(Stack) *stack) +{ + return stack->size; +} // stack_size + +//int +//stack_top (Stack *stack) +TYPE TYPED(stack_top) (TYPED(Stack) *stack) +{ + return stack->top->val; +} // stack_top + +//int +//stack_pop (Stack *stack) +TYPE TYPED(stack_pop) (TYPED(Stack) *stack) +{ + // Remember the top node and its value + struct StackNode *tmp = stack->top; + int top = tmp->val; + // Drop that node + stack->top = stack->top->next; + MEM_free (tmp); + --stack->size; + // And return the saved value + return top; +} // stack_pop + +//void +//stack_push (Stack *stack, int val) +void TYPED(stack_push) (TYPED(Stack) *stack, TYPE val) +{ + struct StackNode *new_top = + (struct StackNode *) MEM_alloc (sizeof (struct StackNode)); + + new_top->val = val; + new_top->next = stack->top; + + stack->top = new_top; + stack->size++; +} // stack_push +#endif // TYPE diff --git a/libs/tilemap.c b/libs/tilemap.c index 62f4c93..b420a69 100644 --- a/libs/tilemap.c +++ b/libs/tilemap.c @@ -1,7 +1,7 @@ #include "genesis.h" #include "blast.h" -void blastmap_init(blastmap* bmap, tilemap* tmap, u16 tileoffset, VDPPlan plane) { +void blastmap_init(blastmap* bmap, tilemap* tmap, u16* tlookup, u16 tileoffset, VDPPlan plane) { bmap->tX = 64; bmap->tY = 64; bmap->winX = bmap->tX; @@ -13,6 +13,10 @@ void blastmap_init(blastmap* bmap, tilemap* tmap, u16 tileoffset, VDPPlan plane) bmap->tileoffset = tileoffset; bmap->plane = plane; bmap->tiles = tmap; + bmap->tlookup = tlookup; + + // Set the global foreground map + fore_map = bmap; } u8 check_up(blastmap* bmap, spritedef* sprite) { @@ -62,12 +66,12 @@ u8 check_col(blastmap* bmap, spritedef* sprite, u8 tile_row) { numcols++; } -#ifdef DEBUG +#ifdef DEBUG1 char str[10]; uintToStr(tile_col, str, 2); - //BMP_drawText(str, 0, 6); + VDP_drawText(str, 24, 16); uintToStr(tile_row, str, 2); - //BMP_drawText(str, 3, 6); + VDP_drawText(str, 24, 17); #endif coll = 0; @@ -77,8 +81,8 @@ u8 check_col(blastmap* bmap, spritedef* sprite, u8 tile_row) { tile_col = 0; } - tile = GET_TILE_XY(bmap, tile_col, tile_row); - coll |= bmap->tiles->coll[(tile-1)]; + tile = GET_COLL_XY(bmap, tile_col, tile_row); + coll |= bmap->tiles->coll[(tile-(bmap->tileoffset))]; } return coll; @@ -97,12 +101,12 @@ u8 check_row(blastmap* bmap, spritedef* sprite, u8 tile_col) { numrows++; } -#ifdef DEBUG +#ifdef DEBUG1 char str[10]; uintToStr(tile_col, str, 2); - //BMP_drawText(str, 0, 6); + VDP_drawText(str, 24, 16); uintToStr(tile_row, str, 2); - //BMP_drawText(str, 3, 6); + VDP_drawText(str, 24, 17); #endif coll = 0; @@ -112,9 +116,8 @@ u8 check_row(blastmap* bmap, spritedef* sprite, u8 tile_col) { tile_row = 0; } - tile = GET_TILE_XY(bmap, tile_col, tile_row); - coll |= bmap->tiles->coll[(tile-1)]; - + tile = GET_COLL_XY(bmap, tile_col, tile_row); + coll |= bmap->tiles->coll[(tile - (bmap->tileoffset))]; } return coll; @@ -152,11 +155,11 @@ u8 check_right(blastmap* bmap, spritedef* sprite) { void screen_left(blastmap* bmap, u16* hScroll) { if(*hScroll % 8 == 0) { - bmap->tX-=1; - bmap->winX-=1; + bmap->tX--; if(bmap->tX>=bmap->planwidth){ bmap->tX = bmap->planwidth - 1; } + bmap->winX--; if(bmap->winX>=bmap->mapw) { bmap->winX = bmap->mapw - 1; } @@ -168,11 +171,11 @@ void screen_left(blastmap* bmap, u16* hScroll) { void screen_right(blastmap* bmap, u16* hScroll) { *hScroll-=1; if(*hScroll % 8 == 0) { - bmap->tX+=1; - bmap->winX+=1; + bmap->tX++; if(bmap->tX>=bmap->planwidth){ bmap->tX = 0; } + bmap->winX++; if(bmap->winX>=bmap->mapw) { bmap->winX = 0; } @@ -185,11 +188,11 @@ void screen_up(blastmap* bmap, u16* vScroll) { // Check only on tile boundaries if(*vScroll % 8 == 0) { - bmap->tY-=1; - bmap->winY-=1; + bmap->tY--; if(bmap->tY>=bmap->planheight){ bmap->tY = bmap->planheight - 1; } + bmap->winY--; if(bmap->winY>=bmap->maph){ bmap->winY = bmap->maph - 1; } @@ -201,11 +204,11 @@ void screen_up(blastmap* bmap, u16* vScroll) { void screen_down(blastmap* bmap, u16* vScroll) { *vScroll+=1; if(*vScroll % 8 == 0) { - bmap->tY+=1; - bmap->winY+=1; + bmap->tY++; if(bmap->tY>=bmap->planheight){ bmap->tY = 0; } + bmap->winY++; if(bmap->winY>=bmap->maph){ bmap->winY = 0; } @@ -217,35 +220,54 @@ void screen_down(blastmap* bmap, u16* vScroll) { void center_screen(blastmap* bmap, u16 sprite_idx, u16* hscroll, u16* vscroll) { spritedef *tsprite; tsprite = _sprite_all[sprite_idx]; - - u8 scroll_factor = 1; + + //(((a)>(b))?(a):(b)) + //u8 velmax = (abs(tsprite->velocity.x)>abs(tsprite->velocity.y))?abs(tsprite->velocity.x):abs(tsprite->velocity.y); + + //u8 scroll_factor = ((velmax/32)>0)?(velmax/32):1; + u8 i; + u8 scroll_factor; + //u8 scroll_factor = 1; //128x104 // Center the screen - if(tsprite->posy > 124) { - //tsprite->posy -= ship->speed; + if(tsprite->circle.position.y > 124) { + scroll_factor = (tsprite->circle.position.y - 104)>>3; + //tsprite->circle.position.y -= ship->speed; vscroll_sprites(-scroll_factor); - screen_down(bmap,vscroll); + for(i=0;ispeed == 2) // screen_down(&backgroundmap,&vScroll); - } else if (tsprite->posy < 84) { - //tsprite->posy += ship->speed; + } else if (tsprite->circle.position.y < 84) { + scroll_factor = (104 - tsprite->circle.position.y)>>3; + //tsprite->circle.position.y += ship->speed; vscroll_sprites(scroll_factor); - screen_up(bmap,vscroll); + for(i=0;ispeed == 2) // screen_up(&backgroundmap,&vScroll); } - if(tsprite->posx > 148){ - //tsprite->posx -= ship->speed; + if(tsprite->circle.position.x > 148){ + scroll_factor = (tsprite->circle.position.x - 128)>>4; + + //tsprite->circle.position.x -= ship->speed; hscroll_sprites(-scroll_factor); - screen_right(bmap,hscroll); + for(i=0;ispeed == 2) // screen_right(&backgroundmap,&hScroll); - } else if(tsprite->posx < 108) { - //tsprite->posx += ship->speed; + } else if(tsprite->circle.position.x < 108) { + scroll_factor = (128 - tsprite->circle.position.x)>>4; + //tsprite->circle.position.x += ship->speed; hscroll_sprites(scroll_factor); - screen_left(bmap,hscroll); + for(i=0;ispeed == 2) // screen_left(&backgroundmap,&hScroll); } @@ -296,6 +318,45 @@ void load_map(blastmap* bmap, int xoffset, int yoffset) { } } +#define BITMAPTILE +void set_tile(blastmap* map, u16 mapx, u16 mapy, u16 screenx, u16 screeny) { +#ifdef BITMAPTILE + VDP_setTileMapXY( + map->plane, + TILE_ATTR_FULL( + PAL0, + TRUE, + FALSE, + FALSE, + (u16*)GET_TILE_XY(map, mapx, mapy)), + //(u16*)(bmap->tiles->data[(iW * (bmap->mapw)) + jW]) + bmap->tileoffset - 1, + /*(u16*)( bmap->tiles->data[ + ( iW * (bmap->mapw)) + jW + ] + + bmap->tileoffset - 1)),*/ + screenx, + screeny + ); +#else + + char str[10]; + //u16 tile_in_map = (u16*)GET_TILE_XY(map, mapx, mapy); + //u16 tile_in_map = (u16*)((map->tiles->data[(mapy * (map->mapw)) + mapx]) - 1); + //u16 converted_tile = (map->tlookup[tile_in_map]) + map->tileoffset; + + u16 converted_tile = (u16*)(map->tlookup[((map->tiles->data[(mapy * (map->mapw)) + mapx]) - 1)] + map->tileoffset); + + uintToStr(converted_tile,str,3); + VDP_drawText(str, 3, 3); + VDP_setTileMapXY( + map->plane, + converted_tile, + screenx, + screeny + ); +#endif +} + void load_visible_map(blastmap* bmap, int xoffset, int yoffset) { /* * load_visible_map @@ -339,13 +400,7 @@ void load_visible_map(blastmap* bmap, int xoffset, int yoffset) { if(jW == bmap->mapw) { jW = 0; } - VDP_setTileMapXY( - bmap->plane, - //(u16*)(bmap->tiles->data[(iW * (bmap->mapw)) + jW]) + bmap->tileoffset - 1, - (u16*)GET_TILE_XY(bmap, jW, iW), - j, - i - ); + set_tile(bmap, jW, iW, j, i); j++; jW++; } diff --git a/libs/u8_stack.c b/libs/u8_stack.c new file mode 100644 index 0000000..dcff536 --- /dev/null +++ b/libs/u8_stack.c @@ -0,0 +1,2 @@ +#include "u8_stack.h" +#include "stack.c" diff --git a/tools/gen_tables.py b/tools/gen_tables.py index 27b5b8a..dd6aa61 100644 --- a/tools/gen_tables.py +++ b/tools/gen_tables.py @@ -5,7 +5,11 @@ if __name__ == "__main__": sint=[ int(round(math.sin(math.radians(i*1.40625))*64)) for i in range(256) ] cost=[ int(round(math.cos(math.radians(i*1.40625))*64)) for i in range(256) ] + #atant=[int(math.degrees(math.atan(float(i)/32))) for i in range(33)] + atant=[int(math.degrees(math.atan(float(i)/16.0))/1.40625) for i in range(17)] + sqrts = [ int(round(math.sqrt(i)*16)) for i in range(256) ] + print('#include "blast.h"') print("const s8 sin_table[%s] = {" % len(sint)) for i in range(0, len(sint), 16): print(" %s," % ",".join([str(j) for j in sint[i:i+16]])) @@ -15,3 +19,14 @@ for i in range(0, len(cost), 16): print(" %s," % ",".join([str(j) for j in cost[i:i+16]])) print("};\n\n") + + print("const u8 atan_table[%s] = {" % len(atant)) + for i in range(0, len(atant), 16): + print(" %s," % ",".join([str(j) for j in atant[i:i+16]])) + print("};\n\n") + + print("const u8 sqrt_table[%s] = {" % len(sqrts)) + for i in range(0, len(sqrts), 16): + print(" %s," % ",".join([str(j) for j in sqrts[i:i+16]])) + print("};\n\n") + diff --git a/tools/png2bmp.sh b/tools/png2bmp.sh old mode 100644 new mode 100755 index 9e660ae..e03634a --- a/tools/png2bmp.sh +++ b/tools/png2bmp.sh @@ -1 +1,7 @@ -convert terrain_test.png -type palette -remap BMP3:palette0.bmp -depth 4 -colors 16 BMP3:terrain1.bmp +#!/bin/bash + +INIMG=${1:?} +OUTIMG=${2:?} +PALIMG=${3:-$INIMG} + +convert $INIMG -type palette -remap BMP3:$PALIMG -depth 4 -colors 16 BMP3:$OUTIMG diff --git a/tools/tiled2c.py b/tools/tiled2c.py index 19e964a..31d624b 100755 --- a/tools/tiled2c.py +++ b/tools/tiled2c.py @@ -1,6 +1,71 @@ #!/usr/bin/env python import argparse import json +import xmltodict +import base64 +import zlib +import struct +import pprint + +class TiledData(object): + + def __init__(self, filename): + with open(filename) as h: + data = h.read() + + tile_data = xmltodict.parse(data) + + self.parsed_data = {k.lstrip('@'):v for k,v in tile_data.get('map').items()} + self.parsed_data['tilesets'] = [] + self.parsed_data['layers'] = [] + + self.parse_tilesets(tile_data.get('map').get('tileset')) + self.parse_layers(tile_data.get('map').get('layer')) + + + def parse_tilesets(self, tileset_data): + tempset = {k.lstrip('@'):v for k,v in tileset_data.items()} + tempset['image'] = {k.lstrip('@'):v for k,v in tileset_data.get('image', {}).items()} + tileprops = { + x.get('@id'):{x.get('properties').get('property').get('@name'):x.get('properties').get('property').get('@value')} + for x in tileset_data.get('tile',{}) + } + tempset['tileproperties'] = tileprops + self.parsed_data['tilesets'].append(tempset) + + + def parse_layers(self, layer_data): + tempset = {k.lstrip('@'):v for k,v in layer_data.items()} + layerdata = layer_data.get('data') + rawdata = layerdata.get('#text') + encoding = layerdata.get('@encoding') + compression = layerdata.get('@compression') + + if encoding == 'base64': + decoded = base64.b64decode(rawdata) + elif encoding == 'csv': + decoded = rawdata.split(',') + else: + decoded = [x.get('@gid') for x in layerdata.get('tile')] + + if compression == 'zlib': + decompressed = zlib.decompress(decoded) + else: + decompressed = decoded + + if encoding == 'base64': + tilesize = struct.calcsize('