]> 4ch.mooo.com Git - 16.git/blob - scroll.c
modified: Project 16.bfproject
[16.git] / scroll.c
1 #include "modex16.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "dos_kb.h"
5
6 //word far *clock= (word far*) 0x046C; /* 18.2hz clock */
7
8 typedef struct {
9         bitmap_t *data;
10         word tileHeight;
11         word tileWidth;
12         unsigned int rows;
13         unsigned int cols;
14         //unsigned int tilex,tiley; // tile position on the map
15 } tiles_t;
16
17
18 typedef struct {
19         byte    *data;
20         tiles_t *tiles;
21         int width;
22         int height;
23 } map_t;
24
25
26 typedef struct {
27         map_t *map;
28         page_t *page;
29         int tx; //appears to be the top left tile position on the viewable screen map
30         int ty; //appears to be the top left tile position on the viewable screen map
31         word dxThresh; //????
32         word dyThresh; //????
33 } map_view_t;
34
35 struct {
36         int x; //player exact position on the viewable map
37         int y; //player exact position on the viewable map
38         int tx; //player tile position on the viewable map
39         int ty; //player tile position on the viewable map
40         int hp; //hitpoints of the player
41 } player;
42
43
44 map_t allocMap(int w, int h);
45 void initMap(map_t *map);
46 void mapScrollRight(map_view_t *mv, byte offset);
47 void mapScrollLeft(map_view_t *mv, byte offest);
48 void mapScrollUp(map_view_t *mv, byte offset);
49 void mapScrollDown(map_view_t *mv, byte offset);
50 void mapGoTo(map_view_t *mv, int tx, int ty);
51 void mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y);
52 void mapDrawRow(map_view_t *mv, int tx, int ty, word y);
53 void mapDrawCol(map_view_t *mv, int tx, int ty, word x);
54 void animatePlayer(map_view_t *src, map_view_t *dest, short d1, short d2, int x, int y, int ls, int lp, bitmap_t *bmp);
55
56 #define TILEWH 16
57 #define QUADWH (TILEWH/4)
58 #define SPEED 4
59
60 //place holder definitions
61 #define MAPX 40
62 #define MAPY 30
63 #define SWAP(a, b) tmp=a; a=b; b=tmp;
64 void main() {
65         bitmap_t ptmp; // player sprite
66         int q=1;
67         static int persist_aniframe = 0;    /* gonna be increased to 1 before being used, so 0 is ok for default */
68         page_t screen, screen2;
69         map_t map;
70         map_view_t mv, mv2;
71         map_view_t *bg, *spri, *tmp;
72         byte *ptr;
73
74         setkb(1);
75         /* create the map */
76         map = allocMap(MAPX,MAPY); //20x15 is the resolution of the screen you can make maps smaller than 20x15 but the null space needs to be drawn properly
77         initMap(&map);
78         mv.map = &map;
79         mv2.map = &map;
80
81         /* draw the tiles */
82         ptr = map.data;
83         ptmp = bitmapLoadPcx("ptmp.pcx"); // load sprite
84         modexEnter();
85         modexPalUpdate(ptmp.palette);
86         screen = modexDefaultPage();
87         screen.width += (TILEWH*2);
88         screen.height += (TILEWH*2);
89         mv.page = &screen;
90         screen2 = modexNextPage(mv.page);
91         mv2.page = &screen2;
92
93         /* set up paging */
94         bg = &mv;
95         spri = &mv2;
96
97 //TODO: LOAD map data and position the map in the middle of the screen if smaller then screen
98         mapGoTo(bg, 0, 0);
99         mapGoTo(spri, 0, 0);
100
101         //TODO: put player in starting position of spot
102         //default player position on the viewable map
103         player.tx = bg->tx + 10;
104         player.ty = bg->ty + 8;
105         player.x = player.tx*TILEWH;
106         player.y = player.ty*TILEWH;
107         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 64, 24, 32, &ptmp);
108         modexCopyPageRegion(bg->page, spri->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
109         modexShowPage(bg->page);
110         while(!keyp(1))
111         {
112         //top left corner & bottem right corner of map veiw be set as map edge trigger since maps are actually square
113         //to stop scrolling and have the player position data move to the edge of the screen with respect to the direction
114         //when player.tx or player.ty == 0 or player.tx == 20 or player.ty == 15 then stop because that is edge of map and you do not want to walk of the map
115         
116         #define INC_PER_FRAME if(q&1) persist_aniframe++; if(persist_aniframe>4) persist_aniframe = 1;
117
118         if(keyp(77) && !keyp(75))
119         {
120                 if(bg->tx >= 0 && bg->tx+20 < MAPX && player.tx == bg->tx + 10)
121                 {
122                         for(q=1; q<=(TILEWH/SPEED); q++)
123                         {
124                                 INC_PER_FRAME;
125                                 animatePlayer(bg, spri, 1, 1, player.x, player.y, persist_aniframe, q, &ptmp);
126                                 mapScrollRight(bg, SPEED);
127                                 mapScrollRight(spri, SPEED);
128                                 modexShowPage(spri->page);
129                         }
130                         player.tx++;
131                 }
132                 else if(player.tx < MAPX)
133                 {
134                         for(q=1; q<=(TILEWH/SPEED); q++)
135                         {
136                                 INC_PER_FRAME;
137                                 player.x+=SPEED;
138                                 animatePlayer(bg, spri, 1, 0, player.x, player.y, persist_aniframe, q, &ptmp);
139                                 modexShowPage(spri->page);
140                         }
141                         player.tx++;
142                 }
143                 else
144                 {
145                         modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
146                         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 32, 24, 32, &ptmp);
147                         modexShowPage(spri->page);
148                 }
149         }
150
151         if(keyp(75) && !keyp(77))
152         {
153                 if(bg->tx > 0 && bg->tx+20 <= MAPX && player.tx == bg->tx + 10)
154                 {
155                         for(q=1; q<=(TILEWH/SPEED); q++)
156                         {
157                                 INC_PER_FRAME;
158                                 animatePlayer(bg, spri, 3, 1, player.x, player.y, persist_aniframe, q, &ptmp);
159                                 mapScrollLeft(bg, SPEED);
160                                 mapScrollLeft(spri, SPEED);
161                                 modexShowPage(spri->page);
162                         }
163                         player.tx--;
164                 }
165                 else if(player.tx > 1)
166                 {
167                         for(q=1; q<=(TILEWH/SPEED); q++)
168                         {
169                                 INC_PER_FRAME;
170                                 player.x-=SPEED;
171                                 animatePlayer(bg, spri, 3, 0, player.x, player.y, persist_aniframe, q, &ptmp);
172                                 modexShowPage(spri->page);
173                         }
174                         player.tx--;
175                 }
176                 else
177                 {
178                         modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
179                         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 96, 24, 32, &ptmp);
180                         modexShowPage(spri->page);
181                 }
182         }
183
184         if(keyp(80) && !keyp(72))
185         {
186                 if(bg->ty >= 0 && bg->ty+15 < MAPY && player.ty == bg->ty + 8)
187                 {
188                         for(q=1; q<=(TILEWH/SPEED); q++)
189                         {
190                                 INC_PER_FRAME;
191                                 animatePlayer(bg, spri, 2, 1, player.x, player.y, persist_aniframe, q, &ptmp);
192                                 mapScrollDown(bg, SPEED);
193                                 mapScrollDown(spri, SPEED);
194                                 modexShowPage(spri->page);
195                         }
196                         player.ty++;
197                 }
198                 else if(player.ty < MAPY)
199                 {
200                         for(q=1; q<=(TILEWH/SPEED); q++)
201                         {
202                                 INC_PER_FRAME;
203                                 player.y+=SPEED;
204                                 animatePlayer(bg, spri, 2, 0, player.x, player.y, persist_aniframe, q, &ptmp);
205                                 modexShowPage(spri->page);
206                         }
207                         player.ty++;
208                 }
209                 else
210                 {
211                         modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
212                         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 64, 24, 32, &ptmp);
213                         modexShowPage(spri->page);
214                 }
215         }
216
217         if(keyp(72) && !keyp(80))
218         {
219                 if(bg->ty > 0 && bg->ty+15 <= MAPY && player.ty == bg->ty + 8)
220                 {
221                         for(q=1; q<=(TILEWH/SPEED); q++)
222                         {
223                                 INC_PER_FRAME;
224                                 animatePlayer(bg, spri, 0, 1, player.x, player.y, persist_aniframe, q, &ptmp);
225                                 mapScrollUp(bg, SPEED);
226                                 mapScrollUp(spri, SPEED);
227                                 modexShowPage(spri->page);
228                         }
229                         player.ty--;
230                 }
231                 else if(player.ty > 1)
232                 {
233                         for(q=1; q<=(TILEWH/SPEED); q++)
234                         {
235                                 INC_PER_FRAME;
236                                 player.y-=SPEED;
237                                 animatePlayer(bg, spri, 0, 0, player.x, player.y, persist_aniframe, q, &ptmp);
238                                 modexShowPage(spri->page);
239                         }
240                         player.ty--;
241                 }
242                 else
243                 {
244                         modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
245                         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 0, 24, 32, &ptmp);
246                         modexShowPage(spri->page);
247                 }
248         }
249
250         }
251
252         modexLeave();
253         setkb(0);
254         printf("Project 16 scroll.exe\n");
255         printf("tx: %d\n", bg->tx);
256         printf("ty: %d\n", bg->ty);
257         printf("player.x: %d\n", player.x);
258         printf("player.y: %d\n", player.y);
259         printf("player.tx: %d\n", player.tx);
260         printf("player.ty: %d\n", player.ty);
261 }
262
263
264 map_t
265 allocMap(int w, int h) {
266         map_t result;
267
268         result.width =w;
269         result.height=h;
270         result.data = malloc(sizeof(byte) * w * h);
271
272         return result;
273 }
274
275
276 void
277 initMap(map_t *map) {
278         /* just a place holder to fill out an alternating pattern */
279         int x, y;
280         int i;
281         int tile = 1;
282         map->tiles = malloc(sizeof(tiles_t));
283
284         /* create the tile set */
285         map->tiles->data = malloc(sizeof(bitmap_t));
286         map->tiles->data->width = (TILEWH*2);
287         map->tiles->data->height= TILEWH;
288         map->tiles->data->data = malloc((TILEWH*2)*TILEWH);
289         map->tiles->tileHeight = TILEWH;
290         map->tiles->tileWidth =TILEWH;
291         map->tiles->rows = 1;
292         map->tiles->cols = 2;
293
294         i=0;
295         for(y=0; y<TILEWH; y++) {
296         for(x=0; x<(TILEWH*2); x++) {
297                 if(x<TILEWH)
298                   map->tiles->data->data[i] = 0x24;
299                 else
300                   map->tiles->data->data[i] = 0x34;
301                 i++;
302         }
303         }
304
305         i=0;
306         for(y=0; y<map->height; y++) {
307                 for(x=0; x<map->width; x++) {
308                         map->data[i] = tile;
309                         tile = tile ? 0 : 1;
310                         i++;
311                 }
312                 tile = tile ? 0 : 1;
313         }
314 }
315
316
317 void
318 mapScrollRight(map_view_t *mv, byte offset) {
319         word x, y;  /* coordinate for drawing */
320
321         /* increment the pixel position and update the page */
322         mv->page->dx += offset;
323
324         /* check to see if this changes the tile */
325         if(mv->page->dx >= mv->dxThresh ) {
326         /* go forward one tile */
327         mv->tx++;
328         /* Snap the origin forward */
329         mv->page->data += 4;
330         mv->page->dx = mv->map->tiles->tileWidth;
331
332
333         /* draw the next column */
334         x= SCREEN_WIDTH + mv->map->tiles->tileWidth;
335                 mapDrawCol(mv, mv->tx + 20 , mv->ty-1, x);
336         }
337 }
338
339
340 void
341 mapScrollLeft(map_view_t *mv, byte offset) {
342         word x, y;  /* coordinate for drawing */
343
344         /* increment the pixel position and update the page */
345         mv->page->dx -= offset;
346
347         /* check to see if this changes the tile */
348         if(mv->page->dx == 0) {
349         /* go backward one tile */
350         mv->tx--;
351                 
352         /* Snap the origin backward */
353         mv->page->data -= 4;
354         mv->page->dx = mv->map->tiles->tileWidth;
355
356         /* draw the next column */
357                 mapDrawCol(mv, mv->tx-1, mv->ty-1, 0);
358         }
359 }
360
361
362 void
363 mapScrollUp(map_view_t *mv, byte offset) {
364         word x, y;  /* coordinate for drawing */
365
366         /* increment the pixel position and update the page */
367         mv->page->dy -= offset;
368
369         /* check to see if this changes the tile */
370         if(mv->page->dy == 0 ) {
371         /* go down one tile */
372         mv->ty--;
373         /* Snap the origin downward */
374         mv->page->data -= mv->page->width*4;
375         mv->page->dy = mv->map->tiles->tileHeight;
376
377
378         /* draw the next row */
379         y= 0;
380                 mapDrawRow(mv, mv->tx-1 , mv->ty-1, y);
381         }
382 }
383
384
385 void
386 mapScrollDown(map_view_t *mv, byte offset) {
387         word x, y;  /* coordinate for drawing */
388
389         /* increment the pixel position and update the page */
390         mv->page->dy += offset;
391
392         /* check to see if this changes the tile */
393         if(mv->page->dy >= mv->dyThresh ) {
394         /* go down one tile */
395         mv->ty++;
396         /* Snap the origin downward */
397         mv->page->data += mv->page->width*4;
398         mv->page->dy = mv->map->tiles->tileHeight;
399
400
401         /* draw the next row */
402         y= SCREEN_HEIGHT + mv->map->tiles->tileHeight;
403                 mapDrawRow(mv, mv->tx-1 , mv->ty+15, y);
404         }
405
406 }
407
408
409 void
410 mapGoTo(map_view_t *mv, int tx, int ty) {
411         int px, py;
412         unsigned int i;
413
414         /* set up the coordinates */
415         mv->tx = tx;
416         mv->ty = ty;
417         mv->page->dx = mv->map->tiles->tileWidth;
418         mv->page->dy = mv->map->tiles->tileHeight;
419
420         /* set up the thresholds */
421         mv->dxThresh = mv->map->tiles->tileWidth * 2;
422         mv->dyThresh = mv->map->tiles->tileHeight * 2;
423
424         /* draw the tiles */
425         modexClearRegion(mv->page, 0, 0, mv->page->width, mv->page->height, 0);
426         py=0;
427         i=mv->ty * mv->map->width + mv->tx;
428         for(ty=mv->ty-1; py < SCREEN_HEIGHT+mv->dyThresh && ty < mv->map->height; ty++, py+=mv->map->tiles->tileHeight) {
429                 mapDrawRow(mv, tx-1, ty, py);
430         i+=mv->map->width - tx;
431         }
432 }
433
434
435 void
436 mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y) {
437         word rx;
438         word ry;
439         rx = (i % t->cols) * t->tileWidth;
440         ry = (i / t->cols) * t->tileHeight;
441         modexDrawBmpRegion(page, x, y, rx, ry, t->tileWidth, t->tileHeight, t->data);
442 }
443
444
445 void 
446 mapDrawRow(map_view_t *mv, int tx, int ty, word y) {
447         word x;
448         int i;
449
450         /* the position within the map array */
451         i=ty * mv->map->width + tx;
452         for(x=0; x<SCREEN_WIDTH+mv->dxThresh && tx < mv->map->width; x+=mv->map->tiles->tileWidth, tx++) {
453         if(i>=0) {
454                 /* we are in the map, so copy! */
455                 mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);
456         }
457         i++; /* next! */
458         }
459 }
460
461
462 void 
463 mapDrawCol(map_view_t *mv, int tx, int ty, word x) {
464         int y;
465         int i;
466
467         /* location in the map array */
468         i=ty * mv->map->width + tx;
469
470         /* We'll copy all of the columns in the screen, 
471            i + 1 row above and one below */
472         for(y=0; y<SCREEN_HEIGHT+mv->dyThresh && ty < mv->map->height; y+=mv->map->tiles->tileHeight, ty++) {
473         if(i>=0) {
474                 /* we are in the map, so copy away! */
475                 mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);
476         }
477         i += mv->map->width;
478         }
479 }
480
481 void
482 animatePlayer(map_view_t *src, map_view_t *dest, short d1, short d2, int x, int y, int ls, int lp, bitmap_t *bmp)
483 {
484         short dire=32*d1;
485         short qq;
486
487         if(d2==0) qq = 0;
488         else qq = ((lp)*SPEED);
489         switch (d1)
490         {
491                 case 0:
492                         //up
493                         x=x-4;
494                         y=y-qq-TILEWH;
495                 break;
496                 case 1:
497                         // right
498                         x=x+qq-4;
499                         y=y-TILEWH;
500                 break;
501                 case 2:
502                         //down
503                         x=x-4;
504                         y=y+qq-TILEWH;
505                 break;
506                 case 3:
507                         //left
508                         x=x-qq-4;
509                         y=y-TILEWH;
510                 break;
511         }
512         //TODO: make flexible animation thingy
513         modexCopyPageRegion(dest->page, src->page, x-4, y-4, x-4, y-4, 28, 40);
514         if(2>ls && ls>=1) { modexDrawSpriteRegion(dest->page, x, y, 48, dire, 24, 32, bmp); }else
515         if(3>ls && ls>=2) { modexDrawSpriteRegion(dest->page, x, y, 24, dire, 24, 32, bmp); }else
516         if(4>ls && ls>=3) { modexDrawSpriteRegion(dest->page, x, y, 0, dire, 24, 32, bmp); }else
517         if(5>ls && ls>=4) { modexDrawSpriteRegion(dest->page, x, y, 24, dire, 24, 32, bmp); }
518         modexWaitBorder();
519 }