-#include "src\scroll.h"
#include "src\lib\modex16.h"
#include <stdio.h>
#include <stdlib.h>
//word far *clock= (word far*) 0x046C; /* 18.2hz clock */
+typedef struct {
+ bitmap_t *data;
+ word tileHeight;
+ word tileWidth;
+ unsigned int rows;
+ unsigned int cols;
+} tiles_t;
+
+
+typedef struct {
+ byte *data;
+ tiles_t *tiles;
+ int width;
+ int height;
+} map_t;
+
+
+typedef struct {
+ map_t *map;
+ page_t *page;
+ int tx; //appears to be the top left tile position on the viewable screen map
+ int ty; //appears to be the top left tile position on the viewable screen map
+ word dxThresh; //????
+ word dyThresh; //????
+} map_view_t;
+
+//TODO: make this into actor_t
+struct {
+ int x; //player exact position on the viewable map
+ int y; //player exact position on the viewable map
+ int tx; //player tile position on the viewable map
+ int ty; //player tile position on the viewable map
+ int triggerx; //player's trigger box tile position on the viewable map
+ int triggery; //player's trigger box tile position on the viewable map
+ int hp; //hitpoints of the player
+} player;
+
+
+map_t allocMap(int w, int h);
+void initMap(map_t *map);
+void mapScrollRight(map_view_t *mv, byte offset, short lp);
+void mapScrollLeft(map_view_t *mv, byte offest, short lp);
+void mapScrollUp(map_view_t *mv, byte offset, short lp);
+void mapScrollDown(map_view_t *mv, byte offset, short lp);
+void mapGoTo(map_view_t *mv, int tx, int ty);
+void mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y);
+void mapDrawRow(map_view_t *mv, int tx, int ty, word y, word poopoffset);
+void mapDrawCol(map_view_t *mv, int tx, int ty, word x, word poopoffset);
+void mapDrawWRow(map_view_t *mv, int tx, int ty, word y);
+void mapDrawWCol(map_view_t *mv, int tx, int ty, word x);
+void animatePlayer(map_view_t *src, map_view_t *dest, short d1, short d2, int x, int y, int ls, int lp, bitmap_t *bmp);
+
+#define TILEWH 16
+#define QUADWH (TILEWH/4)
+#define SPEED 4
+
+//place holder definitions
+#define MAPX 200
+#define MAPY 150
+#define TRIGGX 10
+#define TRIGGY 9
+//#define SWAP(a, b) tmp=a; a=b; b=tmp;
+void main() {
+ bitmap_t ptmp; // player sprite
+ word q=1;
+ const char *cpus;
+ //static int persist_aniframe = 0; /* gonna be increased to 1 before being used, so 0 is ok for default */
+ page_t screen, screen2, screen3;
+ map_t map;
+ map_view_t mv, mv2, mv3;
+ map_view_t *bg, *spri, *mask;//, *tmp;
+ byte *ptr;
+
+ /* create the map */
+ 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
+ initMap(&map);
+ mv.map = ↦
+ mv2.map = ↦
+ mv3.map = ↦
+
+ /* draw the tiles */
+ ptr = map.data;
+ /*data\\*/
+ ptmp = bitmapLoadPcx("ptmp.pcx"); // load sprite
+ setkb(1);
+ modexEnter();
+ modexPalUpdate(ptmp.palette);
+ screen = modexDefaultPage();
+ screen.width += (TILEWH*2);
+ screen.height += (TILEWH*2)+QUADWH;
+ mv.page = &screen;
+ screen2 = modexNextPage(mv.page);
+ mv2.page = &screen2;
+ screen3 = screen2;
+ mv3.page = &screen3;
+
+ /* set up paging */
+ bg = &mv;
+ spri = &mv2;
+ mask = &mv3;
+
+//TODO: LOAD map data and position the map in the middle of the screen if smaller then screen
+ mapGoTo(bg, 0, 0);
+ mapGoTo(spri, 0, 0);
+ //mapGoTo(mask, 0, 0);
+
+ //TODO: put player in starting position of spot
+ //default player position on the viewable map
+ player.tx = bg->tx + 10;
+ player.ty = bg->ty + 8;
+ player.x = player.tx*TILEWH;
+ player.y = player.ty*TILEWH;
+ player.triggerx = player.tx;
+ player.triggery = player.ty+1;
+ //TODO: erase player initial draw
+ modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 64, 24, 32, &ptmp);
+ //temp draw trigger box
+ modexClearRegion(spri->page, player.triggerx*16, player.triggery*16, 16, 16, 1);
+ modexClearRegion(bg->page, player.triggerx*16, player.triggery*16, 16, 16, 1);
+ modexShowPage(spri->page);
+ while(!keyp(1))//!keyp(1))
+ {
+ //top left corner & bottem right corner of map veiw be set as map edge trigger since maps are actually square
+ //to stop scrolling and have the player position data move to the edge of the screen with respect to the direction
+ //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
+
+ #define INC_PER_FRAME if(q&1) persist_aniframe++; if(persist_aniframe>4) persist_aniframe = 1;
+
+ //temp testing
+ /*if(bg->tx >= 0 && bg->tx+20 < MAPX && player.tx == bg->tx + 10)
+ {
+ for(q=1; q<=(TILEWH/SPEED); q++)
+ {
+ //INC_PER_FRAME;
+ //animatePlayer(bg, spri, mask, 1, 1, player.x, player.y, persist_aniframe, q, &ptmp);
+ //animatePlayer(bg, spri, 1, 1, player.x, player.y, persist_aniframe, q, &ptmp);
+ mapScrollRight(bg, SPEED);
+ //mapScrollRight(spri, SPEED);
+ //mapScrollRight(mask, SPEED);
+ modexShowPage(bg->page);
+ }
+ player.tx++;
+ }
+ else if(player.tx < MAPX)
+ {
+ for(q=1; q<=(TILEWH/SPEED); q++)
+ {
+ INC_PER_FRAME;
+ player.x+=SPEED;
+ //animatePlayer(bg, spri, mask, 1, 0, player.x, player.y, persist_aniframe, q, &ptmp);
+ animatePlayer(bg, spri, 1, 0, player.x, player.y, persist_aniframe, q, &ptmp);
+ modexShowPage(spri->page);
+ }
+ player.tx++;
+ }
+ else
+ {
+break;
+ }*/
+ if(keyp(77) && !keyp(75))
+ {
+ if(bg->tx >= 0 && bg->tx+20 < MAPX && player.tx == bg->tx + 10 && !(player.tx+1 == TRIGGX && player.ty == TRIGGY))
+ {
+ for(q=1; q<=(TILEWH/SPEED); q++)
+ {
+ INC_PER_FRAME;
+ //animatePlayer(bg, spri, mask, 1, 1, player.x, player.y, persist_aniframe, q, &ptmp);
+ animatePlayer(bg, spri, 1, 1, player.x, player.y, persist_aniframe, q, &ptmp);
+ mapScrollRight(bg, SPEED, q);
+ mapScrollRight(spri, SPEED, q);
+ //mapScrollRight(mask, SPEED);
+ modexShowPage(spri->page);
+ }
+ player.tx++;
+ }
+ else if(player.tx < MAPX && !(player.tx+1 == TRIGGX && player.ty == TRIGGY))
+ {
+ for(q=1; q<=(TILEWH/SPEED); q++)
+ {
+ INC_PER_FRAME;
+ player.x+=SPEED;
+ //animatePlayer(bg, spri, mask, 1, 0, player.x, player.y, persist_aniframe, q, &ptmp);
+ animatePlayer(bg, spri, 1, 0, player.x, player.y, persist_aniframe, q, &ptmp);
+ modexShowPage(spri->page);
+ }
+ player.tx++;
+ }
+ else
+ {
+ modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
+ modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 32, 24, 32, &ptmp);
+ modexShowPage(spri->page);
+ }
+ player.triggerx = player.tx+1;
+ player.triggery = player.ty;
+ }
+
+ if(keyp(75) && !keyp(77))
+ {
+ if(bg->tx > 0 && bg->tx+20 <= MAPX && player.tx == bg->tx + 10 && !(player.tx-1 == TRIGGX && player.ty == TRIGGY))
+ {
+ for(q=1; q<=(TILEWH/SPEED); q++)
+ {
+ INC_PER_FRAME;
+ //animatePlayer(bg, spri, mask, 3, 1, player.x, player.y, persist_aniframe, q, &ptmp);
+ animatePlayer(bg, spri, 3, 1, player.x, player.y, persist_aniframe, q, &ptmp);
+ mapScrollLeft(bg, SPEED, q);
+ mapScrollLeft(spri, SPEED, q);
+ //mapScrollLeft(mask, SPEED);
+ modexShowPage(spri->page);
+ }
+ player.tx--;
+ }
+ else if(player.tx > 1 && !(player.tx-1 == TRIGGX && player.ty == TRIGGY))
+ {
+ for(q=1; q<=(TILEWH/SPEED); q++)
+ {
+ INC_PER_FRAME;
+ player.x-=SPEED;
+ //animatePlayer(bg, spri, mask, 3, 0, player.x, player.y, persist_aniframe, q, &ptmp);
+ animatePlayer(bg, spri, 3, 0, player.x, player.y, persist_aniframe, q, &ptmp);
+ modexShowPage(spri->page);
+ }
+ player.tx--;
+ }
+ else
+ {
+ modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
+ modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 96, 24, 32, &ptmp);
+ modexShowPage(spri->page);
+ }
+ player.triggerx = player.tx-1;
+ player.triggery = player.ty;
+ }
+
+ if(keyp(80) && !keyp(72))
+ {
+ if(bg->ty >= 0 && bg->ty+15 < MAPY && player.ty == bg->ty + 8 && !(player.tx == TRIGGX && player.ty+1 == TRIGGY))
+ {
+ for(q=1; q<=(TILEWH/SPEED); q++)
+ {
+ INC_PER_FRAME;
+ //animatePlayer(bg, spri, mask, 2, 1, player.x, player.y, persist_aniframe, q, &ptmp);
+ animatePlayer(bg, spri, 2, 1, player.x, player.y, persist_aniframe, q, &ptmp);
+ mapScrollDown(bg, SPEED, q);
+ mapScrollDown(spri, SPEED, q);
+ //mapScrollDown(mask, SPEED);
+ modexShowPage(spri->page);
+ }
+ player.ty++;
+ }
+ else if(player.ty < MAPY && !(player.tx == TRIGGX && player.ty+1 == TRIGGY))
+ {
+ for(q=1; q<=(TILEWH/SPEED); q++)
+ {
+ INC_PER_FRAME;
+ player.y+=SPEED;
+ //animatePlayer(bg, spri, mask, 2, 0, player.x, player.y, persist_aniframe, q, &ptmp);
+ animatePlayer(bg, spri, 2, 0, player.x, player.y, persist_aniframe, q, &ptmp);
+ modexShowPage(spri->page);
+ }
+ player.ty++;
+ }
+ else
+ {
+ modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
+ modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 64, 24, 32, &ptmp);
+ modexShowPage(spri->page);
+ }
+ player.triggerx = player.tx;
+ player.triggery = player.ty+1;
+ }
+
+ if(keyp(72) && !keyp(80))
+ {
+ if(bg->ty > 0 && bg->ty+15 <= MAPY && player.ty == bg->ty + 8 && !(player.tx == TRIGGX && player.ty-1 == TRIGGY))
+ {
+ for(q=1; q<=(TILEWH/SPEED); q++)
+ {
+ INC_PER_FRAME;
+ //animatePlayer(bg, spri, mask, 0, 1, player.x, player.y, persist_aniframe, q, &ptmp);
+ animatePlayer(bg, spri, 0, 1, player.x, player.y, persist_aniframe, q, &ptmp);
+ mapScrollUp(bg, SPEED, q);
+ mapScrollUp(spri, SPEED, q);
+ //mapScrollUp(mask, SPEED);
+ modexShowPage(spri->page);
+ }
+ player.ty--;
+ }
+ else if(player.ty > 1 && !(player.tx == TRIGGX && player.ty-1 == TRIGGY))
+ {
+ for(q=1; q<=(TILEWH/SPEED); q++)
+ {
+ INC_PER_FRAME;
+ player.y-=SPEED;
+ //animatePlayer(bg, spri, mask, 0, 0, player.x, player.y, persist_aniframe, q, &ptmp);
+ modexShowPage(spri->page);
+ animatePlayer(bg, spri, 0, 0, player.x, player.y, persist_aniframe, q, &ptmp);
+ }
+ player.ty--;
+ }
+ else
+ {
+ modexCopyPageRegion(spri->page, bg->page, player.x-4, player.y-TILEWH, player.x-4, player.y-TILEWH, 24, 32);
+ modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 0, 24, 32, &ptmp);
+ modexShowPage(spri->page);
+ }
+ player.triggerx = player.tx;
+ player.triggery = player.ty-1;
+ }
+ //modexClearRegion(mask->page, 66, 66, 2, 40, 0);
+
+ if((player.triggerx == TRIGGX && player.triggery == TRIGGY) && keyp(KEY_ENTER))
+ {
+ short i;
+ for(i=600; i>=400; i--)
+ {
+ sound(i);
+ }
+ nosound();
+ }
+ }
+
+ modexLeave();
+ setkb(0);
+ printf("Project 16 scroll.exe\n");
+ printf("tx: %d\n", bg->tx);
+ printf("ty: %d\n", bg->ty);
+ printf("player.x: %d\n", player.x);
+ printf("player.y: %d\n", player.y);
+ printf("player.tx: %d\n", player.tx);
+ printf("player.ty: %d\n", player.ty);
+ printf("player.triggx: %d\n", player.triggerx);
+ printf("player.triggy: %d\n", player.triggery);
+ printf("temporary player sprite 0: http://www.pixiv.net/member_illust.php?mode=medium&illust_id=45556867\n");
+ printf("temporary player sprite 1: http://www.pixiv.net/member_illust.php?mode=medium&illust_id=44606385\n");
+ printf("\n");
+ switch(detectcpu())
+ {
+ case 0: cpus = "8086/8088 or 186/88"; break;
+ case 1: cpus = "286"; break;
+ case 2: cpus = "386 or newer"; break;
+ default: cpus = "internal error"; break;
+ }
+ printf("detected CPU type: %s\n", cpus);
+}
+
+
map_t
allocMap(int w, int h) {
map_t result;
/* draw the next column */
x= SCREEN_WIDTH + mv->map->tiles->tileWidth;
- if(lp%4)
+ //if(lp%4)
mapDrawCol(mv, mv->tx + 20 , mv->ty-1, x, mv->page->dx);
}
}
if(mv->page->dx == 0) {
/* go backward one tile */
mv->tx--;
-
+
/* Snap the origin backward */
mv->page->data -= 4;
mv->page->dx = mv->map->tiles->tileWidth;
//}
/* draw the next column */
- if(lp%4)
+ //if(lp%4)
mapDrawCol(mv, mv->tx-1, mv->ty-1, 0, mv->page->dx);
}
}
/* draw the next row */
y= 0;
- if(lp%3)
+ //if(lp%3)
mapDrawRow(mv, mv->tx-1 , mv->ty-1, y, mv->page->dy);
}
}
/* draw the next row */
y= SCREEN_HEIGHT + mv->map->tiles->tileHeight;
- if(lp%3)
+ //if(lp%3)
mapDrawRow(mv, mv->tx-1 , mv->ty+15, y, mv->page->dy);
}
}
-void
+void
mapDrawRow(map_view_t *mv, int tx, int ty, word y, word poopoffset) {
word x;
int i;
}
-void
+void
mapDrawCol(map_view_t *mv, int tx, int ty, word x, word poopoffset) {
int y;
int i;
/* location in the map array */
i=ty * mv->map->width + tx;
- /* We'll copy all of the columns in the screen,
+ /* We'll copy all of the columns in the screen,
i + 1 row above and one below */
for(y=poopoffset; y<(SCREEN_HEIGHT+mv->dyThresh)/(poopoffset+1) && ty < mv->map->height; y+=mv->map->tiles->tileHeight, ty++) {
if(i>=0) {
}
}
-void
+void
mapDrawWRow(map_view_t *mv, int tx, int ty, word y) {
word x;
int i;
}
}
-void
+void
mapDrawWCol(map_view_t *mv, int tx, int ty, word x) {
int y;
int i;
/* location in the map array */
i=ty * mv->map->width + tx;
- /* We'll copy all of the columns in the screen,
+ /* We'll copy all of the columns in the screen,
i + 1 row above and one below */
for(y=0; y<SCREEN_HEIGHT+mv->dyThresh && ty < mv->map->height; y+=mv->map->tiles->tileHeight, ty++) {
if(i>=0) {
}
}
-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)
+// animatePlayer(map_view_t *src, map_view_t *dest, 1, 1, player.x, player.y, persist_aniframe, q, &ptmp);
+// animatePlayer(bg, spri, 0, 1, player.x, player.y, persist_aniframe, q, &ptmp);
+// animatePlayer(bg, spri, 0, 0, player.x, player.y, persist_aniframe, q, &ptmp);
+// animatePlayer(map_view_t *src, map_view_t *dest, player_t *player, word playnum, sword scrolloffsetswitch, int ls, bitmap_t *bmp)
+void animatePlayer(map_view_t *src, map_view_t *dest, short d1, short d2, int x, int y, int ls, int lp, bitmap_t *bmp)
{
short dire=32*d1; //direction
short qq; //scroll offset