OSDN Git Service

wwww
[proj16/16.git] / src / scroll.c
1 /* Project 16 Source Code~
2  * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669
3  *
4  * This file is part of Project 16.
5  *
6  * Project 16 is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Project 16 is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
18  * write to the Free Software Foundation, Inc., 51 Franklin Street,
19  * Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  */
22
23 #include "src/lib/dos_kb.h"
24 #include "src/lib/mapread.h"
25 #include "src/lib/wcpu/wcpu.h"
26 #include "src/lib/planar.h"
27 //====#include "src\lib\ems.c"
28
29 //word far *clock= (word far*) 0x046C; /* 18.2hz clock */
30
31 //optimize scroll*!!!!
32
33 typedef struct {
34         map_t *map;
35         page_t *page;
36         int tx; //appears to be the top left tile position on the viewable screen map
37         int ty; //appears to be the top left tile position on the viewable screen map
38         word dxThresh; //????
39         word dyThresh; //????
40 } map_view_t;
41
42 typedef struct {
43         int x; //player exact position on the viewable map
44         int y; //player exact position on the viewable map
45         int tx; //player tile position on the viewable map
46         int ty; //player tile position on the viewable map
47         int triggerx; //player's trigger box tile position on the viewable map
48         int triggery; //player's trigger box tile position on the viewable map
49         int setx; //NOT USED YET! player sprite sheet set on the image x
50         int sety; //NOT USED YET! player sprite sheet set on the image y
51         word q; //loop variable
52         word d; //direction
53         bitmap_t data; //supposively the sprite sheet data
54         int hp; //hitpoints of the player
55 } actor_t;
56
57 typedef struct
58 {
59         map_view_t *mv;
60 } map_view_db_t;
61
62 map_t allocMap(int w, int h);
63 void initMap(map_t *map);
64 void mapScrollRight(map_view_t *mv, byte offset, word id);
65 void mapScrollLeft(map_view_t *mv, byte offest, word id);
66 void mapScrollUp(map_view_t *mv, byte offset, word id);
67 void mapScrollDown(map_view_t *mv, byte offset, word id);
68 void mapGoTo(map_view_t *mv, int tx, int ty);
69 void mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y);
70 void mapDrawRow(map_view_t *mv, int tx, int ty, word y);
71 void mapDrawCol(map_view_t *mv, int tx, int ty, word x);
72 void qclean();
73 void pdump(map_view_t *pee);
74 void animatePlayer(map_view_t *src, map_view_t *dest, /*map_view_t *top, */sword d, short scrolloffsetswitch, int x, int y, int ls, int lp, bitmap_t *bmp);
75
76 #define TILEWH 16
77 #define QUADWH                  TILEWH/2
78 #define SPEED 4
79 //#define LOOPMAX (TILEWH/SPEED)
80
81 //place holder definitions
82 //#define MAPX 200
83 //#define MAPY 150
84 //#define TRIGGX 10
85 //#define TRIGGY 9
86
87 void main() {
88 //++++  size_t oldfreemem=GetFreeSize();
89         /*long emmhandle;
90         long emsavail;
91         char teststr[80];*/
92         word panswitch=0, panq=1, pand=0, panpagenum=0; //for panning!
93         int i;
94         static word paloffset=0;
95         bitmap_t ptmp;//, npctmp; // player sprite
96         planar_buf_t *p;
97         const char *cpus;
98         static int persist_aniframe = 0;    /* gonna be increased to 1 before being used, so 0 is ok for default */
99         page_t screen, screen2, screen3;
100         map_t map;
101         map_view_t mv[3];//mv, mv2, mv3;
102         map_view_t *bg, *spri, *mask;//, *tmp;
103         //map_view_db_t pgid[4];
104         byte *dpal, *gpal;
105         byte *ptr;
106         byte *mappalptr;
107         actor_t player;
108         //actor_t npc0;
109
110 //      atexit(qclean());
111         /*if(!emmtest())
112         {
113                 printf("Expanded memory is not present\n");
114                 exit(0);
115         }
116
117         if(!emmok())
118         {
119                 printf("Expanded memory manager is not present\n");
120                 exit(0);
121         }
122
123         emsavail = emmavail();
124         if(emsavail == -1)
125         {
126                 printf("Expanded memory manager error\n");
127                 exit(0);
128         }
129         printf("There are %ld pages available\n",emsavail);
130
131         if((emmhandle = emmalloc(emsavail)) < 0)
132         {
133                 printf("Insufficient pages available\n");
134                 exit(0);
135         }*/
136
137         /* create the map */
138 //0000  printf("Total used @ before map load:                   %zu\n", oldfreemem-GetFreeSize());
139 //0000  fprintf(stderr, "testing~\n");
140         loadmap("data/test.map", &map);
141 //0000  fprintf(stderr, "yay map loaded~~\n");
142 //----  map = allocMap(map.width,map.height); //20x15 is the resolution of the screen you can make maps smaller than 20x15 but the null space needs to be drawn properly
143         //if(isEMS()) printf("%d tesuto\n", coretotalEMS());
144 //----  initMap(&map);
145         mv[0].map = &map;
146         mv[1].map = &map;
147         mv[2].map = &map;
148
149         /* draw the tiles */
150         ptr = map.data;
151         mappalptr = map.tiles->data->palette;
152         /* data */
153 //0000  printf("Total used @ before image loading:              %zu\n", oldfreemem-GetFreeSize());
154         ptmp = bitmapLoadPcx("data/ptmp.pcx"); // load sprite
155         //npctmp = bitmapLoadPcx("ptmp1.pcx"); // load sprite
156
157         /* create the planar buffer */
158 //0000  printf("Total used @ before planar buffer creation:     %zu\n", oldfreemem-GetFreeSize());
159         p = planar_buf_from_bitmap(&ptmp);
160 //0000  printf("Total used @ after planar buffer creation:      %zu\n", oldfreemem-GetFreeSize());
161
162         /*if(isEMS())
163         {
164                 XMOVE mm;
165                 mm.length=sizeof(map);
166                 mm.sourceH=0;
167                 mm.sourceOff=(long)&map;
168                 mm.destH=emmhandle;
169                 mm.destOff=1;
170                 //halp!
171                 ist = move_emem(&mm);
172                 printf("%d\n", coretotalEMS());
173                 if(!ist){ dealloc_emem(emmhandle); exit(5); }
174                 //printf("%d\n", emmhandle);
175         }
176
177         if(isEMS())
178         {
179                 XMOVE mm;
180                 mm.length=emmhandle;
181                 mm.sourceH=0;
182                 mm.sourceOff=(long)&ptmp;
183                 mm.destH=emmhandle;
184                 mm.destOff=0;
185                 //halp!
186                 ist = move_emem(&mm);
187                 printf("%d\n", coretotalEMS());
188                 if(!ist){ dealloc_emem(emmhandle); exit(5); }
189                 //printf("%d\n", emmhandle);
190         }
191 */
192
193         /* save the palette */
194         dpal = modexNewPal();
195         modexPalSave(dpal);
196         modexFadeOff(4, dpal);
197
198         setkb(1);
199         modexEnter();
200         modexPalBlack();        //reset the palette~
201 //      printf("Total used @ before palette initiation:         %zu\n", oldfreemem-GetFreeSize());
202         ptmp.offset=(paloffset/3);
203         modexPalUpdate(&ptmp, &paloffset, 0, 0);
204         //printf("      %d\n", sizeof(ptmp.data));
205         //printf("1:    %d\n", paloffset);
206         map.tiles->data->offset=(paloffset/3);
207         //XTmodexPalUpdate(map.tiles->data, &paloffset, 0, 0);
208         printf("\n====\n");
209         printf("0       paloffset=      %d\n", paloffset/3);
210         printf("====\n\n");
211         gpal = modexNewPal();
212         modexPalSave(gpal);
213         modexSavePalFile("data/g.pal", gpal);
214         modexPalBlack();        //so player will not see loadings~
215
216         /* setup camera and screen~ */
217         screen = modexDefaultPage();
218         screen.width += (TILEWH*2);
219         screen.height += (TILEWH*2);//+QUADWH;
220         mv[0].page = &screen;
221         screen2 = modexNextPage(mv[0].page);
222         mv[1].page = &screen2;
223         screen3 = modexNextPage0(mv[1].page, 320, 240); //(352*176)+1024 is the remaining amount of memory left wwww
224         //screen3 = modexNextPage0(mv2.page, 320, 192); //(352*176)+1024 is the remaining amount of memory left wwww
225         mv[2].page = &screen3;
226
227         /* set up paging */
228         bg = &mv[0];
229         spri = &mv[1];
230         mask = &mv[2];
231
232 //TODO: LOAD map data and position the map in the middle of the screen if smaller then screen
233         mapGoTo(bg, 0, 0);
234         mapGoTo(spri, 0, 0);
235         //mapGoTo(mask, 0, 0);
236
237         //TODO: put player in starting position of spot
238         //default player position on the viewable map
239         player.tx = bg->tx + 10;
240         player.ty = bg->ty + 8;
241         player.x = player.tx*TILEWH;
242         player.y = player.ty*TILEWH;
243         player.triggerx = player.tx;
244         player.triggery = player.ty+1;
245         player.q=1;
246         player.d=0;
247         player.hp=4;
248         //npc
249         /*npc0.tx = bg->tx + 1;
250         npc0.ty = bg->ty + 1;
251         npc0.x = npc0.tx*TILEWH;
252         npc0.y = npc0.ty*TILEWH;
253         npc0.triggerx = npc0.tx;
254         npc0.triggery = npc0.ty+1;
255         npc0.q=1;
256         npc0.d=0;
257         modexDrawSpriteRegion(spri->page, npc0.x-4, npc0.y-TILEWH, 24, 64, 24, 32, &npctmp);*/
258         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 64, 24, 32, &ptmp);
259
260         modexShowPage(spri->page);
261 //      printf("Total used @ before loop:                       %zu\n", oldfreemem-GetFreeSize());
262         modexClearRegion(mv[2].page, 0, 0, mv[2].page->width, mv[2].page->height, 1);
263         modexFadeOn(4, gpal);
264         while(!keyp(1) && player.hp>0)
265         {
266         //top left corner & bottem right corner of map veiw be set as map edge trigger since maps are actually square
267         //to stop scrolling and have the player position data move to the edge of the screen with respect to the direction
268         //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
269         #define INC_PER_FRAME if(player.q&1) persist_aniframe++; if(persist_aniframe>4) persist_aniframe = 1;
270
271         //player movement
272         //TODO: make movement into a function!
273         if(!panswitch){
274         //right movement
275         if((keyp(77) && !keyp(75) && player.d == 0) || player.d == 2)
276         {
277                 if(player.d == 0){ player.d = 2; }
278                 if(bg->tx >= 0 && bg->tx+20 < map.width && player.tx == bg->tx + 10 &&
279                 !(bg->map->data[(player.tx)+(map.width*(player.ty-1))] == 0))//!(player.tx+1 == TRIGGX && player.ty == TRIGGY)) //collision detection!
280                 {
281                         if(player.q<=(TILEWH/SPEED))
282                         {
283                                 INC_PER_FRAME;
284                                 //animatePlayer(bg, spri, mask, 1, 1, player.x, player.y, persist_aniframe, q, &ptmp);
285                                 animatePlayer(bg, spri, player.d-1, 1, player.x, player.y, persist_aniframe, player.q, &ptmp);
286                                 mapScrollRight(mv, SPEED, 0);
287                                 mapScrollRight(mv, SPEED, 1);
288                                 //mapScrollRight(mask, SPEED);
289                                 modexShowPage(spri->page);
290                                 player.q++;
291                         } else { player.q = 1; player.d = 0; player.tx++; }
292                 }
293                 else if(player.tx < map.width && !(bg->map->data[(player.tx)+(map.width*(player.ty-1))] == 0))//!(player.tx+1 == TRIGGX && player.ty == TRIGGY))
294                 {
295                         if(player.q<=(TILEWH/SPEED))
296                         {
297                                 INC_PER_FRAME;
298                                 player.x+=SPEED;
299                                 //animatePlayer(bg, spri, mask, 1, 0, player.x, player.y, persist_aniframe, q, &ptmp);
300                                 animatePlayer(bg, spri, player.d-1, 0, player.x, player.y, persist_aniframe, player.q, &ptmp);
301                                 modexShowPage(spri->page);
302                                 player.q++;
303                         } else { player.q = 1; player.d = 0; player.tx++; }
304                 }
305                 else
306                 {
307                         modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
308                         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 32, 24, 32, &ptmp);
309                         modexShowPage(spri->page);
310                         player.d = 0;
311                 }
312                 player.triggerx = player.tx+1;
313                 player.triggery = player.ty;
314         }
315
316         //left movement
317         if((keyp(75) && !keyp(77) && player.d == 0) || player.d == 4)
318         {
319                 if(player.d == 0){ player.d = 4; }
320                 if(bg->tx > 0 && bg->tx+20 <= map.width && player.tx == bg->tx + 10 &&
321                 !(bg->map->data[(player.tx-2)+(map.width*(player.ty-1))] == 0))//!(player.tx-1 == TRIGGX && player.ty == TRIGGY))       //collision detection!
322                 {
323                         if(player.q<=(TILEWH/SPEED))
324                         {
325                                 INC_PER_FRAME;
326                                 //animatePlayer(bg, spri, mask, 3, 1, player.x, player.y, persist_aniframe, q, &ptmp);
327                                 animatePlayer(bg, spri, player.d-1, 1, player.x, player.y, persist_aniframe, player.q, &ptmp);
328                                 mapScrollLeft(mv, SPEED, 0);
329                                 mapScrollLeft(mv, SPEED, 1);
330                                 //mapScrollLeft(mask, SPEED);
331                                 modexShowPage(spri->page);
332                                 player.q++;
333                         } else { player.q = 1; player.d = 0; player.tx--; }
334                 }
335                 else if(player.tx > 1 && !(bg->map->data[(player.tx-2)+(map.width*(player.ty-1))] == 0))//!(player.tx-1 == TRIGGX && player.ty == TRIGGY))
336                 {
337                         if(player.q<=(TILEWH/SPEED))
338                         {
339                                 INC_PER_FRAME;
340                                 player.x-=SPEED;
341                                 //animatePlayer(bg, spri, mask, 3, 0, player.x, player.y, persist_aniframe, q, &ptmp);
342                                 animatePlayer(bg, spri, player.d-1, 0, player.x, player.y, persist_aniframe, player.q, &ptmp);
343                                 modexShowPage(spri->page);
344                                 player.q++;
345                         } else { player.q = 1; player.d = 0; player.tx--; }
346                 }
347                 else
348                 {
349                         modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
350                         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 96, 24, 32, &ptmp);
351                         modexShowPage(spri->page);
352                         player.d = 0;
353                 }
354                 player.triggerx = player.tx-1;
355                 player.triggery = player.ty;
356         }
357
358         //down movement
359         if((keyp(80) && !keyp(72) && player.d == 0) || player.d == 3)
360         {
361                 if(player.d == 0){ player.d = 3; }
362                 if(bg->ty >= 0 && bg->ty+15 < map.height && player.ty == bg->ty + 8 &&
363                 !(bg->map->data[(player.tx-1)+(map.width*(player.ty))] == 0))//!(player.tx == TRIGGX && player.ty+1 == TRIGGY)) //collision detection!
364                 {
365                         if(player.q<=(TILEWH/SPEED))
366                         {
367                                 INC_PER_FRAME;
368                                 //animatePlayer(bg, spri, mask, 2, 1, player.x, player.y, persist_aniframe, q, &ptmp);
369                                 animatePlayer(bg, spri, player.d-1, 1, player.x, player.y, persist_aniframe, player.q, &ptmp);
370                                 mapScrollDown(mv, SPEED, 0);
371                                 mapScrollDown(mv, SPEED, 1);
372                                 //mapScrollDown(mask, SPEED);
373                                 modexShowPage(spri->page);
374                                 player.q++;
375                         } else { player.q = 1; player.d = 0; player.ty++; }
376                 }
377                 else if(player.ty < map.height && !(bg->map->data[(player.tx-1)+(map.width*(player.ty))] == 0))//!(player.tx == TRIGGX && player.ty+1 == TRIGGY))
378                 {
379                         if(player.q<=(TILEWH/SPEED))
380                         {
381                                 INC_PER_FRAME;
382                                 player.y+=SPEED;
383                                 //animatePlayer(bg, spri, mask, 2, 0, player.x, player.y, persist_aniframe, q, &ptmp);
384                                 animatePlayer(bg, spri, player.d-1, 0, player.x, player.y, persist_aniframe, player.q, &ptmp);
385                                 modexShowPage(spri->page);
386                                 player.q++;
387                         } else { player.q = 1; player.d = 0; player.ty++; }
388                 }
389                 else
390                 {
391                         modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
392                         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 64, 24, 32, &ptmp);
393                         modexShowPage(spri->page);
394                         player.d = 0;
395                 }
396                 player.triggerx = player.tx;
397                 player.triggery = player.ty+1;
398         }
399
400         //up movement
401         if((keyp(72) && !keyp(80) && player.d == 0) || player.d == 1)
402         {
403                 if(player.d == 0){ player.d = 1; }
404                 if(bg->ty > 0 && bg->ty+15 <= map.height && player.ty == bg->ty + 8 &&
405                 !(bg->map->data[(player.tx-1)+(map.width*(player.ty-2))] == 0))//!(player.tx == TRIGGX && player.ty-1 == TRIGGY))       //collision detection!
406                 {
407                         if(player.q<=(TILEWH/SPEED))
408                         {
409                                 INC_PER_FRAME;
410                                 //animatePlayer(bg, spri, mask, 0, 1, player.x, player.y, persist_aniframe, q, &ptmp);
411                                 animatePlayer(bg, spri, player.d-1, 1, player.x, player.y, persist_aniframe, player.q, &ptmp);
412                                 mapScrollUp(mv, SPEED, 0);
413                                 mapScrollUp(mv, SPEED, 1);
414                                 //mapScrollUp(mask, SPEED);
415                                 modexShowPage(spri->page);
416                                 player.q++;
417                         } else { player.q = 1; player.d = 0; player.ty--; }
418                 }
419                 else if(player.ty > 1 && !(bg->map->data[(player.tx-1)+(map.width*(player.ty-2))] == 0))//!(player.tx == TRIGGX &&  player.ty-1 == TRIGGY))
420                 {
421                         if(player.q<=(TILEWH/SPEED))
422                         {
423                                 INC_PER_FRAME;
424                                 player.y-=SPEED;
425                                 //animatePlayer(bg, spri, mask, 0, 0, player.x, player.y, persist_aniframe, q, &ptmp);
426                                 modexShowPage(spri->page);
427                                 animatePlayer(bg, spri, player.d-1, 0, player.x, player.y, persist_aniframe, player.q, &ptmp);
428                                 player.q++;
429                         } else { player.q = 1; player.d = 0; player.ty--; }
430                 }
431                 else
432                 {
433                         modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
434                         modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 0, 24, 32, &ptmp);
435                         modexShowPage(spri->page);
436                         player.d = 0;
437                 }
438                 player.triggerx = player.tx;
439                 player.triggery = player.ty-1;
440         }
441 }else{
442 //88 switch!
443         //right movement
444         if((keyp(77) && !keyp(75) && pand == 0) || pand == 2)
445         {
446                 if(pand == 0){ pand = 2; }
447                         if(panq<=(TILEWH/SPEED))
448                         {
449                                 switch(panpagenum)
450                                 {
451                                         case 0:
452                                                 //bg
453                                                 bg->page->dx++;
454                                                 modexShowPage(bg->page);
455                                         break;
456                                         case 1:
457                                                 //spri
458                                                 spri->page->dx++;
459                                                 modexShowPage(spri->page);
460                                         break;
461                                         case 2:
462                                                 //fg
463                                                 mask->page->dx++;
464                                                 modexShowPage(mask->page);
465                                         break;
466                                 }
467                                 panq++;
468                         } else { panq = 1; pand = 0; }
469         }
470         //left movement
471         if((keyp(75) && !keyp(77) && pand == 0) || pand == 4)
472         {
473                 if(pand == 0){ pand = 4; }
474                         if(panq<=(TILEWH/SPEED))
475                         {
476                                 switch(panpagenum)
477                                 {
478                                         case 0:
479                                                 //bg
480                                                 bg->page->dx--;
481                                                 modexShowPage(bg->page);
482                                         break;
483                                         case 1:
484                                                 //spri
485                                                 spri->page->dx--;
486                                                 modexShowPage(spri->page);
487                                         break;
488                                         case 2:
489                                                 //fg
490                                                 mask->page->dx--;
491                                                 modexShowPage(mask->page);
492                                         break;
493                                 }
494                                 panq++;
495                         } else { panq = 1; pand = 0; }
496         }
497         //down movement
498         if((keyp(72) && !keyp(80) && pand == 0) || pand == 3)
499         {
500                 if(pand == 0){ pand = 3; }
501                         if(panq<=(TILEWH/SPEED))
502                         {
503                                 switch(panpagenum)
504                                 {
505                                         case 0:
506                                                 //bg
507                                                 bg->page->dy--;
508                                                 modexShowPage(bg->page);
509                                         break;
510                                         case 1:
511                                                 //spri
512                                                 spri->page->dy--;
513                                                 modexShowPage(spri->page);
514                                         break;
515                                         case 2:
516                                                 //fg
517                                                 mask->page->dy--;
518                                                 modexShowPage(mask->page);
519                                         break;
520                                 }
521                                 panq++;
522                         } else { panq = 1; pand = 0; }
523         }
524         //up movement
525         if((keyp(80) && !keyp(72) && pand == 0) || pand == 1)
526         {
527                 if(pand == 0){ pand = 1; }
528                         if(panq<=(TILEWH/SPEED))
529                         {
530                                 switch(panpagenum)
531                                 {
532                                         case 0:
533                                                 //bg
534                                                 bg->page->dy++;
535                                                 modexShowPage(bg->page);
536                                         break;
537                                         case 1:
538                                                 //spri
539                                                 spri->page->dy++;
540                                                 modexShowPage(spri->page);
541                                         break;
542                                         case 2:
543                                                 //fg
544                                                 mask->page->dy++;
545                                                 modexShowPage(mask->page);
546                                         break;
547                                 }
548                                 panq++;
549                         } else { panq = 1; pand = 0; }
550         }
551 }
552
553         //the scripting stuf....
554
555         //if(((player.triggerx == TRIGGX && player.triggery == TRIGGY) && keyp(0x1C))||(player.tx == 5 && player.ty == 5))
556         if(((bg->map->data[(player.triggerx-1)+(map.width*(player.triggery-1))] == 0) && keyp(0x1C))||(player.tx == 5 && player.ty == 5))
557         {
558                 short i;
559                 for(i=800; i>=400; i--)
560                 {
561                         sound(i);
562                 }
563                 nosound();
564         }
565         if(player.q == (TILEWH/SPEED)+1 && player.d > 0 && (player.triggerx == 5 && player.triggery == 5)){ player.hp--; }
566         //debugging binds!
567         //if(keyp(0x0E)) while(1){ if(xmsmalloc(24)) break; }
568         if(keyp(2)){ modexShowPage(bg->page); panpagenum=0; }
569         if(keyp(3)){ modexShowPage(spri->page); panpagenum=1; }
570         if(keyp(4)){ modexShowPage(mask->page); panpagenum=2; }
571         if(keyp(25)){ pdump(bg); pdump(spri); } //p
572         if(keyp(24)){ modexPalUpdate0(gpal); paloffset=0; pdump(bg); pdump(spri); }
573         if(keyp(22)){
574         paloffset=0; modexPalBlack(); modexPalUpdate(&ptmp, &paloffset, 0, 0);
575         printf("1paloffset      =       %d\n", paloffset/3);
576          modexPalUpdate(map.tiles->data, &paloffset, 0, 0);
577         printf("2paloffset      =       %d\n", paloffset/3);
578          pdump(bg); pdump(spri); }
579         //pan switch
580         if(keyp(88)){if(!panswitch) panswitch++; else panswitch--; }    //f12
581         //TSR
582         if(keyp(87))    //f11
583         {
584                 modexLeave();
585                 setkb(0);
586                 __asm
587                 {
588                         mov ah,31h
589                         int 21h
590                 }
591         }
592
593         if((player.q==1) && !(player.x%TILEWH==0 && player.y%TILEWH==0)) break; //incase things go out of sync!
594
595         }
596
597         /* fade back to text mode */
598         /* but 1st lets save the game palette~ */
599         modexPalSave(gpal);
600         modexSavePalFile("data/g.pal", gpal);
601         modexFadeOff(4, gpal);
602         modexLeave();
603         setkb(0);
604         printf("Project 16 scroll.exe\n");
605         printf("tx: %d\n", bg->tx);
606         printf("ty: %d\n", bg->ty);
607         printf("player.x: %d", player.x); printf("              player.y: %d\n", player.y);
608         //if(player.hp==0) printf("%d wwww\n", player.y+8);
609         //else printf("\nplayer.y: %d\n", player.y);
610         printf("player.tx: %d", player.tx); printf("            player.ty: %d\n", player.ty);
611         printf("player.triggx: %d", player.triggerx); printf("  player.triggy: %d\n", player.triggery);
612         printf("player.hp: %d", player.hp);     printf("        player.q: %d", player.q);       printf("        player.d: %d\n", player.d);
613         printf("tile data value at player trigger position: %d\n", bg->map->data[(player.triggerx-1)+(map.width*(player.triggery-1))]);
614         printf("palette offset: %d\n", paloffset/3);
615 //++++  printf("Total used: %zu\n", oldfreemem-GetFreeSize());
616 //++++  printf("Total free: %zu\n", GetFreeSize());
617         printf("temporary player sprite 0: http://www.pixiv.net/member_illust.php?mode=medium&illust_id=45556867\n");
618         printf("temporary player sprite 1: http://www.pixiv.net/member_illust.php?mode=medium&illust_id=44606385\n");
619         printf("Screen: %dx", screen.width);    printf("%d\n", screen.height);
620         printf("Screen2: %dx", screen2.width);  printf("%d\n", screen2.height);
621         //printf("map.width=%d  map.height=%d   map.data[0]=%d\n", bg->map->width, bg->map->height, bg->map->data[0]);
622         //xmsfree(&map);
623         //xmsfree(bg);
624         //xmsfree(spri);
625         //xmsfree(mask);
626         //xmsreport();
627         //emmclose(emmhandle);
628         switch(detectcpu())
629         {
630                 case 0: cpus = "8086/8088 or 186/88"; break;
631                 case 1: cpus = "286"; break;
632                 case 2: cpus = "386 or newer"; break;
633                 default: cpus = "internal error"; break;
634         }
635         printf("detected CPU type: %s\n", cpus);
636         modexFadeOn(4, dpal);
637 }
638
639
640 map_t
641 allocMap(int w, int h) {
642         map_t result;
643
644         result.width =w;
645         result.height=h;
646         result.data = malloc(sizeof(byte) * w * h);
647         //result.data = (byte *)alloc_emem(((int)sizeof(byte) * w * h)/1024);
648         /*if(isEMS() || checkEMS())
649         {
650                 XMOVE mm;
651                 //emmhandle = mallocEMS(coretotalEMS());//alloc_emem((int)sizeof(map))
652                 mm.length=sizeof(result);
653                 mm.sourceH=0;
654                 mm.sourceOff=ptr2long(&result);
655                 mm.destH=emmhandle;
656                 mm.destOff=0;
657                 ist = move_emem(&mm);
658                 if(!ist){ dealloc_emem(emmhandle); exit(5); }
659                 printf("%d\n", coretotalEMS());
660         }*/
661
662         return result;
663 }
664
665 void
666 initMap(map_t *map) {
667         /* just a place holder to fill out an alternating pattern */
668         int x, y, xx, yy;
669         int i, q;
670 //      int tile = 1;
671         //if(!isEMS() || !checkEMS())
672 //              map->tiles = malloc(sizeof(tiles_t));
673         //else
674         //      map->tiles = (tiles_t *)alloc_emem(sizeof(tiles_t));
675
676         /* create the tile set */
677         //if(!isEMS() || !checkEMS())
678 //              map->tiles->data = malloc(sizeof(bitmap_t));
679         //else
680         //      map->tiles->data = (bitmap_t *)alloc_emem(sizeof(bitmap_t));
681 //      map->tiles->data->width = (TILEWH/**2*/);
682 //      map->tiles->data->height= TILEWH;
683         //if(!isEMS() || !checkEMS())
684 //              map->tiles->data->data = malloc((TILEWH*2)*TILEWH);
685         //else
686         //      map->tiles->data->data = (byte *)alloc_emem((TILEWH*2)*TILEWH);
687 //      map->tiles->tileHeight = TILEWH;
688 //      map->tiles->tileWidth =TILEWH;
689 //      map->tiles->rows = 1;
690 //      map->tiles->cols = 1;//2;
691
692         /*q=0;
693         //for(y=0; y<map->height; y++) {
694         //for(x=0; x<map->width; x++) {
695         i=0;
696         for(yy=0; yy<TILEWH; yy++) {
697         for(xx=0; xx<(TILEWH); xx++) {
698                 //if(x<TILEWH){
699                   map->tiles->data->data[i+1] = map->data[q];//28;//0x24;
700 //                printf("[%d]", map->tiles->data->data[i]);
701                 //}else{
702                   //map->tiles->data->data[i] = map->data[q];//0;//0x34;
703                   //printf("]%d[==[%d]", i, map->tiles->data->data[i]);
704                 //}
705                 i++;
706         }
707 //      printf("\n");
708         }
709 //      printf("[%d]", map->data[q]);
710         q++;
711 //      }
712         //printf("\n\n");
713 //      }*/
714
715         /*i=0;
716         for(y=0; y<map->height; y++) {
717                 for(x=0; x<map->width; x++) {
718 //                      map->data[i]=255;
719                         printf("[%d]", map->data[i]);
720                         //tile = tile ? 0 : 1;
721                         i++;
722                 }
723                 //tile = tile ? 0 : 1;
724         }*/
725 }
726
727
728 void
729 mapScrollRight(map_view_t *mv, byte offset, word id)
730 {
731         word x, y;  /* coordinate for drawing */
732
733         /* increment the pixel position and update the page */
734         mv[id].page->dx += offset;
735
736         /* check to see if this changes the tile */
737         if(mv[id].page->dx >= mv[id].dxThresh ) {
738         /* go forward one tile */
739         mv[id].tx++;
740         /* Snap the origin forward */
741         mv[id].page->data += 4;
742         mv[id].page->dx = mv[id].map->tiles->tileWidth;
743
744         /* draw the next column */
745         x= SCREEN_WIDTH + mv[id].map->tiles->tileWidth;
746                 if(id==0)
747                         mapDrawCol(&mv[0], mv[0].tx + 20 , mv[0].ty-1, x);
748                 else
749                         modexCopyPageRegion(mv[id].page, mv[0].page, x, 0, x, 0, mv[id].map->tiles->tileWidth, mv[id].map->tiles->tileHeight*17);
750         }
751 }
752
753
754 void
755 mapScrollLeft(map_view_t *mv, byte offset, word id)
756 {
757         word x, y;  /* coordinate for drawing */
758
759         /* increment the pixel position and update the page */
760         mv[id].page->dx -= offset;
761
762         /* check to see if this changes the tile */
763         if(mv[id].page->dx == 0) {
764         /* go backward one tile */
765         mv[id].tx--;
766
767         /* Snap the origin backward */
768         mv[id].page->data -= 4;
769         mv[id].page->dx = mv[id].map->tiles->tileWidth;
770
771         /* draw the next column */
772         x= 0;
773                 if(id==0)
774                         mapDrawCol(&mv[0], mv[0].tx-1, mv[0].ty-1, 0);
775                 else
776                         modexCopyPageRegion(mv[id].page, mv[0].page, x, 0, x, 0, mv[id].map->tiles->tileWidth, mv[id].map->tiles->tileHeight*17);
777         }
778 }
779
780
781 void
782 mapScrollUp(map_view_t *mv, byte offset, word id)
783 {
784         word x, y;  /* coordinate for drawing */
785
786         /* increment the pixel position and update the page */
787         mv[id].page->dy -= offset;
788
789         /* check to see if this changes the tile */
790         if(mv[id].page->dy == 0 ) {
791         /* go down one tile */
792         mv[id].ty--;
793         /* Snap the origin downward */
794         mv[id].page->data -= mv[id].page->width*4;
795         mv[id].page->dy = mv[id].map->tiles->tileHeight;
796
797         /* draw the next row */
798         y= 0;
799                 if(id==0)
800                         mapDrawRow(&mv[0], mv[0].tx-1 , mv[0].ty-1, 0);
801                 else
802                         modexCopyPageRegion(mv[id].page, mv[0].page, 0, y, 0, y, mv[id].map->tiles->tileWidth*22, mv[id].map->tiles->tileHeight);
803         }
804 }
805
806
807 void
808 mapScrollDown(map_view_t *mv, byte offset, word id)
809 {
810         word x, y;  /* coordinate for drawing */
811
812         /* increment the pixel position and update the page */
813         mv[id].page->dy += offset;
814
815         /* check to see if this changes the tile */
816         if(mv[id].page->dy >= mv[id].dyThresh ) {
817         /* go down one tile */
818         mv[id].ty++;
819         /* Snap the origin downward */
820         mv[id].page->data += mv[id].page->width*4;
821         mv[id].page->dy = mv[id].map->tiles->tileHeight;
822
823         /* draw the next row */
824         y= SCREEN_HEIGHT + mv[id].map->tiles->tileHeight;
825                 if(id==0)
826                         mapDrawRow(&mv[0], mv[0].tx-1 , mv[0].ty+15, y);
827                 else
828                         modexCopyPageRegion(mv[id].page, mv[0].page, 0, y, 0, y, mv[id].map->tiles->tileWidth*22, mv[id].map->tiles->tileHeight);
829         }
830 }
831
832
833 void
834 mapGoTo(map_view_t *mv, int tx, int ty) {
835         int px, py;
836         unsigned int i;
837
838         /* set up the coordinates */
839         mv->tx = tx;
840         mv->ty = ty;
841         mv->page->dx = mv->map->tiles->tileWidth;
842         mv->page->dy = mv->map->tiles->tileHeight;
843
844         /* set up the thresholds */
845         mv->dxThresh = mv->map->tiles->tileWidth * 2;
846         mv->dyThresh = mv->map->tiles->tileHeight * 2;
847
848         /* draw the tiles */
849         modexClearRegion(mv->page, 0, 0, mv->page->width, mv->page->height, 0);
850         py=0;
851         i=mv->ty * mv->map->width + mv->tx;
852         for(ty=mv->ty-1; py < SCREEN_HEIGHT+mv->dyThresh && ty < mv->map->height; ty++, py+=mv->map->tiles->tileHeight) {
853                 mapDrawRow(mv, tx-1, ty, py);
854         i+=mv->map->width - tx;
855         }
856 }
857
858
859 void
860 mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y) {
861         word rx;
862         word ry;
863         //if(i==0) i=2;
864         if(i==0)
865         {
866                 //wwww
867                 modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, 0); //currently the over scan color!
868         }
869         else
870         {
871         rx = (((i-1) % ((t->data->width)/t->tileWidth)) * t->tileWidth);
872         ry = (((i-1) / ((t->data->height)/t->tileHeight)) * t->tileHeight);
873 ////0000        printf("i=%d\n", i);
874         //mxPutTile(t->data, x, y, t->tileWidth, t->tileHeight);
875         modexDrawBmpRegion(page, x, y, rx, ry, t->tileWidth, t->tileHeight, (t->data));
876         }
877 }
878
879
880 void
881 mapDrawRow(map_view_t *mv, int tx, int ty, word y) {
882         word x;
883         int i;
884
885         /* the position within the map array */
886         i=ty * mv->map->width + tx;
887         for(x=0; x<SCREEN_WIDTH+mv->dxThresh && tx < mv->map->width; x+=mv->map->tiles->tileWidth, tx++) {
888         if(i>=0) {
889                 /* we are in the map, so copy! */
890                 mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);
891         }
892         i++; /* next! */
893         }
894 }
895
896 void
897 mapDrawCol(map_view_t *mv, int tx, int ty, word x) {
898         int y;
899         int i;
900
901         /* location in the map array */
902         i=ty * mv->map->width + tx;
903
904         /* We'll copy all of the columns in the screen,
905            i + 1 row above and one below */
906         for(y=0; y<SCREEN_HEIGHT+mv->dyThresh && ty < mv->map->height; y+=mv->map->tiles->tileHeight, ty++) {
907         if(i>=0) {
908                 /* we are in the map, so copy away! */
909                 mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);
910         }
911         i += mv->map->width;
912         }
913 }
914
915 void qclean()
916 {
917         modexLeave();
918         setkb(0);
919 }
920
921 void pdump(map_view_t *pee)
922 {
923         int mult=(QUADWH);
924         int palq=(mult)*TILEWH;
925         int palcol=0;
926         int palx, paly;
927         for(paly=0; paly<palq; paly+=mult){
928                 for(palx=0; palx<palq; palx+=mult){
929                                 modexClearRegion(pee->page, palx+TILEWH, paly+TILEWH, mult, mult, palcol);
930                         palcol++;
931                 }
932         }
933 }
934
935 void
936 animatePlayer(map_view_t *src, map_view_t *dest, /*map_view_t *top, */sword d, short scrolloffsetswitch, int x, int y, int ls, int lp, bitmap_t *bmp)
937 {
938         sword dire=32*d; //direction
939         sword qq; //scroll offset
940
941         if(scrolloffsetswitch==0) qq = 0;
942         else qq = ((lp)*SPEED);
943         switch (d)
944         {
945                 case 0:
946                         //up
947                         x=x-4;
948                         y=y-qq-TILEWH;
949                 break;
950                 case 1:
951                         // right
952                         x=x+qq-4;
953                         y=y-TILEWH;
954                 break;
955                 case 2:
956                         //down
957                         x=x-4;
958                         y=y+qq-TILEWH;
959                 break;
960                 case 3:
961                         //left
962                         x=x-qq-4;
963                         y=y-TILEWH;
964                 break;
965         }
966         modexCopyPageRegion(dest->page, src->page, x-4, y-4, x-4, y-4, 28, 40);
967         if(2>ls && ls>=1) { modexDrawSpriteRegion(dest->page, x, y, 48, dire, 24, 32, bmp); }else
968         if(3>ls && ls>=2) { modexDrawSpriteRegion(dest->page, x, y, 24, dire, 24, 32, bmp); }else
969         if(4>ls && ls>=3) { modexDrawSpriteRegion(dest->page, x, y, 0, dire, 24, 32, bmp); }else
970         if(5>ls && ls>=4) { modexDrawSpriteRegion(dest->page, x, y, 24, dire, 24, 32, bmp); }
971         //TODO: mask copy //modexCopyPageRegion(dest->page, src->page, x-4, y-4, x-4, y-4, 28, 40);
972         //modexClearRegion(top->page, 66, 66, 2, 40, 0);
973         //modexCopyPageRegion(dest->page, top->page, 66, 66, 66, 66, 2, 40);
974         //turn this off if XT
975         //XTif(detectcpu() > 0)
976         modexWaitBorder();
977 }