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