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