Level is now drawn.
[cantaveria.git] / stage.c
bloba849b6b5ed1bb694554016f8be54f908dd62db14
1 /*
2 Cantaveria - action adventure platform game
3 Copyright (C) 2009 2010 Evan Rinehart
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to
18 The Free Software Foundation, Inc.
19 51 Franklin Street, Fifth Floor
20 Boston, MA 02110-1301, USA
25 stage module is responsible for modelling the static world.
26 it has three main functions
27 * load zone files into world
28 * draw world background and foreground layers
29 * calculate if a moving rectangle will collide with world
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <ctype.h>
39 #include <util.h>
40 #include <list.h>
41 #include <loader.h>
42 #include <graphics.h>
43 #include <video.h>
45 #include <stage.h>
49 enum tile_shape {
50 SHAPE_FREE = '0', /* 'air' */
51 SHAPE_SQUARE = 'M',
53 SHAPE_TRI_NE = 'a',
54 SHAPE_TRI_NW = 'b',
55 SHAPE_TRI_SE = 'c',
56 SHAPE_TRI_SW = 'd',
58 SHAPE_LTRAP_FLOOR = '1', /* trapezoid */
59 SHAPE_RTRAP_FLOOR = '2',
60 SHAPE_LSLOPE_FLOOR = '3',
61 SHAPE_RSLOPE_FLOOR = '4',
62 SHAPE_LTRAP_CEIL = '5',
63 SHAPE_RTRAP_CEIL = '6',
64 SHAPE_LSLOPE_CEIL = '7',
65 SHAPE_RSLOPE_CEIL = '8',
67 SHAPE_HALF_FLOOR = 'm',
68 SHAPE_HALF_CEIL = 'w'
71 typedef struct {
72 unsigned char bg;
73 unsigned char fg;
74 unsigned char shape;
75 } tile;
77 typedef struct stage stage;
78 struct stage {
79 char id[256];
80 int w, h;
81 tile* tiles;
82 int bgimage;
83 int bgtiles;
84 int fgtiles;
85 int ox, oy;
86 stage* next;
89 char zone_name[256] = "NO ZONE";
90 stage* stages = NULL;
91 stage* this_stage = NULL;
93 /***/
97 STAGE MODULE
99 DEADLINES AND MILESTONES
101 load zones / stages from new format - May 15
102 display loaded stages - May 22
103 collision algorithm - May 29
109 static void initialize_tiles(int n, tile* tiles){
110 int i;
111 for(i=0; i<n; i++){
112 tiles[i].shape = SHAPE_FREE;
113 tiles[i].fg = 0;
114 tiles[i].bg = 0;
119 static int load_stage(char* gfxpath, char* stagepath){
121 [stage file]
122 width height
123 bgimage
124 dectiles
125 bgtiles
126 fgtiles
127 x y fg bg shape
128 x y fg bg shape
132 reader* f = loader_open(stagepath);
133 char* filename = path_ending(stagepath);
134 char buf[256];
135 char gfx[256];
136 tile* tptr;
137 stage* s = malloc(sizeof(stage));
138 int w = 20;
139 int h = 15;
140 int x, y, ox, oy, fg, bg, shape;
142 loader_scanline(f, "%d %d %d %d", &w, &h, &ox, &oy);
144 loader_scanline(f, "%s", buf);
145 strcpy(gfx, gfxpath);
146 strcat(gfx, buf);
147 s->bgimage = load_bitmap(gfx);
149 loader_scanline(f, "%s", buf);
150 strcpy(gfx, gfxpath);
151 strcat(gfx, buf);
152 s->bgtiles = load_bitmap(gfx);
154 loader_scanline(f, "%s", buf);
155 strcpy(gfx, gfxpath);
156 strcat(gfx, buf);
157 s->fgtiles = load_bitmap(gfx);
159 s->tiles = malloc(w*h*sizeof(tile));
160 initialize_tiles(w*h, s->tiles);
161 s->w = w;
162 s->h = h;
163 s->ox = ox;
164 s->oy = oy;
165 strncpy(s->id, filename, 256);
166 s->id[255] = '\0';
168 while(!loader_feof(f)){
169 loader_scanline(f, "%d %d %d %d %c", &x, &y, &fg, &bg, &shape);
170 tptr = s->tiles + (x+ox) + (s->w * (y+oy));
171 tptr->fg = fg;
172 tptr->bg = bg;
173 tptr->shape = shape;
176 s->next = stages;
177 stages = s;
179 loader_close(f);
180 return 0;
183 /***/
186 int load_zone(string name){
188 loading a zone from a file
189 a zone consists of one or more stages
190 each stage has its own tileset graphics and background
191 it also has a large array of tiles
193 the stage files are in zones/zonename/
194 the name of the file will be used as the id
197 list* dirs;
198 list* ptr;
199 char stagesdir[256] = "";
200 char gfxpath[256] = "";
201 char* stagepath;
203 strcat(stagesdir, "zones/");
204 strcat(stagesdir, name);
205 strcat(stagesdir, "/stages/");
207 strcat(gfxpath, "zones/");
208 strcat(gfxpath, name);
209 strcat(gfxpath, "/gfx/");
211 strncpy(zone_name, name, 256);
212 zone_name[255] = '\0';
214 dirs = loader_readdir((string)stagesdir);
215 if(dirs == NULL){
216 printf("ERROR cant read dirs\n");
217 return -1;
220 ptr = dirs->next;
221 while(ptr){
222 stagepath = ptr->item;
223 if(load_stage(gfxpath, stagepath) < 0){
224 printf("ERROR cant load stage\n");
225 loader_freedirlist(dirs);
226 return -1;
228 ptr = ptr->next;
231 loader_freedirlist(dirs);
232 return 0;
235 void unload_zone(){
236 stage* ptr = stages;
237 stage* prev;
238 while(ptr){
239 free(ptr->tiles);
240 prev = ptr;
241 ptr = ptr->next;
242 free(prev);
245 strcpy(zone_name, "NO ZONE");
248 void switch_stage(string id){
249 stage* ptr = stages;
250 while(ptr){
251 if(strcmp(id, ptr->id) == 0){
252 this_stage = ptr;
253 return;
255 ptr = ptr->next;
258 printf("ERROR stage not found\n");
262 static void draw_tiles(int gfx, char layer, int cx, int cy){
263 tile* tbase = this_stage->tiles;
264 tile* t;
265 int tw = this_stage->w;
266 int th = this_stage->h;
267 int id;
268 int gx, gy;
270 int i;
271 int j;
272 int io = cx/16;
273 int jo = cy/16;
274 int i_ = io + 20;
275 int j_ = jo + 15;
277 int extra_x = 0;
278 int extra_y = 0;
279 int W, H;
280 screen_dimensions(&W, &H);
281 if(W>320){
282 extra_x = (W - 320)/16/2 + 2;
284 if(H>240){
285 extra_y = (H - 240)/16/2 + 2;
288 io -= extra_x;
289 jo -= extra_y;
290 i_ += extra_x;
291 j_ += extra_y+1;
293 if(io > tw-1) return;
294 if(jo > th-1) return;
296 if(io < 0) io = 0;
297 if(jo < 0) jo = 0;
298 if(i_ > tw) i_ = tw;
299 if(j_ > th) j_ = th;
301 for(j=jo; j<j_; j++){
302 for(i=io; i<i_; i++){
303 t = tbase + i + tw*j;
304 if(layer=='b') id = t->bg;
305 else if(layer=='f') id = t->fg;
306 else id = 0;
307 gx = 16*(id%16);
308 gy = 16*(id/16);
309 draw_gfx(gfx, i*16-cx, j*16-cy, gx, gy, 16, 16);
315 cx, cy is the camera position
316 x, y i think is the offset from 0,0 you should shift
317 w, h i think is the width and height of the screen
319 void stage_draw_bg(int cx, int cy){
320 int i;
321 int bw, bh, screen_w, screen_h;
322 int bgimage;
323 int bgshift;
324 int parallax = 2;
326 if(this_stage == NULL) return;
328 /* draw background vertically centered
329 tile horizontally at fraction of camera x */
330 bgimage = this_stage->bgimage;
331 gfx_dimensions(bgimage, &bw, &bh);
332 screen_dimensions(&screen_w, &screen_h);
333 bgshift = cx/parallax/bw;
334 for(i=-1; i<(screen_w/bw)+2; i++){
335 draw_gfx_raw(
336 bgimage,
337 (i+bgshift)*bw-cx/parallax,
338 (screen_h-bh)/2,
339 0, 0, bw, bh
343 draw_tiles(this_stage->bgtiles, 'b', cx, cy);
346 void stage_draw_fg(int cx, int cy){
347 draw_tiles(this_stage->bgtiles, 'f', cx, cy);
352 int stage_xcollide(int x, int y, int w, int h, int v, int* xx){
353 return 0;
356 int stage_ycollide(int x, int y, int w, int h, int v, int* yy){
357 return 0;
360 void stage_init(){
361 /* does nothing */
368 /*** debug ***/
370 void stage_debug(){
371 stage* ptr = stages;
372 int i, j;
373 char c;
375 struct stage {
376 char id[32];
377 int w, h;
378 tile* tiles;
379 int bgimage;
380 int bgtiles;
381 int fgtiles;
382 stage* next;
383 };*/
384 printf("stage debug:\n\n");
385 printf("zone: %s\n\n", zone_name);
387 while(ptr){
388 printf("stage: %s\n", ptr->id);
389 printf("size: %dx%d\n", ptr->w, ptr->h);
390 printf("origin: (%d, %d)\n", ptr->ox, ptr->oy);
391 printf("bgimage: %d\n", ptr->bgimage);
392 printf("bgtiles: %d\n", ptr->bgtiles);
393 printf("fgtiles: %d\n", ptr->fgtiles);
394 printf("tiles:\n");
396 for(j=0; j<ptr->h; j++){
397 for(i=0; i<ptr->w; i++){
398 c = (ptr->tiles + i + ptr->w*j)->fg;
400 if(isprint(c)) printf("%d", c);
401 else printf("?");*/
402 printf("[%02x]", c);
404 printf("\n");
408 printf("\n");
409 ptr = ptr->next;