]> 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 triggerx; //player's trigger box tile position on the viewable map
41         int triggery; //player's trigger box tile position on the viewable map
42         int hp; //hitpoints of the player
43 } player;
44
45
46 map_t allocMap(int w, int h);
47 void initMap(map_t *map);
48 void mapScrollRight(map_view_t *mv, byte offset);
49 void mapScrollLeft(map_view_t *mv, byte offest);
50 void mapScrollUp(map_view_t *mv, byte offset);
51 void mapScrollDown(map_view_t *mv, byte offset);
52 void mapGoTo(map_view_t *mv, int tx, int ty);
53 void mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y);
54 void mapDrawRow(map_view_t *mv, int tx, int ty, word y);
55 void mapDrawCol(map_view_t *mv, int tx, int ty, word x);
56 void animatePlayer(map_view_t *src, map_view_t *dest, /*map_view_t *top, */short d1, short d2, int x, int y, int ls, int lp, bitmap_t *bmp);
57
58 void ma();
59
60 #define TILEWH 16
61 #define QUADWH (TILEWH/4)
62 #define SPEED 4
63
64 //place holder definitions
65 #define MAPX 40
66 #define MAPY 30
67 //#define SWAP(a, b) tmp=a; a=b; b=tmp;
68 void main() {
69         bitmap_t ptmp; // player sprite
70         int q=1;
71         static int persist_aniframe = 0;    /* gonna be increased to 1 before being used, so 0 is ok for default */
72         page_t screen, screen2, screen3;
73         map_t map;
74         map_view_t mv, mv2, mv3;
75         map_view_t *bg, *spri, *mask;//, *tmp;
76         byte *ptr;
77
78         setkb(1);
79         /* create the map */
80         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
81         initMap(&map);
82         mv.map = &map;
83         mv2.map = &map;
84         mv3.map = &map;
85
86         /* draw the tiles */
87         ptr = map.data;
88         ptmp = bitmapLoadPcx("ptmp.pcx"); // load sprite
89         ma();
90         modexEnter();
91         modexPalUpdate(ptmp.palette);
92         screen = modexDefaultPage();
93         screen.width += (TILEWH*2);
94         screen.height += ((TILEWH*2)+QUADWH);
95         mv.page = &screen;
96         screen2 = modexNextPage(mv.page);
97         mv2.page = &screen2;
98         screen3 = screen2;
99         mv3.page = &screen3;
100
101         /* set up paging */
102         bg = &mv;
103         spri = &mv2;
104         mask = &mv3;
105
106 //TODO: LOAD map data and position the map in the middle of the screen if smaller then screen
107         mapGoTo(bg, 0, 0);
108         mapGoTo(spri, 0, 0);
109         //mapGoTo(mask, 0, 0);
110
111         //TODO: put player in starting position of spot
112         //default player position on the viewable map
113         player.tx = bg->tx + 10;
114         player.ty = bg->ty + 8;
115         player.x = player.tx*TILEWH;
116         player.y = player.ty*TILEWH;
117         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 64, 24, 32, &ptmp);
118         modexCopyPageRegion(bg->page, spri->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
119         modexShowPage(bg->page);
120         while(!keyp(1))//!keyp(1))
121         {
122         //top left corner & bottem right corner of map veiw be set as map edge trigger since maps are actually square
123         //to stop scrolling and have the player position data move to the edge of the screen with respect to the direction
124         //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
125         
126         #define INC_PER_FRAME if(q&1) persist_aniframe++; if(persist_aniframe>4) persist_aniframe = 1;  
127
128         //temp testing
129                 /*if(bg->tx >= 0 && bg->tx+20 < MAPX && player.tx == bg->tx + 10)
130                 {
131                         for(q=1; q<=(TILEWH/SPEED); q++)
132                         {
133                                 //INC_PER_FRAME;
134                                 //animatePlayer(bg, spri, mask, 1, 1, player.x, player.y, persist_aniframe, q, &ptmp);
135                                 //animatePlayer(bg, spri, 1, 1, player.x, player.y, persist_aniframe, q, &ptmp);
136                                 mapScrollRight(bg, SPEED);
137                                 //mapScrollRight(spri, SPEED);
138                                 //mapScrollRight(mask, SPEED);
139                                 modexShowPage(bg->page);
140                         }
141                         player.tx++;
142                 }
143                 else if(player.tx < MAPX)
144                 {
145                         for(q=1; q<=(TILEWH/SPEED); q++)
146                         {
147                                 INC_PER_FRAME;
148                                 player.x+=SPEED;
149                                 //animatePlayer(bg, spri, mask, 1, 0, player.x, player.y, persist_aniframe, q, &ptmp);
150                                 animatePlayer(bg, spri, 1, 0, player.x, player.y, persist_aniframe, q, &ptmp);
151                                 modexShowPage(spri->page);
152                         }
153                         player.tx++;
154                 }
155                 else
156                 {
157 break;
158                 }*/
159         if(keyp(77) && !keyp(75))
160         {
161                 if(bg->tx >= 0 && bg->tx+20 < MAPX && player.tx == bg->tx + 10 && !(player.tx+1 == 2 && player.ty == 2))
162                 {
163                         for(q=1; q<=(TILEWH/SPEED); q++)
164                         {
165                                 INC_PER_FRAME;
166                                 //animatePlayer(bg, spri, mask, 1, 1, player.x, player.y, persist_aniframe, q, &ptmp);
167                                 animatePlayer(bg, spri, 1, 1, player.x, player.y, persist_aniframe, q, &ptmp);
168                                 mapScrollRight(bg, SPEED);
169                                 mapScrollRight(spri, SPEED);
170                                 //mapScrollRight(mask, SPEED);
171                                 modexShowPage(spri->page);
172                         }
173                         player.tx++;
174                 }
175                 else if(player.tx < MAPX && !(player.tx+1 == 2 && player.ty == 2))
176                 {
177                         for(q=1; q<=(TILEWH/SPEED); q++)
178                         {
179                                 INC_PER_FRAME;
180                                 player.x+=SPEED;
181                                 //animatePlayer(bg, spri, mask, 1, 0, player.x, player.y, persist_aniframe, q, &ptmp);
182                                 animatePlayer(bg, spri, 1, 0, player.x, player.y, persist_aniframe, q, &ptmp);
183                                 modexShowPage(spri->page);
184                         }
185                         player.tx++;
186                 }
187                 else
188                 {
189                         modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
190                         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 32, 24, 32, &ptmp);
191                         modexShowPage(spri->page);
192                 }
193                 player.triggerx = player.tx+1;
194                 player.triggery = player.ty;
195         }
196
197         if(keyp(75) && !keyp(77))
198         {
199                 if(bg->tx > 0 && bg->tx+20 <= MAPX && player.tx == bg->tx + 10 && !(player.tx-1 == 2 && player.ty == 2))
200                 {
201                         for(q=1; q<=(TILEWH/SPEED); q++)
202                         {
203                                 INC_PER_FRAME;
204                                 //animatePlayer(bg, spri, mask, 3, 1, player.x, player.y, persist_aniframe, q, &ptmp);
205                                 animatePlayer(bg, spri, 3, 1, player.x, player.y, persist_aniframe, q, &ptmp);
206                                 mapScrollLeft(bg, SPEED);
207                                 mapScrollLeft(spri, SPEED);
208                                 //mapScrollLeft(mask, SPEED);
209                                 modexShowPage(spri->page);
210                         }
211                         player.tx--;
212                 }
213                 else if(player.tx > 1 && !(player.tx-1 == 2 && player.ty == 2))
214                 {
215                         for(q=1; q<=(TILEWH/SPEED); q++)
216                         {
217                                 INC_PER_FRAME;
218                                 player.x-=SPEED;
219                                 //animatePlayer(bg, spri, mask, 3, 0, player.x, player.y, persist_aniframe, q, &ptmp);
220                                 animatePlayer(bg, spri, 3, 0, player.x, player.y, persist_aniframe, q, &ptmp);
221                                 modexShowPage(spri->page);
222                         }
223                         player.tx--;
224                 }
225                 else
226                 {
227                         modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
228                         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 96, 24, 32, &ptmp);
229                         modexShowPage(spri->page);
230                 }
231                 player.triggerx = player.tx-1;
232                 player.triggery = player.ty;
233         }
234
235         if(keyp(80) && !keyp(72))
236         {
237                 if(bg->ty >= 0 && bg->ty+15 < MAPY && player.ty == bg->ty + 8 && !(player.tx == 2 && player.ty+1 == 2))
238                 {
239                         for(q=1; q<=(TILEWH/SPEED); q++)
240                         {
241                                 INC_PER_FRAME;
242                                 //animatePlayer(bg, spri, mask, 2, 1, player.x, player.y, persist_aniframe, q, &ptmp);
243                                 animatePlayer(bg, spri, 2, 1, player.x, player.y, persist_aniframe, q, &ptmp);
244                                 mapScrollDown(bg, SPEED);
245                                 mapScrollDown(spri, SPEED);
246                                 //mapScrollDown(mask, SPEED);
247                                 modexShowPage(spri->page);
248                         }
249                         player.ty++;
250                 }
251                 else if(player.ty < MAPY && !(player.tx == 2 && player.ty+1 == 2))
252                 {
253                         for(q=1; q<=(TILEWH/SPEED); q++)
254                         {
255                                 INC_PER_FRAME;
256                                 player.y+=SPEED;
257                                 //animatePlayer(bg, spri, mask, 2, 0, player.x, player.y, persist_aniframe, q, &ptmp);
258                                 animatePlayer(bg, spri, 2, 0, player.x, player.y, persist_aniframe, q, &ptmp);
259                                 modexShowPage(spri->page);
260                         }
261                         player.ty++;
262                 }
263                 else
264                 {
265                         modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
266                         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 64, 24, 32, &ptmp);
267                         modexShowPage(spri->page);
268                 }
269                 player.triggerx = player.tx;
270                 player.triggery = player.ty+1;
271         }
272
273         if(keyp(72) && !keyp(80))
274         {
275                 if(bg->ty > 0 && bg->ty+15 <= MAPY && player.ty == bg->ty + 8 && !(player.tx == 2 && player.ty-1 == 2))
276                 {
277                         for(q=1; q<=(TILEWH/SPEED); q++)
278                         {
279                                 INC_PER_FRAME;
280                                 //animatePlayer(bg, spri, mask, 0, 1, player.x, player.y, persist_aniframe, q, &ptmp);
281                                 animatePlayer(bg, spri, 0, 1, player.x, player.y, persist_aniframe, q, &ptmp);
282                                 mapScrollUp(bg, SPEED);
283                                 mapScrollUp(spri, SPEED);
284                                 //mapScrollUp(mask, SPEED);
285                                 modexShowPage(spri->page);
286                         }
287                         player.ty--;
288                 }
289                 else if(player.ty > 1 && !(player.tx == 2 &&  player.ty-1 == 2))
290                 {
291                         for(q=1; q<=(TILEWH/SPEED); q++)
292                         {
293                                 INC_PER_FRAME;
294                                 player.y-=SPEED;
295                                 //animatePlayer(bg, spri, mask, 0, 0, player.x, player.y, persist_aniframe, q, &ptmp);
296                                 modexShowPage(spri->page);
297                                 animatePlayer(bg, spri, 0, 0, player.x, player.y, persist_aniframe, q, &ptmp);
298                         }
299                         player.ty--;
300                 }
301                 else
302                 {
303                         modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
304                         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 0, 24, 32, &ptmp);
305                         modexShowPage(spri->page);
306                 }
307                 player.triggerx = player.tx;
308                 player.triggery = player.ty-1;
309         }
310         //modexClearRegion(mask->page, 66, 66, 2, 40, 0);
311         if((player.triggerx == 2 && player.triggery == 2) && keyp(KEY_ENTER))
312         {
313                 short i;
314                 for(i=600; i>=400; i--)
315                 {
316                         sound(i);
317                 }
318                 nosound();
319         }
320         }
321
322         modexLeave();
323         setkb(0);
324         printf("Project 16 scroll.exe\n");
325         printf("tx: %d\n", bg->tx);
326         printf("ty: %d\n", bg->ty);
327         printf("player.x: %d\n", player.x);
328         printf("player.y: %d\n", player.y);
329         printf("player.tx: %d\n", player.tx);
330         printf("player.ty: %d\n", player.ty);
331         printf("player.triggx: %d\n", player.triggerx);
332         printf("player.triggy: %d\n", player.triggery);
333 }
334
335
336 map_t
337 allocMap(int w, int h) {
338         map_t result;
339
340         result.width =w;
341         result.height=h;
342         result.data = malloc(sizeof(byte) * w * h);
343
344         return result;
345 }
346
347
348 void
349 initMap(map_t *map) {
350         /* just a place holder to fill out an alternating pattern */
351         int x, y;
352         int i;
353         int tile = 1;
354         map->tiles = malloc(sizeof(tiles_t));
355
356         /* create the tile set */
357         map->tiles->data = malloc(sizeof(bitmap_t));
358         map->tiles->data->width = (TILEWH*2);
359         map->tiles->data->height= TILEWH;
360         map->tiles->data->data = malloc((TILEWH*2)*TILEWH);
361         map->tiles->tileHeight = TILEWH;
362         map->tiles->tileWidth =TILEWH;
363         map->tiles->rows = 1;
364         map->tiles->cols = 2;
365
366         i=0;
367         for(y=0; y<TILEWH; y++) {
368         for(x=0; x<(TILEWH*2); x++) {
369                 if(x<TILEWH)
370                   map->tiles->data->data[i] = 0x24;
371                 else
372                   map->tiles->data->data[i] = 0x34;
373                 i++;
374         }
375         }
376
377         i=0;
378         for(y=0; y<map->height; y++) {
379                 for(x=0; x<map->width; x++) {
380                         map->data[i] = tile;
381                         tile = tile ? 0 : 1;
382                         i++;
383                 }
384                 tile = tile ? 0 : 1;
385         }
386 }
387
388
389 void
390 mapScrollRight(map_view_t *mv, byte offset) {
391         word x, y;  /* coordinate for drawing */
392
393         /* increment the pixel position and update the page */
394         mv->page->dx += offset;
395
396         /* check to see if this changes the tile */
397         if(mv->page->dx >= mv->dxThresh ) {
398         /* go forward one tile */
399         mv->tx++;
400         /* Snap the origin forward */
401         mv->page->data += 4;
402         mv->page->dx = mv->map->tiles->tileWidth;
403
404
405         /* draw the next column */
406         x= SCREEN_WIDTH + mv->map->tiles->tileWidth;
407                 mapDrawCol(mv, mv->tx + 20 , mv->ty-1, x);
408         }
409 }
410
411
412 void
413 mapScrollLeft(map_view_t *mv, byte offset) {
414         word x, y;  /* coordinate for drawing */
415
416         /* increment the pixel position and update the page */
417         mv->page->dx -= offset;
418
419         /* check to see if this changes the tile */
420         if(mv->page->dx == 0) {
421         /* go backward one tile */
422         mv->tx--;
423                 
424         /* Snap the origin backward */
425         mv->page->data -= 4;
426         mv->page->dx = mv->map->tiles->tileWidth;
427
428         /* draw the next column */
429                 mapDrawCol(mv, mv->tx-1, mv->ty-1, 0);
430         }
431 }
432
433
434 void
435 mapScrollUp(map_view_t *mv, byte offset) {
436         word x, y;  /* coordinate for drawing */
437
438         /* increment the pixel position and update the page */
439         mv->page->dy -= offset;
440
441         /* check to see if this changes the tile */
442         if(mv->page->dy == 0 ) {
443         /* go down one tile */
444         mv->ty--;
445         /* Snap the origin downward */
446         mv->page->data -= mv->page->width*4;
447         mv->page->dy = mv->map->tiles->tileHeight;
448
449
450         /* draw the next row */
451         y= 0;
452                 mapDrawRow(mv, mv->tx-1 , mv->ty-1, y);
453         }
454 }
455
456
457 void
458 mapScrollDown(map_view_t *mv, byte offset) {
459         word x, y;  /* coordinate for drawing */
460
461         /* increment the pixel position and update the page */
462         mv->page->dy += offset;
463
464         /* check to see if this changes the tile */
465         if(mv->page->dy >= mv->dyThresh ) {
466         /* go down one tile */
467         mv->ty++;
468         /* Snap the origin downward */
469         mv->page->data += mv->page->width*4;
470         mv->page->dy = mv->map->tiles->tileHeight;
471
472
473         /* draw the next row */
474         y= SCREEN_HEIGHT + mv->map->tiles->tileHeight;
475                 mapDrawRow(mv, mv->tx-1 , mv->ty+15, y);
476         }
477
478 }
479
480
481 void
482 mapGoTo(map_view_t *mv, int tx, int ty) {
483         int px, py;
484         unsigned int i;
485
486         /* set up the coordinates */
487         mv->tx = tx;
488         mv->ty = ty;
489         mv->page->dx = mv->map->tiles->tileWidth;
490         mv->page->dy = mv->map->tiles->tileHeight;
491
492         /* set up the thresholds */
493         mv->dxThresh = mv->map->tiles->tileWidth * 2;
494         mv->dyThresh = mv->map->tiles->tileHeight * 2;
495
496         /* draw the tiles */
497         modexClearRegion(mv->page, 0, 0, mv->page->width, mv->page->height, 0);
498         py=0;
499         i=mv->ty * mv->map->width + mv->tx;
500         for(ty=mv->ty-1; py < SCREEN_HEIGHT+mv->dyThresh && ty < mv->map->height; ty++, py+=mv->map->tiles->tileHeight) {
501                 mapDrawRow(mv, tx-1, ty, py);
502         i+=mv->map->width - tx;
503         }
504 }
505
506
507 void
508 mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y) {
509         word rx;
510         word ry;
511         rx = (i % t->cols) * t->tileWidth;
512         ry = (i / t->cols) * t->tileHeight;
513         modexDrawBmpRegion(page, x, y, rx, ry, t->tileWidth, t->tileHeight, t->data);
514 }
515
516
517 void 
518 mapDrawRow(map_view_t *mv, int tx, int ty, word y) {
519         word x;
520         int i;
521
522         /* the position within the map array */
523         i=ty * mv->map->width + tx;
524         for(x=0; x<SCREEN_WIDTH+mv->dxThresh && tx < mv->map->width; x+=mv->map->tiles->tileWidth, tx++) {
525         if(i>=0) {
526                 /* we are in the map, so copy! */
527                 mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);
528         }
529         i++; /* next! */
530         }
531 }
532
533
534 void 
535 mapDrawCol(map_view_t *mv, int tx, int ty, word x) {
536         int y;
537         int i;
538
539         /* location in the map array */
540         i=ty * mv->map->width + tx;
541
542         /* We'll copy all of the columns in the screen, 
543            i + 1 row above and one below */
544         for(y=0; y<SCREEN_HEIGHT+mv->dyThresh && ty < mv->map->height; y+=mv->map->tiles->tileHeight, ty++) {
545         if(i>=0) {
546                 /* we are in the map, so copy away! */
547                 mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);
548         }
549         i += mv->map->width;
550         }
551 }
552
553 void
554 animatePlayer(map_view_t *src, map_view_t *dest, /*map_view_t *top, */short d1, short d2, int x, int y, int ls, int lp, bitmap_t *bmp)
555 {
556         short dire=32*d1;
557         short qq;
558
559         if(d2==0) qq = 0;
560         else qq = ((lp)*SPEED);
561         switch (d1)
562         {
563                 case 0:
564                         //up
565                         x=x-4;
566                         y=y-qq-TILEWH;
567                 break;
568                 case 1:
569                         // right
570                         x=x+qq-4;
571                         y=y-TILEWH;
572                 break;
573                 case 2:
574                         //down
575                         x=x-4;
576                         y=y+qq-TILEWH;
577                 break;
578                 case 3:
579                         //left
580                         x=x-qq-4;
581                         y=y-TILEWH;
582                 break;
583         }
584         modexCopyPageRegion(dest->page, src->page, x-4, y-4, x-4, y-4, 28, 40);
585         if(2>ls && ls>=1) { modexDrawSpriteRegion(dest->page, x, y, 48, dire, 24, 32, bmp); }else
586         if(3>ls && ls>=2) { modexDrawSpriteRegion(dest->page, x, y, 24, dire, 24, 32, bmp); }else
587         if(4>ls && ls>=3) { modexDrawSpriteRegion(dest->page, x, y, 0, dire, 24, 32, bmp); }else
588         if(5>ls && ls>=4) { modexDrawSpriteRegion(dest->page, x, y, 24, dire, 24, 32, bmp); }
589         //TODO: mask copy //modexCopyPageRegion(dest->page, src->page, x-4, y-4, x-4, y-4, 28, 40);
590         //modexClearRegion(top->page, 66, 66, 2, 40, 0);
591         //modexCopyPageRegion(dest->page, top->page, 66, 66, 66, 66, 2, 40);
592         //turn this off if XT
593         modexWaitBorder();
594 }
595
596 void ma()
597 {
598         int dos_memavail;
599         __asm {
600                 mov bx,0ffffh\r
601                 mov ah,48h\r
602                 int 21h\r
603                 mov dos_memavail,bx
604         }
605         printf("\n%d\n", dos_memavail);
606 }