From 41765ea063cbab26ae05e7259ffc8a7c85db2f5d Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sun, 7 Aug 2022 20:12:06 +0300 Subject: [PATCH] foo --- Makefile | 2 +- src/gamescr.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++--------- src/level.c | 76 ++++++++++++++++++++++++++++++++++++++ src/level.h | 49 +++++++++++++++++++++++++ src/util.c | 53 +++++++++++++++++++++++++++ src/util.h | 16 ++++++++ 6 files changed, 292 insertions(+), 18 deletions(-) create mode 100644 src/level.c create mode 100644 src/level.h diff --git a/Makefile b/Makefile index db4dd95..e61b6b9 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ inc = -I. -Ilibs/maxmod CFLAGS = $(opt) $(dbg) -pedantic -Wall -MMD $(def) $(inc) ASFLAGS = -mthumb-interwork -LDFLAGS = -mthumb -mthumb-interwork $(libs) +LDFLAGS = -mthumb -mthumb-interwork $(libs) -lm -include cfg.mk diff --git a/src/gamescr.c b/src/gamescr.c index cacb40d..3b15a4a 100644 --- a/src/gamescr.c +++ b/src/gamescr.c @@ -8,25 +8,82 @@ #include "input.h" #include "sprite.h" #include "debug.h" +#include "level.h" +#include "xgl.h" +#include "polyfill.h" +static void update(void); static void draw(void); static void vblank(void); static int nframes, num_vbl, backbuf; static uint16_t *vram[] = { (uint16_t*)VRAM_LFB_FB0_ADDR, (uint16_t*)VRAM_LFB_FB1_ADDR }; -static uint16_t bnstate; +static const char *testlvl = + "########\n" + "### s#\n" + "### ####\n" + "### #\n" + "## #\n" + "## #\n" + "## #\n" + "## ### #\n" + "## ### #\n" + "## #\n" + "#### ###\n" + "########\n"; + +static struct xvertex cube[] __attribute__((section(".rodata"))) = { + /* front */ + {-0x10000, -0x10000, -0x10000, 0, 0, -0x10000, 255}, + {0x10000, -0x10000, -0x10000, 0, 0, -0x10000, 255}, + {0x10000, 0x10000, -0x10000, 0, 0, -0x10000, 255}, + {-0x10000, 0x10000, -0x10000, 0, 0, -0x10000, 255}, + /* right */ + {0x10000, -0x10000, -0x10000, 0x10000, 0, 0, 128}, + {0x10000, -0x10000, 0x10000, 0x10000, 0, 0, 128}, + {0x10000, 0x10000, 0x10000, 0x10000, 0, 0, 128}, + {0x10000, 0x10000, -0x10000, 0x10000, 0, 0, 128}, + /* back */ + {0x10000, -0x10000, 0x10000, 0, 0, 0x10000, 200}, + {-0x10000, -0x10000, 0x10000, 0, 0, 0x10000, 200}, + {-0x10000, 0x10000, 0x10000, 0, 0, 0x10000, 200}, + {0x10000, 0x10000, 0x10000, 0, 0, 0x10000, 200}, + /* left */ + {-0x10000, -0x10000, 0x10000, -0x10000, 0, 0, 192}, + {-0x10000, -0x10000, -0x10000, -0x10000, 0, 0, 192}, + {-0x10000, 0x10000, -0x10000, -0x10000, 0, 0, 192}, + {-0x10000, 0x10000, 0x10000, -0x10000, 0, 0, 192}, + /* top */ + {-0x10000, 0x10000, -0x10000, 0, 0x10000, 0, 150}, + {0x10000, 0x10000, -0x10000, 0, 0x10000, 0, 150}, + {0x10000, 0x10000, 0x10000, 0, 0x10000, 0, 150}, + {-0x10000, 0x10000, 0x10000, 0, 0x10000, 0, 150}, + /* bottom */ + {0x10000, -0x10000, -0x10000, 0, -0x10000, 0, 210}, + {-0x10000, -0x10000, -0x10000, 0, -0x10000, 0, 210}, + {-0x10000, -0x10000, 0x10000, 0, -0x10000, 0, 210}, + {0x10000, -0x10000, 0x10000, 0, -0x10000, 0, 210} +}; + + +static struct level *lvl; + +static int32_t cam_theta, cam_phi; void gamescr(void) { - int i; + unsigned char *fb; REG_DISPCNT = 4 | DISPCNT_BG2 | DISPCNT_OBJ | DISPCNT_FB1; - vblperf_setcolor(0xff);//192); + vblperf_setcolor(0xff); + + lvl = init_level(testlvl); - fillblock_16byte(vram[0], 0xffffffff, 240 * 160 / 16); - fillblock_16byte(vram[1], 0xffffffff, 240 * 160 / 16); + xgl_init(); + + select_input(BN_DPAD); mask(INTR_VBLANK); screen_vblank = vblank; @@ -35,9 +92,12 @@ void gamescr(void) nframes = 0; for(;;) { backbuf = ++nframes & 1; + fb = (unsigned char*)vram[backbuf]; - bnstate = ~REG_KEYINPUT; + polyfill_framebuffer(fb, 240, 160); + fillblock_16byte(fb, 0, 240 * 160 / 16); + update(); draw(); vblperf_end(); @@ -47,19 +107,39 @@ void gamescr(void) } } -static void draw(void) +static void update(void) { - int i, j; - uint16_t pix; - uint16_t *fb = vram[backbuf]; - - for(i=0; i<160; i++) { - for(j=0; j<240/2; j++) { - pix = ((i^j) << 1) & 0xff; - pix |= (i^j) << 9; - *fb++ = pix; - } + uint16_t bnstate; + + bnstate = get_input(); + + if(bnstate & KEY_UP) { + cam_phi += 0x2000; + if(cam_phi > X_HPI) cam_phi = X_HPI; } + if(bnstate & KEY_DOWN) { + cam_phi -= 0x2000; + if(cam_phi < -X_HPI) cam_phi = -X_HPI; + } + if(bnstate & KEY_LEFT) { + cam_theta += 0x2000; + if(cam_theta > X_2PI) cam_theta -= X_2PI; + } + if(bnstate & KEY_RIGHT) { + cam_theta -= 0x2000; + if(cam_theta < X_2PI) cam_theta += X_2PI; + } +} + +static void draw(void) +{ + xgl_load_identity(); + //xgl_translate(0, -0x50000, 0); + xgl_translate(0, 0, 0x80000); + xgl_rotate_x(cam_phi); + xgl_rotate_y(cam_theta); + + xgl_draw(XGL_QUADS, cube, sizeof cube / sizeof *cube); } __attribute__((noinline, target("arm"), section(".iwram"))) diff --git a/src/level.c b/src/level.c new file mode 100644 index 0000000..dfe3475 --- /dev/null +++ b/src/level.c @@ -0,0 +1,76 @@ +#include "util.h" +#include "debug.h" +#include "level.h" + +struct level *init_level(const char *descstr) +{ + const char *str, *line; + int i, j, ncols = 0, nrows = 0; + struct level *lvl; + struct cell *cell; + + str = line = descstr; + + while(*str) { + if(*str == '\n') { + if(ncols > 0 && str > line && str - line != ncols) { + panic(get_pc(), "init_level: inconsistent ncols (%d != %d)\n", str - line, ncols); + } + ncols = str - line; + nrows++; + while(*++str == '\n'); + line = str; + } else { + str++; + } + } + + if(!ispow2(ncols)) { + panic(get_pc(), "init_level: width is not pow2 (%d)\n", ncols); + } + + lvl = malloc_nf(sizeof *lvl); + lvl->width = ncols; + lvl->xmask = ncols - 1; + lvl->height = nrows; + lvl->cells = calloc_nf(ncols * nrows, sizeof *lvl->cells); + lvl->mobs = 0; + lvl->items = 0; + + str = descstr; + cell = lvl->cells; + + for(i=0; ix = j; + cell->y = i; + if(*str == '#') { + cell->type = CELL_SOLID; + } else { + cell->type = CELL_WALK; + } + cell++; + while(*++str == '\n') str++; + } + } + + return lvl; +} + +void free_level(struct level *lvl) +{ + void *tmp; + + free(lvl->cells); + + while(lvl->mobs) { + tmp = lvl->mobs; + lvl->mobs = lvl->mobs->next; + free(tmp); + } + while(lvl->items) { + tmp = lvl->items; + lvl->items = lvl->items->next; + free(tmp); + } +} diff --git a/src/level.h b/src/level.h new file mode 100644 index 0000000..0bcf578 --- /dev/null +++ b/src/level.h @@ -0,0 +1,49 @@ +#ifndef LEVEL_H_ +#define LEVEL_H_ + +#include + +enum { MOBS_DEAD, MOBS_IDLE, MOBS_ENGAGE, MOBS_RUN }; + +struct mob { + uint8_t type; + uint8_t x, y; + uint8_t state; + struct mob *next; + struct mob *cellnext; + + void (*update)(void); +}; + +struct item { + uint8_t type; + uint8_t x, y; + uint8_t pad; + struct item *next; + struct item *cellnext; +}; + +enum { CELL_SOLID, CELL_WALK }; + +struct cell { + uint8_t type; + uint8_t x, y; + uint8_t pad; + struct mob *mobs; + struct item *items; +}; + +struct level { + int width, height; + unsigned int xmask; + struct cell *cells; + + struct mob *mobs; + struct item *items; +}; + + +struct level *init_level(const char *descstr); +void free_level(struct level *lvl); + +#endif /* LEVEL_H_ */ diff --git a/src/util.c b/src/util.c index 9bba42f..c734f85 100644 --- a/src/util.c +++ b/src/util.c @@ -1,3 +1,5 @@ +#include +#include #include "util.h" #include "debug.h" @@ -23,3 +25,54 @@ void *iwram_sbrk(intptr_t delta) iwram_brk(top + delta); return prev; } + +int ispow2(unsigned int x) +{ + int cnt = 0; + while(x) { + if(x & 1) cnt++; + x >>= 1; + } + return cnt == 1; +} + + + +void *malloc_nf_impl(size_t sz, const char *file, int line) +{ + void *p; + if(!(p = malloc(sz))) { + panic(get_pc(), "%s:%d malloc %lu\n", file, line, (unsigned long)sz); + } + return p; +} + +void *calloc_nf_impl(size_t num, size_t sz, const char *file, int line) +{ + void *p; + if(!(p = calloc(num, sz))) { + panic(get_pc(), "%s:%d calloc %lu\n", file, line, (unsigned long)(num * sz)); + } + return p; +} + +void *realloc_nf_impl(void *p, size_t sz, const char *file, int line) +{ + if(!(p = realloc(p, sz))) { + panic(get_pc(), "%s:%d realloc %lu\n", file, line, (unsigned long)sz); + } + return p; +} + +char *strdup_nf_impl(const char *s, const char *file, int line) +{ + int len; + char *res; + + len = strlen(s); + if(!(res = malloc(len + 1))) { + panic(get_pc(), "%s:%d strdup\n", file, line); + } + memcpy(res, s, len + 1); + return res; +} diff --git a/src/util.h b/src/util.h index 789e63e..18c513e 100644 --- a/src/util.h +++ b/src/util.h @@ -1,6 +1,7 @@ #ifndef UTIL_H_ #define UTIL_H_ +#include #include #define wait_vblank() \ @@ -33,4 +34,19 @@ void fillblock_16byte(void *dest, uint32_t val, int count); void *get_pc(void); void *get_sp(void); +int ispow2(unsigned int x); + +/* Non-failing versions of malloc/calloc/realloc. They never return 0, they call + * demo_abort on failure. Use the macros, don't call the *_impl functions. + */ +#define malloc_nf(sz) malloc_nf_impl(sz, __FILE__, __LINE__) +void *malloc_nf_impl(size_t sz, const char *file, int line); +#define calloc_nf(n, sz) calloc_nf_impl(n, sz, __FILE__, __LINE__) +void *calloc_nf_impl(size_t num, size_t sz, const char *file, int line); +#define realloc_nf(p, sz) realloc_nf_impl(p, sz, __FILE__, __LINE__) +void *realloc_nf_impl(void *p, size_t sz, const char *file, int line); +#define strdup_nf(s) strdup_nf_impl(s, __FILE__, __LINE__) +char *strdup_nf_impl(const char *s, const char *file, int line); + + #endif /* UTIL_H_ */ -- 1.7.10.4