From 85c8e5ce958cd64ce6cb15be150b98b6102cb705 Mon Sep 17 00:00:00 2001 From: EvanR Date: Sat, 8 May 2010 21:10:49 -0500 Subject: [PATCH] Rewrite of the stage module. This changes the format of the game somewhat. While the stage basically is the same as it was superficially, the world no longer consists of seamlessly linked zones. Instead you pass from stage to stage via doors or other transistion mechanisms, and when you beat the boss you go to a new zone completely. I was having a hard time so I decided to simplify rather than continue to agonize over what seemed like an overly complex and unsuitable for implementation in C problem. The inspiration for the new way is from lynx game gates of zendocon. Rather than progress directly from level to level, there are secret bosses and secret levels which may progress back to the main line. The main format for the game play, and the dialog based plot has not been changed. --- Makefile | 3 +- audio.c | 9 + graphics.c | 16 +- graphics.h | 1 - inner.c | 65 ++--- input.c | 13 + loader.c | 4 +- loader.h | 1 + stage.c | 939 +++++++++++++++++-------------------------------------------- stage.h | 20 +- synth.c | 9 + util.c | 8 + util.h | 2 + video.c | 16 ++ zip.c | 17 ++ 15 files changed, 379 insertions(+), 744 deletions(-) rewrite stage.c (86%) diff --git a/Makefile b/Makefile index ab3c8e4..96333f4 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,8 @@ SRC=video.c audio.c input.c kernel.c main.c gameover.c \ loader.c graphics.c sfx.c text.c console.c music.c stage.c \ intro.c title.c splash.c inner.c \ synth.c seq.c midi.c orc.c dsp.c \ - rng.c util.c list.c zip.c + rng.c util.c list.c zip.c \ + hud.c camera.c OBJ:=$(SRC:.c=.o) CC=gcc LIBS=-lSDL -lGL -lm -lz diff --git a/audio.c b/audio.c index 07b82c9..2855d1d 100644 --- a/audio.c +++ b/audio.c @@ -20,6 +20,15 @@ Boston, MA 02110-1301, USA */ +/* +audio module is the low level audio output support. +the audio thread operates independently of the rest of the +game and is backwards from the rest of the modules. After +initializing the audio system, it will periodically use a +callback to generate needed audio output. This callback is +basically defined in synth.c which mixes music and sound. +*/ + #include #include diff --git a/graphics.c b/graphics.c index 71a3091..5d62742 100644 --- a/graphics.c +++ b/graphics.c @@ -37,7 +37,7 @@ #include #include #include - +#include /* graphics data */ @@ -55,11 +55,6 @@ int stage_enabled = 0; -struct { - int x, y; -} camera; - - void graphics_init(){ int i; minifont_gfx = load_gfx("smallfont.tga"); @@ -72,8 +67,8 @@ void graphics_init(){ /* drawing */ void draw_sprite(sprite* spr){ - int x = spr->x - camera.x; - int y = spr->y - camera.y; + int x = spr->x - camera_x(); + int y = spr->y - camera_y(); int W = spr->w; int H = spr->h; int X = spr->frame.x; @@ -157,11 +152,6 @@ void draw_final(){ -void point_camera(int x, int y){ - camera.x = x; - camera.y = y; -} - void animate_sprite(int i){ diff --git a/graphics.h b/graphics.h index 7647954..9dc7aa0 100644 --- a/graphics.h +++ b/graphics.h @@ -61,7 +61,6 @@ void draw_bitmap(int id, int x, int y); sprite* enable_sprite(int sprnum); void disable_sprite(sprite* spr); sprite* copy_sprite(sprite* spr); -void point_camera(int x, int y); void draw_small_text(char* str, int x, int y); void printf_small(int x, int y, char* format, ...); diff --git a/inner.c b/inner.c index 33329cd..2d52723 100644 --- a/inner.c +++ b/inner.c @@ -15,45 +15,25 @@ #include #include +#include +#include -//int run(Y* y, int dt){ -/* - motion move = get(y->pc); - int passed = move(y->m, dt); - if(passed < dt){ - advance(y); - return passed; -*/ -//return dt; -//} -/* -void move(Y* y){ - int t = QUANTUM; - while(t > 0){ - int dt = QUANTUM; - dt = run(y, dt); - t -= dt; - //collision here - } -} -*/ -/* -void show(Y* y){ - y->draw(y); -} -*/ static void update(){ -/* list* ents = get_active_entities(); - foreach(ents, move);*/ + /* + update camera + update every entity in the update list + dispatch collision events + execute spawn and delete events + */ } static void draw(){ - //int x = camera_x(); - //int y = camera_y(); - //int w = screen_w(); - //int h = screen_h(); -/* list* ents = find_entities_in(x,y,w,h); - foreach(ents, show);*/ + int cx = camera_x(); + int cy = camera_y(); + //stage_draw_bg(cx, cy); + //entity_draw_visible(cx, cy); + //stage_draw_fg(cx, cy); + hud_draw(cx, cy); } static void press(input in){ @@ -62,30 +42,35 @@ static void press(input in){ return; } printf("press: %s\n", input_str(in)); - /* -check global keys -do player specific side effects + /* + send input events */ } static void release(input in){ printf("release: %s\n", input_str(in)); + + /* + send input events + */ } void setup_inner(){ - // create entities + /* create entities */ console_clear(); set_handler(update, draw, press, release); - int x = load_zone("2zone"); + unload_zone(); + int x = load_zone("3ztest/"); if(x < 0){ error_msg("inner: cannot load zone\n"); exit(-1); } else{ - print_zone(x); + //print_zone(x); + unload_zone(); } diff --git a/input.c b/input.c index 62e9386..875f4f9 100644 --- a/input.c +++ b/input.c @@ -21,6 +21,19 @@ evanrinehart@gmail.com */ + + +/* +the input module is an interface to the low level input system +plus a mapper from low level input events to abstract game inputs. +it has several functions: +* generate the next available input, if possible +* save and load input maps +* remap abstract event to last low level event +* convert abstract input to string form +*/ + + #include diff --git a/loader.c b/loader.c index 973fc39..489901f 100644 --- a/loader.c +++ b/loader.c @@ -169,7 +169,9 @@ int loader_scanline(reader* rd, char* format, ...){ return ret; } - +int loader_feof(reader* rd){ + return zip_feof(rd->f); +} /*binary i/o*/ diff --git a/loader.h b/loader.h index 3319a06..131399f 100644 --- a/loader.h +++ b/loader.h @@ -30,6 +30,7 @@ int loader_readline(reader* rd, char* buf, int size); int loader_scanline(reader* rd, char* format, ...); unsigned char* loader_readall(char* filename, int* size); void loader_close(reader* rd); +int loader_feof(reader* rd); list* loader_readdir(char* path); void loader_freedirlist(list* dirs); diff --git a/stage.c b/stage.c dissimilarity index 86% index ae438ad..fba7548 100644 --- a/stage.c +++ b/stage.c @@ -1,678 +1,261 @@ -/* - Cantaveria - action adventure platform game - Copyright (C) 2009 2010 Evan Rinehart - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to - - The Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor - Boston, MA 02110-1301, USA -*/ - - -#include -#include -#include - -#include -#include -#include -#include - -#include - -enum cardinal {NORTH, SOUTH, EAST, WEST}; - - -enum tile_shape { -SHAPE_FREE, -SHAPE_SQUARE, -SHAPE_NULL, - -SHAPE_TRI_NE, -SHAPE_TRI_NW, -SHAPE_TRI_SE, -SHAPE_TRI_SW, - -SHAPE_LTRAP_FLOOR, -SHAPE_RTRAP_FLOOR, -SHAPE_LSLOPE_FLOOR, -SHAPE_RSLOPE_FLOOR, -SHAPE_LTRAP_CEIL, -SHAPE_RTRAP_CEIL, -SHAPE_LSLOPE_CEIL, -SHAPE_RSLOPE_CEIL, - -SHAPE_HALF_FLOOR, -SHAPE_HALF_CEIL -}; - -typedef struct { - int tile; - int i, j; -} decoration; - -typedef struct { - int zone; - int i, j; - enum cardinal dir; -} zoneport; - -typedef struct { - int i, j; - int w, h; - int flags; -} water; - -typedef struct { - int zid; - int i, j; - char fg[20][15]; - char bg[20][15]; - list* decs; - list* waters; - char snap[4]; - zoneport* exit; -} stage; - -typedef struct { - int id; - char name[32]; - int w, h, i, j; - int fgtiles; - int bgtiles; - int dectiles; - int bgimage; - enum tile_shape shapes[256]; - stage** stages; // w by h array -} zone; - -/* -how the above is stored in a binary file -string z->name -byte[256] z->shapes -short[4] z->{i, j, w, h} -short [number of stages N] -[N of the following - short[2] s->{i, j} - byte unknown - string[4] exits - byte[20x15] s->fg -] - -new version -byte[4] 0x0a 0x0b 0x0c 0x0d -int format version (1) -int z->id -short[4] z->{i, j, w, h} -string fgtiles file -string bgtiles file -string dectiles file -string bgimage file -byte[256] z->shapes -short number of stages N -[N of the following - short[2] s->{i, j} - byte[4] s->snap - byte[4] 'exit' or 'none' - a zone port is next if previous was 'exit' - string zone - short[2] i, j - byte 'L' 'U' 'D' or 'R' - short number of decorations M - [M of the following - short[2] i, j - short tile - ] - short number of waters W - [W of the following - short[4] i, j, w, h - int flags - ] - byte[20x15] fg - byte[20x15] bg -] -*/ - -typedef struct { - int x, y; - int shape; - int none; -} block; - - - - -/* VVV */ -list* zones = NULL; -/* ^^^ */ - - - -enum cardinal dir_of(int i, int j){ - if(i < 0) return WEST; - if(j < 0) return NORTH; - if(i > 0) return EAST; - if(j > 0) return SOUTH; - fatal_error("stage.c: (%d,%d) is not a valid direction\n", i, j); - return NORTH; -} - - - - - -/* zones and stages */ -zone* find_zone_by_id(int id){ - list* ptr = zones->next; - while(ptr){ - zone* z = ptr->item; - if(z->id == id) return z; - ptr = ptr->next; - } - return NULL; -} - -zone* zone_of_stage(stage* s){ - return find_zone_by_id(s->zid); -} - -stage* stage_lookup(zone* z, int i, int j){ - if(i < 0 || i >= z->w || j < 0 || j >= z->h){ - return NULL; - } - return *(z->stages + i + j*z->w); -} - - -stage* follow_zoneport(zoneport* zp){ - zone* z = find_zone_by_id(zp->zone); - return stage_lookup(z, zp->i, zp->j); -} - -stage* find_stage(stage* home, int i, int j){ - zone* z = zone_of_stage(home); - int si = i/20; - int sj = j/15; - int di = home->i - si; - int dj = home->j - sj; - if(di==0 && dj==0) - return home; - - else if(home->exit && home->exit->dir == dir_of(di,dj)) - return follow_zoneport(home->exit); - - else - return stage_lookup(z, si - z->w, sj - z->h); -} - - - -/* collision computations */ -/*FIXME*/ -int left_side_of(block bl, int top, int bottom){ - return bl.x; -} - -int right_side_of(block bl, int top, int bottom){ - return bl.x + 16; -} - -int top_of(block bl, int left, int right){ - return bl.y; -} - -int bottom_of(block bl, int left, int right){ - return bl.y + 16; -} - -int xhit(int v, block block, int top, int bottom){ - if(v > 0) return left_side_of(block, top, bottom); - if(v < 0) return right_side_of(block, top, bottom); - return 0; -} - -int yhit(int v, block block, int left, int right){ - if(v > 0) return top_of(block, left, right); - if(v < 0) return bottom_of(block, left, right); - return 0; -} - -int rect_is_on(block bl, int L, int R, int T, int B){ - int l = bl.x; - int r = bl.x + 16; - int t = bl.y; - int b = bl.y + 16; - return !(r < L || l > R || t > B || b < T); -} - - - - - -/* blocks */ -block make_block(int shape, int x, int y, int none){ - block bl; - bl.x = x; - bl.y = y; - bl.none = none; - bl.shape = shape; - return bl; -} - -block no_block(){ - return make_block(0, 0, 0, 1); -} - -block null_block(){ - return make_block(SHAPE_NULL, 0, 0, 0); -} - -block block_of(int shape, int x, int y){ - return make_block(shape, x, y, 0); -} - -/* get block in s at i j */ -block block_from_stage(stage* s, int i, int j){ - zone* z = zone_of_stage(s); - int tile = s->fg[i][j]; - int shape = z->shapes[tile]; - return block_of(shape, i, j); -} - -/* get block at absolute x y if you are in stage home */ -block get_block(stage* home, int x, int y){ - zone* z = zone_of_stage(home); - int i = x/1024/16 - (home->i + z->i)*20; - int j = y/1024/16 - (home->j + z->j)*15; - - stage* s = find_stage(home, i, j); - if(s == NULL) - return null_block(); - else - return block_from_stage(s, i, j); -} - -/* returns either a block that the rect is intersecting - or it returns a block with none set to 1 */ -block intersecting_block(stage* s, int left, int right, int top, int bottom){ - int i; - for(i=0; i<4; i++){ - block bl; - switch(i){ - case 0: bl = get_block(s, top, left); break; - case 1: bl = get_block(s, top, right); break; - case 2: bl = get_block(s, bottom, left); break; - case 3: bl = get_block(s, bottom, right); break; - } - if(rect_is_on(bl, left, right, top, bottom)) return bl; - } - return no_block(); -} - - - - - - -/******** stage loading routines ********/ -static int load_stage_dimensions(stage* s, reader* rd){ - return - read_short(rd, &s->i) || - read_short(rd, &s->j); -} - -static int load_stage_snap(stage* s, reader* rd){ - return read_bytes(rd, (unsigned char*)s->snap, 4); -} - -static int load_stage_exit(stage* s, reader* rd){ - char what[5] = {0,0,0,0,0}; - if(read_bytes(rd, (unsigned char*)what, 4)) return -1; - - if(strcmp(what, "none") == 0){ - return 0; - } - if(strcmp(what, "exit") == 0){ -/* FIXME */ -printf("INCOMPLETE load_stage_exit doesnt work yet\n"); - return -1; - } - - error_msg("load_zone: invalid stage header (missing exit)\n"); - return -1; -} - -static int load_stage_decorations(stage* s, reader* rd){ - int N; - if(read_short(rd, &N)) return -1; - - if(N > 0){ -/* FIXME */ -printf("INCOMPLETE load_stage_decorations doesnt work yet\n"); - return -1; - } - - return 0; -} - -static int load_stage_waters(stage* s, reader* rd){ - int N; - if(read_short(rd, &N)) return -1; - - if(N > 0){ -/* FIXME */ -printf("INCOMPLETE load_stage_waters doesnt work yet\n"); - return -1; - } - - return 0; -} - -static int load_stage_data(stage* s, reader* rd){ - int i, j; - for(i=0; i<15; i++){ - for(j=0; j<20; j++){ - if(read_byte(rd, (int*)&s->fg[i][j])) return -1; - } - } - for(i=0; i<15; i++){ - for(j=0; j<20; j++){ - if(read_byte(rd, (int*)&s->bg[i][j])) return -1; - } - } - return 0; -} - -static stage* load_stage(reader* rd){ - stage* s = xmalloc(sizeof(stage)); - s->decs = empty(); - s->exit = NULL; - s->snap[NORTH] = 0; - s->snap[WEST] = 0; - s->snap[EAST] = 0; - s->snap[SOUTH] = 0; - - if( - load_stage_dimensions(s, rd) || - load_stage_snap(s, rd) || - load_stage_exit(s, rd) || - load_stage_decorations(s, rd) || - load_stage_waters(s, rd) || - load_stage_data(s, rd) - ) - { - recycle(s->decs); - free(s); - return NULL; - } - return s; -} - -static int load_zone_bitmap(reader* rd, int* out){ - char* filename; - if(read_string(rd, &filename)){ - error_msg("load_zone: read error (graphics list)\n"); - return -1; - } - - if(strlen(filename) == 0){ - error_msg("load_zone: no graphics file specified\n"); - return -1; - } - - *out = load_bitmap(filename); - free(filename); - if(*out < 0){ - error_msg("load_zone: can't load graphics %s\n", filename); - return -1; - } - else{ - return 0; - } -} - -static int load_zone_gfx(zone* z, reader* rd){ - return - load_zone_bitmap(rd, &z->fgtiles) || - load_zone_bitmap(rd, &z->bgtiles) || - load_zone_bitmap(rd, &z->dectiles) || - load_zone_bitmap(rd, &z->bgimage); -} - -static int load_zone_shapes(zone* z, reader* rd){ - int i; - for(i=0; i<256; i++){ - if(read_byte(rd, (int*)&z->shapes[i])){ - return -1; - } - } - return 0; -} - -static int load_zone_dimensions(zone* z, reader* rd){ - return - read_short(rd, &z->i) || - read_short(rd, &z->j) || - read_short(rd, &z->w) || - read_short(rd, &z->h); -} - -static int load_zone_stages(zone* z, reader* rd){ - int i, j, N; - - z->stages = xmalloc(z->w * z->h * sizeof(stage*)); - - for(i=0; i < z->w; i++){ - for(j=0; j < z->h; j++){ - *(z->stages + i + j*z->w) = NULL; - } - } - - if(read_short(rd, &N)) return -1; - -printf("number of stages %d\n", N); - for(i=0; istages[s->i + s->j * z->w] = s; - } - - return 0; -} - -int load_zone_header(zone* z, reader* rd){ - unsigned char magic1[4]; - unsigned char magic2[4] = {0x0a, 0x0b, 0x0c, 0x0d}; - int format; - - if( - read_bytes(rd, magic1, 4) || - read_int(rd, &format) || - read_int(rd, &z->id) - ) - return -1; - - if(memcmp(magic1, magic2, 4) != 0){ - error_msg("load_zone: wrong file type (missing magic)\n"); - return -1; - } - - if(format != 1){ - error_msg("load_zone: wrong format version\n"); - return -1; - } - - return 0; -} - - -int load_zone(char* filename){ - reader* rd = data_open("zones/", filename); - if(rd == NULL){ - error_msg("load_zone: error opening \"%s\"\n", filename); - return -1; - } - - zone* z = xmalloc(sizeof(zone)); - strncpy(z->name, filename, 32); - z->id = 0; /* supposed to be in file */ - z->fgtiles = -1; - z->bgtiles = -1; - z->dectiles = -1; - z->bgimage = -1; - - if( - load_zone_header(z, rd) || - load_zone_dimensions(z, rd) || - load_zone_gfx(z, rd) || - load_zone_shapes(z, rd) || - load_zone_stages(z, rd) - ){ - error_msg("load_zone: error reading \"%s\"\n", filename); - free(z); - loader_close(rd); - return -1; - } - - push(zones, z); - return z->id; -} -/**************************************/ - - - - - -void print_shapes(enum tile_shape shapes[256]){ - int i, j; - for(i=0; i<16; i++){ - printf(" "); - for(j=0; j<16; j++){ - printf("%02x ", shapes[i*16 + j]); - } - printf("\n"); - } -} - -void print_dir(char snap[4], enum cardinal dir, char* c){ - if(snap[dir]) printf("%s", c); - else printf(" "); -} - -void print_snaps(char snap[4]){ - printf(" snap: ("); - print_dir(snap, WEST, "L"); - print_dir(snap, NORTH, "U"); - print_dir(snap, SOUTH, "D"); - print_dir(snap, EAST, "R"); - printf(")\n"); -} - -void print_stages(stage** stages, int w, int h){ - int i, j; - for(j=0; jdecs)); - print_snaps(s->snap); - printf(" exit: %p\n", s->exit); - printf("\n"); - } - } -} - - -void print_zone(int id){ - zone* z = find_zone_by_id(id); - printf("zone: %s\n", z->name); - - printf(" id: %d\n", z->id); - printf(" dimensions: %d x %d\n", z->w, z->h); - printf(" position: (%d, %d)\n", z->i, z->j); - printf(" fg: %d\n", z->fgtiles); - printf(" bg: %d\n", z->bgtiles); - printf(" dec: %d\n", z->dectiles); - printf(" bgimage: %d\n", z->bgimage); - printf(" shapes:\n"); - print_shapes(z->shapes); - printf(" stages:\n"); - print_stages(z->stages, z->w, z->h); -} - - - -void stage_bind_camera(location l, int* x, int* y){ - //for each snap, snap x y -} - -void draw_stage_bg(location loc, int cx, int cy){ - //draw background - //draw bg tiles -} - -void draw_stage_fg(location loc, int cx, int cy){ - //draw water - //fg tiles - //draw decorations -} - - -/* returns 1 if a collision will occur, 0 otherwise - if 1 is returned, x will be set to the collision point */ -int stage_xcollide(location loc, int w, int h, int v, int* x){ - zone* z = find_zone_by_id(loc.z); - stage* s = stage_lookup(z, loc.i, loc.j); - int X = loc.x + v*10; /* FIXME dt */ - int right = X + w; - int left = X; - int top = loc.y; - int bottom = loc.y + h; - - block bl = intersecting_block(s, left, right, top, bottom); - - if(bl.none) return 0; - else{ - *x = xhit(v, bl, top, bottom); - return 1; - } -} - -int stage_ycollide(location loc, int w, int h, int v, int* y){ - return 0; -} - - - - -void stage_init(){ - zones = empty(); -} +/* + Cantaveria - action adventure platform game + Copyright (C) 2009 2010 Evan Rinehart + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to + + The Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor + Boston, MA 02110-1301, USA +*/ + + +/* +stage module is responsible for modelling the static world. +it has three main functions +* load zone files into world +* draw world background and foreground layers +* calculate if a moving rectangle will collide with world +*/ + + + +#include +#include +#include + +#include +#include +#include +#include + +#include + + + +enum tile_shape { +SHAPE_FREE, /* 'air' */ +SHAPE_SQUARE, +SHAPE_NULL, /*does not exist*/ + +SHAPE_TRI_NE, +SHAPE_TRI_NW, +SHAPE_TRI_SE, +SHAPE_TRI_SW, + +SHAPE_LTRAP_FLOOR, /* trapezoid */ +SHAPE_RTRAP_FLOOR, +SHAPE_LSLOPE_FLOOR, +SHAPE_RSLOPE_FLOOR, +SHAPE_LTRAP_CEIL, +SHAPE_RTRAP_CEIL, +SHAPE_LSLOPE_CEIL, +SHAPE_RSLOPE_CEIL, + +SHAPE_HALF_FLOOR, +SHAPE_HALF_CEIL +}; + +typedef struct { + unsigned char bg; + unsigned char fg; + unsigned char shape; +} tile; + +typedef struct stage stage; +struct stage { + char id[32]; + int w, h; + tile* tiles; + int bgimage; + int dectiles; + int bgtiles; + int fgtiles; + stage* next; +}; + +char zone_name[32] = "NO ZONE"; +stage* stages = NULL; +stage* this_stage = NULL; + +/***/ + + +/* +STAGE MODULE + +DEADLINES AND MILESTONES + +load zones / stages from new format - May 15 + this may be done. + needs testing (print out the stage after loading) +display loaded stages - May 22 +collision algorithm - May 29 + +*/ + + + +static int load_stage(char* path){ +/* +[stage file] +width height +bgimage +dectiles +bgtiles +fgtiles +x y fg bg shape +x y fg bg shape +... +*/ + + reader* f = loader_open(path); + char* filename = path_ending(path); + char buf[256]; + tile* tptr; + stage* s = malloc(sizeof(stage)); + int w = 20; + int h = 15; + int x, y, fg, bg, shape; + + loader_scanline(f, "%d %d", &w, &h); + loader_scanline(f, "%s", buf); + s->bgimage = load_bitmap(buf); + loader_scanline(f, "%s", buf); + s->dectiles = load_bitmap(buf); + loader_scanline(f, "%s", buf); + s->bgtiles = load_bitmap(buf); + loader_scanline(f, "%s", buf); + s->fgtiles = load_bitmap(buf); + + s->tiles = malloc(w*h*sizeof(tile)); + s->w = w; + s->h = h; + strcpy(s->id, filename); + + while(!loader_feof(f)){ + loader_scanline(f, "%d %d %d %d %d", &x, &y, &fg, &bg, &shape); + tptr = s->tiles + x + (s->w * y); + tptr->fg = fg; + tptr->bg = bg; + tptr->shape = shape; + } + + s->next = stages; + stages = s; + + loader_close(f); + return 0; +} + +/***/ + + +int load_zone(char* name){ + /* +loading a zone from a file +a zone consists of one or more stages +each stage has its own tileset graphics and background +it also has a large array of tiles + +the stage files are in zones/zonename/ +the name of the file will be used as the id + */ + + list* dirs; + list* ptr; + char path[256] = ""; + char* filename; + + /* "zones/" ++ filename */ + strncat(path, "zones/", 256); /* check for correctness */ + strncat(path, name, 256 - strlen("zones/")); + strncpy(zone_name, name, 32); + zone_name[31] = '\0'; + + dirs = loader_readdir(path); + if(dirs == NULL){ + printf("ERROR cant read dirs\n"); + return -1; + } + + ptr = dirs->next; + while(ptr){ + filename = ptr->item; + if(load_stage(filename) < 0){ + printf("ERROR cant load stage\n"); + loader_freedirlist(dirs); + return -1; + } + ptr = ptr->next; + } + + loader_freedirlist(dirs); + return 0; +} + +void unload_zone(){ + stage* ptr = stages; + stage* prev; + while(ptr){ + free(ptr->tiles); + prev = ptr; + ptr = ptr->next; + free(prev); + } +} + +void switch_stage(char* id){ + stage* ptr = stages; + while(ptr){ + if(strcmp(id, ptr->id) == 0){ + this_stage = ptr; + return; + } + ptr = ptr->next; + } + + printf("ERROR stage not found\n"); +} + +void draw_stage_fg(int cx, int cy, int x, int y, int w, int h){ + //draw background + /* draw background on tiles where at least + the fg or bg tile is partial*/ + //draw bg tiles + /* draw bg tile where fg is partial */ +} + +void draw_stage_bg(int cx, int cy, int x, int y, int w, int h){ + //draw water + /* calculate water surfaces, draw them */ + //fg tiles + /* draw all fg visible fg tiles */ + //draw decorations + /* draw all decorations */ +} + +int stage_xcollide(int x, int y, int w, int h, int v, int* xx){ + return 0; +} + +int stage_ycollide(int x, int y, int w, int h, int v, int* yy){ + return 0; +} + +void stage_init(){ + /* does nothing */ +} + + diff --git a/stage.h b/stage.h index 5c1ddfa..187c6c4 100644 --- a/stage.h +++ b/stage.h @@ -20,15 +20,15 @@ Boston, MA 02110-1301, USA */ -typedef struct { - int z; /* which zone */ - int i, j; /* which stage */ - int x, y; /* absolute coords in 1024th of a pixel */ -} location; int load_zone(char* filename); -void print_zone(int id); -void stage_draw_fg(int cx, int cy); -void stage_draw_bg(int cx, int cy); -int stage_xcollide(location loc, int w, int h, int v, int* x); -int stage_ycollide(location loc, int w, int h, int v, int* y); +void unload_zone(); + +void switch_stage(char* id); + +void stage_draw_fg(int cx, int cy, int x, int y, int w, int h); +void stage_draw_bg(int cx, int cy, int x, int y, int w, int h); + +int stage_xcollide(int x, int y, int w, int h, int v, int* xx); +int stage_ycollide(int x, int y, int w, int h, int v, int* yy); + diff --git a/synth.c b/synth.c index fe94a84..50c82c9 100644 --- a/synth.c +++ b/synth.c @@ -22,6 +22,15 @@ evanrinehart@gmail.com */ +/* +the synth module exports a mixer callback for the audio output. +it uses support from orc (instruments) and seq (sequencer) to +generate that output. +* generate N samples of stereo output +*/ + + + #include #include #include diff --git a/util.c b/util.c index 0d56030..f8d795d 100644 --- a/util.c +++ b/util.c @@ -234,6 +234,14 @@ double randf(){ } + +char* path_ending(char* path){ + char* c = path + strlen(path); + while(*(c-1) != '/' && c > path) c--; + return c; +} + + /* Copyright 300BC Euclid */ int gcd(int a, int b){ while(b){ diff --git a/util.h b/util.h index bc18a5a..1b3f4e5 100644 --- a/util.h +++ b/util.h @@ -37,6 +37,8 @@ void rand_reset(unsigned s); int randi(int a, int b); double randf(); +char* path_ending(char* path); + int gcd(int u, int v); typedef struct treenode treenode; diff --git a/video.c b/video.c index 71df5e1..8034cde 100644 --- a/video.c +++ b/video.c @@ -20,6 +20,22 @@ Boston, MA 02110-1301, USA */ + +/* +video module is the low level interface to video output. +it has several low level functions. +* initialize the video system for a certain video mode +* load graphics data into the abstract graphics pool +* draw a portion of some graphics somewhere on screen +* millisecond time delta generator +* screen clear +* screen flip +* process suspend +*/ + + + + #include #include diff --git a/zip.c b/zip.c index 5820677..855bb34 100644 --- a/zip.c +++ b/zip.c @@ -9,6 +9,23 @@ This software comes with no warranty. 2. Modifications must retain this license, at least in spirit. */ +/* +read files from a zip file. + +*depends on zlib +*zip archive may be in a file, or accessed using a reader struct +*reader struct must support seeking +*directory listing is supported +*various errors with the archive and i/o are reported via zip_geterror() + +*files in the archive are accessed sequentially, no seek supported +*writing is not supported +*zip64 not supported +*only inflate compression method supported + +*/ + + #include #include #include -- 2.11.4.GIT