]> 4ch.mooo.com Git - 16.git/commitdiff
16_pm worked on~
authorsparky4 <sparky4@cock.li>
Thu, 22 Sep 2016 18:29:56 +0000 (13:29 -0500)
committersparky4 <sparky4@cock.li>
Thu, 22 Sep 2016 18:29:56 +0000 (13:29 -0500)
51 files changed:
DEBUG.16W
MMDUMP.16W
bcexmm.dsk
bcexmm.exe [deleted file]
bcexmm.prj
src/0.c
src/16.ses
src/_scroll.c
src/bakapi.c
src/bakapi.h
src/emmtest.c
src/emsdump.c
src/emstest.c
src/exmmtest.c
src/lib/16_dbg.c
src/lib/16_dbg.h
src/lib/16_hc.c
src/lib/16_hc.h
src/lib/16_head.h
src/lib/16_map.c
src/lib/16_mm.c
src/lib/16_mm.h
src/lib/16_pm.c
src/lib/16_sprit.c
src/lib/16_sprit.h
src/lib/16_vrs.c
src/lib/16_vrs.h
src/lib/_croll16.c
src/lib/bakapee.c
src/lib/ems.c
src/lib/ems.h
src/lib/mapread.c
src/lib/midi.c
src/lib/midi.h
src/lib/modex16.h
src/lib/scroll16.c
src/lib/scroll16.h
src/lib/xms.c
src/lib/xms.h
src/lib/zcroll16.c
src/lib/zcroll16.h
src/midi.c
src/miditest.c
src/scroll.c
src/testemm.c
src/testemm0.c
src/testsnd.c
src/tesuto.c
src/tesuto.h
src/tsthimem.c
src/vrstest.c

index 5fb5e282c3084f1c5ba84b10a3537a53ba0187ba..e42fdf08b1bc6f986d23703aedae0f7dae4cb5dd 100755 (executable)
--- a/DEBUG.16W
+++ b/DEBUG.16W
@@ -1,12 +1,8 @@
-\e[0mSeg:0      Size:8568       Owner:0xfe7e\r
+\e[0mSeg:0      Size:8601       Owner:0x0\r
 \e[41;31m++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\e[0m\e[42;32m0\r
-\e[0m\e[0mSeg:2178       Size:256        Owner:0x5434\r
+\e[0m\e[0mSeg:2199       Size:256        Owner:0x5424\r
 \e[44;34m++++\e[0m\e[42;32m\r
-\e[0m\e[0mSeg:2278       Size:17 Owner:0x9480\r
-\e[44;34m+\e[0m\e[42;32m\r
-\e[0m\e[0mSeg:27ec       Size:44 Owner:0x0\r
-\e[41;31m++\e[0m\e[42;32m0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\r
-\e[0m\e[0mSeg:b818       Size:10216      Owner:0x0\r
-\e[41;31m++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\e[0m\e[42;32m\r
-\e[0m\e[0mSeg:e000       Size:8191       Owner:0x0\r
-\e[41;31m++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\e[0m
\ No newline at end of file
+\e[0m\e[0mSeg:280e       Size:44 Owner:0x0\r
+\e[41;31m+\e[0m\e[42;32m0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\r
+\e[0m\e[0mSeg:b83a       Size:18373      Owner:0x0\r
+\e[41;31m+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\e[0m
\ No newline at end of file
index 4bf1c809f6d6b2988d2b2f86a1bfb477c54c02e3..86d239b00841ce04466efae3ed916a82d1f0cd6a 100755 (executable)
Binary files a/MMDUMP.16W and b/MMDUMP.16W differ
index b1f56e47ef6d21ac09a1dde6261b3b34e374cad8..81894b494a595c5452c0980cd68b4b69c5f98441 100755 (executable)
Binary files a/bcexmm.dsk and b/bcexmm.dsk differ
diff --git a/bcexmm.exe b/bcexmm.exe
deleted file mode 100755 (executable)
index a86e818..0000000
Binary files a/bcexmm.exe and /dev/null differ
index e5ab4e6fe8291cf9cf99e35c77b293b2a4f426bd..a9e71b315010eccf1cc980a91a5b0164d944cf71 100755 (executable)
Binary files a/bcexmm.prj and b/bcexmm.prj differ
diff --git a/src/0.c b/src/0.c
index ae51d0582567000e69f387bae1740df8d9378c8c..09e8953df6d271e368b80d0486d15f9d755393e3 100755 (executable)
--- a/src/0.c
+++ b/src/0.c
-#include <hw/cpu/cpu.h>
-#include <hw/dos/dos.h>
-#include <hw/vga/vga.h>
-#include <hw/vga/vrl.h>
-
-#include "src/tesuto.h"
-
-#define FILENAME_1 "data/aconita.vrl"
-#define FILENAME_2 "data/aconita.pal"
-
-static unsigned char palette[768];
-global_game_variables_t gvar;
-player_t player[1];
-
-int main(int argc,char **argv) {
-       struct vrl1_vgax_header *vrl_header;
-       vrl1_vgax_offset_t *vrl_lineoffs;
-       unsigned char *buffer;
-       unsigned int bufsz;
-       int fd;
-       char *bakapee1,*bakapee2;
-
-       bakapee1=malloc(64);
-       bakapee2=malloc(1024);
-
-       IN_Startup();
-       IN_Default(0,&player,ctrl_Joystick);
-       IN_initplayer(&player, 0);
-
-       if (argc < 3) {
-               fprintf(stderr,"drawvrl <VRL file> <palette file>\n");
-               bakapee1 = FILENAME_1;//"data/aconita.vrl";
-               bakapee2 = FILENAME_2;//"data/aconita.pal";
-               //return 1;
-       }else{
-               if(argv[1]) bakapee1 = argv[1];
-               if(argv[2]) bakapee2 = argv[2];
-       }
-
-       fd = open(bakapee1,O_RDONLY|O_BINARY);
-       if (fd < 0) {
-               fprintf(stderr,"Unable to open '%s'\n", bakapee1);
-               return 1;
-       }
-       {
-               unsigned long sz = lseek(fd,0,SEEK_END);
-               if (sz < sizeof(*vrl_header)) return 1;
-               if (sz >= 65535UL) return 1;
-
-               bufsz = (unsigned int)sz;
-               buffer = malloc(bufsz);
-               if (buffer == NULL) return 1;
-
-               lseek(fd,0,SEEK_SET);
-               if ((unsigned int)read(fd,buffer,bufsz) < bufsz) return 1;
-
-               vrl_header = (struct vrl1_vgax_header*)buffer;
-               if (memcmp(vrl_header->vrl_sig,"VRL1",4) || memcmp(vrl_header->fmt_sig,"VGAX",4)) return 1;
-               if (vrl_header->width == 0 || vrl_header->height == 0) return 1;
-       }
-       close(fd);
-
-       probe_dos();
-       if (!probe_vga()) {
-               printf("VGA probe failed\n");
-               return 1;
-       }
-       VGAmodeX(1, 1, &gvar);
-
-       /* load color palette */
-       fd = open(bakapee2,O_RDONLY|O_BINARY);
-       if (fd >= 0) {
-               unsigned int i;
-
-               read(fd,palette,768);
-               close(fd);
-
-               vga_palette_lseek(0);
-               for (i=0;i < 256;i++) vga_palette_write(palette[(i*3)+0]>>2,palette[(i*3)+1]>>2,palette[(i*3)+2]>>2);
-       }
-
-       /* preprocess the sprite to generate line offsets */
-       vrl_lineoffs = vrl1_vgax_genlineoffsets(vrl_header,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));
-       if (vrl_lineoffs == NULL) return 1;
-
-       /* setup camera and screen~ */
-       modexHiganbanaPageSetup(&gvar.video);
-       gvar.video.page[1].dx=gvar.video.page[0].dx=16;
-       gvar.video.page[1].dy=gvar.video.page[0].dy=16;
-       modexShowPage(&(gvar.video.page[0]));
-
-       #define VMEMHEIGHT gvar.video.page[0].height+gvar.video.page[1].height
-
-       //4     this dose the screen
-       {
-               unsigned int i,j,o;
-               /* fill screen with a distinctive pattern */
-               for (i=0;i < gvar.video.page[0].width;i++) {
-                       o = i >> 2;
-                       vga_write_sequencer(0x02/*map mask*/,1 << (i&3));
-                       for (j=0;j < VMEMHEIGHT;j++,o += gvar.video.page[0].stridew)
-                               vga_state.vga_graphics_ram[o] = (i^j)&15; // VRL samples put all colors in first 15!
-               }
-       }
-
-       //while (getch() != 13);
-
-       /* make distinctive pattern offscreen, render sprite, copy onscreen.
-        * this time, we render the distinctive pattern to another offscreen location and just copy.
-        * note this version is much faster too! */
-       {
-               unsigned int i,j,o,o2;
-               int x,y,rx,ry,w,h;
-               unsigned int overdraw = 1;      // how many pixels to "overdraw" so that moving sprites with edge pixels don't leave streaks.
-                                               // if the sprite's edge pixels are clear anyway, you can set this to 0.
-               VGA_RAM_PTR omemptr;
-               int xdir=1,ydir=1;
-
-               //4     this dose the sprite? wwww
-               /* fill pattern offset with a distinctive pattern */
-               for (i=0;i < gvar.video.page[0].width;i++) {
-                       o = (i >> 2) + (0x10000UL - (uint16_t)gvar.video.page[1].data);
-                       vga_write_sequencer(0x02/*map mask*/,1 << (i&3));
-                       for (j=0;j < VMEMHEIGHT;j++,o += gvar.video.page[0].stridew)
-                               vga_state.vga_graphics_ram[o] = (i^j)&15; // VRL samples put all colors in first 15!
-               }
-
-               /* starting coords. note: this technique is limited to x coordinates of multiple of 4 */
-               x = 0;
-               y = 0;
-
-               /* do it */
-               omemptr = vga_state.vga_graphics_ram; // save original mem ptr
-
-               while(!IN_KeyDown(sc_Escape))
-               {
-                       IN_ReadControl(0,&player);
-                       if(IN_KeyDown(2)) modexShowPage(&(gvar.video.page[0]));
-                       if(IN_KeyDown(3)) modexShowPage(&(gvar.video.page[1]));
-                       if(IN_KeyDown(68))      //f10
-                       {
-                               //gvar.kurokku.fpscap=!gvar.kurokku.fpscap;
-                               IN_UserInput(1,1);
-                       }
-
-                       /* render box bounds. y does not need modification, but x and width must be multiple of 4 */
-                       if (x >= overdraw) rx = (x - overdraw) & (~3);
-                       else rx = -(gvar.video.page[0].dx);
-                       if (y >= overdraw) ry = (y - overdraw);
-                       else ry = -(gvar.video.page[0].dy);
-                       h = vrl_header->height + overdraw + y - ry;
-                       w = (x + vrl_header->width + (overdraw*2) + 3/*round up*/ - rx) & (~3);
-                       if ((rx+w) > gvar.video.page[0].width) w = gvar.video.page[0].width-rx;
-                       if ((ry+h) > gvar.video.page[0].height) h = (gvar.video.page[0].height)-ry;
-
-                       /* block copy pattern to where we will draw the sprite */
-                       vga_setup_wm1_block_copy();
-                       o2 = gvar.video.page[0].pagesize;
-                       o = (0x10000UL - (uint16_t)gvar.video.page[1].data) + (ry * gvar.video.page[0].stridew) + (rx >> 2); // source offscreen
-                       for (i=0;i < h;i++,o += gvar.video.page[0].stridew,o2 += (w >> 2)) vga_wm1_mem_block_copy(o2,o,w >> 2);
-                       /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */
-                       vga_restore_rm0wm0();
-
-                       /* replace VGA stride with our own and mem ptr. then sprite rendering at this stage is just (0,0) */
-                       vga_state.vga_draw_stride_limit = (gvar.video.page[0].width + 3/*round up*/ - x) >> 2;
-                       vga_state.vga_draw_stride = w >> 2;
-                       vga_state.vga_graphics_ram = omemptr + gvar.video.page[0].pagesize;
-
-                       /* then the sprite. note modding ram ptr means we just draw to (x&3,0) */
-                       draw_vrl1_vgax_modex(x-rx,y-ry,vrl_header,vrl_lineoffs,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));
-
-                       /* restore ptr */
-                       vga_state.vga_graphics_ram = omemptr;
-
-                       /* block copy to visible RAM from offscreen */
-                       vga_setup_wm1_block_copy();
-                       o = gvar.video.page[0].pagesize; // source offscreen
-                       o2 = (ry * gvar.video.page[0].stridew) + (rx >> 2); // dest visible (original stride)
-                       for (i=0;i < h;i++,o += vga_state.vga_draw_stride,o2 += gvar.video.page[0].stridew) vga_wm1_mem_block_copy(o2,o,w >> 2);
-                       /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */
-                       vga_restore_rm0wm0();
-
-                       /* restore stride */
-                       vga_state.vga_draw_stride_limit = vga_state.vga_draw_stride = gvar.video.page[0].stridew;
-
-                       /* step */
-                       x += xdir; y += ydir;
-                       if ((x + vrl_header->width) >= ((gvar.video.page[0].width + gvar.video.page[0].dx) - 1) || x == -(gvar.video.page[0].dx))
-                               xdir = -xdir;
-                       if ((y + vrl_header->height) >= ((gvar.video.page[0].height + gvar.video.page[0].dy) - 1) || y == -(gvar.video.page[0].dy))
-                               ydir = -ydir;
-                       //printf("[x%u y%u]     [rx%u ry%u]             [w%u h%u]\n", x, y, rx, ry, w, h);
-               }
-       }
-
-       IN_UserInput(1,1);
-
-       while(!IN_KeyDown(sc_Escape))
-       {
-               if(IN_KeyDown(2)) modexShowPage(&(gvar.video.page[0]));
-               if(IN_KeyDown(3)) modexShowPage(&(gvar.video.page[1]));
-       }
-
-       modexShowPage(&(gvar.video.page[0]));
-       /* another handy "demo" effect using VGA write mode 1.
-        * we can take what's on screen and vertically squash it like an old analog TV set turning off. */
-       {
-               unsigned int blank_line_ofs = (gvar.video.page[0].stridew * gvar.video.page[0].height * 2);
-               unsigned int copy_ofs = (gvar.video.page[0].stridew * gvar.video.page[0].height);
-               unsigned int display_ofs = 0x0000;
-               unsigned int i,y,soh,doh,dstart;
-               unsigned int dh_blankfill = 8;
-               unsigned int dh_step = 8;
-               uint32_t sh,dh,yf,ystep;
-
-               /* copy active display (0) to offscreen buffer (0x4000) */
-               vga_state.vga_draw_stride_limit = vga_state.vga_draw_stride = gvar.video.page[0].stridew;
-               vga_setup_wm1_block_copy();
-               vga_wm1_mem_block_copy(copy_ofs,display_ofs,gvar.video.page[0].stridew * gvar.video.page[0].height);
-               vga_restore_rm0wm0();
-
-               /* need a blank line as well */
-               for (i=0;i < gvar.video.page[0].stridew;i++) vga_state.vga_graphics_ram[i+blank_line_ofs] = 0;
-
-               sh = dh = gvar.video.page[0].height;
-               while (dh >= dh_step) {
-                       /* stop animating if the user hits ENTER */
-                       if (kbhit()) {
-                               if (getch() == 13) break;
-                       }
-
-                       /* wait for vsync end */
-                       vga_wait_for_vsync_end();
-
-                       /* what scalefactor to use for stretching? */
-                       ystep = (0x10000UL * sh) / dh;
-                       dstart = (gvar.video.page[0].height - dh) / 2; // center the squash effect on screen, otherwise it would squash to top of screen
-                       doh = display_ofs;
-                       soh = copy_ofs;
-                       yf = 0;
-                       y = 0;
-
-                       /* for performance, keep VGA in write mode 1 the entire render */
-                       vga_setup_wm1_block_copy();
-
-                       /* blank lines */
-                       if (dstart >= dh_blankfill) y = dstart - dh_blankfill;
-                       else y = 0;
-                       doh = gvar.video.page[0].stridew * y;
-
-                       while (y < dstart) {
-                               vga_wm1_mem_block_copy(doh,blank_line_ofs,gvar.video.page[0].stridew);
-                               doh += gvar.video.page[0].stridew;
-                               y++;
-                       }
-
-                       /* draw */
-                       while (y < (dh+dstart)) {
-                               soh = copy_ofs + ((yf >> 16UL) * gvar.video.page[0].stridew);
-                               vga_wm1_mem_block_copy(doh,soh,gvar.video.page[0].stridew);
-                               doh += gvar.video.page[0].stridew;
-                               yf += ystep;
-                               y++;
-                       }
-
-                       /* blank lines */
-                       while (y < gvar.video.page[0].height && y < (dh+dstart+dh_blankfill)) {
-                               vga_wm1_mem_block_copy(doh,blank_line_ofs,gvar.video.page[0].stridew);
-                               doh += gvar.video.page[0].stridew;
-                               y++;
-                       }
-
-                       /* done */
-                       vga_restore_rm0wm0();
-
-                       /* wait for vsync */
-                       vga_wait_for_vsync();
-
-                       /* make it shrink */
-                       dh -= dh_step;
-                       if (dh < 40) dh_step = 1;
-               }
-       }
-
-       IN_Shutdown();
-       VGAmodeX(0, 1, &gvar);
-       free(vrl_lineoffs);
-       buffer = NULL;
-       free(buffer);
-       bufsz = 0;
-       free(bakapee1);
-       free(bakapee2);
-       return 0;
-}
+#include <hw/cpu/cpu.h>\r
+#include <hw/dos/dos.h>\r
+#include <hw/vga/vga.h>\r
+#include <hw/vga/vrl.h>\r
+\r
+#include "src/tesuto.h"\r
+\r
+#define FILENAME_1 "data/aconita.vrl"\r
+#define FILENAME_2 "data/aconita.pal"\r
+\r
+static unsigned char palette[768];\r
+global_game_variables_t gvar;\r
+player_t player[1];\r
+\r
+int main(int argc,char **argv) {\r
+       struct vrl1_vgax_header *vrl_header;\r
+       vrl1_vgax_offset_t *vrl_lineoffs;\r
+       unsigned char *buffer;\r
+       unsigned int bufsz;\r
+       int fd;\r
+       char *bakapee1,*bakapee2;\r
+\r
+       bakapee1=malloc(64);\r
+       bakapee2=malloc(1024);\r
+\r
+       IN_Startup();\r
+       IN_Default(0,&player,ctrl_Joystick);\r
+       IN_initplayer(&player, 0);\r
+\r
+       if (argc < 3) {\r
+               fprintf(stderr,"drawvrl <VRL file> <palette file>\n");\r
+               bakapee1 = FILENAME_1;//"data/aconita.vrl";\r
+               bakapee2 = FILENAME_2;//"data/aconita.pal";\r
+               //return 1;\r
+       }else{\r
+               if(argv[1]) bakapee1 = argv[1];\r
+               if(argv[2]) bakapee2 = argv[2];\r
+       }\r
+\r
+       fd = open(bakapee1,O_RDONLY|O_BINARY);\r
+       if (fd < 0) {\r
+               fprintf(stderr,"Unable to open '%s'\n", bakapee1);\r
+               return 1;\r
+       }\r
+       {\r
+               unsigned long sz = lseek(fd,0,SEEK_END);\r
+               if (sz < sizeof(*vrl_header)) return 1;\r
+               if (sz >= 65535UL) return 1;\r
+\r
+               bufsz = (unsigned int)sz;\r
+               buffer = malloc(bufsz);\r
+               if (buffer == NULL) return 1;\r
+\r
+               lseek(fd,0,SEEK_SET);\r
+               if ((unsigned int)read(fd,buffer,bufsz) < bufsz) return 1;\r
+\r
+               vrl_header = (struct vrl1_vgax_header*)buffer;\r
+               if (memcmp(vrl_header->vrl_sig,"VRL1",4) || memcmp(vrl_header->fmt_sig,"VGAX",4)) return 1;\r
+               if (vrl_header->width == 0 || vrl_header->height == 0) return 1;\r
+       }\r
+       close(fd);\r
+\r
+       probe_dos();\r
+       if (!probe_vga()) {\r
+               printf("VGA probe failed\n");\r
+               return 1;\r
+       }\r
+       VGAmodeX(1, 1, &gvar);\r
+\r
+       /* load color palette */\r
+       fd = open(bakapee2,O_RDONLY|O_BINARY);\r
+       if (fd >= 0) {\r
+               unsigned int i;\r
+\r
+               read(fd,palette,768);\r
+               close(fd);\r
+\r
+               vga_palette_lseek(0);\r
+               for (i=0;i < 256;i++) vga_palette_write(palette[(i*3)+0]>>2,palette[(i*3)+1]>>2,palette[(i*3)+2]>>2);\r
+       }\r
+\r
+       /* preprocess the sprite to generate line offsets */\r
+       vrl_lineoffs = vrl1_vgax_genlineoffsets(vrl_header,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));\r
+       if (vrl_lineoffs == NULL) return 1;\r
+\r
+       /* setup camera and screen~ */\r
+       modexHiganbanaPageSetup(&gvar.video);\r
+       gvar.video.page[1].dx=gvar.video.page[0].dx=16;\r
+       gvar.video.page[1].dy=gvar.video.page[0].dy=16;\r
+       modexShowPage(&(gvar.video.page[0]));\r
+\r
+       #define VMEMHEIGHT gvar.video.page[0].height+gvar.video.page[1].height\r
+\r
+       //4     this dose the screen\r
+       {\r
+               unsigned int i,j,o;\r
+               /* fill screen with a distinctive pattern */\r
+               for (i=0;i < gvar.video.page[0].width;i++) {\r
+                       o = i >> 2;\r
+                       vga_write_sequencer(0x02/*map mask*/,1 << (i&3));\r
+                       for (j=0;j < VMEMHEIGHT;j++,o += gvar.video.page[0].stridew)\r
+                               vga_state.vga_graphics_ram[o] = (i^j)&15; // VRL samples put all colors in first 15!\r
+               }\r
+       }\r
+\r
+       //while (getch() != 13);\r
+\r
+       /* make distinctive pattern offscreen, render sprite, copy onscreen.\r
+        * this time, we render the distinctive pattern to another offscreen location and just copy.\r
+        * note this version is much faster too! */\r
+       {\r
+               unsigned int i,j,o,o2;\r
+               int x,y,rx,ry,w,h;\r
+               unsigned int overdraw = 1;      // how many pixels to "overdraw" so that moving sprites with edge pixels don't leave streaks.\r
+                                               // if the sprite's edge pixels are clear anyway, you can set this to 0.\r
+               VGA_RAM_PTR omemptr;\r
+               int xdir=1,ydir=1;\r
+\r
+               //4     this dose the sprite? wwww\r
+               /* fill pattern offset with a distinctive pattern */\r
+               for (i=0;i < gvar.video.page[0].width;i++) {\r
+                       o = (i >> 2) + (0x10000UL - (uint16_t)gvar.video.page[1].data);\r
+                       vga_write_sequencer(0x02/*map mask*/,1 << (i&3));\r
+                       for (j=0;j < VMEMHEIGHT;j++,o += gvar.video.page[0].stridew)\r
+                               vga_state.vga_graphics_ram[o] = (i^j)&15; // VRL samples put all colors in first 15!\r
+               }\r
+\r
+               /* starting coords. note: this technique is limited to x coordinates of multiple of 4 */\r
+               x = 0;\r
+               y = 0;\r
+\r
+               /* do it */\r
+               omemptr = vga_state.vga_graphics_ram; // save original mem ptr\r
+\r
+               while(!IN_KeyDown(sc_Escape))\r
+               {\r
+                       IN_ReadControl(0,&player);\r
+                       if(IN_KeyDown(2)) modexShowPage(&(gvar.video.page[0]));\r
+                       if(IN_KeyDown(3)) modexShowPage(&(gvar.video.page[1]));\r
+                       if(IN_KeyDown(68))      //f10\r
+                       {\r
+                               //gvar.kurokku.fpscap=!gvar.kurokku.fpscap;\r
+                               IN_UserInput(1,1);\r
+                       }\r
+\r
+                       /* render box bounds. y does not need modification, but x and width must be multiple of 4 */\r
+                       if (x >= overdraw) rx = (x - overdraw) & (~3);\r
+                       else rx = -(gvar.video.page[0].dx);\r
+                       if (y >= overdraw) ry = (y - overdraw);\r
+                       else ry = -(gvar.video.page[0].dy);\r
+                       h = vrl_header->height + overdraw + y - ry;\r
+                       w = (x + vrl_header->width + (overdraw*2) + 3/*round up*/ - rx) & (~3);\r
+                       if ((rx+w) > gvar.video.page[0].width) w = gvar.video.page[0].width-rx;\r
+                       if ((ry+h) > gvar.video.page[0].height) h = (gvar.video.page[0].height)-ry;\r
+\r
+                       /* block copy pattern to where we will draw the sprite */\r
+                       vga_setup_wm1_block_copy();\r
+                       o2 = gvar.video.page[0].pagesize;\r
+                       o = (0x10000UL - (uint16_t)gvar.video.page[1].data) + (ry * gvar.video.page[0].stridew) + (rx >> 2); // source offscreen\r
+                       for (i=0;i < h;i++,o += gvar.video.page[0].stridew,o2 += (w >> 2)) vga_wm1_mem_block_copy(o2,o,w >> 2);\r
+                       /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */\r
+                       vga_restore_rm0wm0();\r
+\r
+                       /* replace VGA stride with our own and mem ptr. then sprite rendering at this stage is just (0,0) */\r
+                       vga_state.vga_draw_stride_limit = (gvar.video.page[0].width + 3/*round up*/ - x) >> 2;\r
+                       vga_state.vga_draw_stride = w >> 2;\r
+                       vga_state.vga_graphics_ram = omemptr + gvar.video.page[0].pagesize;\r
+\r
+                       /* then the sprite. note modding ram ptr means we just draw to (x&3,0) */\r
+                       draw_vrl1_vgax_modex(x-rx,y-ry,vrl_header,vrl_lineoffs,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));\r
+\r
+                       /* restore ptr */\r
+                       vga_state.vga_graphics_ram = omemptr;\r
+\r
+                       /* block copy to visible RAM from offscreen */\r
+                       vga_setup_wm1_block_copy();\r
+                       o = gvar.video.page[0].pagesize; // source offscreen\r
+                       o2 = (ry * gvar.video.page[0].stridew) + (rx >> 2); // dest visible (original stride)\r
+                       for (i=0;i < h;i++,o += vga_state.vga_draw_stride,o2 += gvar.video.page[0].stridew) vga_wm1_mem_block_copy(o2,o,w >> 2);\r
+                       /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */\r
+                       vga_restore_rm0wm0();\r
+\r
+                       /* restore stride */\r
+                       vga_state.vga_draw_stride_limit = vga_state.vga_draw_stride = gvar.video.page[0].stridew;\r
+\r
+                       /* step */\r
+                       x += xdir; y += ydir;\r
+                       if ((x + vrl_header->width) >= ((gvar.video.page[0].width + gvar.video.page[0].dx) - 1) || x == -(gvar.video.page[0].dx))\r
+                               xdir = -xdir;\r
+                       if ((y + vrl_header->height) >= ((gvar.video.page[0].height + gvar.video.page[0].dy) - 1) || y == -(gvar.video.page[0].dy))\r
+                               ydir = -ydir;\r
+                       //printf("[x%u y%u]     [rx%u ry%u]             [w%u h%u]\n", x, y, rx, ry, w, h);\r
+               }\r
+       }\r
+\r
+       IN_UserInput(1,1);\r
+\r
+       while(!IN_KeyDown(sc_Escape))\r
+       {\r
+               if(IN_KeyDown(2)) modexShowPage(&(gvar.video.page[0]));\r
+               if(IN_KeyDown(3)) modexShowPage(&(gvar.video.page[1]));\r
+       }\r
+\r
+       modexShowPage(&(gvar.video.page[0]));\r
+       /* another handy "demo" effect using VGA write mode 1.\r
+        * we can take what's on screen and vertically squash it like an old analog TV set turning off. */\r
+       {\r
+               unsigned int blank_line_ofs = (gvar.video.page[0].stridew * gvar.video.page[0].height * 2);\r
+               unsigned int copy_ofs = (gvar.video.page[0].stridew * gvar.video.page[0].height);\r
+               unsigned int display_ofs = 0x0000;\r
+               unsigned int i,y,soh,doh,dstart;\r
+               unsigned int dh_blankfill = 8;\r
+               unsigned int dh_step = 8;\r
+               uint32_t sh,dh,yf,ystep;\r
+\r
+               /* copy active display (0) to offscreen buffer (0x4000) */\r
+               vga_state.vga_draw_stride_limit = vga_state.vga_draw_stride = gvar.video.page[0].stridew;\r
+               vga_setup_wm1_block_copy();\r
+               vga_wm1_mem_block_copy(copy_ofs,display_ofs,gvar.video.page[0].stridew * gvar.video.page[0].height);\r
+               vga_restore_rm0wm0();\r
+\r
+               /* need a blank line as well */\r
+               for (i=0;i < gvar.video.page[0].stridew;i++) vga_state.vga_graphics_ram[i+blank_line_ofs] = 0;\r
+\r
+               sh = dh = gvar.video.page[0].height;\r
+               while (dh >= dh_step) {\r
+                       /* stop animating if the user hits ENTER */\r
+                       if (kbhit()) {\r
+                               if (getch() == 13) break;\r
+                       }\r
+\r
+                       /* wait for vsync end */\r
+                       vga_wait_for_vsync_end();\r
+\r
+                       /* what scalefactor to use for stretching? */\r
+                       ystep = (0x10000UL * sh) / dh;\r
+                       dstart = (gvar.video.page[0].height - dh) / 2; // center the squash effect on screen, otherwise it would squash to top of screen\r
+                       doh = display_ofs;\r
+                       soh = copy_ofs;\r
+                       yf = 0;\r
+                       y = 0;\r
+\r
+                       /* for performance, keep VGA in write mode 1 the entire render */\r
+                       vga_setup_wm1_block_copy();\r
+\r
+                       /* blank lines */\r
+                       if (dstart >= dh_blankfill) y = dstart - dh_blankfill;\r
+                       else y = 0;\r
+                       doh = gvar.video.page[0].stridew * y;\r
+\r
+                       while (y < dstart) {\r
+                               vga_wm1_mem_block_copy(doh,blank_line_ofs,gvar.video.page[0].stridew);\r
+                               doh += gvar.video.page[0].stridew;\r
+                               y++;\r
+                       }\r
+\r
+                       /* draw */\r
+                       while (y < (dh+dstart)) {\r
+                               soh = copy_ofs + ((yf >> 16UL) * gvar.video.page[0].stridew);\r
+                               vga_wm1_mem_block_copy(doh,soh,gvar.video.page[0].stridew);\r
+                               doh += gvar.video.page[0].stridew;\r
+                               yf += ystep;\r
+                               y++;\r
+                       }\r
+\r
+                       /* blank lines */\r
+                       while (y < gvar.video.page[0].height && y < (dh+dstart+dh_blankfill)) {\r
+                               vga_wm1_mem_block_copy(doh,blank_line_ofs,gvar.video.page[0].stridew);\r
+                               doh += gvar.video.page[0].stridew;\r
+                               y++;\r
+                       }\r
+\r
+                       /* done */\r
+                       vga_restore_rm0wm0();\r
+\r
+                       /* wait for vsync */\r
+                       vga_wait_for_vsync();\r
+\r
+                       /* make it shrink */\r
+                       dh -= dh_step;\r
+                       if (dh < 40) dh_step = 1;\r
+               }\r
+       }\r
+\r
+       IN_Shutdown();\r
+       VGAmodeX(0, 1, &gvar);\r
+       free(vrl_lineoffs);\r
+       buffer = NULL;\r
+       free(buffer);\r
+       bufsz = 0;\r
+       free(bakapee1);\r
+       free(bakapee2);\r
+       return 0;\r
+}\r
index 60043f41f2daac292baec37fe1791ac73aa20ef1..faba5120b37e0eda5cec750f6c58f1d9b85f1e6d 100755 (executable)
@@ -1,8 +1,8 @@
-# SciTE session file
-
-buffer.1.path=/dos/z/16/src/16.c
-buffer.1.position=1
-
-buffer.2.path=/dos/z/16/src/16.h
-buffer.2.position=1
-buffer.2.current=1
+# SciTE session file\r
+\r
+buffer.1.path=/dos/z/16/src/16.c\r
+buffer.1.position=1\r
+\r
+buffer.2.path=/dos/z/16/src/16.h\r
+buffer.2.position=1\r
+buffer.2.current=1\r
index 5a16247dc77b08733c6dead71510d6650c4d88d6..0db48708670fa5c9ce751da0e65728666f605992 100755 (executable)
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "src/lib/scroll16.h"
-#include "src/lib/16_timer.h"
-#include "src/lib/wcpu/wcpu.h"
-#include "src/lib/16_sprite.h"
-#include "src/lib/16_ca.h"
-#include "src/lib/16_mm.h"
-//#include "src/lib/16_head.h"//included already
-
-//#define FADE
-#define MODEX  //this is for mode x initiating
-
-//word far *clock= (word far*) 0x046C; /* 18.2hz clock */
-//bitmap_t *p;
-global_game_variables_t gvar;
-static map_t map;
-player_t player[MaxPlayers];
-map_view_t mv[4];
-byte *ppal;
-//word pn=0; //i forgot ww
-float t;
-sword bakapee;
-pan_t pan;
-//debugswitches
-boolean panswitch=0;
-//extern boolean pageflipflop=1;
-       unsigned int i;
-       const char *cpus;
-       //static int persist_aniframe = 0;    /* gonna be increased to 1 before being used, so 0 is ok for default */
-
-       //map_view_db_t pgid[4];
-       word pg;
-//#ifdef FADE
-       static word paloffset=0;
-       byte *dpal;
-//#endif
-       byte *gpal;
-       byte *ptr;
-       byte *mappalptr;
-
-void main(int argc, char *argv[])
-{
-       struct sprite sp;
-       __segment sega;
-       void __based(sega)* bigbuffer;
-
-       byte *mesg=malloc(sizeof(dword));
-       int i;
-
-       if(argv[1]) bakapee = atoi(argv[1]);
-       else bakapee = 1;
-
-       gvar.mm.mmstarted=0;
-       gvar.bigbuffer=bigbuffer;
-
-       MM_Startup(&gvar.mm, &gvar.mmi);
-       CA_Startup(&gvar);
-       // DOSLIB: check our environment
-       probe_dos();
-
-       // DOSLIB: what CPU are we using?
-       // NTS: I can see from the makefile Sparky4 intends this to run on 8088 by the -0 switch in CFLAGS.
-       //      So this code by itself shouldn't care too much what CPU it's running on. Except that other
-       //      parts of this project (DOSLIB itself) rely on CPU detection to know what is appropriate for
-       //      the CPU to carry out tasks. --J.C.
-       cpu_probe();
-
-       // DOSLIB: check for VGA
-       if (!probe_vga()) {
-               printf("VGA probe failed\n");
-               return;
-       }
-       // hardware must be VGA or higher!
-       if (!(vga_state.vga_flags & VGA_IS_VGA)) {
-               printf("This program requires VGA or higher graphics hardware\n");
-               return;
-       }
-
-       if (_DEBUG_INIT() == 0) {
-#ifdef DEBUGSERIAL
-               printf("WARNING: Failed to initialize DEBUG output\n");
-#endif
-       }
-       _DEBUG("Serial debug output started\n"); // NTS: All serial output must end messages with newline, or DOSBox-X will not emit text to log
-       _DEBUGF("Serial debug output printf test %u %u %u\n",1U,2U,3U);
-
-       pan.pn=1;
-
-       start_timer(&gvar);
-
-       /* create the map */
-       fprintf(stderr, "testing map load~      ");
-       loadmap("data/test.map", &map);
-       chkmap(&map, 0);
-       printf("chkmap ok       ");
-       fprintf(stderr, "yay map loaded~~\n");
-
-       /* draw the tiles */
-#ifdef MODEX
-       ptr = map.data;
-
-       /* data */
-       i = read_vrs(&gvar, "data/spri/chikyuu.vrs", sp.spritesheet);
-       if (i)
-       {
-               puts("Error! Did not load sprite!");
-               return;
-       }
-       puts("Sprite should be loaded now");
-       putch('q');
-       print_anim_ids(&sp);
-       putch('r');
-       i = set_anim_by_id(&sp, 10);
-       if (i == -1)
-       {
-               printf("Anim id not found!");
-               return;
-       }
-/*     player[0].spri = malloc(...)
- *     read_vrs(&gvar, "data/spri/chikyuu.vrs", player[0].spri->spritesheet); // load sprite
-       putch('s');
-       print_anim_ids(player[0].spri);
-       putch('t');
-       i = set_anim_by_id(player[0].spri, 10);
-       if (i == -1)
-       {
-               printf("Anim id not found!");
-               return;
-       }*/
-       player[0].spri = &sp;
-
-#endif
-       /*      input!  */
-       IN_Startup();
-       IN_Default(0,&player,ctrl_Joystick);
-
-       /* save the palette */
-#ifdef MODEX
-#ifdef FADE
-       dpal = modexNewPal();
-       modexPalSave(dpal);
-       modexFadeOff(4, dpal);
-#endif
-
-       textInit();
-       VGAmodeX(bakapee, 1, &gvar);
-#ifdef FADE
-       modexPalBlack();        //reset the palette~
-#endif
-#endif
-       modexLoadPalFile("data/spri/chikyuu.pal", &ppal);
-       modexPalUpdate1(ppal);
-#ifdef MODEX
-#ifdef FADE
-       gpal = modexNewPal();
-       modexPalSave(gpal);
-       modexSavePalFile("data/g.pal", gpal);
-       modexPalBlack();        //so player will not see loadings~
-#endif
-#endif
-
-       /* setup camera and screen~ */
-       modexHiganbanaPageSetup(&gvar.video);
-       for(i=0;i<gvar.video.num_of_pages;i++)
-       {
-               mv[i].page = &gvar.video.page[i];
-               mv[i].map = &map;
-               mv[i].video = &gvar.video;
-               mv[i].pan       = &pan;
-       }
-
-       /* set up paging */
-       //TODO: LOAD map data and position the map in the middle of the screen if smaller then screen
-       mapGoTo(mv, 0, 0);
-       //_fmemcpy(mv[1].page->data, mv[0].page->data, mv[0].page->pagesize);
-
-       //TODO: put player in starting position of spot
-       //default player position on the viewable map
-       player[0].tx = mv[0].tx + mv[0].page->tilemidposscreenx;
-       player[0].ty = mv[0].ty + mv[0].page->tilemidposscreeny;
-       IN_initplayer(&player, 0);
-       //IN_initplayer(&player, 1);
-
-#ifndef        SPRITE
-       modexClearRegion(mv[0].page, player[0].x, player[0].y-TILEWH, 16, 32, 15);
-       //modexClearRegion(mv[1].page, player[0].x, player[0].y-TILEWH, 16, 32, 15);
-#else
-       //PBUFSFUN(mv[1].page, player[0].x, player[0].y-TILEWH, 16, 64, 24, 32, PLAYERBMPDATA);
-       //PBUFSFUN(mv[0].page, player[0].x, player[0].y-TILEWH, 16, 64, 16, 32, player[0].data);
-       animate_spri(player[0].spri);
-#endif
-
-       if(!pageflipflop)       modexShowPage(mv[1].page);
-       else                    modexShowPage(mv[0].page);//!(gvar.video.p)
-               shinku_fps_indicator_page = 0; // we're on page 1 now, shinku(). follow along please or it will not be visible.
-
-       /* buffer pages */
-//     modexClearRegion(mv[2].page, 0, 0, mv[2].page->width, mv[2].page->height, 47);
-//     modexClearRegion(mv[3].page, 0, 0, mv[3].page->width, mv[3].page->height, 45);
-//     {
-//             unsigned int k,j,o;
-//             /* fill screen with a distinctive pattern */
-//             for (k=0;k < vga_state.vga_width;k++) {
-//                     o = k >> 2;
-//                     vga_write_sequencer(0x02/*map mask*/,1 << (k&3));
-//                             for (j=0;j < vga_state.vga_height;j++,o += vga_state.vga_stride)
-//                                     vga_state.vga_graphics_ram[o] = (k^j)&15; // VRL samples put all colors in first 15!
-//             }
-//     }
-       modexClearRegion(mv[3].page, 0, 128, 24, 36, 15);
-
-#ifdef MODEX
-#ifdef FADE
-       modexFadeOn(4, gpal);
-#endif
-#endif
-       while(!IN_KeyDown(sc_Escape) && player[0].hp>0)
-       {
-               shinku(&gvar);
-       //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[0].tx or player[0].ty == 0 or player[0].tx == 20 or player[0].ty == 15 then stop because that is edge of map and you do not want to walk of the map
-
-       //player movement
-               IN_ReadControl(0,&player);
-       if(!panswitch){
-               walk(mv, player, 0);
-       }else{
-               panpagemanual(mv, player, 0);
-               //printf("      player[0].q: %d", player[0].q); printf("        player[0].d: %d\n", player[0].d);
-       }
-
-       //the scripting stuff....
-       //if(((player[0].triggerx == TRIGGX && player[0].triggery == TRIGGY) && IN_KeyDown(0x1C))||(player[0].tx == 5 && player[0].ty == 5))
-       if(((mv[0].map->data[(player[0].triggerx-1)+(map.width*(player[0].triggery-1))] == 0) && IN_KeyDown(0x1C))||(player[0].tx == 5 && player[0].ty == 5))
-       {
-               short i;
-               for(i=800; i>=400; i--)
-               {
-                       sound(i);
-               }
-               nosound();
-       }
-       if(player[0].q == (TILEWH/(player[0].speed))+1 && player[0].info.dir != 2 && (player[0].triggerx == 5 && player[0].triggery == 5)){ player[0].hp--; }
-       //debugging binds!
-       if(IN_KeyDown(2)){ modexShowPage(mv[0].page); pan.pn=0; }
-       if(IN_KeyDown(3)){ modexShowPage(mv[1].page); pan.pn=1; }
-       if(IN_KeyDown(4)){ modexShowPage(mv[2].page); pan.pn=2; }
-       if(IN_KeyDown(4+1)){ modexShowPage(mv[3].page); pan.pn=3; }
-       if(IN_KeyDown(25)){ modexpdump(mv[0].page); modexpdump(mv[1].page);
-                IN_UserInput(1,1);
-       }       //p
-#ifdef MODEX
-#ifdef FADE
-       if(IN_KeyDown(24)){ modexPalUpdate0(gpal); paloffset=0; modexpdump(mv[0].page); modexpdump(mv[1].page);  IN_UserInput(1,1); }
-       if(IN_KeyDown(22)){
-//     paloffset=0; modexPalBlack(); modexPalUpdate(player[0].data, &paloffset, 0, 0);
-//     printf("1paloffset      =       %d\n", paloffset/3);
-//      modexPalUpdate(map.tiles->data, &paloffset, 0, 0);
-//     printf("2paloffset      =       %d\n", paloffset/3);
-//      modexpdump(mv[0].page); modexpdump(mv[1].page);
-               IN_UserInput(1,1);
-       }
-#endif
-#endif
-       //pan switch
-       if(IN_KeyDown(88)){panswitch=!panswitch; IN_UserInput(1,1);}    //f12
-       if(IN_KeyDown(87))      //f11
-       {
-               pageflipflop=!pageflipflop;
-               IN_UserInput(1,1);
-//             VGAmodeX(0, 0, &gvar);
-//             IN_Shutdown();
-//             __asm
-//             {
-//                     mov ah,31h
-//                     int 21h
-//             }
-       }
-       if(IN_KeyDown(68))      //f10
-       {
-               gvar.kurokku.fpscap=!gvar.kurokku.fpscap;
-               IN_UserInput(1,1);
-       }
-       if(IN_KeyDown(67))      //f9
-       {
-               modexClearRegion(mv[1].page, 0, 0, mv[1].page->width, mv[1].page->height, 2);
-               modexClearRegion(mv[2].page, 0, 0, mv[2].page->width, mv[2].page->height, 3);
-               modexClearRegion(mv[3].page, 0, 0, mv[3].page->width, mv[3].page->height, 4);
-               modexClearRegion(mv[3].page, 0, 0, 20, 36, 15);
-               //IN_UserInput(1,1);
-       }
-       if(IN_KeyDown(66))      //f8
-       {
-//             modexDrawSprite(mv[0].page, 16, 16, p);
-//             modexDrawSprite(mv[0].page, 32+48, 16, (player[0].data));
-       }
-       //TODO fmemtest into page
-       /*if(IN_KeyDown(4+1))   //4
-       {
-               pg=1;
-               SELECT_ALL_PLANES();
-               _fmemset(((mv[pg].page->data+4)+(16*(mv[pg].page->width/4))), 15, 4);
-       }*/
-
-       //9
-       if(IN_KeyDown(10)){ modexPalOverscan(rand()%56); modexPalUpdate1(dpal); IN_UserInput(1,1); }
-       //if(IN_KeyDown(11)){ modexPalOverscan(15); }
-       if((player[0].q==1) && !(player[0].x%TILEWH==0 && player[0].y%TILEWH==0)) break;        //incase things go out of sync!
-       }
-
-       /* fade back to text mode */
-       /* but 1st lets save the game palette~ */
-#ifdef MODEX
-#ifdef FADE
-       modexPalSave(gpal);
-       modexSavePalFile("data/g.pal", gpal);
-       modexFadeOff(4, gpal);
-#endif
-       VGAmodeX(0, 1, &gvar);
-#endif
-       IN_Shutdown();
-       MM_FreePtr(&bigbuffer, &gvar.mm);
-       CA_Shutdown(&gvar);
-       MM_Shutdown(&gvar.mm);
-       printf("\nProject 16 scroll.exe. This is just a test file!\n");
-       printf("version %s\n", VERSION);
-       printf("tx: %d  ", mv[0].tx);
-       printf("ty: %d\n", mv[0].ty);
-       printf("\n");
-       printf("player vars:\n");
-       printf("        x: %d", player[0].x); printf("  y: %d\n", player[0].y);
-       //if(player[0].hp==0) printf("%d wwww\n", player[0].y+8);
-       //else printf("\nplayer[0].y: %d\n", player[0].y);
-       printf("        tx: %d", player[0].tx); printf("        ty: %d\n", player[0].ty);
-       printf("        triggx: %d", player[0].triggerx); printf("      triggy: %d\n", player[0].triggery);
-       printf("        hp: %d", (player[0].hp));       printf("        q: %d", player[0].q);   printf("        player.info.dir: %d", player[0].info.dir);      printf("        player.d: %d ", player[0].d);
-               printf("        pdir=%d\n", player[0].pdir);
-       printf("        tile data value at player trigger position: %d\n\n", mv[0].map->data[(player[0].triggerx-1)+(map.width*(player[0].triggery-1))]);
-//     printf("palette offset: %d\n", paloffset/3);
-//++++ printf("Total used: %zu\n", oldfreemem-GetFreeSize());
-//++++ printf("Total free: %zu\n", GetFreeSize());
-//not used now printf("temporary player sprite 0: http://www.pixiv.net/member_illust.php?mode=medium&illust_id=45556867\n");
-//not used now printf("temporary player sprite 1: http://www.pixiv.net/member_illust.php?mode=medium&illust_id=44606385\n");
-       printf("Virtual Screen: %dx", gvar.video.page[0].width);        printf("%d      ", gvar.video.page[0].height);
-       printf("Screen: %dx", gvar.video.page[0].sw);   printf("%d\n", gvar.video.page[0].sh);
-       printf("virtual tile resolution: %dx", gvar.video.page[0].tilesw);      printf("%d      ", gvar.video.page[0].tilesh);
-       printf("tile resolution: %dx", gvar.video.page[0].tw);  printf("%d\n", gvar.video.page[0].th);
-       printf("middle tile position: %dx", gvar.video.page[0].tilemidposscreenx);      printf("%d\n", gvar.video.page[0].tilemidposscreeny);
-       modexprintmeminfo(&gvar.video);
-       //printf("mv[%u].tx: %d", pan.pn, mv[pan.pn].tx); printf("      mv[%u].ty: %d   ", pan.pn, mv[pan.pn].ty);
-       printf("gvar.video.p=%u ", gvar.video.p); printf("gvar.video.r=%u ", gvar.video.r);
-       printf("pageflipflop=%u\n", pageflipflop);
-       //0000printf("\ngvar.video.tickclk=%f\n", gvar.video.tickclk);
-       //0000printf("gvar.video.clk=%f", gvar.video.clk);
-       printf("\n");
-       //printf("map.width=%d  map.height=%d   map.data[0]=%d\n", mv[0].map->width, mv[0].map->height, mv[0].map->data[0]);
-
-       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);
-#ifdef MODEX
-#ifdef FADE
-       modexFadeOn(4, dpal);
-#endif
-#endif
-}
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+\r
+#include "src/lib/scroll16.h"\r
+#include "src/lib/16_timer.h"\r
+#include "src/lib/wcpu/wcpu.h"\r
+#include "src/lib/16_sprite.h"\r
+#include "src/lib/16_ca.h"\r
+#include "src/lib/16_mm.h"\r
+//#include "src/lib/16_head.h"//included already\r
+\r
+//#define FADE\r
+#define MODEX  //this is for mode x initiating\r
+\r
+//word far *clock= (word far*) 0x046C; /* 18.2hz clock */\r
+//bitmap_t *p;\r
+global_game_variables_t gvar;\r
+static map_t map;\r
+player_t player[MaxPlayers];\r
+map_view_t mv[4];\r
+byte *ppal;\r
+//word pn=0; //i forgot ww\r
+float t;\r
+sword bakapee;\r
+pan_t pan;\r
+//debugswitches\r
+boolean panswitch=0;\r
+//extern boolean pageflipflop=1;\r
+       unsigned int i;\r
+       const char *cpus;\r
+       //static int persist_aniframe = 0;    /* gonna be increased to 1 before being used, so 0 is ok for default */\r
+\r
+       //map_view_db_t pgid[4];\r
+       word pg;\r
+//#ifdef FADE\r
+       static word paloffset=0;\r
+       byte *dpal;\r
+//#endif\r
+       byte *gpal;\r
+       byte *ptr;\r
+       byte *mappalptr;\r
+\r
+void main(int argc, char *argv[])\r
+{\r
+       struct sprite sp;\r
+       __segment sega;\r
+       void __based(sega)* bigbuffer;\r
+\r
+       byte *mesg=malloc(sizeof(dword));\r
+       int i;\r
+\r
+       if(argv[1]) bakapee = atoi(argv[1]);\r
+       else bakapee = 1;\r
+\r
+       gvar.mm.mmstarted=0;\r
+       gvar.bigbuffer=bigbuffer;\r
+\r
+       MM_Startup(&gvar.mm, &gvar.mmi);\r
+       CA_Startup(&gvar);\r
+       // DOSLIB: check our environment\r
+       probe_dos();\r
+\r
+       // DOSLIB: what CPU are we using?\r
+       // NTS: I can see from the makefile Sparky4 intends this to run on 8088 by the -0 switch in CFLAGS.\r
+       //      So this code by itself shouldn't care too much what CPU it's running on. Except that other\r
+       //      parts of this project (DOSLIB itself) rely on CPU detection to know what is appropriate for\r
+       //      the CPU to carry out tasks. --J.C.\r
+       cpu_probe();\r
+\r
+       // DOSLIB: check for VGA\r
+       if (!probe_vga()) {\r
+               printf("VGA probe failed\n");\r
+               return;\r
+       }\r
+       // hardware must be VGA or higher!\r
+       if (!(vga_state.vga_flags & VGA_IS_VGA)) {\r
+               printf("This program requires VGA or higher graphics hardware\n");\r
+               return;\r
+       }\r
+\r
+       if (_DEBUG_INIT() == 0) {\r
+#ifdef DEBUGSERIAL\r
+               printf("WARNING: Failed to initialize DEBUG output\n");\r
+#endif\r
+       }\r
+       _DEBUG("Serial debug output started\n"); // NTS: All serial output must end messages with newline, or DOSBox-X will not emit text to log\r
+       _DEBUGF("Serial debug output printf test %u %u %u\n",1U,2U,3U);\r
+\r
+       pan.pn=1;\r
+\r
+       start_timer(&gvar);\r
+\r
+       /* create the map */\r
+       fprintf(stderr, "testing map load~      ");\r
+       loadmap("data/test.map", &map);\r
+       chkmap(&map, 0);\r
+       printf("chkmap ok       ");\r
+       fprintf(stderr, "yay map loaded~~\n");\r
+\r
+       /* draw the tiles */\r
+#ifdef MODEX\r
+       ptr = map.data;\r
+\r
+       /* data */\r
+       i = read_vrs(&gvar, "data/spri/chikyuu.vrs", sp.spritesheet);\r
+       if (i)\r
+       {\r
+               puts("Error! Did not load sprite!");\r
+               return;\r
+       }\r
+       puts("Sprite should be loaded now");\r
+       putch('q');\r
+       print_anim_ids(&sp);\r
+       putch('r');\r
+       i = set_anim_by_id(&sp, 10);\r
+       if (i == -1)\r
+       {\r
+               printf("Anim id not found!");\r
+               return;\r
+       }\r
+/*     player[0].spri = malloc(...)\r
+ *     read_vrs(&gvar, "data/spri/chikyuu.vrs", player[0].spri->spritesheet); // load sprite\r
+       putch('s');\r
+       print_anim_ids(player[0].spri);\r
+       putch('t');\r
+       i = set_anim_by_id(player[0].spri, 10);\r
+       if (i == -1)\r
+       {\r
+               printf("Anim id not found!");\r
+               return;\r
+       }*/\r
+       player[0].spri = &sp;\r
+\r
+#endif\r
+       /*      input!  */\r
+       IN_Startup();\r
+       IN_Default(0,&player,ctrl_Joystick);\r
+\r
+       /* save the palette */\r
+#ifdef MODEX\r
+#ifdef FADE\r
+       dpal = modexNewPal();\r
+       modexPalSave(dpal);\r
+       modexFadeOff(4, dpal);\r
+#endif\r
+\r
+       textInit();\r
+       VGAmodeX(bakapee, 1, &gvar);\r
+#ifdef FADE\r
+       modexPalBlack();        //reset the palette~\r
+#endif\r
+#endif\r
+       modexLoadPalFile("data/spri/chikyuu.pal", &ppal);\r
+       modexPalUpdate1(ppal);\r
+#ifdef MODEX\r
+#ifdef FADE\r
+       gpal = modexNewPal();\r
+       modexPalSave(gpal);\r
+       modexSavePalFile("data/g.pal", gpal);\r
+       modexPalBlack();        //so player will not see loadings~\r
+#endif\r
+#endif\r
+\r
+       /* setup camera and screen~ */\r
+       modexHiganbanaPageSetup(&gvar.video);\r
+       for(i=0;i<gvar.video.num_of_pages;i++)\r
+       {\r
+               mv[i].page = &gvar.video.page[i];\r
+               mv[i].map = &map;\r
+               mv[i].video = &gvar.video;\r
+               mv[i].pan       = &pan;\r
+       }\r
+\r
+       /* set up paging */\r
+       //TODO: LOAD map data and position the map in the middle of the screen if smaller then screen\r
+       mapGoTo(mv, 0, 0);\r
+       //_fmemcpy(mv[1].page->data, mv[0].page->data, mv[0].page->pagesize);\r
+\r
+       //TODO: put player in starting position of spot\r
+       //default player position on the viewable map\r
+       player[0].tx = mv[0].tx + mv[0].page->tilemidposscreenx;\r
+       player[0].ty = mv[0].ty + mv[0].page->tilemidposscreeny;\r
+       IN_initplayer(&player, 0);\r
+       //IN_initplayer(&player, 1);\r
+\r
+#ifndef        SPRITE\r
+       modexClearRegion(mv[0].page, player[0].x, player[0].y-TILEWH, 16, 32, 15);\r
+       //modexClearRegion(mv[1].page, player[0].x, player[0].y-TILEWH, 16, 32, 15);\r
+#else\r
+       //PBUFSFUN(mv[1].page, player[0].x, player[0].y-TILEWH, 16, 64, 24, 32, PLAYERBMPDATA);\r
+       //PBUFSFUN(mv[0].page, player[0].x, player[0].y-TILEWH, 16, 64, 16, 32, player[0].data);\r
+       animate_spri(player[0].spri);\r
+#endif\r
+\r
+       if(!pageflipflop)       modexShowPage(mv[1].page);\r
+       else                    modexShowPage(mv[0].page);//!(gvar.video.p)\r
+               shinku_fps_indicator_page = 0; // we're on page 1 now, shinku(). follow along please or it will not be visible.\r
+\r
+       /* buffer pages */\r
+//     modexClearRegion(mv[2].page, 0, 0, mv[2].page->width, mv[2].page->height, 47);\r
+//     modexClearRegion(mv[3].page, 0, 0, mv[3].page->width, mv[3].page->height, 45);\r
+//     {\r
+//             unsigned int k,j,o;\r
+//             /* fill screen with a distinctive pattern */\r
+//             for (k=0;k < vga_state.vga_width;k++) {\r
+//                     o = k >> 2;\r
+//                     vga_write_sequencer(0x02/*map mask*/,1 << (k&3));\r
+//                             for (j=0;j < vga_state.vga_height;j++,o += vga_state.vga_stride)\r
+//                                     vga_state.vga_graphics_ram[o] = (k^j)&15; // VRL samples put all colors in first 15!\r
+//             }\r
+//     }\r
+       modexClearRegion(mv[3].page, 0, 128, 24, 36, 15);\r
+\r
+#ifdef MODEX\r
+#ifdef FADE\r
+       modexFadeOn(4, gpal);\r
+#endif\r
+#endif\r
+       while(!IN_KeyDown(sc_Escape) && player[0].hp>0)\r
+       {\r
+               shinku(&gvar);\r
+       //top left corner & bottem right corner of map veiw be set as map edge trigger since maps are actually square\r
+       //to stop scrolling and have the player position data move to the edge of the screen with respect to the direction\r
+       //when player[0].tx or player[0].ty == 0 or player[0].tx == 20 or player[0].ty == 15 then stop because that is edge of map and you do not want to walk of the map\r
+\r
+       //player movement\r
+               IN_ReadControl(0,&player);\r
+       if(!panswitch){\r
+               walk(mv, player, 0);\r
+       }else{\r
+               panpagemanual(mv, player, 0);\r
+               //printf("      player[0].q: %d", player[0].q); printf("        player[0].d: %d\n", player[0].d);\r
+       }\r
+\r
+       //the scripting stuff....\r
+       //if(((player[0].triggerx == TRIGGX && player[0].triggery == TRIGGY) && IN_KeyDown(0x1C))||(player[0].tx == 5 && player[0].ty == 5))\r
+       if(((mv[0].map->data[(player[0].triggerx-1)+(map.width*(player[0].triggery-1))] == 0) && IN_KeyDown(0x1C))||(player[0].tx == 5 && player[0].ty == 5))\r
+       {\r
+               short i;\r
+               for(i=800; i>=400; i--)\r
+               {\r
+                       sound(i);\r
+               }\r
+               nosound();\r
+       }\r
+       if(player[0].q == (TILEWH/(player[0].speed))+1 && player[0].info.dir != 2 && (player[0].triggerx == 5 && player[0].triggery == 5)){ player[0].hp--; }\r
+       //debugging binds!\r
+       if(IN_KeyDown(2)){ modexShowPage(mv[0].page); pan.pn=0; }\r
+       if(IN_KeyDown(3)){ modexShowPage(mv[1].page); pan.pn=1; }\r
+       if(IN_KeyDown(4)){ modexShowPage(mv[2].page); pan.pn=2; }\r
+       if(IN_KeyDown(4+1)){ modexShowPage(mv[3].page); pan.pn=3; }\r
+       if(IN_KeyDown(25)){ modexpdump(mv[0].page); modexpdump(mv[1].page);\r
+                IN_UserInput(1,1);\r
+       }       //p\r
+#ifdef MODEX\r
+#ifdef FADE\r
+       if(IN_KeyDown(24)){ modexPalUpdate0(gpal); paloffset=0; modexpdump(mv[0].page); modexpdump(mv[1].page);  IN_UserInput(1,1); }\r
+       if(IN_KeyDown(22)){\r
+//     paloffset=0; modexPalBlack(); modexPalUpdate(player[0].data, &paloffset, 0, 0);\r
+//     printf("1paloffset      =       %d\n", paloffset/3);\r
+//      modexPalUpdate(map.tiles->data, &paloffset, 0, 0);\r
+//     printf("2paloffset      =       %d\n", paloffset/3);\r
+//      modexpdump(mv[0].page); modexpdump(mv[1].page);\r
+               IN_UserInput(1,1);\r
+       }\r
+#endif\r
+#endif\r
+       //pan switch\r
+       if(IN_KeyDown(88)){panswitch=!panswitch; IN_UserInput(1,1);}    //f12\r
+       if(IN_KeyDown(87))      //f11\r
+       {\r
+               pageflipflop=!pageflipflop;\r
+               IN_UserInput(1,1);\r
+//             VGAmodeX(0, 0, &gvar);\r
+//             IN_Shutdown();\r
+//             __asm\r
+//             {\r
+//                     mov ah,31h\r
+//                     int 21h\r
+//             }\r
+       }\r
+       if(IN_KeyDown(68))      //f10\r
+       {\r
+               gvar.kurokku.fpscap=!gvar.kurokku.fpscap;\r
+               IN_UserInput(1,1);\r
+       }\r
+       if(IN_KeyDown(67))      //f9\r
+       {\r
+               modexClearRegion(mv[1].page, 0, 0, mv[1].page->width, mv[1].page->height, 2);\r
+               modexClearRegion(mv[2].page, 0, 0, mv[2].page->width, mv[2].page->height, 3);\r
+               modexClearRegion(mv[3].page, 0, 0, mv[3].page->width, mv[3].page->height, 4);\r
+               modexClearRegion(mv[3].page, 0, 0, 20, 36, 15);\r
+               //IN_UserInput(1,1);\r
+       }\r
+       if(IN_KeyDown(66))      //f8\r
+       {\r
+//             modexDrawSprite(mv[0].page, 16, 16, p);\r
+//             modexDrawSprite(mv[0].page, 32+48, 16, (player[0].data));\r
+       }\r
+       //TODO fmemtest into page\r
+       /*if(IN_KeyDown(4+1))   //4\r
+       {\r
+               pg=1;\r
+               SELECT_ALL_PLANES();\r
+               _fmemset(((mv[pg].page->data+4)+(16*(mv[pg].page->width/4))), 15, 4);\r
+       }*/\r
+\r
+       //9\r
+       if(IN_KeyDown(10)){ modexPalOverscan(rand()%56); modexPalUpdate1(dpal); IN_UserInput(1,1); }\r
+       //if(IN_KeyDown(11)){ modexPalOverscan(15); }\r
+       if((player[0].q==1) && !(player[0].x%TILEWH==0 && player[0].y%TILEWH==0)) break;        //incase things go out of sync!\r
+       }\r
+\r
+       /* fade back to text mode */\r
+       /* but 1st lets save the game palette~ */\r
+#ifdef MODEX\r
+#ifdef FADE\r
+       modexPalSave(gpal);\r
+       modexSavePalFile("data/g.pal", gpal);\r
+       modexFadeOff(4, gpal);\r
+#endif\r
+       VGAmodeX(0, 1, &gvar);\r
+#endif\r
+       IN_Shutdown();\r
+       MM_FreePtr(&bigbuffer, &gvar.mm);\r
+       CA_Shutdown(&gvar);\r
+       MM_Shutdown(&gvar.mm);\r
+       printf("\nProject 16 scroll.exe. This is just a test file!\n");\r
+       printf("version %s\n", VERSION);\r
+       printf("tx: %d  ", mv[0].tx);\r
+       printf("ty: %d\n", mv[0].ty);\r
+       printf("\n");\r
+       printf("player vars:\n");\r
+       printf("        x: %d", player[0].x); printf("  y: %d\n", player[0].y);\r
+       //if(player[0].hp==0) printf("%d wwww\n", player[0].y+8);\r
+       //else printf("\nplayer[0].y: %d\n", player[0].y);\r
+       printf("        tx: %d", player[0].tx); printf("        ty: %d\n", player[0].ty);\r
+       printf("        triggx: %d", player[0].triggerx); printf("      triggy: %d\n", player[0].triggery);\r
+       printf("        hp: %d", (player[0].hp));       printf("        q: %d", player[0].q);   printf("        player.info.dir: %d", player[0].info.dir);      printf("        player.d: %d ", player[0].d);\r
+               printf("        pdir=%d\n", player[0].pdir);\r
+       printf("        tile data value at player trigger position: %d\n\n", mv[0].map->data[(player[0].triggerx-1)+(map.width*(player[0].triggery-1))]);\r
+//     printf("palette offset: %d\n", paloffset/3);\r
+//++++ printf("Total used: %zu\n", oldfreemem-GetFreeSize());\r
+//++++ printf("Total free: %zu\n", GetFreeSize());\r
+//not used now printf("temporary player sprite 0: http://www.pixiv.net/member_illust.php?mode=medium&illust_id=45556867\n");\r
+//not used now printf("temporary player sprite 1: http://www.pixiv.net/member_illust.php?mode=medium&illust_id=44606385\n");\r
+       printf("Virtual Screen: %dx", gvar.video.page[0].width);        printf("%d      ", gvar.video.page[0].height);\r
+       printf("Screen: %dx", gvar.video.page[0].sw);   printf("%d\n", gvar.video.page[0].sh);\r
+       printf("virtual tile resolution: %dx", gvar.video.page[0].tilesw);      printf("%d      ", gvar.video.page[0].tilesh);\r
+       printf("tile resolution: %dx", gvar.video.page[0].tw);  printf("%d\n", gvar.video.page[0].th);\r
+       printf("middle tile position: %dx", gvar.video.page[0].tilemidposscreenx);      printf("%d\n", gvar.video.page[0].tilemidposscreeny);\r
+       modexprintmeminfo(&gvar.video);\r
+       //printf("mv[%u].tx: %d", pan.pn, mv[pan.pn].tx); printf("      mv[%u].ty: %d   ", pan.pn, mv[pan.pn].ty);\r
+       printf("gvar.video.p=%u ", gvar.video.p); printf("gvar.video.r=%u ", gvar.video.r);\r
+       printf("pageflipflop=%u\n", pageflipflop);\r
+       //0000printf("\ngvar.video.tickclk=%f\n", gvar.video.tickclk);\r
+       //0000printf("gvar.video.clk=%f", gvar.video.clk);\r
+       printf("\n");\r
+       //printf("map.width=%d  map.height=%d   map.data[0]=%d\n", mv[0].map->width, mv[0].map->height, mv[0].map->data[0]);\r
+\r
+       printf("\n");\r
+       switch(detectcpu())\r
+       {\r
+               case 0: cpus = "8086/8088 or 186/88"; break;\r
+               case 1: cpus = "286"; break;\r
+               case 2: cpus = "386 or newer"; break;\r
+               default: cpus = "internal error"; break;\r
+       }\r
+       printf("detected CPU type: %s\n", cpus);\r
+#ifdef MODEX\r
+#ifdef FADE\r
+       modexFadeOn(4, dpal);\r
+#endif\r
+#endif\r
+}\r
index a74e7711dc3b7afd02629d749879cabc7d35c110..a94cf391067b5037e1fbaf842cac0d883cc675cc 100755 (executable)
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You screen.heightould have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "src/bakapi.h"
-
-/*
- * BAKAPEE!
- */
-global_game_variables_t gvar;
-static bakapee_t bakapee;
-word key,d,xpos,ypos,xdir,ydir;
-sword vgamodex_mode = 1; // 320x240 default
-int ch=0x0;
-
-void
-main(int argc, char *argvar[])
-{
-       char *a;
-       int i;
-       word panq=1, pand=0;
-       boolean panswitch=0;
-
-       // allow changing default mode from command line
-       for (i=1;i < argc;) {
-               a = argvar[i++];
-
-               if (*a == '-') {
-                       do { a++; } while (*a == '-');
-
-                       if (!strcmp(a,"mx")) {
-                               // (based on src/lib/modex16.c)
-                               // 1 = 320x240
-                               // 2 = 160x120
-                               // 3 = 320x200
-                               // 4 = 192x144
-                               // 5 = 256x192
-                               vgamodex_mode = (sword)strtoul(argvar[i++],NULL,0);
-                       }
-                       else {
-                               fprintf(stderr,"Unknown switch %s\n",a);
-                               return;
-                       }
-               }
-               else {
-                       fprintf(stderr,"Unknown command arg %s\n",a);
-                       return;
-               }
-       }
-
-       // DOSLIB: check our environment
-       probe_dos();
-
-       // DOSLIB: what CPU are we using?
-       // NTS: I can see from the makefile Sparky4 intends this to run on 8088 by the -0 switch in CFLAGS.
-       //      So this code by itself shouldn't care too much what CPU it's running on. Except that other
-       //      parts of this project (DOSLIB itself) rely on CPU detection to know what is appropriate for
-       //      the CPU to carry out tasks. --J.C.
-       cpu_probe();
-
-       // DOSLIB: check for VGA
-       if (!probe_vga()) {
-               printf("VGA probe failed\n");
-               return;
-       }
-       // hardware must be VGA or higher!
-       if (!(vga_state.vga_flags & VGA_IS_VGA)) {
-               printf("This program requires VGA or higher graphics hardware\n");
-               return;
-       }
-
-       // main variables values
-       d=4; // switch variable
-       key=2; // default screensaver number
-       xpos=TILEWHD;
-       ypos=TILEWHD;
-       xdir=1;
-       ydir=1;
-
-       VGAmodeX(vgamodex_mode, 1, &gvar); // TODO: Suggestion: Instead of magic numbers for the first param, might I suggest defining an enum or some #define constants that are easier to remember? --J.C.
-               // this code is written around modex16 which so far is a better fit than using DOSLIB vga directly, so leave MXLIB code in.
-               // we'll integrate DOSLIB vga into that part of the code instead for less disruption. -- J.C.
-
-       bakapee.xx = rand()&0%gvar.video.page[0].width;
-       bakapee.yy = rand()&0%gvar.video.page[0].height;
-       bakapee.gq = 0;
-       bakapee.sx=0;
-       bakapee.sy=0;
-       bakapee.bakax=0;
-       bakapee.bakay=0;
-       bakapee.coor=0;
-       bakapee.tile=0;
-
-       /* setup camera and screen~ */
-       gvar.video.page[0] = modexDefaultPage(&gvar.video.page[0]);
-       textInit();
-
-       //modexPalUpdate(bmp.palette); //____
-       //modexDrawBmp(VGA, 0, 0, &bmp, 0); //____
-       //getch(); //____
-
-       modexShowPage(&gvar.video.page[0]);
-
-// screen savers
-#ifdef BOINK
-       while(d>0)      // on!
-       {
-               int c;
-               /* run screensaver routine until keyboard input */
-               while (key > 0) {
-                       if (kbhit()) {
-                               if(!panswitch)
-                               {
-                                       getch(); // eat keyboard input
-                                       break;
-                               }else c=getch();
-                       }
-
-                       if(!panswitch)  ding(&gvar.video.page[0], &bakapee, key);
-                       else                    ding(&gvar.video.page[0], &bakapee, 2);
-                       if(panswitch!=0)
-                       {
-                               //right movement
-                               if((c==0x4d && pand == 0) || pand == 2)
-                               {
-                                       if(pand == 0){ pand = 2; }
-                                       if(panq<=(TILEWH/(4)))
-                                       {
-                                               gvar.video.page[0].dx++;
-                                               modexShowPage(&gvar.video.page[0]);
-                                               panq++;
-                                       } else { panq = 1; pand = 0; }
-                               }
-                               //left movement
-                               if((c==0x4b && pand == 0) || pand == 4)
-                               {
-                                       if(pand == 0){ pand = 4; }
-                                       if(panq<=(TILEWH/(4)))
-                                       {
-                                               gvar.video.page[0].dx--;
-                                               modexShowPage(&gvar.video.page[0]);
-                                               panq++;
-                                       } else { panq = 1; pand = 0; }
-                               }
-                               //down movement
-                               if((c==0x50 && pand == 0) || pand == 3)
-                               {
-                                       if(pand == 0){ pand = 3; }
-                                       if(panq<=(TILEWH/(4)))
-                                       {
-                                               gvar.video.page[0].dy++;
-                                               modexShowPage(&gvar.video.page[0]);
-                                               panq++;
-                                       } else { panq = 1; pand = 0; }
-                               }
-                               //up movement
-                               if((c==0x48 && pand == 0) || pand == 1)
-                               {
-                                       if(pand == 0){ pand = 1; }
-                                       if(panq<=(TILEWH/(4)))
-                                       {
-                                               gvar.video.page[0].dy--;
-                                               modexShowPage(&gvar.video.page[0]);
-                                               panq++;
-                                       } else { panq = 1; pand = 0; }
-                               }
-                               if(c==0x71 || c==0xb1 || c=='p')
-                               {
-                                       //getch(); // eat keyboard input
-                                       panswitch=0;
-                                       break; // 'q' or 'ESC' or 'p'
-                               }
-                       }
-               }
-
-               {
-
-               // this code is written around modex16 which so far is a better fit than using DOSLIB vga directly, so leave MXLIB code in.
-               // we'll integrate DOSLIB vga into that part of the code instead for less disruption. -- J.C.
-                       VGAmodeX(0, 0, &gvar);
-                       // user imput switch
-                       //fprintf(stderr, "xx=%d        yy=%d   tile=%d\n", bakapee.xx, bakapee.yy, bakapee.tile);
-                       //fprintf(stderr, "dx=%d        dy=%d   ", gvar.video.page[0].dx, gvar.video.page[0].dy);
-                       printf("Tiled mode is ");
-                       switch (bakapee.tile)
-                       {
-                               case 0:
-                                       printf("off.    ");
-                               break;
-                               case 1:
-                                       printf("on.     ");
-                               break;
-                       }
-                       //printf("\n");
-                       printf("Pan mode is ");
-                       switch (panswitch)
-                       {
-                               case 0:
-                                       printf("off.\n");
-                               break;
-                               case 1:
-                                       printf("on.\n");
-                               break;
-                       }
-                       printf("Enter 1, 2, 3, 4, 5, 6, 8, or 9 to run a screensaver, or enter 0 to quit.\n");
-pee:
-                       c = getch();
-                       switch (c) {
-                               case 27: /* Escape key */
-                               case '0':
-                                       d=0;
-                                       break;
-                               case 'p': // test pan
-                               switch (panswitch)
-                               {
-                                       case 0:
-                                               panswitch=1;
-                                       break;
-                                       case 1:
-                                               panswitch=0;
-                                       break;
-                               }
-                               goto pee;
-                               break;
-                               case 'b': // test tile change
-                                       switch (bakapee.tile)
-                                       {
-                                               case 0:
-                                                       bakapee.tile=1;
-                                               break;
-                                               case 1:
-                                                       bakapee.tile=0;
-                                               break;
-                                       }
-                                       key=0;
-                                       break;
-                               case '8':
-                                       c+=8;
-                               case '1':
-                               case '2':
-                               case '3':
-                               case '4':
-                               case '5':
-                               case '6':
-                               case '9':
-                                       key = c - '0';
-                                       VGAmodeX(vgamodex_mode, 0, &gvar);
-                                       gvar.video.page[0] = modexDefaultPage(&gvar.video.page[0]);
-               // this code is written around modex16 which so far is a better fit than using DOSLIB vga directly, so leave MXLIB code in.
-               // we'll integrate DOSLIB vga into that part of the code instead for less disruption. -- J.C.
-                                       modexShowPage(&gvar.video.page[0]);
-                                       break;
-                               default:
-                                       key=0;
-                                       break;
-                       }
-               }
-       }
-#else // !defined(BOINK)
-// FIXME: Does not compile. Do you want to remove this?
-// TODO: This is a testing sextion for textrendering and panning for project 16 --sparky4
-       while(1)
-       { // conditions of screen saver
-//             while(!kbhit())
-//             {
-//                     ding(&gvar.video.page[0], &bakapee, key);
-//             }
-               //end of screen savers
-               //pdump(&gvar.video.page[0]);
-
-//             mxOutText(xpos+1, ypos+gvar.video.page[0].height-48, "========================================");
-//             mxOutText(xpos+1, ypos+gvar.video.page[0].height-40, "|    |Chikyuu:$line1");
-//             mxOutText(xpos+1, ypos+gvar.video.page[0].height-32, "|    |$line2");
-//             mxOutText(xpos+1, ypos+gvar.video.page[0].height-24, "|    |$line3");
-//             mxOutText(xpos+1, ypos+gvar.video.page[0].height-16, "|    |$line4");
-//             mxOutText(xpos+1, ypos+gvar.video.page[0].height-8,  "========================================");
-
-       ding(&gvar.video.page[0], &bakapee, key);
-       modexPanPage(&gvar.video.page[0], xpos, ypos);
-       c = getch();
-
-//     xpos+=xdir;
-//     ypos+=ydir;
-//     if( (xpos>(gvar.video.page[0].sw-gvar.video.page[0].width-1))  || (xpos<1)){xdir=-xdir;}
-//     if( (ypos>(gvar.video.page[0].sh-gvar.video.page[0].height-1)) || (ypos<1)){ydir=-ydir;}
-//     ch=getch();
-       if(ch==0x71)break; // 'q'
-       if(ch==0x1b)break; // 'ESC'
-       }
-       VGAmodeX(0, 1, &gvar);
-#endif // defined(BOINK)
-//     printf("page.width=%u   ", gvar.video.page[0].width); printf("page.height=%u\n", gvar.video.page[0].height);
-       printf("bakapi ver. 1.04.16.04\nis made by sparky4\81i\81\86\83Ö\81\85\81j feel free to use it ^^\nLicence: GPL v3\n");
-       printf("compiled on 2016/04/04\n");
-}
-//pee!
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You screen.heightould have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+\r
+#include "src/bakapi.h"\r
+\r
+/*\r
+ * BAKAPEE!\r
+ */\r
+global_game_variables_t gvar;\r
+static bakapee_t bakapee;\r
+word key,d,xpos,ypos,xdir,ydir;\r
+sword vgamodex_mode = 1; // 320x240 default\r
+int ch=0x0;\r
+\r
+void\r
+main(int argc, char *argvar[])\r
+{\r
+       char *a;\r
+       int i;\r
+       word panq=1, pand=0;\r
+       boolean panswitch=0;\r
+\r
+       // allow changing default mode from command line\r
+       for (i=1;i < argc;) {\r
+               a = argvar[i++];\r
+\r
+               if (*a == '-') {\r
+                       do { a++; } while (*a == '-');\r
+\r
+                       if (!strcmp(a,"mx")) {\r
+                               // (based on src/lib/modex16.c)\r
+                               // 1 = 320x240\r
+                               // 2 = 160x120\r
+                               // 3 = 320x200\r
+                               // 4 = 192x144\r
+                               // 5 = 256x192\r
+                               vgamodex_mode = (sword)strtoul(argvar[i++],NULL,0);\r
+                       }\r
+                       else {\r
+                               fprintf(stderr,"Unknown switch %s\n",a);\r
+                               return;\r
+                       }\r
+               }\r
+               else {\r
+                       fprintf(stderr,"Unknown command arg %s\n",a);\r
+                       return;\r
+               }\r
+       }\r
+\r
+       // DOSLIB: check our environment\r
+       probe_dos();\r
+\r
+       // DOSLIB: what CPU are we using?\r
+       // NTS: I can see from the makefile Sparky4 intends this to run on 8088 by the -0 switch in CFLAGS.\r
+       //      So this code by itself shouldn't care too much what CPU it's running on. Except that other\r
+       //      parts of this project (DOSLIB itself) rely on CPU detection to know what is appropriate for\r
+       //      the CPU to carry out tasks. --J.C.\r
+       cpu_probe();\r
+\r
+       // DOSLIB: check for VGA\r
+       if (!probe_vga()) {\r
+               printf("VGA probe failed\n");\r
+               return;\r
+       }\r
+       // hardware must be VGA or higher!\r
+       if (!(vga_state.vga_flags & VGA_IS_VGA)) {\r
+               printf("This program requires VGA or higher graphics hardware\n");\r
+               return;\r
+       }\r
+\r
+       // main variables values\r
+       d=4; // switch variable\r
+       key=2; // default screensaver number\r
+       xpos=TILEWHD;\r
+       ypos=TILEWHD;\r
+       xdir=1;\r
+       ydir=1;\r
+\r
+       VGAmodeX(vgamodex_mode, 1, &gvar); // TODO: Suggestion: Instead of magic numbers for the first param, might I suggest defining an enum or some #define constants that are easier to remember? --J.C.\r
+               // this code is written around modex16 which so far is a better fit than using DOSLIB vga directly, so leave MXLIB code in.\r
+               // we'll integrate DOSLIB vga into that part of the code instead for less disruption. -- J.C.\r
+\r
+       bakapee.xx = rand()&0%gvar.video.page[0].width;\r
+       bakapee.yy = rand()&0%gvar.video.page[0].height;\r
+       bakapee.gq = 0;\r
+       bakapee.sx=0;\r
+       bakapee.sy=0;\r
+       bakapee.bakax=0;\r
+       bakapee.bakay=0;\r
+       bakapee.coor=0;\r
+       bakapee.tile=0;\r
+\r
+       /* setup camera and screen~ */\r
+       gvar.video.page[0] = modexDefaultPage(&gvar.video.page[0]);\r
+       textInit();\r
+\r
+       //modexPalUpdate(bmp.palette); //____\r
+       //modexDrawBmp(VGA, 0, 0, &bmp, 0); //____\r
+       //getch(); //____\r
+\r
+       modexShowPage(&gvar.video.page[0]);\r
+\r
+// screen savers\r
+#ifdef BOINK\r
+       while(d>0)      // on!\r
+       {\r
+               int c;\r
+               /* run screensaver routine until keyboard input */\r
+               while (key > 0) {\r
+                       if (kbhit()) {\r
+                               if(!panswitch)\r
+                               {\r
+                                       getch(); // eat keyboard input\r
+                                       break;\r
+                               }else c=getch();\r
+                       }\r
+\r
+                       if(!panswitch)  ding(&gvar.video.page[0], &bakapee, key);\r
+                       else                    ding(&gvar.video.page[0], &bakapee, 2);\r
+                       if(panswitch!=0)\r
+                       {\r
+                               //right movement\r
+                               if((c==0x4d && pand == 0) || pand == 2)\r
+                               {\r
+                                       if(pand == 0){ pand = 2; }\r
+                                       if(panq<=(TILEWH/(4)))\r
+                                       {\r
+                                               gvar.video.page[0].dx++;\r
+                                               modexShowPage(&gvar.video.page[0]);\r
+                                               panq++;\r
+                                       } else { panq = 1; pand = 0; }\r
+                               }\r
+                               //left movement\r
+                               if((c==0x4b && pand == 0) || pand == 4)\r
+                               {\r
+                                       if(pand == 0){ pand = 4; }\r
+                                       if(panq<=(TILEWH/(4)))\r
+                                       {\r
+                                               gvar.video.page[0].dx--;\r
+                                               modexShowPage(&gvar.video.page[0]);\r
+                                               panq++;\r
+                                       } else { panq = 1; pand = 0; }\r
+                               }\r
+                               //down movement\r
+                               if((c==0x50 && pand == 0) || pand == 3)\r
+                               {\r
+                                       if(pand == 0){ pand = 3; }\r
+                                       if(panq<=(TILEWH/(4)))\r
+                                       {\r
+                                               gvar.video.page[0].dy++;\r
+                                               modexShowPage(&gvar.video.page[0]);\r
+                                               panq++;\r
+                                       } else { panq = 1; pand = 0; }\r
+                               }\r
+                               //up movement\r
+                               if((c==0x48 && pand == 0) || pand == 1)\r
+                               {\r
+                                       if(pand == 0){ pand = 1; }\r
+                                       if(panq<=(TILEWH/(4)))\r
+                                       {\r
+                                               gvar.video.page[0].dy--;\r
+                                               modexShowPage(&gvar.video.page[0]);\r
+                                               panq++;\r
+                                       } else { panq = 1; pand = 0; }\r
+                               }\r
+                               if(c==0x71 || c==0xb1 || c=='p')\r
+                               {\r
+                                       //getch(); // eat keyboard input\r
+                                       panswitch=0;\r
+                                       break; // 'q' or 'ESC' or 'p'\r
+                               }\r
+                       }\r
+               }\r
+\r
+               {\r
+\r
+               // this code is written around modex16 which so far is a better fit than using DOSLIB vga directly, so leave MXLIB code in.\r
+               // we'll integrate DOSLIB vga into that part of the code instead for less disruption. -- J.C.\r
+                       VGAmodeX(0, 0, &gvar);\r
+                       // user imput switch\r
+                       //fprintf(stderr, "xx=%d        yy=%d   tile=%d\n", bakapee.xx, bakapee.yy, bakapee.tile);\r
+                       //fprintf(stderr, "dx=%d        dy=%d   ", gvar.video.page[0].dx, gvar.video.page[0].dy);\r
+                       printf("Tiled mode is ");\r
+                       switch (bakapee.tile)\r
+                       {\r
+                               case 0:\r
+                                       printf("off.    ");\r
+                               break;\r
+                               case 1:\r
+                                       printf("on.     ");\r
+                               break;\r
+                       }\r
+                       //printf("\n");\r
+                       printf("Pan mode is ");\r
+                       switch (panswitch)\r
+                       {\r
+                               case 0:\r
+                                       printf("off.\n");\r
+                               break;\r
+                               case 1:\r
+                                       printf("on.\n");\r
+                               break;\r
+                       }\r
+                       printf("Enter 1, 2, 3, 4, 5, 6, 8, or 9 to run a screensaver, or enter 0 to quit.\n");\r
+pee:\r
+                       c = getch();\r
+                       switch (c) {\r
+                               case 27: /* Escape key */\r
+                               case '0':\r
+                                       d=0;\r
+                                       break;\r
+                               case 'p': // test pan\r
+                               switch (panswitch)\r
+                               {\r
+                                       case 0:\r
+                                               panswitch=1;\r
+                                       break;\r
+                                       case 1:\r
+                                               panswitch=0;\r
+                                       break;\r
+                               }\r
+                               goto pee;\r
+                               break;\r
+                               case 'b': // test tile change\r
+                                       switch (bakapee.tile)\r
+                                       {\r
+                                               case 0:\r
+                                                       bakapee.tile=1;\r
+                                               break;\r
+                                               case 1:\r
+                                                       bakapee.tile=0;\r
+                                               break;\r
+                                       }\r
+                                       key=0;\r
+                                       break;\r
+                               case '8':\r
+                                       c+=8;\r
+                               case '1':\r
+                               case '2':\r
+                               case '3':\r
+                               case '4':\r
+                               case '5':\r
+                               case '6':\r
+                               case '9':\r
+                                       key = c - '0';\r
+                                       VGAmodeX(vgamodex_mode, 0, &gvar);\r
+                                       gvar.video.page[0] = modexDefaultPage(&gvar.video.page[0]);\r
+               // this code is written around modex16 which so far is a better fit than using DOSLIB vga directly, so leave MXLIB code in.\r
+               // we'll integrate DOSLIB vga into that part of the code instead for less disruption. -- J.C.\r
+                                       modexShowPage(&gvar.video.page[0]);\r
+                                       break;\r
+                               default:\r
+                                       key=0;\r
+                                       break;\r
+                       }\r
+               }\r
+       }\r
+#else // !defined(BOINK)\r
+// FIXME: Does not compile. Do you want to remove this?\r
+// TODO: This is a testing sextion for textrendering and panning for project 16 --sparky4\r
+       while(1)\r
+       { // conditions of screen saver\r
+//             while(!kbhit())\r
+//             {\r
+//                     ding(&gvar.video.page[0], &bakapee, key);\r
+//             }\r
+               //end of screen savers\r
+               //pdump(&gvar.video.page[0]);\r
+\r
+//             mxOutText(xpos+1, ypos+gvar.video.page[0].height-48, "========================================");\r
+//             mxOutText(xpos+1, ypos+gvar.video.page[0].height-40, "|    |Chikyuu:$line1");\r
+//             mxOutText(xpos+1, ypos+gvar.video.page[0].height-32, "|    |$line2");\r
+//             mxOutText(xpos+1, ypos+gvar.video.page[0].height-24, "|    |$line3");\r
+//             mxOutText(xpos+1, ypos+gvar.video.page[0].height-16, "|    |$line4");\r
+//             mxOutText(xpos+1, ypos+gvar.video.page[0].height-8,  "========================================");\r
+\r
+       ding(&gvar.video.page[0], &bakapee, key);\r
+       modexPanPage(&gvar.video.page[0], xpos, ypos);\r
+       c = getch();\r
+\r
+//     xpos+=xdir;\r
+//     ypos+=ydir;\r
+//     if( (xpos>(gvar.video.page[0].sw-gvar.video.page[0].width-1))  || (xpos<1)){xdir=-xdir;}\r
+//     if( (ypos>(gvar.video.page[0].sh-gvar.video.page[0].height-1)) || (ypos<1)){ydir=-ydir;}\r
+//     ch=getch();\r
+       if(ch==0x71)break; // 'q'\r
+       if(ch==0x1b)break; // 'ESC'\r
+       }\r
+       VGAmodeX(0, 1, &gvar);\r
+#endif // defined(BOINK)\r
+//     printf("page.width=%u   ", gvar.video.page[0].width); printf("page.height=%u\n", gvar.video.page[0].height);\r
+       printf("bakapi ver. 1.04.16.04\nis made by sparky4\81i\81\86\83Ö\81\85\81j feel free to use it ^^\nLicence: GPL v3\n");\r
+       printf("compiled on 2016/04/04\n");\r
+}\r
+//pee!\r
index 1270fab732222efb06a5dc4b4c4a5215e4374048..7c1fb1ab8531176d8fa27149e49d9352ec765bbe 100755 (executable)
@@ -1,31 +1,31 @@
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef __BAKAPI_H_
-#define __BAKAPI_H_
-
-#include "src/lib/bakapee.h"
-
-//project 16 testing define switch for veiwing the contents of the video memory --sparky4
-#define BOINK // what does this mean? --J.C.
-
-#endif /*__BAKAPI_H_*/
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+\r
+#ifndef __BAKAPI_H_\r
+#define __BAKAPI_H_\r
+\r
+#include "src/lib/bakapee.h"\r
+\r
+//project 16 testing define switch for veiwing the contents of the video memory --sparky4\r
+#define BOINK // what does this mean? --J.C.\r
+\r
+#endif /*__BAKAPI_H_*/\r
index eefab9ea8cf7337f1a8740d6b0ba38818e92614e..e8bfe1f549254a0d9c32df7287073c8b8e6b001d 100755 (executable)
@@ -8,8 +8,8 @@
 \r
         minor mods by Alex Russell to simplify\r
 \r
-        Must use memory model with FAR code
-
+        Must use memory model with FAR code\r
+\r
                Open Watcom patch by sparky4~\r
 \r
  */\r
 #include <stdio.h>\r
 #include <stdlib.h>\r
 #include <mem.h>\r
-#include <conio.h>
+#include <conio.h>\r
+\r
+#include "src/lib/exmm/memory.h"\r
+#include "src/lib/types.h"\r
 \r
-#include "src/lib/exmm/memory.h"
-#include "src/lib/types.h"
-
 #define PEMMDATAPAGENUM        4\r
 \r
 void TransformData(char *pEmmData, unsigned int len)\r
@@ -37,30 +37,30 @@ void TransformData(char *pEmmData, unsigned int len)
 \r
 int main(int argc, char *argv[])\r
 {\r
-       byte *pEmmData;
-       int hEData;
-       unsigned long advi;
-       unsigned long i=0;
-       char huge *p =(char huge *)(GetEMMSeg0()*0x10000);
+       byte *pEmmData;\r
+       int hEData;\r
+       unsigned long advi;\r
+       unsigned long i=0;\r
+       char huge *p =(char huge *)(GetEMMSeg0()*0x10000);\r
 \r
        if(OpenEMM() != SUCCESS)\r
        {               // make sure we got EMM\r
                printf("EMM unavailable.\n");\r
                exit(1);\r
        }\r
-       else
+       else\r
        {\r
-               printf("Emm %x available\n", EMVer());
-               printf("EMS pages available are %lu\n", EMMCoreLeft());
-               //printf("EMM Hardware Information %lu\n", EMInfo());
+               printf("Emm %x available\n", EMVer());\r
+               printf("EMS pages available are %lu\n", EMMCoreLeft());\r
+               //printf("EMM Hardware Information %lu\n", EMInfo());\r
        }\r
-
-       printf("b4 EMS          pEmmData=%p\n", pEmmData);
-       //printf("b4 EMS        *pEmmData=%s\n", *pEmmData);
-       advi=EMMCoreLeft()*EMMPAGESIZE;
-       printf("advi=%lu\n", advi);
-
-       pEmmData = (byte *)EMMalloc(&hEData, EMMCoreLeft());  // get 6 * 16K bytes - 96K
+\r
+       printf("b4 EMS          pEmmData=%p\n", pEmmData);\r
+       //printf("b4 EMS        *pEmmData=%s\n", *pEmmData);\r
+       advi=EMMCoreLeft()*EMMPAGESIZE;\r
+       printf("advi=%lu\n", advi);\r
+\r
+       pEmmData = (byte *)EMMalloc(&hEData, EMMCoreLeft());  // get 6 * 16K bytes - 96K\r
        if(pEmmData == NULL/* ||  pEmmData0 == NULL*/)\r
        {\r
                printf("Not enough EMM or out of handles.\n");\r
@@ -68,73 +68,73 @@ int main(int argc, char *argv[])
        }\r
        else\r
                printf("EMM allocate OK\n");\r
-
-       printf("EMS pages available are %lu\n", EMMCoreLeft());
-
-
-
+\r
+       printf("EMS pages available are %lu\n", EMMCoreLeft());\r
+\r
+\r
+\r
        printf("Map 1st 4 pages\n");\r
        MapEMM(hEData, 0, PEMMDATAPAGENUM);   // load 1st 4 pages into page frame: 0-3\r
-       //memset(pEmmData, 0x0e, 64000u);
-//0000 printf("(advi*EMMPAGESIZE)=%lu\n", advi);
-       memset(pEmmData, atoi(argv[1]), 0xffff);//sizeof(atoi(argv[1])));//((EMMCoreLeft())*EMMPAGESIZE));
-//qqqq memset(pEmmData+0x10000, atoi(argv[1]), 0xffff);//sizeof(atoi(argv[1])));//((EMMCoreLeft())*EMMPAGESIZE));
-//---- UnmapEMM(hEData, 0, 4);          // not absolutely necessary
-       printf("%p= %c %c %c %c %c %c %c %c\n", pEmmData,
-*pEmmData, *(pEmmData+1), *(pEmmData+2), *(pEmmData+3), *(pEmmData+4), *(pEmmData+5), *(pEmmData+6), *(pEmmData+7));
+       //memset(pEmmData, 0x0e, 64000u);\r
+//0000 printf("(advi*EMMPAGESIZE)=%lu\n", advi);\r
+       memset(pEmmData, atoi(argv[1]), 0xffff);//sizeof(atoi(argv[1])));//((EMMCoreLeft())*EMMPAGESIZE));\r
+//qqqq memset(pEmmData+0x10000, atoi(argv[1]), 0xffff);//sizeof(atoi(argv[1])));//((EMMCoreLeft())*EMMPAGESIZE));\r
+//---- UnmapEMM(hEData, 0, 4);          // not absolutely necessary\r
+       printf("%p= %c %c %c %c %c %c %c %c\n", pEmmData,\r
+*pEmmData, *(pEmmData+1), *(pEmmData+2), *(pEmmData+3), *(pEmmData+4), *(pEmmData+5), *(pEmmData+6), *(pEmmData+7));\r
 \r
        /*printf("Map next 2 pages\n");\r
        MapEMM(hEData, 4, 2);            // map last 2 pages: 4-5\r
-       memset(pEmmData, 0x04, 32768u);
-//     memset(pEmmData, atoi(argv[0]), 32768u);
-       printf("*pEmmData=%c\n", *pEmmData);
-       printf(" pEmmData=%p\n", pEmmData);*/
+       memset(pEmmData, 0x04, 32768u);\r
+//     memset(pEmmData, atoi(argv[0]), 32768u);\r
+       printf("*pEmmData=%c\n", *pEmmData);\r
+       printf(" pEmmData=%p\n", pEmmData);*/\r
 \r
    /*MapEMM(hEData, 0, 4);\r
    // do some stuff with the first 64K of file data.\r
    printf("Transform data\n");\r
-   TransformData(pEmmData, 64000UL);
+   TransformData(pEmmData, 64000UL);\r
        printf("*pEmmData=%lu\n", *pEmmData);\r
    MapEMM(hEData, 4, 2);  // only unmaps 1st two pages of prior 64k mapping\r
    // do stuff with remaining 32K of data\r
-   TransformData(pEmmData, 32768UL);
-       printf("*pEmmData=%lu\n", *pEmmData);*/
-       if(atoi(argv[2]))
-       {
-               while(p<(char huge *)((GetEMMSeg0()*0x10000)+0xffff) && !kbhit())
-               {
-                       if((i%16)==0) printf("%p= %c %c %c %c %c %c %c %c %c %c %c %c %c %c %c %c\n", p,
-*p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5), *(p+6), *(p+7),
-*(p+8), *(p+9), *(p+10), *(p+11), *(p+12), *(p+13), *(p+14), *(p+15));
-       //              (*p)++;
-                       i++;
-                       p++;
-               }
-       }
-       /*if(atoi(argv[3]))
-               p =(char huge *)(GetEMMSeg0()*0x20000);
-               while(p<(char huge *)((GetEMMSeg0()*0x20000)+0xffff) && !kbhit())
-               {
-                       if((i%16)==0) printf("%p= %c %c %c %c %c %c %c %c %c %c %c %c %c %c %c %c\n", p,
-*p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5), *(p+6), *(p+7),
-*(p+8), *(p+9), *(p+10), *(p+11), *(p+12), *(p+13), *(p+14), *(p+15));
-       //              (*p)++;
-                       i++;
-                       p++;
-               }
-               //free(p);
-       }*/
-       if(!atoi(argv[3]))
+   TransformData(pEmmData, 32768UL);\r
+       printf("*pEmmData=%lu\n", *pEmmData);*/\r
+       if(atoi(argv[2]))\r
        {\r
-               UnmapEMM(hEData, 0, PEMMDATAPAGENUM);  // should unmap before freeing
+               while(p<(char huge *)((GetEMMSeg0()*0x10000)+0xffff) && !kbhit())\r
+               {\r
+                       if((i%16)==0) printf("%p= %c %c %c %c %c %c %c %c %c %c %c %c %c %c %c %c\n", p,\r
+*p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5), *(p+6), *(p+7),\r
+*(p+8), *(p+9), *(p+10), *(p+11), *(p+12), *(p+13), *(p+14), *(p+15));\r
+       //              (*p)++;\r
+                       i++;\r
+                       p++;\r
+               }\r
+       }\r
+       /*if(atoi(argv[3]))\r
+               p =(char huge *)(GetEMMSeg0()*0x20000);\r
+               while(p<(char huge *)((GetEMMSeg0()*0x20000)+0xffff) && !kbhit())\r
+               {\r
+                       if((i%16)==0) printf("%p= %c %c %c %c %c %c %c %c %c %c %c %c %c %c %c %c\n", p,\r
+*p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5), *(p+6), *(p+7),\r
+*(p+8), *(p+9), *(p+10), *(p+11), *(p+12), *(p+13), *(p+14), *(p+15));\r
+       //              (*p)++;\r
+                       i++;\r
+                       p++;\r
+               }\r
+               //free(p);\r
+       }*/\r
+       if(!atoi(argv[3]))\r
+       {\r
+               UnmapEMM(hEData, 0, PEMMDATAPAGENUM);  // should unmap before freeing\r
                //printf("after EMS     *pEmmData=%c\n", *pEmmData);\r
                printf("Close emm\n");\r
                EMMFree(hEData);     // finished with the file data\r
-               CloseEMM();
-       }
-       printf("after EMS       pEmmData=%p\n", pEmmData);
-       printf("EMS pages available are %lu\n", EMMCoreLeft());
-       printf("GetEMMSeg0=%p\n", GetEMMSeg0()*0x10000);
-       //printf("EMMPAGESIZE=%d\n", EMMPAGESIZE);
-       return 0;
+               CloseEMM();\r
+       }\r
+       printf("after EMS       pEmmData=%p\n", pEmmData);\r
+       printf("EMS pages available are %lu\n", EMMCoreLeft());\r
+       printf("GetEMMSeg0=%p\n", GetEMMSeg0()*0x10000);\r
+       //printf("EMMPAGESIZE=%d\n", EMMPAGESIZE);\r
+       return 0;\r
 }\r
index b07f7c66d86c976cbcf688578e7a531e64118e5d..4506986331adef8a881472fc6c6dfaec4a30bb74 100755 (executable)
@@ -1,58 +1,58 @@
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include<stdio.h>
-#include <conio.h>
-//#include <limits.h>
-
-#include "src/lib/exmm/memory.h"
-
-int main(int argc, char *argv[])
-{
-       unsigned long i=0;
-       char near w;
-       char huge *p =(char huge *)(GetEMMSeg0()*0x10000);//0xD0000000;
-       //char far *q =(char far *)0x53332225;
-       printf("1p=%p   %ul\n", p, GetEMMSeg0());
-       //while(!kbhit()){              printf("%p\n", ((GetEMMSeg0()*0x10000)+0x0fffffff));    }
-       //while(!kbhit()){              printf("%p\n", ((GetEMMSeg0()*0x10000)+0xffff));        }
-       if(argv[1])     {               printf("switch on!\n");         while(!kbhit()){}       }
-       while(p<=(char huge *)((GetEMMSeg0()*0x10000)+0xffff)/*i<262144UL*/ && !kbhit())
-       {
-               if(argv[1]!=NULL) (*p) = i; else
-               //else printf("%p=      %x%     %ul\n", p, *p, i);
-               if((i%8)==0) printf("%p= %c %c %c %c %c %c %c %c\n", p,
-*p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5), *(p+6), *(p+7));
-//             (*p)++;
-//             printf("                                %p\n", ((GetEMMSeg0()*0x10000)+0x0fffffff));
-               i++;
-               p++;
-       }
-       w=104;
-       //printf("*q=%d\n",*q);
-       //printf(" q=%p\n", q);
-       printf(" p=%p\n", p);
-       printf(" w=%d\n", w);
-       printf(" w=%p\n", w);
-       printf("GetEMMSeg0()=%p\n", GetEMMSeg0()*0x10000);
-       return 0;
-}
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+\r
+#include<stdio.h>\r
+#include <conio.h>\r
+//#include <limits.h>\r
+\r
+#include "src/lib/exmm/memory.h"\r
+\r
+int main(int argc, char *argv[])\r
+{\r
+       unsigned long i=0;\r
+       char near w;\r
+       char huge *p =(char huge *)(GetEMMSeg0()*0x10000);//0xD0000000;\r
+       //char far *q =(char far *)0x53332225;\r
+       printf("1p=%p   %ul\n", p, GetEMMSeg0());\r
+       //while(!kbhit()){              printf("%p\n", ((GetEMMSeg0()*0x10000)+0x0fffffff));    }\r
+       //while(!kbhit()){              printf("%p\n", ((GetEMMSeg0()*0x10000)+0xffff));        }\r
+       if(argv[1])     {               printf("switch on!\n");         while(!kbhit()){}       }\r
+       while(p<=(char huge *)((GetEMMSeg0()*0x10000)+0xffff)/*i<262144UL*/ && !kbhit())\r
+       {\r
+               if(argv[1]!=NULL) (*p) = i; else\r
+               //else printf("%p=      %x%     %ul\n", p, *p, i);\r
+               if((i%8)==0) printf("%p= %c %c %c %c %c %c %c %c\n", p,\r
+*p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5), *(p+6), *(p+7));\r
+//             (*p)++;\r
+//             printf("                                %p\n", ((GetEMMSeg0()*0x10000)+0x0fffffff));\r
+               i++;\r
+               p++;\r
+       }\r
+       w=104;\r
+       //printf("*q=%d\n",*q);\r
+       //printf(" q=%p\n", q);\r
+       printf(" p=%p\n", p);\r
+       printf(" w=%d\n", w);\r
+       printf(" w=%p\n", w);\r
+       printf("GetEMMSeg0()=%p\n", GetEMMSeg0()*0x10000);\r
+       return 0;\r
+}\r
index f9c6500d20a55b9cd1797174a0a971e1c7f07fe3..8c570b2e1fe143f4102855d85c737325340efee6 100755 (executable)
@@ -1,7 +1,7 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "src\lib\ems.c"
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include "src\lib\ems.c"\r
      /*\r
      Test function for the EMM routines\r
      */\r
@@ -55,4 +55,4 @@
           }\r
      \r
           emmclose(emmhandle);\r
-     }
+     }\r
index bddf4a09c13aac7606de08628ae080b1b5eaa613..aa21497ee851f36d7ffd905fc14c91183b565da9 100755 (executable)
@@ -98,7 +98,8 @@ main(int argc, char *argv[])
        //printf("main()=%Fp    start MM\n", *argv[0]);\r
        MM_Startup(&gvar);\r
        PM_Startup(&gvar);\r
-       //PM_UnlockMainMem(&gvar);\r
+       PM_CheckMainMem(&gvar);\r
+       PM_UnlockMainMem(&gvar);\r
        CA_Startup(&gvar);\r
 //     printf("                done!\n");\r
        PRINTBB;\r
index 2215c42002c2acaa5ac9de10655db74ac1efa3a7..7766a1d443592a49cc64c032d357fa02e1a6584f 100755 (executable)
@@ -1,76 +1,76 @@
-
-#include "src/16.h"
-
-// TODO: Could we also provide a build mode to emit debug to the "Bochs E9 hack?"
-#ifdef DEBUGSERIAL
-# include <stdarg.h>
-# include <stdlib.h>
-# include <stdio.h>
-
-unsigned char _DEBUG_INITed = 0;
-struct info_8250 *_DEBUG_uart = NULL;
-
-int _DEBUG_INIT() {
-       if (!_DEBUG_INITed) {
-               unsigned int i;
-               uint16_t port;
-
-               if (!init_8250()) return 0;
-
-               // what does the BIOS say the serial ports are?
-               probe_8250_bios_ports();
-               for (i=0;i < bios_8250_ports;i++) {
-                       port = get_8250_bios_port(i);
-                       if (port == 0) continue;
-                       probe_8250(port);
-               }
-
-               // what about the standard serial ports?
-               for (i=0;i < (sizeof(standard_8250_ports)/sizeof(standard_8250_ports[0]));i++) {
-                       port = standard_8250_ports[i];
-                       if (port == 0) continue;
-                       probe_8250(port);
-               }
-
-               // pick the first port, which is probably COM1
-               if (base_8250_ports == 0) return 0; // FIXME: You know "base_8250_ports" is probably a bad variable name for the max entries in info_8250_port[]
-               _DEBUG_uart = &info_8250_port[0];
-               _DEBUG_INITed = 1;
-
-               // init the COM port.
-               // in DOSBox-X, the "log" mode will receive our text and print it into the log file
-               // on real hardware, our text will likely go over a null modem cable to another PC running a serial terminal program like PuTTY or minicom.
-               // if nothing is connected, then the bytes go off into the ether to get lost and life goes on.
-               uart_8250_enable_interrupt(_DEBUG_uart,0);      // disable interrupts
-               uart_8250_set_FIFO(_DEBUG_uart,0x07);           // enable FIFO (why not?), also clear xmit/recv FIFO buffers, set threshhold to 1 byte
-               uart_8250_set_MCR(_DEBUG_uart,3);               // RTS and DTS on
-               uart_8250_set_line_control(_DEBUG_uart,UART_8250_LCR_8BIT | UART_8250_LCR_PARITY); // 8 bit 1 stop bit odd parity
-               uart_8250_set_baudrate(_DEBUG_uart,uart_8250_baud_to_divisor(_DEBUG_uart,9600)); // 9600 baud
-       }
-
-       return _DEBUG_INITed;
-}
-
-void _DEBUG(const char *msg) {
-       if (_DEBUG_uart != NULL) {
-               char c;
-
-               while ((c=(*msg++)) != 0/*NUL*/) {
-                       while (!uart_8250_can_write(_DEBUG_uart)); // wait for the UART to indicate readiness for our output
-                       uart_8250_write(_DEBUG_uart,(uint8_t)c); // then write it
-               }
-       }
-}
-
-static char _DEBUGF_TMP[256];
-
-void _DEBUGF(const char *fmt,...) {
-       va_list va;
-
-       va_start(va,fmt);
-       vsnprintf(_DEBUGF_TMP,sizeof(_DEBUGF_TMP),fmt,va);
-       _DEBUG(_DEBUGF_TMP);
-       va_end(va);
-}
-#endif
-
+\r
+#include "src/16.h"\r
+\r
+// TODO: Could we also provide a build mode to emit debug to the "Bochs E9 hack?"\r
+#ifdef DEBUGSERIAL\r
+# include <stdarg.h>\r
+# include <stdlib.h>\r
+# include <stdio.h>\r
+\r
+unsigned char _DEBUG_INITed = 0;\r
+struct info_8250 *_DEBUG_uart = NULL;\r
+\r
+int _DEBUG_INIT() {\r
+       if (!_DEBUG_INITed) {\r
+               unsigned int i;\r
+               uint16_t port;\r
+\r
+               if (!init_8250()) return 0;\r
+\r
+               // what does the BIOS say the serial ports are?\r
+               probe_8250_bios_ports();\r
+               for (i=0;i < bios_8250_ports;i++) {\r
+                       port = get_8250_bios_port(i);\r
+                       if (port == 0) continue;\r
+                       probe_8250(port);\r
+               }\r
+\r
+               // what about the standard serial ports?\r
+               for (i=0;i < (sizeof(standard_8250_ports)/sizeof(standard_8250_ports[0]));i++) {\r
+                       port = standard_8250_ports[i];\r
+                       if (port == 0) continue;\r
+                       probe_8250(port);\r
+               }\r
+\r
+               // pick the first port, which is probably COM1\r
+               if (base_8250_ports == 0) return 0; // FIXME: You know "base_8250_ports" is probably a bad variable name for the max entries in info_8250_port[]\r
+               _DEBUG_uart = &info_8250_port[0];\r
+               _DEBUG_INITed = 1;\r
+\r
+               // init the COM port.\r
+               // in DOSBox-X, the "log" mode will receive our text and print it into the log file\r
+               // on real hardware, our text will likely go over a null modem cable to another PC running a serial terminal program like PuTTY or minicom.\r
+               // if nothing is connected, then the bytes go off into the ether to get lost and life goes on.\r
+               uart_8250_enable_interrupt(_DEBUG_uart,0);      // disable interrupts\r
+               uart_8250_set_FIFO(_DEBUG_uart,0x07);           // enable FIFO (why not?), also clear xmit/recv FIFO buffers, set threshhold to 1 byte\r
+               uart_8250_set_MCR(_DEBUG_uart,3);               // RTS and DTS on\r
+               uart_8250_set_line_control(_DEBUG_uart,UART_8250_LCR_8BIT | UART_8250_LCR_PARITY); // 8 bit 1 stop bit odd parity\r
+               uart_8250_set_baudrate(_DEBUG_uart,uart_8250_baud_to_divisor(_DEBUG_uart,9600)); // 9600 baud\r
+       }\r
+\r
+       return _DEBUG_INITed;\r
+}\r
+\r
+void _DEBUG(const char *msg) {\r
+       if (_DEBUG_uart != NULL) {\r
+               char c;\r
+\r
+               while ((c=(*msg++)) != 0/*NUL*/) {\r
+                       while (!uart_8250_can_write(_DEBUG_uart)); // wait for the UART to indicate readiness for our output\r
+                       uart_8250_write(_DEBUG_uart,(uint8_t)c); // then write it\r
+               }\r
+       }\r
+}\r
+\r
+static char _DEBUGF_TMP[256];\r
+\r
+void _DEBUGF(const char *fmt,...) {\r
+       va_list va;\r
+\r
+       va_start(va,fmt);\r
+       vsnprintf(_DEBUGF_TMP,sizeof(_DEBUGF_TMP),fmt,va);\r
+       _DEBUG(_DEBUGF_TMP);\r
+       va_end(va);\r
+}\r
+#endif\r
+\r
index 9aaf9644c1757ef922bec2c51c10d536e9dd290a..58c5a05a33b0f3ecb5f0b9f278dc6a2fa8c728f2 100755 (executable)
@@ -1,25 +1,25 @@
-
-#ifndef _SRC_LIB_16_DBG
-#define _SRC_LIB_16_DBG
-
-# ifdef DEBUGSERIAL
-#  include <hw/8250/8250.h>
-
-void _DEBUGF(const char *fmt,...);
-void _DEBUG(const char *msg);
-int _DEBUG_INIT();
-# else
-static inline void _DEBUGF(const char *fmt,...) {
-       // NOTHING
-}
-static inline void _DEBUG(const char *msg) {
-       // NOTHING
-}
-
-static inline int _DEBUG_INIT() {
-       // NOTHING
-       return -1;
-}
-# endif
-#endif // _SRC_LIB_16_DBG
-
+\r
+#ifndef _SRC_LIB_16_DBG\r
+#define _SRC_LIB_16_DBG\r
+\r
+# ifdef DEBUGSERIAL\r
+#  include <hw/8250/8250.h>\r
+\r
+void _DEBUGF(const char *fmt,...);\r
+void _DEBUG(const char *msg);\r
+int _DEBUG_INIT();\r
+# else\r
+static inline void _DEBUGF(const char *fmt,...) {\r
+       // NOTHING\r
+}\r
+static inline void _DEBUG(const char *msg) {\r
+       // NOTHING\r
+}\r
+\r
+static inline int _DEBUG_INIT() {\r
+       // NOTHING\r
+       return -1;\r
+}\r
+# endif\r
+#endif // _SRC_LIB_16_DBG\r
+\r
index 8743a38dc51e8fb479e1547ea99061ec128b0442..13dd3f0e5addcc9080dd48417d188bd1e086f695 100755 (executable)
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-/*
-       heap test stuff
-*/
-
-#include "src/lib/16_hc.h"
-
-#ifdef __BORLANDC__
-void * LargestFreeBlock(size_t* Size)
-#endif
-#ifdef __WATCOMC__
-void __near* LargestFreeBlock(size_t* Size)
-#endif
-{
-       size_t s0, s1;
-#ifdef __BORLANDC__
-       void * p;
-#endif
-#ifdef __WATCOMC__
-       void __near* p;
-#endif
-
-       s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
-#ifdef __BORLANDC__
-       while (s0 && (p = malloc(s0)) == NULL)
-#endif
-#ifdef __WATCOMC__
-       while (s0 && (p = _nmalloc(s0)) == NULL)
-#endif
-               s0 >>= 1;
-
-       if (p)
-#ifdef __BORLANDC__
-               free(p);
-#endif
-#ifdef __WATCOMC__
-               _nfree(p);
-#endif
-
-       s1 = s0 >> 1;
-       while (s1)
-       {
-#ifdef __BORLANDC__
-               if ((p = malloc(s0 + s1)) != NULL)
-#endif
-#ifdef __WATCOMC__
-               if ((p = _nmalloc(s0 + s1)) != NULL)
-#endif
-               {
-                       s0 += s1;
-#ifdef __BORLANDC__
-                       free(p);
-#endif
-#ifdef __WATCOMC__
-                       _nfree(p);
-#endif
-               }
-       s1 >>= 1;
-       }
-#ifdef __BORLANDC__
-       while (s0 && (p = malloc(s0)) == NULL)
-#endif
-#ifdef __WATCOMC__
-       while (s0 && (p = _nmalloc(s0)) == NULL)
-#endif
-               s0 ^= s0 & -s0;
-
-       *Size = s0;
-       return p;
-}
-
-size_t _coreleft(void)
-{
-       size_t total = 0;
-       void __near* pFirst = NULL;
-       void __near* pLast = NULL;
-       for(;;)
-       {
-               size_t largest;
-               void __near* p = (void __near *)LargestFreeBlock(&largest);
-               if (largest < sizeof(void __near*))
-               {
-                       if (p != NULL)
-#ifdef __BORLANDC__
-                       free(p);
-#endif
-#ifdef __WATCOMC__
-                       _nfree(p);
-#endif
-                       break;
-               }
-               *(void __near* __near*)p = NULL;
-               total += largest;
-               if (pFirst == NULL)
-                       pFirst = p;
-
-               if (pLast != NULL)
-                       *(void __near* __near*)pLast = p;
-               pLast = p;
-       }
-
-       while (pFirst != NULL)
-       {
-               void __near* p = *(void __near* __near*)pFirst;
-#ifdef __BORLANDC__
-               free(pFirst);
-#endif
-#ifdef __WATCOMC__
-               _nfree(pFirst);
-#endif
-               pFirst = p;
-       }
-       return total;
-}
-
-void far* LargestFarFreeBlock(size_t* Size)
-{
-       size_t s0, s1;
-       void far* p;
-
-       s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
-       while (s0 && (p = _fmalloc(s0)) == NULL)
-               s0 >>= 1;
-
-       if (p)
-               _ffree(p);
-
-       s1 = s0 >> 1;
-       while (s1)
-       {
-               if ((p = _fmalloc(s0 + s1)) != NULL)
-               {
-                       s0 += s1;
-                       _ffree(p);
-               }
-       s1 >>= 1;
-       }
-       while (s0 && (p = _fmalloc(s0)) == NULL)
-               s0 ^= s0 & -s0;
-
-       *Size = s0;
-       return p;
-}
-
-size_t _farcoreleft(void)
-{
-       size_t total = 0;
-       void far* pFirst = NULL;
-       void far* pLast = NULL;
-       for(;;)
-       {
-               size_t largest;
-               void far* p = LargestFarFreeBlock(&largest);
-               if (largest < sizeof(void far*))
-               {
-                       if (p != NULL)
-                       _ffree(p);
-                       break;
-               }
-               *(void far* far*)p = NULL;
-               total += largest;
-               if (pFirst == NULL)
-                       pFirst = p;
-
-               if (pLast != NULL)
-                       *(void far* far*)pLast = p;
-               pLast = p;
-       }
-
-       while (pFirst != NULL)
-       {
-               void far* p = *(void far* far*)pFirst;
-               _ffree(pFirst);
-               pFirst = p;
-       }
-       return total;
-}
-
-#ifdef __WATCOMC__
-void huge* LargestHugeFreeBlock(size_t* Size)
-{
-       size_t s0, s1;
-       void huge* p;
-
-       s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
-       while (s0 && (p = halloc((dword)s0, 1)) == NULL)
-               s0 >>= 1;
-
-       if (p)
-               hfree(p);
-
-       s1 = s0 >> 1;
-       while (s1)
-       {
-               if ((p = halloc((dword)(s0 + s1), 1)) != NULL)
-               {
-                       s0 += s1;
-                       hfree(p);
-               }
-       s1 >>= 1;
-       }
-       while (s0 && (p = halloc((dword)s0, 1)) == NULL)
-               s0 ^= s0 & -s0;
-
-       *Size = s0;
-       return p;
-}
-
-size_t _hugecoreleft(void)
-{
-       size_t total = 0;
-       void huge* pFirst = NULL;
-       void huge* pLast = NULL;
-       for(;;)
-       {
-               size_t largest;
-               void huge* p = LargestHugeFreeBlock(&largest);
-               if (largest < sizeof(void huge*))
-               {
-                       if (p != NULL)
-                       hfree(p);
-                       break;
-               }
-               *(void huge* huge*)p = NULL;
-               total += largest;
-               if (pFirst == NULL)
-                       pFirst = p;
-
-               if (pLast != NULL)
-                       *(void huge* huge*)pLast = p;
-               pLast = p;
-       }
-
-       while (pFirst != NULL)
-       {
-               void huge* p = *(void huge* huge*)pFirst;
-               hfree(pFirst);
-               pFirst = p;
-       }
-       return total;
-}
-
-/*void __based(__self)* LargestBasedFreeBlock(size_t* Size)
-{
-       __segment segu;
-       size_t s0, s1;
-       void __based(__self)* p;
-
-       s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);
-       while (s0 && (p = _bmalloc(segu, s0)) == NULL)
-               s0 >>= 1;
-
-       if (p)
-               _ffree(p);
-
-       s1 = s0 >> 1;
-       while (s1)
-       {
-               if ((p = _bmalloc(segu, s0 + s1)) != NULL)
-               {
-                       s0 += s1;
-                       _ffree(p);
-               }
-       s1 >>= 1;
-       }
-       while (s0 && (p = _bmalloc(segu, s0)) == NULL)
-               s0 ^= s0 & -s0;
-
-       *Size = s0;
-       return p;
-}
-
-size_t _basedcoreleft(void)
-{
-       __segment segu;
-       size_t total = 0;
-       void __based(segu)* pFirst = NULL;
-       void __based(segu)* pLast = NULL;
-       // allocate based heap
-       segu = _bheapseg( 1024 );
-       if( segu == _NULLSEG ) {
-               printf( "Unable to allocate based heap\n" );
-               return 0;
-               //exit( 1 );
-       }
-       else
-
-       for(;;)
-       {
-               size_t largest;
-               void __based(segu)* p = LargestBasedFreeBlock(&largest);
-               if (largest < sizeof(void far*))
-               {
-                       if (p != NULL)
-                       _ffree(p);
-                       break;
-               }
-               *(void far* far*)p = NULL;
-               total += largest;
-               if (pFirst == NULL)
-                       pFirst = p;
-
-               if (pLast != NULL)
-                       *(void far* far*)pLast = p;
-               pLast = p;
-       }
-
-       while (pFirst != NULL)
-       {
-               void far* p = *(void far* far*)pFirst;
-               _ffree(pFirst);
-               pFirst = p;
-       }
-       return total;
-}*/
-
-size_t GetFreeSize(void)
-{
-       struct _heapinfo h_info;
-       int heap_status;
-       size_t h_free=0, h_total=0, h_used=0;
-
-       h_info._pentry = NULL;
-       for(;;) {
-               heap_status = _heapwalk( &h_info );
-               if( heap_status != _HEAPOK ) break;
-               if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") h_free += h_info._size;
-               if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") h_used += h_info._size;
-               h_total += h_info._size;
-       }
-       heapstat0(heap_status);
-       return h_free;
-}
-
-size_t GetFarFreeSize(void)
-{
-       struct _heapinfo fh_info;
-       int heap_status;
-       size_t fh_free=0, fh_total=0, fh_used=0;
-
-       fh_info._pentry = NULL;
-       for(;;) {
-               heap_status = _fheapwalk( &fh_info );
-               if( heap_status != _HEAPOK ) break;
-               if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") fh_free += fh_info._size;
-               if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") fh_used += fh_info._size;
-               fh_total += fh_info._size;
-       }
-       heapstat0(heap_status);
-       return fh_free;
-}
-
-size_t GetNearFreeSize(void)
-{
-       struct _heapinfo nh_info;
-       int heap_status;
-       size_t nh_free=0, nh_total=0, nh_used=0;
-
-       nh_info._pentry = NULL;
-       for(;;) {
-               heap_status = _nheapwalk( &nh_info );
-               if( heap_status != _HEAPOK ) break;
-               if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") nh_free += nh_info._size;
-               if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") nh_used += nh_info._size;
-               nh_total += nh_info._size;
-       }
-       heapstat0(heap_status);
-       return nh_free;
-}
-
-void heapdump(global_game_variables_t *gvar)
-{
-       struct _heapinfo fh_info, nh_info, h_info;
-       int heap_status;
-       size_t h_free, nh_free, fh_free, h_total, nh_total, fh_total, h_used, nh_used, fh_used;
-       byte    scratch[1024],str[16];
-
-       HC_OpenDebug(gvar);
-
-       strcpy(scratch,"\n      == default ==\n\n");
-       write(gvar->handle.heaphandle,scratch,strlen(scratch));
-       h_info._pentry = NULL;
-       h_free=0; h_total=0; h_used=0;
-       for(;;) {
-               heap_status = _heapwalk( &h_info );
-               if( heap_status != _HEAPOK ) break;
-               strcpy(scratch,"  "); strcat(scratch,(h_info._useflag == _USEDENTRY ? "USED" : "FREE")); strcat(scratch," block at "); ultoa((dword)h_info._pentry,str,16); strcat(scratch,str); strcat(scratch," of size "); ultoa(h_info._size,str,10); strcat(scratch,str); strcat(scratch,"\n");
-               if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") h_free += h_info._size;
-               if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") h_used += h_info._size;
-               h_total += h_info._size;
-               write(gvar->handle.heaphandle,scratch,strlen(scratch));
-       }
-       heapstat(gvar, heap_status, &scratch);
-
-       //near
-       strcpy(scratch,"\n      == near ==\n\n");
-       write(gvar->handle.heaphandle,scratch,strlen(scratch));
-       nh_info._pentry = NULL;
-       nh_free=0; nh_total=0; nh_used=0;
-       for(;;) {
-               heap_status = _nheapwalk( &nh_info );
-               if( heap_status != _HEAPOK ) break;
-               strcpy(scratch,"  "); strcat(scratch,(h_info._useflag == _USEDENTRY ? "USED" : "FREE")); strcat(scratch," block at "); ultoa((dword)nh_info._pentry,str,16); strcat(scratch,str); strcat(scratch," of size "); ultoa(nh_info._size,str,10); strcat(scratch,str); strcat(scratch,"\n");
-/*             printf( "  %s block at %Fp of size %4.4X\n",
-(nh_info._useflag == _USEDENTRY ? "USED" : "FREE"),
-nh_info._pentry, nh_info._size );*/
-               if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") nh_free += nh_info._size;
-               if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") nh_used += nh_info._size;
-               nh_total += nh_info._size;
-               write(gvar->handle.heaphandle,scratch,strlen(scratch));
-       }
-       heapstat(gvar, heap_status, &scratch);
-
-       //far
-       strcpy(scratch,"\n      == far ==\n\n");
-       write(gvar->handle.heaphandle,scratch,strlen(scratch));
-       fh_info._pentry = NULL;
-       fh_free=0; fh_total=0; fh_used=0;
-       for(;;) {
-               heap_status = _fheapwalk( &fh_info );
-               if( heap_status != _HEAPOK ) break;
-               strcpy(scratch,"  "); strcat(scratch,(h_info._useflag == _USEDENTRY ? "USED" : "FREE")); strcat(scratch," block at "); ultoa((dword)fh_info._pentry,str,16); strcat(scratch,str); strcat(scratch," of size "); ultoa(fh_info._size,str,10); strcat(scratch,str); strcat(scratch,"\n");
-               /*printf( "  %s block at %Fp of size %4.4X\n",
-(fh_info._useflag == _USEDENTRY ? "USED" : "FREE"),
-fh_info._pentry, fh_info._size );*/
-               if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") fh_free += fh_info._size;
-               if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") fh_used += fh_info._size;
-               fh_total += fh_info._size;
-               write(gvar->handle.heaphandle,scratch,strlen(scratch));
-       }
-       heapstat(gvar, heap_status, &scratch);
-
-       strcpy(scratch,"\n");
-       strcat(scratch,kittengets(2,0,"Memory Type         Total      Used       Free\n"));
-       strcat(scratch,"----------------  --------   --------   --------\n");
-       printmeminfoline(&scratch, "Default", h_total, h_used, h_free);
-       printmeminfoline(&scratch, "Near", nh_total, nh_used, nh_free);
-       printmeminfoline(&scratch, "Far", fh_total, fh_used, fh_free);
-       strcat(scratch,"----------------  --------   --------   --------\n");
-       strcat(scratch,"coreleft = ");                  ultoa((dword)_coreleft(),str,10);               strcat(scratch,str);    strcat(scratch,"\n");
-       strcat(scratch,"farcoreleft = ");               ultoa((dword)_farcoreleft(),str,10);    strcat(scratch,str);    strcat(scratch,"\n");
-       strcat(scratch,"GetFreeSize = ");               ultoa((dword)GetFreeSize(),str,10);             strcat(scratch,str);    strcat(scratch,"\n");
-       strcat(scratch,"GetNearFreeSize = ");   ultoa((dword)GetNearFreeSize(),str,10); strcat(scratch,str);    strcat(scratch,"\n");
-       strcat(scratch,"GetFarFreeSize = ");    ultoa((dword)GetFarFreeSize(),str,10);  strcat(scratch,str);    strcat(scratch,"\n");
-       strcat(scratch,"memavl = ");                    ultoa((dword)_memavl(),str,10);                 strcat(scratch,str);    strcat(scratch,"\n");
-       strcat(scratch,"stackavail = ");                ultoa((dword)stackavail(),str,10);              strcat(scratch,str);    strcat(scratch,"\n");
-       write(gvar->handle.heaphandle,scratch,strlen(scratch));
-       HC_CloseDebug(gvar);
-}
-
-void heapstat(global_game_variables_t *gvar, int heap_status, byte *str)
-{
-       switch( heap_status ) {
-               case _HEAPEND:
-                       strcpy((str),"OK - end of heap\n");
-               break;
-               case _HEAPEMPTY:
-                       strcpy((str),"OK - heap is empty\n");
-
-               break;
-               case _HEAPBADBEGIN:
-                       strcpy((str),"ERROR - heap is damaged\n");
-               break;
-               case _HEAPBADPTR:
-                       strcpy((str),"ERROR - bad pointer to heap\n");
-               break;
-               case _HEAPBADNODE:
-                       strcpy((str),"ERROR - bad node in heap\n");
-       }
-       write(gvar->handle.heaphandle,(str),strlen((str)));
-}
-
-void heapstat0(int heap_status)
-{
-       switch( heap_status ) {
-               case _HEAPEND:
-                       //printf("OK - end of heap\n");
-               break;
-               case _HEAPEMPTY:
-                       //printf("OK - heap is empty\n");
-               break;
-               case _HEAPBADBEGIN:
-                       printf("ERROR - heap is damaged\n");
-               break;
-               case _HEAPBADPTR:
-                       printf("ERROR - bad pointer to heap\n");
-               break;
-               case _HEAPBADNODE:
-                       printf("ERROR - bad node in heap\n");
-       }
-}
-#endif
-/*
-============================
-=
-= HC_OpenDebug / HC_CloseDebug
-=
-= Opens a binary file with the handle "heaphandle"
-=
-============================
-*/
-void HC_OpenDebug(global_game_variables_t *gvar)
-{
-#ifdef __BORLANDC__
-       unlink("heap.16b");
-       gvar->handle.heaphandle = open("heap.16b", O_CREAT | O_WRONLY | O_TEXT);
-#endif
-#ifdef __WATCOMC__
-       unlink("heap.16w");
-       gvar->handle.heaphandle = open("heap.16w", O_CREAT | O_WRONLY | O_TEXT);
-#endif
-}
-
-void HC_CloseDebug(global_game_variables_t *gvar)
-{
-       close(gvar->handle.heaphandle);
-}
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+/*\r
+       heap test stuff\r
+*/\r
+\r
+#include "src/lib/16_hc.h"\r
+\r
+#ifdef __BORLANDC__\r
+void * LargestFreeBlock(size_t* Size)\r
+#endif\r
+#ifdef __WATCOMC__\r
+void __near* LargestFreeBlock(size_t* Size)\r
+#endif\r
+{\r
+       size_t s0, s1;\r
+#ifdef __BORLANDC__\r
+       void * p;\r
+#endif\r
+#ifdef __WATCOMC__\r
+       void __near* p;\r
+#endif\r
+\r
+       s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);\r
+#ifdef __BORLANDC__\r
+       while (s0 && (p = malloc(s0)) == NULL)\r
+#endif\r
+#ifdef __WATCOMC__\r
+       while (s0 && (p = _nmalloc(s0)) == NULL)\r
+#endif\r
+               s0 >>= 1;\r
+\r
+       if (p)\r
+#ifdef __BORLANDC__\r
+               free(p);\r
+#endif\r
+#ifdef __WATCOMC__\r
+               _nfree(p);\r
+#endif\r
+\r
+       s1 = s0 >> 1;\r
+       while (s1)\r
+       {\r
+#ifdef __BORLANDC__\r
+               if ((p = malloc(s0 + s1)) != NULL)\r
+#endif\r
+#ifdef __WATCOMC__\r
+               if ((p = _nmalloc(s0 + s1)) != NULL)\r
+#endif\r
+               {\r
+                       s0 += s1;\r
+#ifdef __BORLANDC__\r
+                       free(p);\r
+#endif\r
+#ifdef __WATCOMC__\r
+                       _nfree(p);\r
+#endif\r
+               }\r
+       s1 >>= 1;\r
+       }\r
+#ifdef __BORLANDC__\r
+       while (s0 && (p = malloc(s0)) == NULL)\r
+#endif\r
+#ifdef __WATCOMC__\r
+       while (s0 && (p = _nmalloc(s0)) == NULL)\r
+#endif\r
+               s0 ^= s0 & -s0;\r
+\r
+       *Size = s0;\r
+       return p;\r
+}\r
+\r
+size_t _coreleft(void)\r
+{\r
+       size_t total = 0;\r
+       void __near* pFirst = NULL;\r
+       void __near* pLast = NULL;\r
+       for(;;)\r
+       {\r
+               size_t largest;\r
+               void __near* p = (void __near *)LargestFreeBlock(&largest);\r
+               if (largest < sizeof(void __near*))\r
+               {\r
+                       if (p != NULL)\r
+#ifdef __BORLANDC__\r
+                       free(p);\r
+#endif\r
+#ifdef __WATCOMC__\r
+                       _nfree(p);\r
+#endif\r
+                       break;\r
+               }\r
+               *(void __near* __near*)p = NULL;\r
+               total += largest;\r
+               if (pFirst == NULL)\r
+                       pFirst = p;\r
+\r
+               if (pLast != NULL)\r
+                       *(void __near* __near*)pLast = p;\r
+               pLast = p;\r
+       }\r
+\r
+       while (pFirst != NULL)\r
+       {\r
+               void __near* p = *(void __near* __near*)pFirst;\r
+#ifdef __BORLANDC__\r
+               free(pFirst);\r
+#endif\r
+#ifdef __WATCOMC__\r
+               _nfree(pFirst);\r
+#endif\r
+               pFirst = p;\r
+       }\r
+       return total;\r
+}\r
+\r
+void far* LargestFarFreeBlock(size_t* Size)\r
+{\r
+       size_t s0, s1;\r
+       void far* p;\r
+\r
+       s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);\r
+       while (s0 && (p = _fmalloc(s0)) == NULL)\r
+               s0 >>= 1;\r
+\r
+       if (p)\r
+               _ffree(p);\r
+\r
+       s1 = s0 >> 1;\r
+       while (s1)\r
+       {\r
+               if ((p = _fmalloc(s0 + s1)) != NULL)\r
+               {\r
+                       s0 += s1;\r
+                       _ffree(p);\r
+               }\r
+       s1 >>= 1;\r
+       }\r
+       while (s0 && (p = _fmalloc(s0)) == NULL)\r
+               s0 ^= s0 & -s0;\r
+\r
+       *Size = s0;\r
+       return p;\r
+}\r
+\r
+size_t _farcoreleft(void)\r
+{\r
+       size_t total = 0;\r
+       void far* pFirst = NULL;\r
+       void far* pLast = NULL;\r
+       for(;;)\r
+       {\r
+               size_t largest;\r
+               void far* p = LargestFarFreeBlock(&largest);\r
+               if (largest < sizeof(void far*))\r
+               {\r
+                       if (p != NULL)\r
+                       _ffree(p);\r
+                       break;\r
+               }\r
+               *(void far* far*)p = NULL;\r
+               total += largest;\r
+               if (pFirst == NULL)\r
+                       pFirst = p;\r
+\r
+               if (pLast != NULL)\r
+                       *(void far* far*)pLast = p;\r
+               pLast = p;\r
+       }\r
+\r
+       while (pFirst != NULL)\r
+       {\r
+               void far* p = *(void far* far*)pFirst;\r
+               _ffree(pFirst);\r
+               pFirst = p;\r
+       }\r
+       return total;\r
+}\r
+\r
+#ifdef __WATCOMC__\r
+void huge* LargestHugeFreeBlock(size_t* Size)\r
+{\r
+       size_t s0, s1;\r
+       void huge* p;\r
+\r
+       s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);\r
+       while (s0 && (p = halloc((dword)s0, 1)) == NULL)\r
+               s0 >>= 1;\r
+\r
+       if (p)\r
+               hfree(p);\r
+\r
+       s1 = s0 >> 1;\r
+       while (s1)\r
+       {\r
+               if ((p = halloc((dword)(s0 + s1), 1)) != NULL)\r
+               {\r
+                       s0 += s1;\r
+                       hfree(p);\r
+               }\r
+       s1 >>= 1;\r
+       }\r
+       while (s0 && (p = halloc((dword)s0, 1)) == NULL)\r
+               s0 ^= s0 & -s0;\r
+\r
+       *Size = s0;\r
+       return p;\r
+}\r
+\r
+size_t _hugecoreleft(void)\r
+{\r
+       size_t total = 0;\r
+       void huge* pFirst = NULL;\r
+       void huge* pLast = NULL;\r
+       for(;;)\r
+       {\r
+               size_t largest;\r
+               void huge* p = LargestHugeFreeBlock(&largest);\r
+               if (largest < sizeof(void huge*))\r
+               {\r
+                       if (p != NULL)\r
+                       hfree(p);\r
+                       break;\r
+               }\r
+               *(void huge* huge*)p = NULL;\r
+               total += largest;\r
+               if (pFirst == NULL)\r
+                       pFirst = p;\r
+\r
+               if (pLast != NULL)\r
+                       *(void huge* huge*)pLast = p;\r
+               pLast = p;\r
+       }\r
+\r
+       while (pFirst != NULL)\r
+       {\r
+               void huge* p = *(void huge* huge*)pFirst;\r
+               hfree(pFirst);\r
+               pFirst = p;\r
+       }\r
+       return total;\r
+}\r
+\r
+/*void __based(__self)* LargestBasedFreeBlock(size_t* Size)\r
+{\r
+       __segment segu;\r
+       size_t s0, s1;\r
+       void __based(__self)* p;\r
+\r
+       s0 = ~(size_t)0 ^ (~(size_t)0 >> 1);\r
+       while (s0 && (p = _bmalloc(segu, s0)) == NULL)\r
+               s0 >>= 1;\r
+\r
+       if (p)\r
+               _ffree(p);\r
+\r
+       s1 = s0 >> 1;\r
+       while (s1)\r
+       {\r
+               if ((p = _bmalloc(segu, s0 + s1)) != NULL)\r
+               {\r
+                       s0 += s1;\r
+                       _ffree(p);\r
+               }\r
+       s1 >>= 1;\r
+       }\r
+       while (s0 && (p = _bmalloc(segu, s0)) == NULL)\r
+               s0 ^= s0 & -s0;\r
+\r
+       *Size = s0;\r
+       return p;\r
+}\r
+\r
+size_t _basedcoreleft(void)\r
+{\r
+       __segment segu;\r
+       size_t total = 0;\r
+       void __based(segu)* pFirst = NULL;\r
+       void __based(segu)* pLast = NULL;\r
+       // allocate based heap\r
+       segu = _bheapseg( 1024 );\r
+       if( segu == _NULLSEG ) {\r
+               printf( "Unable to allocate based heap\n" );\r
+               return 0;\r
+               //exit( 1 );\r
+       }\r
+       else\r
+\r
+       for(;;)\r
+       {\r
+               size_t largest;\r
+               void __based(segu)* p = LargestBasedFreeBlock(&largest);\r
+               if (largest < sizeof(void far*))\r
+               {\r
+                       if (p != NULL)\r
+                       _ffree(p);\r
+                       break;\r
+               }\r
+               *(void far* far*)p = NULL;\r
+               total += largest;\r
+               if (pFirst == NULL)\r
+                       pFirst = p;\r
+\r
+               if (pLast != NULL)\r
+                       *(void far* far*)pLast = p;\r
+               pLast = p;\r
+       }\r
+\r
+       while (pFirst != NULL)\r
+       {\r
+               void far* p = *(void far* far*)pFirst;\r
+               _ffree(pFirst);\r
+               pFirst = p;\r
+       }\r
+       return total;\r
+}*/\r
+\r
+size_t GetFreeSize(void)\r
+{\r
+       struct _heapinfo h_info;\r
+       int heap_status;\r
+       size_t h_free=0, h_total=0, h_used=0;\r
+\r
+       h_info._pentry = NULL;\r
+       for(;;) {\r
+               heap_status = _heapwalk( &h_info );\r
+               if( heap_status != _HEAPOK ) break;\r
+               if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") h_free += h_info._size;\r
+               if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") h_used += h_info._size;\r
+               h_total += h_info._size;\r
+       }\r
+       heapstat0(heap_status);\r
+       return h_free;\r
+}\r
+\r
+size_t GetFarFreeSize(void)\r
+{\r
+       struct _heapinfo fh_info;\r
+       int heap_status;\r
+       size_t fh_free=0, fh_total=0, fh_used=0;\r
+\r
+       fh_info._pentry = NULL;\r
+       for(;;) {\r
+               heap_status = _fheapwalk( &fh_info );\r
+               if( heap_status != _HEAPOK ) break;\r
+               if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") fh_free += fh_info._size;\r
+               if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") fh_used += fh_info._size;\r
+               fh_total += fh_info._size;\r
+       }\r
+       heapstat0(heap_status);\r
+       return fh_free;\r
+}\r
+\r
+size_t GetNearFreeSize(void)\r
+{\r
+       struct _heapinfo nh_info;\r
+       int heap_status;\r
+       size_t nh_free=0, nh_total=0, nh_used=0;\r
+\r
+       nh_info._pentry = NULL;\r
+       for(;;) {\r
+               heap_status = _nheapwalk( &nh_info );\r
+               if( heap_status != _HEAPOK ) break;\r
+               if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") nh_free += nh_info._size;\r
+               if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") nh_used += nh_info._size;\r
+               nh_total += nh_info._size;\r
+       }\r
+       heapstat0(heap_status);\r
+       return nh_free;\r
+}\r
+\r
+void heapdump(global_game_variables_t *gvar)\r
+{\r
+       struct _heapinfo fh_info, nh_info, h_info;\r
+       int heap_status;\r
+       size_t h_free, nh_free, fh_free, h_total, nh_total, fh_total, h_used, nh_used, fh_used;\r
+       byte    scratch[1024],str[16];\r
+\r
+       HC_OpenDebug(gvar);\r
+\r
+       strcpy(scratch,"\n      == default ==\n\n");\r
+       write(gvar->handle.heaphandle,scratch,strlen(scratch));\r
+       h_info._pentry = NULL;\r
+       h_free=0; h_total=0; h_used=0;\r
+       for(;;) {\r
+               heap_status = _heapwalk( &h_info );\r
+               if( heap_status != _HEAPOK ) break;\r
+               strcpy(scratch,"  "); strcat(scratch,(h_info._useflag == _USEDENTRY ? "USED" : "FREE")); strcat(scratch," block at "); ultoa((dword)h_info._pentry,str,16); strcat(scratch,str); strcat(scratch," of size "); ultoa(h_info._size,str,10); strcat(scratch,str); strcat(scratch,"\n");\r
+               if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") h_free += h_info._size;\r
+               if((h_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") h_used += h_info._size;\r
+               h_total += h_info._size;\r
+               write(gvar->handle.heaphandle,scratch,strlen(scratch));\r
+       }\r
+       heapstat(gvar, heap_status, &scratch);\r
+\r
+       //near\r
+       strcpy(scratch,"\n      == near ==\n\n");\r
+       write(gvar->handle.heaphandle,scratch,strlen(scratch));\r
+       nh_info._pentry = NULL;\r
+       nh_free=0; nh_total=0; nh_used=0;\r
+       for(;;) {\r
+               heap_status = _nheapwalk( &nh_info );\r
+               if( heap_status != _HEAPOK ) break;\r
+               strcpy(scratch,"  "); strcat(scratch,(h_info._useflag == _USEDENTRY ? "USED" : "FREE")); strcat(scratch," block at "); ultoa((dword)nh_info._pentry,str,16); strcat(scratch,str); strcat(scratch," of size "); ultoa(nh_info._size,str,10); strcat(scratch,str); strcat(scratch,"\n");\r
+/*             printf( "  %s block at %Fp of size %4.4X\n",\r
+(nh_info._useflag == _USEDENTRY ? "USED" : "FREE"),\r
+nh_info._pentry, nh_info._size );*/\r
+               if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") nh_free += nh_info._size;\r
+               if((nh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") nh_used += nh_info._size;\r
+               nh_total += nh_info._size;\r
+               write(gvar->handle.heaphandle,scratch,strlen(scratch));\r
+       }\r
+       heapstat(gvar, heap_status, &scratch);\r
+\r
+       //far\r
+       strcpy(scratch,"\n      == far ==\n\n");\r
+       write(gvar->handle.heaphandle,scratch,strlen(scratch));\r
+       fh_info._pentry = NULL;\r
+       fh_free=0; fh_total=0; fh_used=0;\r
+       for(;;) {\r
+               heap_status = _fheapwalk( &fh_info );\r
+               if( heap_status != _HEAPOK ) break;\r
+               strcpy(scratch,"  "); strcat(scratch,(h_info._useflag == _USEDENTRY ? "USED" : "FREE")); strcat(scratch," block at "); ultoa((dword)fh_info._pentry,str,16); strcat(scratch,str); strcat(scratch," of size "); ultoa(fh_info._size,str,10); strcat(scratch,str); strcat(scratch,"\n");\r
+               /*printf( "  %s block at %Fp of size %4.4X\n",\r
+(fh_info._useflag == _USEDENTRY ? "USED" : "FREE"),\r
+fh_info._pentry, fh_info._size );*/\r
+               if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="FREE") fh_free += fh_info._size;\r
+               if((fh_info._useflag == _USEDENTRY ? "USED" : "FREE")=="USED") fh_used += fh_info._size;\r
+               fh_total += fh_info._size;\r
+               write(gvar->handle.heaphandle,scratch,strlen(scratch));\r
+       }\r
+       heapstat(gvar, heap_status, &scratch);\r
+\r
+       strcpy(scratch,"\n");\r
+       strcat(scratch,kittengets(2,0,"Memory Type         Total      Used       Free\n"));\r
+       strcat(scratch,"----------------  --------   --------   --------\n");\r
+       printmeminfoline(&scratch, "Default", h_total, h_used, h_free);\r
+       printmeminfoline(&scratch, "Near", nh_total, nh_used, nh_free);\r
+       printmeminfoline(&scratch, "Far", fh_total, fh_used, fh_free);\r
+       strcat(scratch,"----------------  --------   --------   --------\n");\r
+       strcat(scratch,"coreleft = ");                  ultoa((dword)_coreleft(),str,10);               strcat(scratch,str);    strcat(scratch,"\n");\r
+       strcat(scratch,"farcoreleft = ");               ultoa((dword)_farcoreleft(),str,10);    strcat(scratch,str);    strcat(scratch,"\n");\r
+       strcat(scratch,"GetFreeSize = ");               ultoa((dword)GetFreeSize(),str,10);             strcat(scratch,str);    strcat(scratch,"\n");\r
+       strcat(scratch,"GetNearFreeSize = ");   ultoa((dword)GetNearFreeSize(),str,10); strcat(scratch,str);    strcat(scratch,"\n");\r
+       strcat(scratch,"GetFarFreeSize = ");    ultoa((dword)GetFarFreeSize(),str,10);  strcat(scratch,str);    strcat(scratch,"\n");\r
+       strcat(scratch,"memavl = ");                    ultoa((dword)_memavl(),str,10);                 strcat(scratch,str);    strcat(scratch,"\n");\r
+       strcat(scratch,"stackavail = ");                ultoa((dword)stackavail(),str,10);              strcat(scratch,str);    strcat(scratch,"\n");\r
+       write(gvar->handle.heaphandle,scratch,strlen(scratch));\r
+       HC_CloseDebug(gvar);\r
+}\r
+\r
+void heapstat(global_game_variables_t *gvar, int heap_status, byte *str)\r
+{\r
+       switch( heap_status ) {\r
+               case _HEAPEND:\r
+                       strcpy((str),"OK - end of heap\n");\r
+               break;\r
+               case _HEAPEMPTY:\r
+                       strcpy((str),"OK - heap is empty\n");\r
+\r
+               break;\r
+               case _HEAPBADBEGIN:\r
+                       strcpy((str),"ERROR - heap is damaged\n");\r
+               break;\r
+               case _HEAPBADPTR:\r
+                       strcpy((str),"ERROR - bad pointer to heap\n");\r
+               break;\r
+               case _HEAPBADNODE:\r
+                       strcpy((str),"ERROR - bad node in heap\n");\r
+       }\r
+       write(gvar->handle.heaphandle,(str),strlen((str)));\r
+}\r
+\r
+void heapstat0(int heap_status)\r
+{\r
+       switch( heap_status ) {\r
+               case _HEAPEND:\r
+                       //printf("OK - end of heap\n");\r
+               break;\r
+               case _HEAPEMPTY:\r
+                       //printf("OK - heap is empty\n");\r
+               break;\r
+               case _HEAPBADBEGIN:\r
+                       printf("ERROR - heap is damaged\n");\r
+               break;\r
+               case _HEAPBADPTR:\r
+                       printf("ERROR - bad pointer to heap\n");\r
+               break;\r
+               case _HEAPBADNODE:\r
+                       printf("ERROR - bad node in heap\n");\r
+       }\r
+}\r
+#endif\r
+/*\r
+============================\r
+=\r
+= HC_OpenDebug / HC_CloseDebug\r
+=\r
+= Opens a binary file with the handle "heaphandle"\r
+=\r
+============================\r
+*/\r
+void HC_OpenDebug(global_game_variables_t *gvar)\r
+{\r
+#ifdef __BORLANDC__\r
+       unlink("heap.16b");\r
+       gvar->handle.heaphandle = open("heap.16b", O_CREAT | O_WRONLY | O_TEXT);\r
+#endif\r
+#ifdef __WATCOMC__\r
+       unlink("heap.16w");\r
+       gvar->handle.heaphandle = open("heap.16w", O_CREAT | O_WRONLY | O_TEXT);\r
+#endif\r
+}\r
+\r
+void HC_CloseDebug(global_game_variables_t *gvar)\r
+{\r
+       close(gvar->handle.heaphandle);\r
+}\r
index 4d0375e2f72f96eeb779a593934abee2b9481d1a..870d50c7c89927a5f8e32e6ec716e0353771a221 100755 (executable)
@@ -1,54 +1,54 @@
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-/*
-       heap test stuff
-*/
-
-#ifndef __16HC__
-#define __16HC__
-
-#include "src/lib/16_head.h"
-
-#ifdef __BORLANDC__
-void * LargestFreeBlock(size_t* Size);
-#endif
-#ifdef __WATCOMC__
-void __near* LargestFreeBlock(size_t* Size);
-#endif
-size_t _coreleft(void);
-void far* LargestFarFreeBlock(size_t* Size);
-size_t _farcoreleft(void);
-void huge* LargestHugeFreeBlock(size_t* Size);
-size_t _hugecoreleft(void);
-//void __based(__self)* LargestBasedFreeBlock(size_t* Size);
-//size_t _basedcoreleft(void);
-size_t GetFreeSize(void);
-size_t GetFarFreeSize(void);
-size_t GetNearFreeSize(void);
-void heapdump(global_game_variables_t *gvar);
-void heapstat(global_game_variables_t *gvar, int heap_status, byte *str);
-void heapstat0(int heap_status);
-
-void HC_OpenDebug(global_game_variables_t *gvar);
-void HC_CloseDebug(global_game_variables_t *gvar);
-
-#endif /* __16HC__ */
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+/*\r
+       heap test stuff\r
+*/\r
+\r
+#ifndef __16HC__\r
+#define __16HC__\r
+\r
+#include "src/lib/16_head.h"\r
+\r
+#ifdef __BORLANDC__\r
+void * LargestFreeBlock(size_t* Size);\r
+#endif\r
+#ifdef __WATCOMC__\r
+void __near* LargestFreeBlock(size_t* Size);\r
+#endif\r
+size_t _coreleft(void);\r
+void far* LargestFarFreeBlock(size_t* Size);\r
+size_t _farcoreleft(void);\r
+void huge* LargestHugeFreeBlock(size_t* Size);\r
+size_t _hugecoreleft(void);\r
+//void __based(__self)* LargestBasedFreeBlock(size_t* Size);\r
+//size_t _basedcoreleft(void);\r
+size_t GetFreeSize(void);\r
+size_t GetFarFreeSize(void);\r
+size_t GetNearFreeSize(void);\r
+void heapdump(global_game_variables_t *gvar);\r
+void heapstat(global_game_variables_t *gvar, int heap_status, byte *str);\r
+void heapstat0(int heap_status);\r
+\r
+void HC_OpenDebug(global_game_variables_t *gvar);\r
+void HC_CloseDebug(global_game_variables_t *gvar);\r
+\r
+#endif /* __16HC__ */\r
index b3423ed0e146d5572c56c10a1b19a9adebebf62f..0155c81e5e2fd5b8a1d9bc936a46457add364bef 100755 (executable)
@@ -152,6 +152,7 @@ static word far* clockw= (word far*) 0x046C; /* 18.2hz clock */
 extern int                     profilehandle,debughandle;      //make it into game global\r
 \r
 #define __DEBUG__\r
+#define __DEBUG_PM__\r
 \r
 #define        nil     ((void *)0)\r
 #ifdef __BORLANDC__\r
@@ -198,6 +199,7 @@ int US_CheckParm(char *parm,char **strings);
 #ifdef __BORLANDC__\r
 void Quit (char *error);\r
 #endif\r
+void   XMS_CALL(byte v, global_game_variables_t *gvar);\r
 byte dirchar(byte in);\r
 \r
 #endif/*_LIBHEAD_H_*/\r
index 8e2d65b2de75763aabe807e57fd894b08e699be2..d697142d34a940f639141a717857513451fb60b9 100755 (executable)
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "16_map.h"
-
-// Ideally, preprocess json during compilation and read serialized data
-
-int jsoneq(const char *json, jsmntok_t *tok, const char *s) {
-       if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start &&
-                       strncmp(json + tok->start, s, tok->end - tok->start) == 0) {
-               return 0;
-       }
-       return -1;
-}
-
-void extract_map(const char *js, jsmntok_t *t, size_t count, map_t *map) {
-       int i, j, k, indent, inner_end;
-       bitmap_t bp;
-       char *s;
-       i = 0;
-       while(i<count) {
-               if(jsoneq(js, &(t[i]), "layers") == 0) {
-                       i++;
-                       map->data = malloc(sizeof(byte*) * t[i].size);
-                       inner_end = t[i].end;
-                       k = 0;
-                       while(t[i].start < inner_end) {
-                               printf("%d, %d\n", t[i].start, inner_end);
-                               if(jsoneq(js, &(t[i]), "data") == 0) {
-                                       #ifdef DEBUG_MAPVAR
-                                       printf("Layer %d data: [", k);
-                                       #endif
-                                       map->data[k] = malloc(sizeof(byte) * t[i+1].size);
-                                       for(j = 0; j < t[i+1].size; j++) {
-                                               map->data[k][j] = (byte)atoi(js + t[i+2+j].start);
-                                               #ifdef DEBUG_MAPVAR
-                                               printf("%d, ", map->data[k][j]);
-                                               #endif
-                                       }
-                                       i += j + 2;
-                                       k++;
-                                       #ifdef DEBUG_MAPVAR
-                                       puts("]");
-                                       #endif
-                               }
-                               else{
-                                       i++;
-                               }
-                       }
-               }
-               if(jsoneq(js, &(t[i]), "tilesets") == 0) {
-                       i++;
-                       map->tiles = malloc(sizeof(tiles_t*) * t[i].size);
-                       inner_end = t[i].end;
-                       k = 0;
-                       while(t[i].start < inner_end) {
-                               if(jsoneq(js, &(t[i]), "image") == 0) {
-                                       //fix this to be far~
-                                       map->tiles[k] = malloc(sizeof(tiles_t));
-                                       map->tiles[k]->btdata = malloc(sizeof(bitmap_t));
-                                       map->tiles[k]->tileHeight = 16;
-                                       map->tiles[k]->tileWidth = 16;
-                                       map->tiles[k]->rows = 1;
-                                       map->tiles[k]->cols = 1;
-                                       map->tiles[k]->debug_text=false;
-                                       //Fix to load tileset specified.
-                                       //And move to vrs, probably
-                                       bp = bitmapLoadPcx("data/ed.pcx");
-                                       map->tiles[k]->btdata = &bp;
-                                       k++;
-                               }
-                               i++;
-                       }
-               }
-
-               if (jsoneq(js, &(t[i]), "height") == 0 && indent<=1) {
-                       map->height = atoi(js + t[i+1].start);
-                       #ifdef DEBUG_MAPVAR
-                       printf("Height: %d\n", map->height);
-                       #endif
-                       i++;
-               }
-               else if(jsoneq(js, &(t[i]), "width") == 0 && indent<=1) {
-                       map->width = atoi(js + t[i+1].start);
-                       #ifdef DEBUG_MAPVAR
-                       printf("Width: %d\n", map->width);
-                       #endif
-                       i++;
-               }
-               i++;
-       }
-}
-
-int loadmap(char *mn, map_t *map) {
-       char *js;
-
-       jsmn_parser p;
-       jsmntok_t *tok = NULL;
-       size_t tokcount, file_s;
-
-       FILE *fh = fopen(mn, "r");
-       int status;
-
-       /* Prepare parser */
-       jsmn_init(&p);
-
-       file_s = filesize(fh);
-       js = malloc(file_s);
-       if(js == NULL) {
-               fprintf(stderr, "malloc(): errno = %d", 2);
-               fclose(fh);
-               return 3;
-       }
-       if(fread(js, 1, file_s, fh) != file_s) {
-               fprintf(stderr, "Map read error");
-               free(js);
-               fclose(fh);
-               return 1;
-       }
-       tokcount = jsmn_parse(&p, js, file_s, NULL, 0);
-       tok = malloc(tokcount*sizeof(jsmntok_t));
-       printf("Allocated %d tokens", tokcount);
-       jsmn_init(&p);
-       if((status = jsmn_parse(&p, js, file_s, tok, tokcount)) < 0)
-       {
-               printf("Error: %d\n", status);
-               return status;
-       }
-       else if(status != tokcount) { printf("Warning: used %d tok\n", status);}
-       extract_map(js, tok, tokcount, map);
-
-       free(js);
-       free(tok);
-       fclose(fh);
-       
-       return 0;
-}
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+\r
+#include "16_map.h"\r
+\r
+// Ideally, preprocess json during compilation and read serialized data\r
+\r
+int jsoneq(const char *json, jsmntok_t *tok, const char *s) {\r
+       if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start &&\r
+                       strncmp(json + tok->start, s, tok->end - tok->start) == 0) {\r
+               return 0;\r
+       }\r
+       return -1;\r
+}\r
+\r
+void extract_map(const char *js, jsmntok_t *t, size_t count, map_t *map) {\r
+       int i, j, k, indent, inner_end;\r
+       bitmap_t bp;\r
+       char *s;\r
+       i = 0;\r
+       while(i<count) {\r
+               if(jsoneq(js, &(t[i]), "layers") == 0) {\r
+                       i++;\r
+                       map->data = malloc(sizeof(byte*) * t[i].size);\r
+                       inner_end = t[i].end;\r
+                       k = 0;\r
+                       while(t[i].start < inner_end) {\r
+                               printf("%d, %d\n", t[i].start, inner_end);\r
+                               if(jsoneq(js, &(t[i]), "data") == 0) {\r
+                                       #ifdef DEBUG_MAPVAR\r
+                                       printf("Layer %d data: [", k);\r
+                                       #endif\r
+                                       map->data[k] = malloc(sizeof(byte) * t[i+1].size);\r
+                                       for(j = 0; j < t[i+1].size; j++) {\r
+                                               map->data[k][j] = (byte)atoi(js + t[i+2+j].start);\r
+                                               #ifdef DEBUG_MAPVAR\r
+                                               printf("%d, ", map->data[k][j]);\r
+                                               #endif\r
+                                       }\r
+                                       i += j + 2;\r
+                                       k++;\r
+                                       #ifdef DEBUG_MAPVAR\r
+                                       puts("]");\r
+                                       #endif\r
+                               }\r
+                               else{\r
+                                       i++;\r
+                               }\r
+                       }\r
+               }\r
+               if(jsoneq(js, &(t[i]), "tilesets") == 0) {\r
+                       i++;\r
+                       map->tiles = malloc(sizeof(tiles_t*) * t[i].size);\r
+                       inner_end = t[i].end;\r
+                       k = 0;\r
+                       while(t[i].start < inner_end) {\r
+                               if(jsoneq(js, &(t[i]), "image") == 0) {\r
+                                       //fix this to be far~\r
+                                       map->tiles[k] = malloc(sizeof(tiles_t));\r
+                                       map->tiles[k]->btdata = malloc(sizeof(bitmap_t));\r
+                                       map->tiles[k]->tileHeight = 16;\r
+                                       map->tiles[k]->tileWidth = 16;\r
+                                       map->tiles[k]->rows = 1;\r
+                                       map->tiles[k]->cols = 1;\r
+                                       map->tiles[k]->debug_text=false;\r
+                                       //Fix to load tileset specified.\r
+                                       //And move to vrs, probably\r
+                                       bp = bitmapLoadPcx("data/ed.pcx");\r
+                                       map->tiles[k]->btdata = &bp;\r
+                                       k++;\r
+                               }\r
+                               i++;\r
+                       }\r
+               }\r
+\r
+               if (jsoneq(js, &(t[i]), "height") == 0 && indent<=1) {\r
+                       map->height = atoi(js + t[i+1].start);\r
+                       #ifdef DEBUG_MAPVAR\r
+                       printf("Height: %d\n", map->height);\r
+                       #endif\r
+                       i++;\r
+               }\r
+               else if(jsoneq(js, &(t[i]), "width") == 0 && indent<=1) {\r
+                       map->width = atoi(js + t[i+1].start);\r
+                       #ifdef DEBUG_MAPVAR\r
+                       printf("Width: %d\n", map->width);\r
+                       #endif\r
+                       i++;\r
+               }\r
+               i++;\r
+       }\r
+}\r
+\r
+int loadmap(char *mn, map_t *map) {\r
+       char *js;\r
+\r
+       jsmn_parser p;\r
+       jsmntok_t *tok = NULL;\r
+       size_t tokcount, file_s;\r
+\r
+       FILE *fh = fopen(mn, "r");\r
+       int status;\r
+\r
+       /* Prepare parser */\r
+       jsmn_init(&p);\r
+\r
+       file_s = filesize(fh);\r
+       js = malloc(file_s);\r
+       if(js == NULL) {\r
+               fprintf(stderr, "malloc(): errno = %d", 2);\r
+               fclose(fh);\r
+               return 3;\r
+       }\r
+       if(fread(js, 1, file_s, fh) != file_s) {\r
+               fprintf(stderr, "Map read error");\r
+               free(js);\r
+               fclose(fh);\r
+               return 1;\r
+       }\r
+       tokcount = jsmn_parse(&p, js, file_s, NULL, 0);\r
+       tok = malloc(tokcount*sizeof(jsmntok_t));\r
+       printf("Allocated %d tokens", tokcount);\r
+       jsmn_init(&p);\r
+       if((status = jsmn_parse(&p, js, file_s, tok, tokcount)) < 0)\r
+       {\r
+               printf("Error: %d\n", status);\r
+               return status;\r
+       }\r
+       else if(status != tokcount) { printf("Warning: used %d tok\n", status);}\r
+       extract_map(js, tok, tokcount, map);\r
+\r
+       free(js);\r
+       free(tok);\r
+       fclose(fh);\r
+       \r
+       return 0;\r
+}\r
index 9333d380c0583eca68456bbc7df610217da89a5b..5f5b6444a7cb70190cf9c367f4ee59c6fa7bd8f5 100755 (executable)
-/* Catacomb Apocalypse Source Code
- * Copyright (C) 1993-2014 Flat Rock Software
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-// NEWMM.C
-
-/*
-=============================================================================
-
-                       ID software memory manager
-                       --------------------------
-
-Primary coder: John Carmack
-
-RELIES ON
----------
-Quit (char *error) function
-
-
-WORK TO DO
-----------
-MM_SizePtr to change the size of a given pointer
-
-Multiple purge levels utilized
-
-EMS / XMS unmanaged routines
-
-=============================================================================
-*/
-/*
-
-Open Watcom port by sparky4
-
-*/
-#include "src/lib/16_mm.h"
-#include "src/lib/16_ca.h"
-#pragma hdrstop
-
-#pragma warn -pro
-#pragma warn -use
-
-/*
-=============================================================================
-
-                                                GLOBAL VARIABLES
-
-=============================================================================
-*/
-
-void           (* beforesort) (void);
-void           (* aftersort) (void);
-void           (* XMSaddr) (void);             // far pointer to XMS driver
-
-/*
-=============================================================================
-
-                                                LOCAL VARIABLES
-
-=============================================================================
-*/
-
-static char *ParmStringsexmm[] = {"noems","noxms",""};
-
-/*
-======================
-=
-= MML_CheckForEMS
-=
-= Routine from p36 of Extending DOS
-=
-=======================
-*/
-
-boolean MML_CheckForEMS(void)
-{
-       boolean emmcfems;
-       static char     emmname[] = "EMMXXXX0"; //fix by andrius4669
-       __asm {
-               mov     dx,OFFSET emmname       //fix by andrius4669
-               mov     ax,0x3d00
-               int     0x21            // try to open EMMXXXX0 device
-               jc      error
-
-               mov     bx,ax
-               mov     ax,0x4400
-
-               int     0x21            // get device info
-               jc      error
-
-               and     dx,0x80
-               jz      error
-
-               mov     ax,0x4407
-
-               int     0x21            // get status
-               jc      error
-               or      al,al
-               jz      error
-
-               mov     ah,0x3e
-               int     0x21            // close handle
-               jc      error
-               //
-               // EMS is good
-               //
-               mov     emmcfems,1
-               jmp End
-#ifdef __BORLANDC__
-       }
-#endif
-               error:
-#ifdef __BORLANDC__
-       __asm {
-#endif
-               //
-               // EMS is bad
-               //
-               mov     emmcfems,0
-#ifdef __BORLANDC__
-       }
-#endif
-               End:
-#ifdef __WATCOMC__
-       }
-#endif
-       return(emmcfems);
-}
-
-
-/*
-======================
-=
-= MML_SetupEMS
-=
-=======================
-*/
-
-byte MML_SetupEMS(global_game_variables_t *gvar)
-{
-       byte    str[160];
-       byte    err;
-       boolean errorflag=false;
-
-       unsigned int EMSVer = 0;
-       //byte  EMS_status;
-       unsigned        totalEMSpages,freeEMSpages,EMSPageFrame,EMSpagesmapped,EMSHandle;
-       totalEMSpages = freeEMSpages = EMSPageFrame = EMSpagesmapped = 0;
-
-       __asm {
-               mov     ah,EMS_STATUS
-               int     EMS_INT                                         // make sure EMS hardware is present
-               or      ah,ah
-               //mov   [EMS_status],ah
-               jnz     error
-
-               mov     ah,EMS_VERSION
-               int     EMS_INT
-               or      ah,ah
-               jnz     error
-               mov     [EMSVer],ax                             //      set EMSVer
-               cmp     al,0x32                                         // only work on ems 3.2 or greater
-               jb      error
-
-               mov     ah,EMS_GETFRAME
-               int     EMS_INT                                         // find the page frame address
-               or      ah,ah
-               jnz     error
-               mov     [EMSPageFrame],bx
-
-               mov     ah,EMS_GETPAGES
-               int     EMS_INT                                         // find out how much EMS is there
-               or      ah,ah
-               jnz     error
-               mov     [totalEMSpages],dx
-               mov     [freeEMSpages],bx
-               or      bx,bx
-               jz      noEMS                                           // no EMS at all to allocate
-                                                                                       //EXPAND DONG!!!!
-               cmp     [EMSVer],0x40
-               jb      low
-               cmp     bx,[freeEMSpages]
-               jle     getpages
-               mov     bx,[freeEMSpages]
-               jmp     getpages
-#ifdef __BORLANDC__
-       }
-#endif
-       low:
-#ifdef __BORLANDC__
-       __asm {
-#endif
-               cmp     bx,4
-               jle     getpages                                        // there is only 1,2,3,or 4 pages
-               mov     bx,4                                            // we can't use more than 4 pages
-#ifdef __BORLANDC__
-       }
-#endif
-       getpages:
-#ifdef __BORLANDC__
-       __asm {
-#endif
-               mov     [EMSpagesmapped],bx
-               mov     ah,EMS_ALLOCPAGES                       // allocate up to 64k of EMS
-               int     EMS_INT
-               or      ah,ah
-               jnz     error
-               mov     [EMSHandle],dx
-               jmp End
-#ifdef __BORLANDC__
-       }
-#endif
-       error:
-#ifdef __BORLANDC__
-       __asm {
-#endif
-               mov     err,ah
-               mov     errorflag,1
-               jmp End
-#ifdef __BORLANDC__
-       }
-#endif
-noEMS:
-End:
-#ifdef __WATCOMC__
-       }
-#endif
-       if(errorflag==true)
-       {
-               strcpy(str,"MM_SetupEMS: EMS error ");
-               MM_EMSerr(str, err);
-               printf("%s\n",str);
-               return err;
-       }
-       gvar->pm.emm.totalEMSpages=totalEMSpages;
-       gvar->pm.emm.freeEMSpages=freeEMSpages;
-       gvar->pm.emm.EMSPageFrame=EMSPageFrame;
-       gvar->pm.emm.EMSpagesmapped=EMSpagesmapped;
-       gvar->pm.emm.EMSHandle=EMSHandle;
-       gvar->pm.emm.EMSVer=EMSVer;
-       return 0;
-}
-
-
-/*
-======================
-=
-= MML_ShutdownEMS
-=
-=======================
-*/
-
-void MML_ShutdownEMS(global_game_variables_t *gvar)
-{
-       boolean errorflag=false;
-       unsigned EMSHandle=gvar->pm.emm.EMSHandle;
-
-       if(!EMSHandle)
-               return;
-       __asm {
-               mov     ah,EMS_FREEPAGES
-               mov     dx,[EMSHandle]
-               int     EMS_INT
-               or      ah,ah
-               jz      ok
-               mov     errorflag,1
-#ifdef __BORLANDC__
-       }
-#endif
-               ok:
-#ifdef __WATCOMC__
-       }
-#endif
-       if(errorflag==true)
-               Quit("MML_ShutdownEMS: Error freeing EMS!\n");  //++++ add something
-}
-
-/*
-====================
-=
-= MM_MapEMS
-=
-= Maps the 64k of EMS used by memory manager into the page frame
-= for general use.  This only needs to be called if you are keeping
-= other things in EMS.
-=
-====================
-*/
-
-byte MM_MapEMS(global_game_variables_t *gvar)
-{
-       byte    str[160];
-       unsigned        EMSHandle;
-       byte err;
-       boolean errorflag=false;
-       int     i;
-       EMSHandle=gvar->pm.emm.EMSHandle;
-
-       for (i=0;i<4/*MAPPAGES*/;i++)
-       {
-               __asm {
-                       mov     ah,EMS_MAPPAGE
-                       mov     bx,[i]                  // logical page
-                       mov     al,bl                   // physical page
-                       mov     dx,[EMSHandle]  // handle
-                       int     EMS_INT
-                       or      ah,ah
-                       jnz     error
-                       jmp End
-#ifdef __BORLANDC__
-               }
-#endif
-                       error:
-#ifdef __BORLANDC__
-               __asm {
-#endif
-                       mov     err,ah
-                       mov     errorflag,1
-#ifdef __BORLANDC__
-               }
-#endif
-                       End:
-#ifdef __WATCOMC__
-               }
-#endif
-               if(errorflag==true)
-               {
-                       strcpy(str,"MM_MapEMS: EMS error ");
-                       MM_EMSerr(str, err);
-                       printf("%s\n",str);
-                       return err;
-               }
-       }
-       gvar->mmi.EMSmem = (i)*0x4000lu;
-       //printf("              gvar->mmi.EMSmem=%lu\n", gvar->mmi.EMSmem);
-       return 0;
-}
-
-byte MM_MapXEMS(global_game_variables_t *gvar)
-{
-//SUB EMS.MapXPages (PhysicalStart, LogicalStart, NumPages, Handle)
-
-       //Maps up to 4 logical EMS pages to physical pages in the page frame, where:
-       //PhysicalStart = Physical page first logical page is mapped to
-       //LogicalStart  = First logical page to map
-       //NumPages      = Number of pages to map (1 to 4)
-       //Handle        = EMS handle logical pages are allocated to
-
-  /*//Create a buffer containing the page information
-//  FOR x = 0 TO NumPages - 1
-//    MapInfo$ = MapInfo$ + MKI$(LogicalStart + x) + MKI$(PhysicalStart + x)
-//  NEXT*/
-
-//  Regs.ax = 0x5000                           //Map the pages in the buffer
-//  Regs.cx = NumPages                         //to the pageframe
-//  Regs.dx = Handle
-//  Regs.ds = VARSEG(MapInfo$)
-//  Regs.si = SADD(MapInfo$)
-//  InterruptX 0x67, Regs, Regs
-//     EMS.Error = (Regs.ax AND 0xFF00&) \ 0x100  //Store the status code
-
-//END SUB
-       byte    str[160];
-       byte err;
-       word    EMSHandle;
-       boolean errorflag=false;
-       int     i;
-       EMSHandle=gvar->pm.emm.EMSHandle;
-
-       if(gvar->pm.emm.EMSVer<0x40)
-               return 5;
-
-       for (i=0;i<MAPPAGES;i++)
-       {
-               __asm {
-                       mov     ah,EMS_MAPXPAGE
-                       mov     cx,[i]                  // logical page
-                       mov     al,bl                   // physical page
-                       mov     dx,[EMSHandle]  // handle
-                       int     EMS_INT
-                       or      ah,ah
-                       jnz     error
-                       jmp End
-#ifdef __BORLANDC__
-               }
-#endif
-                       error:
-#ifdef __BORLANDC__
-               __asm {
-#endif
-                       mov     err,ah
-                       mov     errorflag,1
-#ifdef __BORLANDC__
-               }
-#endif
-                       End:
-#ifdef __WATCOMC__
-               }
-#endif
-               if(errorflag==true)
-               {
-                       //strcpy(str,"MM_MapXEMS: EMS error 0x");
-                       strcpy(str,"MM_MapXEMS: EMS error ");
-                       //itoa(err,str2,16);
-                       MM_EMSerr(str, err);
-                       printf("%s\n",str);
-                       //printf("%s%x\n",str, err);
-                       //printf("FACK! %x\n", err);
-                       return err;
-               }
-       }
-       gvar->mmi.EMSmem = (i)*0x4000lu;
-       return 0;
-}
-
-//==========================================================================
-
-/*
-======================
-=
-= MML_CheckForXMS
-=
-= Check for XMM driver
-=
-=======================
-*/
-
-boolean MML_CheckForXMS(global_game_variables_t *gvar)
-{
-       boolean errorflag=false;
-       gvar->mm.numUMBs = 0;
-
-       __asm {
-               mov     ax,0x4300
-               int     0x2f                            // query status of installed diver
-               cmp     al,0x80
-               je      good
-               mov     errorflag,1
-#ifdef __BORLANDC__
-       }
-#endif
-               good:
-#ifdef __WATCOMC__
-       }
-#endif
-       if(errorflag==true) return false;
-       else return true;
-}
-
-
-/*
-======================
-=
-= MML_SetupXMS
-=
-= Try to allocate all upper memory block
-=
-=======================
-*/
-
-void MML_SetupXMS(global_game_variables_t *gvar)
-{
-       word    base,size;
-
-
-       __asm {
-               mov     ax,0x4310
-               int     0x2f
-               mov     [WORD PTR XMSaddr],bx
-               mov     [WORD PTR XMSaddr+2],es         // function pointer to XMS driver
-       }
-getmemory:
-       __asm {
-               mov     ah,XMS_ALLOCUMB
-               mov     dx,0xffff                                       // try for largest block possible
-               //mov     ax,dx                                         // Set available Kbytes.
-               call    [DWORD PTR XMSaddr]
-               or      ax,ax
-               jnz     gotone
-
-               cmp     bl,0xb0                                         // error: smaller UMB is available
-               jne     done;
-
-               mov     ah,XMS_ALLOCUMB
-               call    [DWORD PTR XMSaddr]             // DX holds largest available UMB
-               or      ax,ax
-               jz      done                                            // another error...
-#ifdef __BORLANDC__
-       }
-#endif
-               gotone:
-#ifdef __BORLANDC__
-       __asm {
-#endif
-               mov     [base],bx
-               mov     [size],dx
-#ifdef __BORLANDC__
-       }
-#endif
-               done:
-#ifdef __WATCOMC__
-       }
-#endif
-//     printf("base=%u ", base); printf("size=%u\n", size);
-       MML_UseSpace(base,size, gvar);
-       gvar->mmi.XMSmem += size*16;
-       gvar->mm.UMBbase[gvar->mm.numUMBs] = base;
-       gvar->mm.numUMBs++;
-       if(gvar->mm.numUMBs < MAXUMBS)
-               goto getmemory;
-}
-
-
-/*
-======================
-=
-= MML_ShutdownXMS
-=
-======================
-*/
-
-void MML_ShutdownXMS(global_game_variables_t *gvar)
-{
-       int     i;
-       unsigned        base;
-
-       for (i=0;i<gvar->mm.numUMBs;i++)
-       {
-               base = gvar->mm.UMBbase[i];
-               __asm {
-                       mov     ah,XMS_FREEUMB
-                       mov     dx,[base]
-                       call    [DWORD PTR XMSaddr]
-               }
-       }
-}
-
-//==========================================================================
-
-/*
-======================
-=
-= MML_UseSpace
-=
-= Marks a range of paragraphs as usable by the memory manager
-= This is used to mark space for the near heap, far heap, ems page frame,
-= and upper memory blocks
-=
-======================
-*/
-
-/*void MML_UseSpace(word segstart, dword seglength, global_game_variables_t *gvar)
-{
-       //huge mmblocktype huge *scan,huge *last;
-       word            segm=1;
-       word    oldend;
-       dword           segmlen;
-       dword           extra;
-
-       scan = last = gvar->mm.mmhead;
-       gvar->mm.mmrover = gvar->mm.mmhead;             // reset rover to start of memory
-
-//
-// search for the block that contains the range of segments
-//
-       while(scan->start+scan->length < segstart)
-       {
-               last = scan;
-               scan = scan->next;
-       }
-
-//
-// take the given range out of the block
-//
-       oldend = scan->start + scan->length;
-       extra = oldend - (segstart+seglength);
-
-       segmlen=extra;
-
-       //++++emsver stuff!
-       if(segm>1)/// || extra>=0x10000lu)
-       //if(extra>0xfffflu)
-       {
-               scan->blob=segm;
-
-               //MML_UseSpace(segstart, seglength, gvar);
-
-               printf("MML_UseSpace: Segment spans two blocks!\n");
-       //}
-       printf("segm=%u         ", segm);
-       printf("ex=%lu  ", extra);
-       printf("old=%u  ", oldend);
-       printf("start+seglen=%lu\n", segstart+seglength);
-       printf("segsta=%x       ", segstart);
-       printf("len=%lu ", scan->length);
-       printf("seglen=%lu      ", seglength);
-       printf("segmlen=%lu\n", segmlen);
-       }
-//++++todo: linked list of segment!
-       if(segstart == scan->start)
-       {
-               last->next = scan->next;                        // unlink block
-               FREEBLOCK(scan);
-               scan = last;
-       }
-       else
-               scan->length = segstart-scan->start;    // shorten block
-
-       if(extra > 0)
-       {
-               GETNEWBLOCK;
-               gvar->mm.mmnew->useptr = NULL;
-
-               gvar->mm.mmnew->next = scan->next;
-               scan->next = gvar->mm.mmnew;
-               gvar->mm.mmnew->start = segstart+seglength;
-               gvar->mm.mmnew->length = extra;
-               gvar->mm.mmnew->attributes = LOCKBIT;
-       }//else if(segm>0) goto segu;
-
-}*/
-void MML_UseSpace(word segstart, dword seglength, global_game_variables_t *gvar)
-{
-       mmblocktype far *scan,far *last;
-       word    oldend;
-       sdword          extra;
-       //word segm=1;
-
-       scan = last = gvar->mm.mmhead;
-       gvar->mm.mmrover = gvar->mm.mmhead;             // reset rover to start of memory
-
-//
-// search for the block that contains the range of segments
-//
-       while (scan->start+scan->length < segstart)
-       {
-               last = scan;
-               scan = scan->next;
-       }
-
-//
-// find out how many blocks it spans!
-//
-       /*for(;seglength>=0x10000;seglength-=0xFFFF)
-       {
-               //printf("      seglen=%lu\n", segmlen);
-               segm++;
-       }*/
-
-//
-// take the given range out of the block
-//
-       oldend = scan->start + scan->length;
-       extra = oldend - (segstart+((unsigned)seglength));
-       if (extra < 0)
-       {
-               printf("========================================\n");
-               printf("start=%x        ", scan->start);
-               printf("old=%u  ", oldend);
-               printf("start+seglen=%lu\n", segstart+seglength);
-               printf("segsta=%x       ", segstart);
-               printf("len=%lu ", scan->length);
-               printf("seglen=%lu      ", seglength);
-               printf("\n");
-               printf("MML_UseSpace: Segment spans two blocks! %d\n", extra);
-               printf("========================================\n");
-               //return;
-       }
-
-       if (segstart == scan->start)
-       {
-               last->next = scan->next;                        // unlink block
-               FREEBLOCK(scan);
-               scan = last;
-       }
-       else
-               scan->length = segstart-scan->start;    // shorten block
-
-       if (extra > 0)
-       {
-               GETNEWBLOCK;
-               gvar->mm.mmnew->useptr = NULL;
-
-               gvar->mm.mmnew->next = scan->next;
-               scan->next = gvar->mm.mmnew;
-               gvar->mm.mmnew->start = segstart+seglength;
-               gvar->mm.mmnew->length = extra;
-               gvar->mm.mmnew->attributes = LOCKBIT;
-       }
-
-}
-
-//==========================================================================
-
-/*
-====================
-=
-= MML_ClearBlock
-=
-= We are out of blocks, so free a purgable block
-=
-====================
-*/
-
-void MML_ClearBlock(global_game_variables_t *gvar)
-{
-       //huge mmblocktype huge *scan,huge *last;
-       mmblocktype far *scan,far *last;
-
-       scan = gvar->mm.mmhead->next;
-
-       while(scan)
-       {
-               if(!(scan->attributes&LOCKBIT) && (scan->attributes&PURGEBITS))
-               {
-                       MM_FreePtr(scan->useptr, gvar);
-                       return;
-               }
-               scan = scan->next;
-       }
-
-       printf("MM_ClearBlock: No purgable blocks!\n");
-}
-
-
-//==========================================================================
-
-/*
-===================
-=
-= MM_Startup
-=
-= Grabs all space from turbo with malloc/farmalloc
-= Allocates bufferseg misc buffer
-=
-===================
-*/
-
-void MM_Startup(global_game_variables_t *gvar)
-{
-       int i;
-       //dword length,seglength;
-       dword length; word seglength;
-       //huge void huge        *start;
-       void far        *start;
-       word    segstart;//,endfree;
-       //memptr *peeonself;
-
-       if(gvar->mm.mmstarted)
-               MM_Shutdown(gvar);
-
-       gvar->mm.mmstarted = true;
-       gvar->mm.bombonerror = true;
-
-//
-// set up the linked list (everything in the free list;
-//
-       gvar->mm.mmhead = NULL;
-       gvar->mm.mmfree = &(gvar->mm.mmblocks[0]);
-       for(i=0;i<MAXBLOCKS-1;i++)
-       {
-               gvar->mm.mmblocks[i].next = &(gvar->mm.mmblocks[i+1]);
-       }
-       gvar->mm.mmblocks[i].next = NULL;
-
-//
-// locked block of all memory until we punch out free space
-//
-       GETNEWBLOCK;
-       gvar->mm.mmhead = gvar->mm.mmnew;                               // this will allways be the first node
-       gvar->mm.mmnew->start = 0;
-       gvar->mm.mmnew->length = 0xffff;
-       gvar->mm.mmnew->attributes = LOCKBIT;
-       gvar->mm.mmnew->next = NULL;
-       //gvar->mm.mmnew->useptr = peeonself;
-       gvar->mm.mmrover = gvar->mm.mmhead;
-
-       //printf("              %x\n", peeonself);
-       //printf("              %x\n", *peeonself);
-//
-// get all available near conventional memory segments
-//
-#ifdef __WATCOMC__
-       _nheapgrow();
-       length=(dword)_memavl();//(dword)GetFreeSize();
-       //huge start = (void huge *)(gvar->mm.nearheap = _nmalloc(length));
-       start = (void far *)(gvar->mm.nearheap = _nmalloc(length));
-#endif
-#ifdef __BORLANDC__
-       length=coreleft();
-       //huge start = (void huge *)(gvar->mm.nearheap = malloc(length));
-       start = (void far *)(gvar->mm.nearheap = malloc(length));
-#endif
-       length -= 16-(FP_OFF(start)&15);
-       length -= SAVENEARHEAP;
-       seglength = length / 16;                        // now in paragraphs
-       segstart = FP_SEG(start)+(FP_OFF(start)+15)/16;
-       MML_UseSpace(segstart,seglength, gvar);
-       gvar->mmi.nearheap = length;
-       //printf("start=%Fp     segstart=%x     seglen=%lu      len=%lu\n", start, segstart, seglength, length);
-
-//
-// get all available far conventional memory segments
-//
-       //printf("_FARCORELEFT                          %lu\n", _FCORELEFT);
-#ifdef __WATCOMC__
-       _fheapgrow();
-#endif
-#ifdef __BORLANDC__
-       printf("farcoreleft()                           %lu\n", farcoreleft());
-       printf("(farcoreleft()+32)-_FCORELEFT   %d\n", (sword)((farcoreleft()+32)-_FCORELEFT));
-#endif
-       length=_FCORELEFT;//_fcoreleft();//(dword)GetFarFreeSize();//0xffffUL*4UL;
-       start = gvar->mm.farheap = _fmalloc(length);
-       //start = gvar->mm.farheap = halloc(length, 1);
-       length -= 16-(FP_OFF(start)&15);
-       length -= SAVEFARHEAP;
-       seglength = length / 16;                        // now in paragraphs
-       segstart = FP_SEG(start)+(FP_OFF(start)+15)/16;
-       MML_UseSpace(segstart,seglength, gvar);
-       gvar->mmi.farheap = length;
-       //printf("start=%Fp     segstart=%x     seglen=%lu      len=%lu\n", start, segstart, seglength, length);
-
-       gvar->mmi.mainmem = gvar->mmi.nearheap + gvar->mmi.farheap;
-
-//
-// detect EMS and allocate up to 64K at page frame
-//
-       gvar->mmi.EMSmem = 0;
-//goto emsskip;        //0000
-       for(i = 1;i <
-#ifdef __WATCOMC__
-       __argc
-#endif
-#ifdef __BORLANDC__
-       _argc
-#endif
-       ;i++)
-       {
-               if(US_CheckParm(
-#ifdef __WATCOMC__
-       __argv[i]
-#endif
-#ifdef __BORLANDC__
-       _argv[i]
-#endif
-                       ,ParmStringsexmm) == 0)
-                       goto emsskip;                           // param NOEMS
-       }
-       if(MML_CheckForEMS())
-       {
-               MML_SetupEMS(gvar);                                     // allocate space
-               //TODO: EMS4! AND EMS 3.2 MASSIVE DATA HANDLMENT!
-               MML_UseSpace(gvar->pm.emm.EMSPageFrame,(MAPPAGES)*0x4000lu, gvar);
-               //if(gvar->pm.emm.EMSVer<0x40)
-                       MM_MapEMS(gvar);                                        // map in used pages
-               //else
-                       //MM_MapXEMS(gvar);                                     // map in used pages
-       }
-
-//
-// detect XMS and get upper memory blocks
-//
-emsskip:
-       gvar->mmi.XMSmem = 0;
-goto xmsskip;//0000
-       for(i = 1;i <
-#ifdef __WATCOMC__
-       __argc
-#endif
-#ifdef __BORLANDC__
-       _argc
-#endif
-       ;i++)
-       {
-               if(US_CheckParm(
-#ifdef __WATCOMC__
-       __argv[i]
-#endif
-#ifdef __BORLANDC__
-       _argv[i]
-#endif
-                       ,ParmStringsexmm) == 0)
-                       goto xmsskip;                           // param NOXMS
-       }
-       if(MML_CheckForXMS(gvar))
-       {
-               MML_SetupXMS(gvar);                                     // allocate as many UMBs as possible
-       }
-
-//
-// allocate the misc buffer
-//
-xmsskip:
-       gvar->mm.mmrover = gvar->mm.mmhead;             // start looking for space after low block
-
-       MM_GetPtr(&(gvar->mm.bufferseg),BUFFERSIZE, gvar);
-}
-
-//==========================================================================
-
-/*
-====================
-=
-= MM_Shutdown
-=
-= Frees all conventional, EMS, and XMS allocated
-=
-====================
-*/
-
-void MM_Shutdown(global_game_variables_t *gvar)
-{
-       if(!(gvar->mm.mmstarted))
-               return;
-
-       _ffree(gvar->mm.farheap);//     printf("                far freed\n");
-#ifdef __WATCOMC__
-       _nfree(gvar->mm.nearheap);//    printf("                near freed\n");
-#endif
-#ifdef __BORLANDC__
-       free(gvar->mm.nearheap);//      printf("                near freed\n");
-#endif
-       if(MML_CheckForEMS()){ MML_ShutdownEMS(gvar); }//printf("               EMS freed\n"); }
-       if(MML_CheckForXMS(gvar)){ MML_ShutdownXMS(gvar); }//printf("           XMS freed\n"); }
-}
-
-//==========================================================================
-
-/*
-====================
-=
-= MM_GetPtr
-=
-= Allocates an unlocked, unpurgable block
-=
-====================
-*/
-
-void MM_GetPtr (memptr *baseptr, dword size, global_game_variables_t *gvar)
-{
-       //huge mmblocktype huge *scan,huge *lastscan,huge *endscan,huge *purge,huge *next;
-       mmblocktype far *scan,far *lastscan,far *endscan,far *purge,far *next;
-       int                     search;
-       unsigned        needed,startseg;
-
-       needed = (size+15)/16;          // convert size from bytes to paragraphs
-
-       GETNEWBLOCK;                            // fill in start and next after a spot is found
-       gvar->mm.mmnew->length = needed;
-       gvar->mm.mmnew->useptr = baseptr;
-       //if(gvar->mm.mmnew->useptr==NULL){
-#ifdef __DEBUG__
-               printf("        MM_GetPtr\n");
-               printf("                baseptr=%04x    ", baseptr); printf("useptr=%04x\n", gvar->mm.mmnew->useptr);
-               printf("                *baseptr=%04x   ", *baseptr); printf("*useptr=%04x\n", *(gvar->mm.mmnew->useptr));
-               printf("                *baseptr=%Fp    ", *baseptr); printf("*useptr=%Fp\n", *(gvar->mm.mmnew->useptr));
-#endif
-       //exit(-5); }
-       gvar->mm.mmnew->attributes = BASEATTRIBUTES;
-
-//tryagain:
-       for (search = 0; search<3; search++)
-       {
-       //
-       // first search:        try to allocate right after the rover, then on up
-       // second search:       search from the head pointer up to the rover
-       // third search:        compress memory, then scan from start
-               if (search == 1 && gvar->mm.mmrover == gvar->mm.mmhead)
-                       search++;
-
-               switch (search)
-               {
-               case 0:
-                       lastscan = gvar->mm.mmrover;
-                       scan = gvar->mm.mmrover->next;
-                       endscan = NULL;
-                       break;
-               case 1:
-                       lastscan = gvar->mm.mmhead;
-                       scan = gvar->mm.mmhead->next;
-                       endscan = gvar->mm.mmrover;
-                       break;
-               case 2:
-                       MM_SortMem (gvar);
-                       lastscan = gvar->mm.mmhead;
-                       scan = gvar->mm.mmhead->next;
-                       endscan = NULL;
-                       break;
-               }
-
-               startseg = lastscan->start + lastscan->length;
-
-               while (scan != endscan)
-               {
-                       if (scan->start - startseg >= needed)
-                       {
-                       //
-                       // got enough space between the end of lastscan and
-                       // the start of scan, so throw out anything in the middle
-                       // and allocate the new block
-                       //
-                               purge = lastscan->next;
-                               lastscan->next = gvar->mm.mmnew;
-                               gvar->mm.mmnew->start = *(unsigned *)baseptr = startseg;
-                               gvar->mm.mmnew->next = scan;
-                               while ( purge != scan)
-                               {       // free the purgable block
-                                       next = purge->next;
-                                       FREEBLOCK(purge);
-                                       purge = next;           // purge another if not at scan
-                               }
-                               gvar->mm.mmrover = gvar->mm.mmnew;
-                               return; // good allocation!
-                       }
-
-                       //
-                       // if this block is purge level zero or locked, skip past it
-                       //
-                       if ( (scan->attributes & LOCKBIT)
-                               || !(scan->attributes & PURGEBITS) )
-                       {
-                               lastscan = scan;
-                               startseg = lastscan->start + lastscan->length;
-                       }
-
-
-                       scan=scan->next;                // look at next line
-               }
-       }
-
-       if (gvar->mm.bombonerror)
-       {
-#ifdef __WATCOMC__
-               //heapdump();
-#endif
-               printf(OUT_OF_MEM_MSG,(size-gvar->mmi.nearheap));
-               printf("for stability reasons the program will shut down! wwww\n");
-               MM_Shutdown(gvar);
-               exit(-1);
-       }
-       else
-               gvar->mm.mmerror = true;
-}
-
-//==========================================================================
-
-/*
-====================
-=
-= MM_FreePtr
-=
-= Allocates an unlocked, unpurgable block
-=
-====================
-*/
-
-void MM_FreePtr(memptr *baseptr, global_game_variables_t *gvar)
-{
-       //huge mmblocktype huge *scan,huge *last;
-       mmblocktype far *scan,far *last;
-
-       last = gvar->mm.mmhead;
-       scan = last->next;
-
-       if(baseptr == gvar->mm.mmrover->useptr) // removed the last allocated block
-               gvar->mm.mmrover = gvar->mm.mmhead;
-
-       while(scan->useptr != baseptr && scan)
-       {
-               last = scan;
-               scan = scan->next;
-       }
-
-       if(!scan)
-       {
-               printf("MM_FreePtr: Block not found!\n");
-               return;
-       }
-
-       last->next = scan->next;
-
-       FREEBLOCK(scan);
-}
-//==========================================================================
-
-/*
-=====================
-=
-= MM_SetPurge
-=
-= Sets the purge level for a block (locked blocks cannot be made purgable)
-=
-=====================
-*/
-
-void MM_SetPurge(memptr *baseptr, int purge, global_game_variables_t *gvar)
-{
-       //huge mmblocktype huge *start;
-       mmblocktype far *start;
-
-       start = gvar->mm.mmrover;
-
-       do
-       {
-               if(gvar->mm.mmrover->useptr == baseptr)
-                       break;
-
-               gvar->mm.mmrover = gvar->mm.mmrover->next;
-
-               if(!gvar->mm.mmrover)
-                       gvar->mm.mmrover = gvar->mm.mmhead;
-               else if(gvar->mm.mmrover == start)
-               {
-                       //Quit("MM_SetPurge: Block not found!");
-                       printf("%Fp     %u\n", start->start, start->length);
-                       printf("MM_SetPurge: Block not found!\n");
-                       exit(1);
-                       return;
-               }
-
-       } while(1);
-
-       gvar->mm.mmrover->attributes &= ~PURGEBITS;
-       gvar->mm.mmrover->attributes |= purge;
-}
-
-//==========================================================================
-
-/*
-=====================
-=
-= MM_SetLock
-=
-= Locks / unlocks the block
-=
-=====================
-*/
-
-void MM_SetLock(memptr *baseptr, boolean locked, global_game_variables_t *gvar)
-{
-       //huge mmblocktype huge *start;
-       mmblocktype far *start;
-
-       start = gvar->mm.mmrover;
-
-       do
-       {
-               if(gvar->mm.mmrover->useptr == baseptr)
-                       break;
-
-               gvar->mm.mmrover = gvar->mm.mmrover->next;
-
-               if(!gvar->mm.mmrover)
-                       gvar->mm.mmrover = gvar->mm.mmhead;
-               else if(gvar->mm.mmrover == start)
-               {
-                       Quit("MM_SetLock: Block not found!");
-                       //return;
-               }
-
-       } while(1);
-
-       gvar->mm.mmrover->attributes &= ~LOCKBIT;
-       gvar->mm.mmrover->attributes |= locked*LOCKBIT;
-}
-
-//==========================================================================
-
-/*
-=====================
-=
-= MM_SortMem
-=
-= Throws out all purgable stuff and compresses movable blocks
-=
-=====================
-*/
-
-void MM_SortMem(global_game_variables_t *gvar)
-{
-       //huge mmblocktype huge *scan,huge *last,huge *next;
-       mmblocktype far *scan,far *last,far *next;
-       unsigned        start,length,source,dest,oldborder;
-       int                     playing;
-
-       //
-       // lock down a currently playing sound
-       //
-/*++++ playing = SD_SoundPlaying ();
-       if(playing)
-       {
-               switch (SoundMode)
-               {
-               case sdm_PC:
-                       playing += STARTPCSOUNDS;
-                       break;
-               case sdm_AdLib:
-                       playing += STARTADLIBSOUNDS;
-                       break;
-               }
-               MM_SetLock(&(memptr)audiosegs[playing],true);
-       }
-
-
-       SD_StopSound();*/
-//     oldborder = bordercolor;
-//     VW_ColorBorder (15);
-
-       if(beforesort)
-               beforesort();
-
-       scan = gvar->mm.mmhead;
-
-       last = NULL;            // shut up compiler warning
-
-       while(scan)
-       {
-               if(scan->attributes & LOCKBIT)
-               {
-               //
-               // block is locked, so try to pile later blocks right after it
-               //
-                       start = scan->start + scan->length;
-               }
-               else
-               {
-                       if(scan->attributes & PURGEBITS)
-                       {
-                       //
-                       // throw out the purgable block
-                       //
-                               next = scan->next;
-                               FREEBLOCK(scan);
-                               //MM_FreeBlock(scan, gvar);
-                               last->next = next;
-                               scan = next;
-                               continue;
-                       }
-                       else
-                       {
-                       //
-                       // push the non purgable block on top of the last moved block
-                       //
-                               if(scan->start != start)
-                               {
-                                       length = scan->length;
-                                       source = scan->start;
-                                       dest = start;
-                                       while(length > 0xf00)
-                                       {
-                                               movedata(source,0,dest,0,0xf00*16);
-                                               length -= 0xf00;
-                                               source += 0xf00;
-                                               dest += 0xf00;
-                                       }
-                                       movedata(source,0,dest,0,length*16);
-
-                                       scan->start = start;
-                                       *(unsigned *)scan->useptr = start;
-                               }
-                               start = scan->start + scan->length;
-                       }
-               }
-
-               last = scan;
-               scan = scan->next;              // go to next block
-       }
-
-       gvar->mm.mmrover = gvar->mm.mmhead;
-
-       if(aftersort)
-               aftersort();
-
-//     VW_ColorBorder (oldborder);
-
-/*++++ if(playing)
-               MM_SetLock(&(memptr)audiosegs[playing],false);*/
-}
-
-//==========================================================================
-
-/*
-=====================
-=
-= MM_ShowMemory
-=
-=====================
-*/
-
-void MM_ShowMemory(global_game_variables_t *gvar)
-{
-       //huge mmblocktype huge *scan;
-       mmblocktype far *scan;
-       word temp;
-       sdword  end,owner;
-       //word chx,chy;
-       word w;
-       //dword wwww;
-       byte    scratch[160],scratch0[4096],scratch1[160],str[16];
-       //byte d = '#';
-//**** VW_SetDefaultColors();
-//**** VW_SetLineWidth(40);
-//++++mh       temp = bufferofs;
-//++++mh       bufferofs = 0;
-//**** VW_SetScreen (0,0);
-       scan = gvar->mm.mmhead;
-       end = -1;
-
-       CA_OpenDebug (gvar);
-       w=0;
-       while(scan)
-       {
-               strcpy(scratch, AARESET);
-               if(scan->attributes & PURGEBITS)
-                       strcpy(scratch0, AAMAGENTA);            // dark purple = purgable
-               else
-                       strcpy(scratch0, AABLUE);               // medium blue = non purgable
-               if(scan->attributes & LOCKBIT)
-                       strcpy(scratch0, AARED);                // red = locked
-               if(scan->start<=end)
-               {
-                       printf("\nend==%d\n\n", end);
-                       strcat(scratch, "MM_ShowMemory: Memory block order currupted!\n");
-                       strcat(scratch, "End's Size: ");
-                       ultoa (end,str,10);
-                       strcat (scratch,str);
-                       strcat(scratch, "\nscan->start's Size: ");
-                       ultoa (scan->start,str,10);
-                       strcat (scratch,str);
-                       write(gvar->handle.debughandle,scratch,strlen(scratch));
-                       //modexprint(&page, chx, chy, 1, 0, 24, "\nMM_ShowMemory: Memory block order currupted!\n");
-                       break;
-               }
-               end = scan->start+(scan->length)-1;
-//++++         chy = scan->start/320;
-//++++         chx = scan->start%320;
-                               //modexhlin(page, scan->start, (unsigned)end, chy, color);
-                               //for(chx=scan->start;chx+4>=(word)end;chx+=4)
-                               //{
-//++++                                 modexClearRegion(page, chx, chy, 4, 4, color);
-                               //}
-//++++         VW_Hlin(scan->start,(unsigned)end,0,color);
-               for(w=(scan->start)/80;w<=end/80;w++)
-               {
-                       //printf("+     %u      %lu\n", w, scan->length);
-                       strcat(scratch0, "+");
-               }
-               //++==++==optional strcat(scratch0, AARESET); strcat(scratch0, AAGREY); strcat(scratch0,"_");
-//++++         VW_Plot(scan->start,0,15);
-//++++                         modexClearRegion(page, chx, chy, 4, 4, 15);
-//++++                 VW_Hlin(end+1,scan->next->start,0,0);   // black = free
-
-               //wwww=(dword)(scan->next->start)-(dword)scan->start;
-               //wwww=(dword)scan->start+(dword)(scan->next->start);
-               if (scan->next && scan->next->start >= end+1)
-               {
-                       strcat(scratch0, AARESET);
-                       //++==++==optional strcat(scratch0, "\n");
-                       strcat(scratch0,AAGREEN);
-                       for(w=(end+1)/80;w<=((scan->next->start-scan->start)/80);w++)
-                       //for(w=(wwww)/80;w<=((end+1)/80);w++)
-                       //for(w=(end+1)/80;w<=((wwww)/80);w++)
-                       {
-                               //printf("0     %x      %u      %lu\n", scan->next->start, w, scan->length);
-                               strcat(scratch0,"0");
-                       }
-                       //printf("==================\n");
-                       //printf("w=%u  wwww=%lu        start=%04x      next=%04x       end=%lu\n", w/80, wwww/80, scan->start, (scan->next->start), end+1);
-                       //printf("==================\n");
-                       strcat(scratch0, "\n");
-                       //getch();
-               }/*else {//if(scan->next->start <= scan->start){
-                       scan->next->start=scan->start+0x1000;
-                       wwww=(dword)(scan->next->start)-(dword)scan->start;
-                       strcat(scratch0, AARESET);
-                       strcat(scratch0, "\n");
-                       strcat(scratch0,AAGREEN);
-                       for(w=(end+1);w<=(0x1000/80);w++)
-                       {
-                               //printf("0     %x      %x      %u\n", scan->start, w);
-                               strcat(scratch0,"0");
-                       }
-                       printf("================\n");
-                       printf("w=%x    start=%x        next=%x end=%u  %lu\n", w, scan->start, (scan->next->start), end+1, wwww);
-                       printf("================\n");
-                       getch();
-               }*/
-               strcat(scratch0, AARESET);
-               //strcat(scratch0,"\n");
-                       //for(chx=scan->next->start;chx+4>=(word)end+1;chx+=4)
-                       //{
-//                             chx+=scan->next->start;
-//                             modexClearRegion(page, chx, chy, 4, 4, 2);
-                       //}
-                                       //modexhlin(page, end+1,scan->next->start, chy, 0);
-/*             y = scan->start/320;
-               x = scan->start%320;
-               VW_Hlin(x,x+end,y,color);
-               VW_Plot(x,y,15);*/
-//++++                 VW_Hlin(x+end+1,x+(scan->next->start-scan->start),y,0); // black = free
-               strcat(scratch,"Seg:");
-               ultoa (scan->start,str,16);
-               strcat (scratch,str);
-               strcat (scratch,"\tSize:");
-               ultoa ((unsigned)scan->length,str,10);
-               strcat (scratch,str);
-               strcat (scratch,"\tOwner:0x");
-               owner = (unsigned)scan->useptr;
-               ultoa (owner,str,16);
-               strcat (scratch,str);
-               strcat (scratch,"\n");
-               write(gvar->handle.debughandle,scratch,strlen(scratch));
-               write(gvar->handle.debughandle,scratch0,strlen(scratch0));
-//modexprint(page, chx, chy, 1, 0, 24, &scratch);
-//++++chy+=4;
-//fprintf(stdout, "%s", scratch);
-
-               scan = scan->next;
-       }
-       /*strcpy(scratch1, AARESET);
-       strcat(scratch1, "========================================\n");
-       strcat(scratch1, "near=  ");
-       ultoa (*(gvar->mm.nearheap),str,10);
-       strcat (scratch1,str);
-       strcat(scratch1, "      far= ");
-       ultoa (*(gvar->mm.farheap),str,10);
-       strcat (scratch1,str);
-       strcat(scratch1, "\n");
-       //strcat(scratch1, "&near=      %Fp ", &(gvar->mm.nearheap));
-       //strcat(scratch1, "&far=       %Fp", &(gvar->mm.farheap));
-       //strcat(scratch1, "\n");
-       strcat(scratch1, "========================================\n");
-       write(gvar->handle.debughandle,scratch1,strlen(scratch1));*/
-
-
-       CA_CloseDebug (gvar);
-
-//++++mh       IN_Ack();
-//**** VW_SetLineWidth(64);
-//++++mh       bufferofs = temp;
-}
-
-//==========================================================================
-
-/*
-=====================
-=
-= MM_DumpData
-=
-=====================
-*/
-
-void MM_DumpData(global_game_variables_t *gvar)
-{
-       //huge mmblocktype huge *scan,huge *best;
-       mmblocktype far *scan,far *best;
-       long    lowest,oldlowest;
-       word    owner;
-       byte    lock,purge;
-       FILE    *dumpfile;
-
-       free(gvar->mm.nearheap);
-#ifdef __BORLANDC__
-               dumpfile = fopen ("mmdump.16b","w");
-#endif
-#ifdef __WATCOMC__
-               dumpfile = fopen ("mmdump.16w","w");
-#endif
-       if (!dumpfile){
-               printf("MM_DumpData: Couldn't open MMDUMP.16!\n");
-               return;
-       }
-
-       lowest = -1;
-       do
-       {
-               oldlowest = lowest;
-               lowest = 0xffff;
-
-               scan = gvar->mm.mmhead;
-               while (scan)
-               {
-                       owner = (unsigned)scan->useptr;
-
-                       if (owner && owner<lowest && owner > oldlowest)
-                       {
-                               best = scan;
-                               lowest = owner;
-                       }
-
-                       scan = scan->next;
-               }
-
-               if (lowest != 0xffff)
-               {
-                       if (best->attributes & PURGEBITS)
-                               purge = 'P';
-                       else
-                               purge = '-';
-                       if (best->attributes & LOCKBIT)
-                               lock = 'L';
-                       else
-                               lock = '-';
-                       fprintf (dumpfile,"0x%p (%c%c) = %u\n"
-                       ,(unsigned)lowest,lock,purge,best->length);
-               }
-
-       } while (lowest != 0xffff);
-
-       fclose(dumpfile);
-       printf("MMDUMP.16 created.\n");
-}
-
-//==========================================================================
-
-
-/*
-======================
-=
-= MM_UnusedMemory
-=
-= Returns the total free space without purging
-=
-======================
-*/
-
-dword MM_UnusedMemory(global_game_variables_t *gvar)
-{
-       dword free;
-       //huge mmblocktype huge *scan;
-       mmblocktype far *scan;
-
-       free = 0;
-       scan = gvar->mm.mmhead;
-
-       while(scan->next)
-       {
-               free += scan->next->start - (scan->start + scan->length);
-               scan = scan->next;
-       }
-
-       return free*16lu;
-//     return free;
-}
-
-//==========================================================================
-
-
-/*
-======================
-=
-= MM_TotalFree
-=
-= Returns the total free space with purging
-=
-======================
-*/
-
-dword MM_TotalFree(global_game_variables_t *gvar)
-{
-       dword free;
-       //huge mmblocktype huge *scan;
-       mmblocktype far *scan;
-
-       free = 0;
-       scan = gvar->mm.mmhead;
-
-       while(scan->next)
-       {
-               if((scan->attributes&PURGEBITS) && !(scan->attributes&LOCKBIT))
-                       free += scan->length;
-               free += scan->next->start - (scan->start + scan->length);
-               scan = scan->next;
-       }
-
-       return free*16lu;
-//     return free;
-}
-
-//==========================================================================
-
-/*
-=====================
-=
-= MM_Report
-=
-=====================
-*/
-
-void MM_Report_(global_game_variables_t *gvar)
-{
-       printf("========================================\n");
-       printf("                MM_Report\n");
-       printf("========================================\n");
-       if(MML_CheckForEMS())
-       {
-               printf("        LIMEMS\n");
-               printf("                EMM v%x.%x available\n", gvar->pm.emm.EMSVer>>4,gvar->pm.emm.EMSVer&0x0F);
-               printf("                totalEMSpages:  %u      ", gvar->pm.emm.totalEMSpages); printf("freeEMSpages:   %u\n", gvar->pm.emm.freeEMSpages);
-               printf("                EMSPageFrame:   %x\n", gvar->pm.emm.EMSPageFrame);
-       }
-       if(MML_CheckForXMS(gvar))
-       {
-               printf("        XMS\n");
-               printf("                XMSaddr:        %X\n", *XMSaddr);
-       }
-       printf("near:   %lu     ", gvar->mmi.nearheap); printf("far:    %lu\n", gvar->mmi.farheap); if(MML_CheckForEMS())
-       printf("EMSmem: %lu     ", gvar->mmi.EMSmem); if(MML_CheckForXMS(gvar)) printf("XMSmem: %lu", gvar->mmi.XMSmem); printf("\n");
-       //printf("mainmem:      %lu\n", gvar->mmi.mainmem);
-       printf("Total convmem:  %lu     ", gvar->mmi.mainmem); printf("TotalFree:       %lu     ", MM_TotalFree(gvar)); printf("TotalUsed:      %lu\n", gvar->mmi.mainmem+gvar->mmi.EMSmem+gvar->mmi.XMSmem+gvar->mmi.XMSmem);
-       printf("                        UnusedMemory:   %lu\n", MM_UnusedMemory(gvar));
-}
-
-//==========================================================================
-
-/*
-=====================
-=
-= MM_EMSerr
-=
-=====================
-*/
-
-void MM_EMSerr(byte *stri, byte err)
-{
-       //Returns a text string describing the error code in EMS.Error.
-       switch(err)
-       {
-               case 0x0:
-                       strcat(stri, "successful");
-               break;
-               case 0x80:
-                       strcat(stri, "internal error");
-               break;
-               case 0x81:
-                       strcat(stri, "hardware malfunction");
-               break;
-               case 0x82:
-                       strcat(stri, "busy .. retry later");
-               break;
-               case 0x83:
-                       strcat(stri, "invalid handle");
-               break;
-               case 0x84:
-                       strcat(stri, "undefined function requested by application");
-               break;
-               case 0x85:
-                       strcat(stri, "no more handles available");
-               break;
-               case 0x86:
-                       strcat(stri, "error in save or restore of mapping context");
-               break;
-               case 0x87:
-                       strcat(stri, "insufficient memory pages in system");
-               break;
-               case 0x88:
-                       strcat(stri, "insufficient memory pages available");
-               break;
-               case 0x89:
-                       strcat(stri, "zero pages requested");
-               break;
-               case 0x8A:
-                       strcat(stri, "invalid logical page number encountered");
-               break;
-               case 0x8B:
-                       strcat(stri, "invalid physical page number encountered");
-               break;
-               case 0x8C:
-                       strcat(stri, "page-mapping hardware state save area is full");
-               break;
-               case 0x8D:
-                       strcat(stri, "save of mapping context failed");
-               break;
-               case 0x8E:
-                       strcat(stri, "restore of mapping context failed");
-               break;
-               case 0x8F:
-                       strcat(stri, "undefined subfunction");
-               break;
-               case 0x90:
-                       strcat(stri, "undefined attribute type");
-               break;
-               case 0x91:
-                       strcat(stri, "feature not supported");
-               break;
-               case 0x92:
-                       strcat(stri, "successful, but a portion of the source region has been overwritten");
-               break;
-               case 0x93:
-                       strcat(stri, "length of source or destination region exceeds length of region allocated to either source or destination handle");
-               break;
-               case 0x94:
-                       strcat(stri, "conventional and expanded memory regions overlap");
-               break;
-               case 0x95:
-                       strcat(stri, "offset within logical page exceeds size of logical page");
-               break;
-               case 0x96:
-                       strcat(stri, "region length exceeds 1 MB");
-               break;
-               case 0x97:
-                       strcat(stri, "source and destination EMS regions have same handle and overlap");
-               break;
-               case 0x98:
-                       strcat(stri, "memory source or destination type undefined");
-               break;
-               case 0x9A:
-                       strcat(stri, "specified alternate map register or DMA register set not supported");
-               break;
-               case 0x9B:
-                       strcat(stri, "all alternate map register or DMA register sets currently allocated");
-               break;
-               case 0x9C:
-                       strcat(stri, "alternate map register or DMA register sets not supported");
-               break;
-               case 0x9D:
-                       strcat(stri, "undefined or unallocated alternate map register or DMA register set");
-               break;
-               case 0x9E:
-                       strcat(stri, "dedicated DMA channels not supported");
-               break;
-               case 0x9F:
-                       strcat(stri, "specified dedicated DMA channel not supported");
-               break;
-               case 0xA0:
-                       strcat(stri, "no such handle name");
-               break;
-               case 0xA1:
-                       strcat(stri, "a handle found had no name, or duplicate handle name");
-               break;
-               case 0xA2:
-                       strcat(stri, "attempted to wrap around 1M conventional address space");
-               break;
-               case 0xA3:
-                       strcat(stri, "source array corrupted");
-               break;
-               case 0xA4:
-                       strcat(stri, "operating system denied access");
-               break;
-               default:
-                       strcat(stri, "undefined error");
-       }
-}
-
-//==========================================================================
-
-/*
-=====================
-=
-= MM_BombOnError
-=
-=====================
-*/
-
-void MM_BombOnError(boolean bomb, global_game_variables_t *gvar)
-{
-       gvar->mm.bombonerror = bomb;
-}
-
-/*void MM_GetNewBlock(global_game_variables_t *gvar)
-{
-       if(!gvar->mm.mmfree)
-               MML_ClearBlock(gvar);
-       gvar->mm.mmnew=gvar->mm.mmfree;
-       gvar->mm.mmfree=gvar->mm.mmfree->next;
-       if(!(gvar->mm.mmnew=gvar->mm.mmfree))
-       {
-               printf("MM_GETNEWBLOCK: No free blocks!\n");
-               return;
-       }
-       gvar->mm.mmfree=gvar->mm.mmfree->next;
-}
-
-void MM_FreeBlock(mmblocktype *x, global_game_variables_t *gvar)
-{
-       x->useptr=NULL;
-       x->next=gvar->mm.mmfree;
-       gvar->mm.mmfree=x;
-}*/
-
-/*void MM_seguin(void)
-{
-       __asm {
-               push    ds
-               mov     ax,ds
-               inc             ax
-               mov     ds,ax
-       }
-}
-
-void MM_segude(void)
-{
-       __asm {
-               pop ds
-       }
-}*/
-
-/*
-pull data from far and put it into ds var
-mov ax,es:si
-mov x,ax
-*/
-/*
-ss stack segment
-sp top of stack
-bp bottem of stack
-*/
+/* Catacomb Apocalypse Source Code\r
+ * Copyright (C) 1993-2014 Flat Rock Software\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License along\r
+ * with this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+ */\r
+\r
+// NEWMM.C\r
+\r
+/*\r
+=============================================================================\r
+\r
+                       ID software memory manager\r
+                       --------------------------\r
+\r
+Primary coder: John Carmack\r
+\r
+RELIES ON\r
+---------\r
+Quit (char *error) function\r
+\r
+\r
+WORK TO DO\r
+----------\r
+MM_SizePtr to change the size of a given pointer\r
+\r
+Multiple purge levels utilized\r
+\r
+EMS / XMS unmanaged routines\r
+\r
+=============================================================================\r
+*/\r
+/*\r
+\r
+Open Watcom port by sparky4\r
+\r
+*/\r
+#include "src/lib/16_mm.h"\r
+#include "src/lib/16_ca.h"\r
+#pragma hdrstop\r
+\r
+#pragma warn -pro\r
+#pragma warn -use\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                GLOBAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+void           (* beforesort) (void);\r
+void           (* aftersort) (void);\r
+void           (* XMSaddr) (void);             // far pointer to XMS driver\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                LOCAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+/*\r
+======================\r
+=\r
+= MML_CheckForEMS\r
+=\r
+= Routine from p36 of Extending DOS\r
+=\r
+=======================\r
+*/\r
+\r
+boolean MML_CheckForEMS(void)\r
+{\r
+       boolean emmcfems;\r
+       static char     emmname[] = "EMMXXXX0"; //fix by andrius4669\r
+       __asm {\r
+               mov     dx,OFFSET emmname       //fix by andrius4669\r
+               mov     ax,0x3d00\r
+               int     0x21            // try to open EMMXXXX0 device\r
+               jc      error\r
+\r
+               mov     bx,ax\r
+               mov     ax,0x4400\r
+\r
+               int     0x21            // get device info\r
+               jc      error\r
+\r
+               and     dx,0x80\r
+               jz      error\r
+\r
+               mov     ax,0x4407\r
+\r
+               int     0x21            // get status\r
+               jc      error\r
+               or      al,al\r
+               jz      error\r
+\r
+               mov     ah,0x3e\r
+               int     0x21            // close handle\r
+               jc      error\r
+               //\r
+               // EMS is good\r
+               //\r
+               mov     emmcfems,1\r
+               jmp End\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+               error:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               //\r
+               // EMS is bad\r
+               //\r
+               mov     emmcfems,0\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+               End:\r
+#ifdef __WATCOMC__\r
+       }\r
+#endif\r
+       return(emmcfems);\r
+}\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= MML_SetupEMS\r
+=\r
+=======================\r
+*/\r
+\r
+byte MML_SetupEMS(global_game_variables_t *gvar)\r
+{\r
+       byte    str[160];\r
+       byte    err;\r
+       boolean errorflag=false;\r
+\r
+       unsigned int EMSVer = 0;\r
+       //byte  EMS_status;\r
+       unsigned        totalEMSpages,freeEMSpages,EMSPageFrame,EMSpagesmapped,EMSHandle;\r
+       totalEMSpages = freeEMSpages = EMSPageFrame = EMSpagesmapped = 0;\r
+\r
+       __asm {\r
+               mov     ah,EMS_STATUS\r
+               int     EMS_INT                                         // make sure EMS hardware is present\r
+               or      ah,ah\r
+               //mov   [EMS_status],ah\r
+               jnz     error\r
+\r
+               mov     ah,EMS_VERSION\r
+               int     EMS_INT\r
+               or      ah,ah\r
+               jnz     error\r
+               mov     [EMSVer],ax                             //      set EMSVer\r
+               cmp     al,0x32                                         // only work on ems 3.2 or greater\r
+               jb      error\r
+\r
+               mov     ah,EMS_GETFRAME\r
+               int     EMS_INT                                         // find the page frame address\r
+               or      ah,ah\r
+               jnz     error\r
+               mov     [EMSPageFrame],bx\r
+\r
+               mov     ah,EMS_GETPAGES\r
+               int     EMS_INT                                         // find out how much EMS is there\r
+               or      ah,ah\r
+               jnz     error\r
+               mov     [totalEMSpages],dx\r
+               mov     [freeEMSpages],bx\r
+               or      bx,bx\r
+               jz      noEMS                                           // no EMS at all to allocate\r
+                                                                                       //EXPAND DONG!!!!\r
+               cmp     [EMSVer],0x40\r
+               jb      low\r
+               cmp     bx,[freeEMSpages]\r
+               jle     getpages\r
+               mov     bx,[freeEMSpages]\r
+               jmp     getpages\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+       low:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               cmp     bx,4\r
+               jle     getpages                                        // there is only 1,2,3,or 4 pages\r
+               mov     bx,4                                            // we can't use more than 4 pages\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+       getpages:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               mov     [EMSpagesmapped],bx\r
+               mov     ah,EMS_ALLOCPAGES                       // allocate up to 64k of EMS\r
+               int     EMS_INT\r
+               or      ah,ah\r
+               jnz     error\r
+               mov     [EMSHandle],dx\r
+               jmp End\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+       error:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               mov     err,ah\r
+               mov     errorflag,1\r
+               jmp End\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+noEMS:\r
+End:\r
+#ifdef __WATCOMC__\r
+       }\r
+#endif\r
+       if(errorflag==true)\r
+       {\r
+               strcpy(str,"MM_SetupEMS: EMS error ");\r
+               MM_EMSerr(str, err);\r
+               printf("%s\n",str);\r
+               return err;\r
+       }\r
+       gvar->pm.emm.totalEMSpages=totalEMSpages;\r
+       gvar->pm.emm.freeEMSpages=freeEMSpages;\r
+       gvar->pm.emm.EMSPageFrame=EMSPageFrame;\r
+       gvar->pm.emm.EMSpagesmapped=EMSpagesmapped;\r
+       gvar->pm.emm.EMSHandle=EMSHandle;\r
+       gvar->pm.emm.EMSVer=EMSVer;\r
+       return 0;\r
+}\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= MML_ShutdownEMS\r
+=\r
+=======================\r
+*/\r
+\r
+void MML_ShutdownEMS(global_game_variables_t *gvar)\r
+{\r
+       boolean errorflag=false;\r
+       unsigned EMSHandle=gvar->pm.emm.EMSHandle;\r
+\r
+       if(!EMSHandle)\r
+               return;\r
+       __asm {\r
+               mov     ah,EMS_FREEPAGES\r
+               mov     dx,[EMSHandle]\r
+               int     EMS_INT\r
+               or      ah,ah\r
+               jz      ok\r
+               mov     errorflag,1\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+               ok:\r
+#ifdef __WATCOMC__\r
+       }\r
+#endif\r
+       if(errorflag==true)\r
+               Quit("MML_ShutdownEMS: Error freeing EMS!\n");  //++++ add something\r
+}\r
+\r
+/*\r
+====================\r
+=\r
+= MM_MapEMS\r
+=\r
+= Maps the 64k of EMS used by memory manager into the page frame\r
+= for general use.  This only needs to be called if you are keeping\r
+= other things in EMS.\r
+=\r
+====================\r
+*/\r
+\r
+byte MM_MapEMS(global_game_variables_t *gvar)\r
+{\r
+       byte    str[160];\r
+       unsigned        EMSHandle;\r
+       byte err;\r
+       boolean errorflag=false;\r
+       int     i;\r
+       EMSHandle=gvar->pm.emm.EMSHandle;\r
+\r
+       for (i=0;i<4/*MAPPAGES*/;i++)\r
+       {\r
+               __asm {\r
+                       mov     ah,EMS_MAPPAGE\r
+                       mov     bx,[i]                  // logical page\r
+                       mov     al,bl                   // physical page\r
+                       mov     dx,[EMSHandle]  // handle\r
+                       int     EMS_INT\r
+                       or      ah,ah\r
+                       jnz     error\r
+                       jmp End\r
+#ifdef __BORLANDC__\r
+               }\r
+#endif\r
+                       error:\r
+#ifdef __BORLANDC__\r
+               __asm {\r
+#endif\r
+                       mov     err,ah\r
+                       mov     errorflag,1\r
+#ifdef __BORLANDC__\r
+               }\r
+#endif\r
+                       End:\r
+#ifdef __WATCOMC__\r
+               }\r
+#endif\r
+               if(errorflag==true)\r
+               {\r
+                       strcpy(str,"MM_MapEMS: EMS error ");\r
+                       MM_EMSerr(str, err);\r
+                       printf("%s\n",str);\r
+                       return err;\r
+               }\r
+       }\r
+       gvar->mmi.EMSmem = (i)*0x4000lu;\r
+       //printf("              gvar->mmi.EMSmem=%lu\n", gvar->mmi.EMSmem);\r
+       return 0;\r
+}\r
+\r
+byte MM_MapXEMS(global_game_variables_t *gvar)\r
+{\r
+//SUB EMS.MapXPages (PhysicalStart, LogicalStart, NumPages, Handle)\r
+\r
+       //Maps up to 4 logical EMS pages to physical pages in the page frame, where:\r
+       //PhysicalStart = Physical page first logical page is mapped to\r
+       //LogicalStart  = First logical page to map\r
+       //NumPages      = Number of pages to map (1 to 4)\r
+       //Handle        = EMS handle logical pages are allocated to\r
+\r
+  /*//Create a buffer containing the page information\r
+//  FOR x = 0 TO NumPages - 1\r
+//    MapInfo$ = MapInfo$ + MKI$(LogicalStart + x) + MKI$(PhysicalStart + x)\r
+//  NEXT*/\r
+\r
+//  Regs.ax = 0x5000                           //Map the pages in the buffer\r
+//  Regs.cx = NumPages                         //to the pageframe\r
+//  Regs.dx = Handle\r
+//  Regs.ds = VARSEG(MapInfo$)\r
+//  Regs.si = SADD(MapInfo$)\r
+//  InterruptX 0x67, Regs, Regs\r
+//     EMS.Error = (Regs.ax AND 0xFF00&) \ 0x100  //Store the status code\r
+\r
+//END SUB\r
+       byte    str[160];\r
+       byte err;\r
+       word    EMSHandle;\r
+       boolean errorflag=false;\r
+       int     i;\r
+       EMSHandle=gvar->pm.emm.EMSHandle;\r
+\r
+       if(gvar->pm.emm.EMSVer<0x40)\r
+               return 5;\r
+\r
+       for (i=0;i<MAPPAGES;i++)\r
+       {\r
+               __asm {\r
+                       mov     ah,EMS_MAPXPAGE\r
+                       mov     cx,[i]                  // logical page\r
+                       mov     al,bl                   // physical page\r
+                       mov     dx,[EMSHandle]  // handle\r
+                       int     EMS_INT\r
+                       or      ah,ah\r
+                       jnz     error\r
+                       jmp End\r
+#ifdef __BORLANDC__\r
+               }\r
+#endif\r
+                       error:\r
+#ifdef __BORLANDC__\r
+               __asm {\r
+#endif\r
+                       mov     err,ah\r
+                       mov     errorflag,1\r
+#ifdef __BORLANDC__\r
+               }\r
+#endif\r
+                       End:\r
+#ifdef __WATCOMC__\r
+               }\r
+#endif\r
+               if(errorflag==true)\r
+               {\r
+                       //strcpy(str,"MM_MapXEMS: EMS error 0x");\r
+                       strcpy(str,"MM_MapXEMS: EMS error ");\r
+                       //itoa(err,str2,16);\r
+                       MM_EMSerr(str, err);\r
+                       printf("%s\n",str);\r
+                       //printf("%s%x\n",str, err);\r
+                       //printf("FACK! %x\n", err);\r
+                       return err;\r
+               }\r
+       }\r
+       gvar->mmi.EMSmem = (i)*0x4000lu;\r
+       return 0;\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+======================\r
+=\r
+= MML_CheckForXMS\r
+=\r
+= Check for XMM driver\r
+=\r
+=======================\r
+*/\r
+\r
+boolean MML_CheckForXMS(global_game_variables_t *gvar)\r
+{\r
+       boolean errorflag=false;\r
+       gvar->mm.numUMBs = 0;\r
+\r
+       __asm {\r
+               mov     ax,0x4300\r
+               int     0x2f                            // query status of installed diver\r
+               cmp     al,0x80\r
+               je      good\r
+               mov     errorflag,1\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+               good:\r
+#ifdef __WATCOMC__\r
+       }\r
+#endif\r
+       if(errorflag==true) return false;\r
+       else return true;\r
+}\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= MML_SetupXMS\r
+=\r
+= Try to allocate all upper memory block\r
+=\r
+=======================\r
+*/\r
+\r
+void MML_SetupXMS(global_game_variables_t *gvar)\r
+{\r
+       word    base,size;\r
+\r
+\r
+       __asm {\r
+               mov     ax,0x4310\r
+               int     0x2f\r
+               mov     [WORD PTR XMSaddr],bx\r
+               mov     [WORD PTR XMSaddr+2],es         // function pointer to XMS driver\r
+       }\r
+getmemory:\r
+       __asm {\r
+               mov     ah,XMS_ALLOCUMB\r
+               mov     dx,0xffff                                       // try for largest block possible\r
+               //mov     ax,dx                                         // Set available Kbytes.\r
+               call    [DWORD PTR XMSaddr]\r
+               or      ax,ax\r
+               jnz     gotone\r
+\r
+               cmp     bl,0xb0                                         // error: smaller UMB is available\r
+               jne     done;\r
+\r
+               mov     ah,XMS_ALLOCUMB\r
+               call    [DWORD PTR XMSaddr]             // DX holds largest available UMB\r
+               or      ax,ax\r
+               jz      done                                            // another error...\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+               gotone:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               mov     [base],bx\r
+               mov     [size],dx\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+               done:\r
+#ifdef __WATCOMC__\r
+       }\r
+#endif\r
+//     printf("base=%u ", base); printf("size=%u\n", size);\r
+       MML_UseSpace(base,size, gvar);\r
+       gvar->mmi.XMSmem += size*16;\r
+       gvar->mm.UMBbase[gvar->mm.numUMBs] = base;\r
+       gvar->mm.numUMBs++;\r
+       if(gvar->mm.numUMBs < MAXUMBS)\r
+               goto getmemory;\r
+}\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= MML_ShutdownXMS\r
+=\r
+======================\r
+*/\r
+\r
+void MML_ShutdownXMS(global_game_variables_t *gvar)\r
+{\r
+       int     i;\r
+       unsigned        base;\r
+\r
+       for (i=0;i<gvar->mm.numUMBs;i++)\r
+       {\r
+               base = gvar->mm.UMBbase[i];\r
+               __asm {\r
+                       mov     ah,XMS_FREEUMB\r
+                       mov     dx,[base]\r
+                       call    [DWORD PTR XMSaddr]\r
+               }\r
+       }\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+======================\r
+=\r
+= MML_UseSpace\r
+=\r
+= Marks a range of paragraphs as usable by the memory manager\r
+= This is used to mark space for the near heap, far heap, ems page frame,\r
+= and upper memory blocks\r
+=\r
+======================\r
+*/\r
+\r
+/*void MML_UseSpace(word segstart, dword seglength, global_game_variables_t *gvar)\r
+{\r
+       //huge mmblocktype huge *scan,huge *last;\r
+       word            segm=1;\r
+       word    oldend;\r
+       dword           segmlen;\r
+       dword           extra;\r
+\r
+       scan = last = gvar->mm.mmhead;\r
+       gvar->mm.mmrover = gvar->mm.mmhead;             // reset rover to start of memory\r
+\r
+//\r
+// search for the block that contains the range of segments\r
+//\r
+       while(scan->start+scan->length < segstart)\r
+       {\r
+               last = scan;\r
+               scan = scan->next;\r
+       }\r
+\r
+//\r
+// take the given range out of the block\r
+//\r
+       oldend = scan->start + scan->length;\r
+       extra = oldend - (segstart+seglength);\r
+\r
+       segmlen=extra;\r
+\r
+       //++++emsver stuff!\r
+       if(segm>1)/// || extra>=0x10000lu)\r
+       //if(extra>0xfffflu)\r
+       {\r
+               scan->blob=segm;\r
+\r
+               //MML_UseSpace(segstart, seglength, gvar);\r
+\r
+               printf("MML_UseSpace: Segment spans two blocks!\n");\r
+       //}\r
+       printf("segm=%u         ", segm);\r
+       printf("ex=%lu  ", extra);\r
+       printf("old=%u  ", oldend);\r
+       printf("start+seglen=%lu\n", segstart+seglength);\r
+       printf("segsta=%x       ", segstart);\r
+       printf("len=%lu ", scan->length);\r
+       printf("seglen=%lu      ", seglength);\r
+       printf("segmlen=%lu\n", segmlen);\r
+       }\r
+//++++todo: linked list of segment!\r
+       if(segstart == scan->start)\r
+       {\r
+               last->next = scan->next;                        // unlink block\r
+               FREEBLOCK(scan);\r
+               scan = last;\r
+       }\r
+       else\r
+               scan->length = segstart-scan->start;    // shorten block\r
+\r
+       if(extra > 0)\r
+       {\r
+               GETNEWBLOCK;\r
+               gvar->mm.mmnew->useptr = NULL;\r
+\r
+               gvar->mm.mmnew->next = scan->next;\r
+               scan->next = gvar->mm.mmnew;\r
+               gvar->mm.mmnew->start = segstart+seglength;\r
+               gvar->mm.mmnew->length = extra;\r
+               gvar->mm.mmnew->attributes = LOCKBIT;\r
+       }//else if(segm>0) goto segu;\r
+\r
+}*/\r
+void MML_UseSpace(word segstart, dword seglength, global_game_variables_t *gvar)\r
+{\r
+       mmblocktype far *scan,far *last;\r
+       word    oldend;\r
+       sdword          extra;\r
+       //word segm=1;\r
+\r
+       scan = last = gvar->mm.mmhead;\r
+       gvar->mm.mmrover = gvar->mm.mmhead;             // reset rover to start of memory\r
+\r
+//\r
+// search for the block that contains the range of segments\r
+//\r
+       while (scan->start+scan->length < segstart)\r
+       {\r
+               last = scan;\r
+               scan = scan->next;\r
+       }\r
+\r
+//\r
+// find out how many blocks it spans!\r
+//\r
+       /*for(;seglength>=0x10000;seglength-=0xFFFF)\r
+       {\r
+               //printf("      seglen=%lu\n", segmlen);\r
+               segm++;\r
+       }*/\r
+\r
+//\r
+// take the given range out of the block\r
+//\r
+       oldend = scan->start + scan->length;\r
+       extra = oldend - (segstart+((unsigned)seglength));\r
+       if (extra < 0)\r
+       {\r
+               printf("========================================\n");\r
+               printf("start=%x        ", scan->start);\r
+               printf("old=%u  ", oldend);\r
+               printf("start+seglen=%lu\n", segstart+seglength);\r
+               printf("segsta=%x       ", segstart);\r
+               printf("len=%lu ", scan->length);\r
+               printf("seglen=%lu      ", seglength);\r
+               printf("\n");\r
+               printf("MML_UseSpace: Segment spans two blocks! %d\n", extra);\r
+               printf("========================================\n");\r
+               //return;\r
+       }\r
+\r
+       if (segstart == scan->start)\r
+       {\r
+               last->next = scan->next;                        // unlink block\r
+               FREEBLOCK(scan);\r
+               scan = last;\r
+       }\r
+       else\r
+               scan->length = segstart-scan->start;    // shorten block\r
+\r
+       if (extra > 0)\r
+       {\r
+               GETNEWBLOCK;\r
+               gvar->mm.mmnew->useptr = NULL;\r
+\r
+               gvar->mm.mmnew->next = scan->next;\r
+               scan->next = gvar->mm.mmnew;\r
+               gvar->mm.mmnew->start = segstart+seglength;\r
+               gvar->mm.mmnew->length = extra;\r
+               gvar->mm.mmnew->attributes = LOCKBIT;\r
+       }\r
+\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+====================\r
+=\r
+= MML_ClearBlock\r
+=\r
+= We are out of blocks, so free a purgable block\r
+=\r
+====================\r
+*/\r
+\r
+void MML_ClearBlock(global_game_variables_t *gvar)\r
+{\r
+       //huge mmblocktype huge *scan,huge *last;\r
+       mmblocktype far *scan,far *last;\r
+\r
+       scan = gvar->mm.mmhead->next;\r
+\r
+       while(scan)\r
+       {\r
+               if(!(scan->attributes&LOCKBIT) && (scan->attributes&PURGEBITS))\r
+               {\r
+                       MM_FreePtr(scan->useptr, gvar);\r
+                       return;\r
+               }\r
+               scan = scan->next;\r
+       }\r
+\r
+       printf("MM_ClearBlock: No purgable blocks!\n");\r
+}\r
+\r
+\r
+//==========================================================================\r
+\r
+/*\r
+===================\r
+=\r
+= MM_Startup\r
+=\r
+= Grabs all space from turbo with malloc/farmalloc\r
+= Allocates bufferseg misc buffer\r
+=\r
+===================\r
+*/\r
+\r
+void MM_Startup(global_game_variables_t *gvar)\r
+{\r
+       int i;\r
+       //dword length,seglength;\r
+       dword length;\r
+       //huge void huge        *start;\r
+       void far        *start;\r
+       word    segstart,seglength,endfree;\r
+       //memptr *peeonself;\r
+\r
+       if(gvar->mm.mmstarted)\r
+               MM_Shutdown(gvar);\r
+\r
+\r
+       gvar->mm.mmstarted = true;\r
+       gvar->mm.bombonerror = true;\r
+//\r
+// set up the linked list (everything in the free list;\r
+//\r
+       gvar->mm.mmhead = NULL;\r
+       gvar->mm.mmfree = &(gvar->mm.mmblocks[0]);\r
+       for(i=0;i<MAXBLOCKS-1;i++)\r
+       {\r
+               gvar->mm.mmblocks[i].next = &(gvar->mm.mmblocks[i+1]);\r
+       }\r
+       gvar->mm.mmblocks[i].next = NULL;\r
+\r
+//\r
+// locked block of all memory until we punch out free space\r
+//\r
+       GETNEWBLOCK;\r
+       gvar->mm.mmhead = gvar->mm.mmnew;                               // this will allways be the first node\r
+       gvar->mm.mmnew->start = 0;\r
+       gvar->mm.mmnew->length = 0xffff;\r
+       gvar->mm.mmnew->attributes = LOCKBIT;\r
+       gvar->mm.mmnew->next = NULL;\r
+       //gvar->mm.mmnew->useptr = peeonself;\r
+       gvar->mm.mmrover = gvar->mm.mmhead;\r
+\r
+       //printf("              %x\n", peeonself);\r
+       //printf("              %x\n", *peeonself);\r
+//\r
+// get all available near conventional memory segments\r
+//\r
+#ifdef __WATCOMC__\r
+       _nheapgrow();\r
+       length=(dword)_memavl();//(dword)GetFreeSize();\r
+       //huge start = (void huge *)(gvar->mm.nearheap = _nmalloc(length));\r
+       start = (void far *)(gvar->mm.nearheap = _nmalloc(length));\r
+#endif\r
+#ifdef __BORLANDC__\r
+       length=coreleft();\r
+       //huge start = (void huge *)(gvar->mm.nearheap = malloc(length));\r
+       start = (void far *)(gvar->mm.nearheap = malloc(length));\r
+       printf("Borland C unique function\n");\r
+       printf("        coreleft()                              %lu\n", coreleft());\r
+#endif\r
+       length -= 16-(FP_OFF(start)&15);\r
+       length -= SAVENEARHEAP;\r
+       seglength = length / 16;                        // now in paragraphs\r
+       segstart = FP_SEG(start)+(FP_OFF(start)+15)/16;\r
+       MML_UseSpace(segstart,seglength, gvar);\r
+       gvar->mmi.nearheap = length;\r
+       //printf("start=%Fp     segstart=%x     seglen=%lu      len=%lu\n", start, segstart, seglength, length);\r
+\r
+//\r
+// get all available far conventional memory segments\r
+//\r
+       //printf("_FARCORELEFT                          %lu\n", _FCORELEFT);\r
+#ifdef __WATCOMC__\r
+       _fheapgrow();\r
+#endif\r
+#ifdef __BORLANDC__\r
+       printf("        farcoreleft()                           %lu\n", farcoreleft());\r
+       printf("        (farcoreleft()+32)-_FCORELEFT   %d\n", (sword)((farcoreleft()+32)-_FCORELEFT));\r
+#endif\r
+       length=_FCORELEFT;//_fcoreleft();//(dword)GetFarFreeSize();//0xffffUL*4UL;\r
+       start = gvar->mm.farheap = _fmalloc(length);\r
+       //start = gvar->mm.farheap = halloc(length, 1);\r
+       length -= 16-(FP_OFF(start)&15);\r
+       length -= SAVEFARHEAP;\r
+       seglength = length / 16;                        // now in paragraphs\r
+       segstart = FP_SEG(start)+(FP_OFF(start)+15)/16;\r
+       MML_UseSpace(segstart,seglength, gvar);\r
+       gvar->mmi.farheap = length;\r
+       gvar->mmi.mainmem = gvar->mmi.nearheap + gvar->mmi.farheap;\r
+       //printf("start=%Fp     segstart=%x     seglen=%lu      len=%lu\n", start, segstart, seglength, length);\r
+\r
+goto xmsskip;  //INFO: 16_PM dose this job better\r
+\r
+//\r
+// detect EMS and allocate up to 64K at page frame\r
+//\r
+       gvar->mmi.EMSmem = 0;\r
+//goto emsskip;        //0000\r
+       if(MML_CheckForEMS())\r
+       {\r
+               MML_SetupEMS(gvar);                                     // allocate space\r
+               //TODO: EMS4! AND EMS 3.2 MASSIVE DATA HANDLMENT!\r
+               MML_UseSpace(gvar->pm.emm.EMSPageFrame,(MAPPAGES)*0x4000lu, gvar);\r
+               //if(gvar->pm.emm.EMSVer<0x40)\r
+                       MM_MapEMS(gvar);                                        // map in used pages\r
+               //else\r
+                       //MM_MapXEMS(gvar);                                     // map in used pages\r
+       }\r
+\r
+//\r
+// detect XMS and get upper memory blocks\r
+//\r
+//emsskip:\r
+       gvar->mmi.XMSmem = 0;\r
+//goto xmsskip;//0000\r
+       if(MML_CheckForXMS(gvar))\r
+       {\r
+               MML_SetupXMS(gvar);                                     // allocate as many UMBs as possible\r
+       }\r
+\r
+//\r
+// allocate the misc buffer\r
+//\r
+xmsskip:\r
+       gvar->mm.mmrover = gvar->mm.mmhead;             // start looking for space after low block\r
+\r
+       MM_GetPtr(&(gvar->mm.bufferseg),BUFFERSIZE, gvar);\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+====================\r
+=\r
+= MM_Shutdown\r
+=\r
+= Frees all conventional, EMS, and XMS allocated\r
+=\r
+====================\r
+*/\r
+\r
+void MM_Shutdown(global_game_variables_t *gvar)\r
+{\r
+       if(!(gvar->mm.mmstarted))\r
+               return;\r
+\r
+       _ffree(gvar->mm.farheap);//     printf("                far freed\n");\r
+#ifdef __WATCOMC__\r
+       _nfree(gvar->mm.nearheap);//    printf("                near freed\n");\r
+#endif\r
+#ifdef __BORLANDC__\r
+       free(gvar->mm.nearheap);//      printf("                near freed\n");\r
+#endif\r
+       if(MML_CheckForEMS()){ MML_ShutdownEMS(gvar); }//printf("               EMS freed\n"); }\r
+       if(MML_CheckForXMS(gvar)){ MML_ShutdownXMS(gvar); }//printf("           XMS freed\n"); }\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+====================\r
+=\r
+= MM_GetPtr\r
+=\r
+= Allocates an unlocked, unpurgable block\r
+=\r
+====================\r
+*/\r
+\r
+void MM_GetPtr (memptr *baseptr, dword size, global_game_variables_t *gvar)\r
+{\r
+       //huge mmblocktype huge *scan,huge *lastscan,huge *endscan,huge *purge,huge *next;\r
+       mmblocktype far *scan,far *lastscan,far *endscan,far *purge,far *next;\r
+       int                     search;\r
+       unsigned        needed,startseg;\r
+\r
+       needed = (size+15)/16;          // convert size from bytes to paragraphs\r
+\r
+       GETNEWBLOCK;                            // fill in start and next after a spot is found\r
+       gvar->mm.mmnew->length = needed;\r
+       gvar->mm.mmnew->useptr = baseptr;\r
+       //if(gvar->mm.mmnew->useptr==NULL){\r
+#ifdef __DEBUG__\r
+               printf("        MM_GetPtr\n");\r
+               printf("                baseptr=%04x    ", baseptr); printf("useptr=%04x\n", gvar->mm.mmnew->useptr);\r
+               printf("                *baseptr=%04x   ", *baseptr); printf("*useptr=%04x\n", *(gvar->mm.mmnew->useptr));\r
+               printf("                *baseptr=%Fp    ", *baseptr); printf("*useptr=%Fp\n", *(gvar->mm.mmnew->useptr));\r
+#endif\r
+       //exit(-5); }\r
+       gvar->mm.mmnew->attributes = BASEATTRIBUTES;\r
+\r
+//tryagain:\r
+       for (search = 0; search<3; search++)\r
+       {\r
+       //\r
+       // first search:        try to allocate right after the rover, then on up\r
+       // second search:       search from the head pointer up to the rover\r
+       // third search:        compress memory, then scan from start\r
+               if (search == 1 && gvar->mm.mmrover == gvar->mm.mmhead)\r
+                       search++;\r
+\r
+               switch (search)\r
+               {\r
+               case 0:\r
+                       lastscan = gvar->mm.mmrover;\r
+                       scan = gvar->mm.mmrover->next;\r
+                       endscan = NULL;\r
+                       break;\r
+               case 1:\r
+                       lastscan = gvar->mm.mmhead;\r
+                       scan = gvar->mm.mmhead->next;\r
+                       endscan = gvar->mm.mmrover;\r
+                       break;\r
+               case 2:\r
+                       MM_SortMem (gvar);\r
+                       lastscan = gvar->mm.mmhead;\r
+                       scan = gvar->mm.mmhead->next;\r
+                       endscan = NULL;\r
+                       break;\r
+               }\r
+\r
+               startseg = lastscan->start + lastscan->length;\r
+\r
+               while (scan != endscan)\r
+               {\r
+                       if (scan->start - startseg >= needed)\r
+                       {\r
+                       //\r
+                       // got enough space between the end of lastscan and\r
+                       // the start of scan, so throw out anything in the middle\r
+                       // and allocate the new block\r
+                       //\r
+                               purge = lastscan->next;\r
+                               lastscan->next = gvar->mm.mmnew;\r
+                               gvar->mm.mmnew->start = *(unsigned *)baseptr = startseg;\r
+                               gvar->mm.mmnew->next = scan;\r
+                               while ( purge != scan)\r
+                               {       // free the purgable block\r
+                                       next = purge->next;\r
+                                       FREEBLOCK(purge);\r
+                                       purge = next;           // purge another if not at scan\r
+                               }\r
+                               gvar->mm.mmrover = gvar->mm.mmnew;\r
+                               return; // good allocation!\r
+                       }\r
+\r
+                       //\r
+                       // if this block is purge level zero or locked, skip past it\r
+                       //\r
+                       if ( (scan->attributes & LOCKBIT)\r
+                               || !(scan->attributes & PURGEBITS) )\r
+                       {\r
+                               lastscan = scan;\r
+                               startseg = lastscan->start + lastscan->length;\r
+                       }\r
+\r
+\r
+                       scan=scan->next;                // look at next line\r
+               }\r
+       }\r
+\r
+       if (gvar->mm.bombonerror)\r
+       {\r
+#ifdef __WATCOMC__\r
+               //heapdump();\r
+#endif\r
+               printf(OUT_OF_MEM_MSG,(size-gvar->mmi.nearheap));\r
+               printf("for stability reasons the program will shut down! wwww\n");\r
+               MM_Shutdown(gvar);\r
+               exit(-1);\r
+       }\r
+       else\r
+               gvar->mm.mmerror = true;\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+====================\r
+=\r
+= MM_FreePtr\r
+=\r
+= Allocates an unlocked, unpurgable block\r
+=\r
+====================\r
+*/\r
+\r
+void MM_FreePtr(memptr *baseptr, global_game_variables_t *gvar)\r
+{\r
+       //huge mmblocktype huge *scan,huge *last;\r
+       mmblocktype far *scan,far *last;\r
+\r
+       last = gvar->mm.mmhead;\r
+       scan = last->next;\r
+\r
+       if(baseptr == gvar->mm.mmrover->useptr) // removed the last allocated block\r
+               gvar->mm.mmrover = gvar->mm.mmhead;\r
+\r
+       while(scan->useptr != baseptr && scan)\r
+       {\r
+               last = scan;\r
+               scan = scan->next;\r
+       }\r
+\r
+       if(!scan)\r
+       {\r
+               printf("MM_FreePtr: Block not found!\n");\r
+               return;\r
+       }\r
+\r
+       last->next = scan->next;\r
+\r
+       FREEBLOCK(scan);\r
+}\r
+//==========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= MM_SetPurge\r
+=\r
+= Sets the purge level for a block (locked blocks cannot be made purgable)\r
+=\r
+=====================\r
+*/\r
+\r
+void MM_SetPurge(memptr *baseptr, int purge, global_game_variables_t *gvar)\r
+{\r
+        mmblocktype huge *start;\r
+       //mmblocktype far *start;\r
+\r
+       start = gvar->mm.mmrover;\r
+\r
+       do\r
+       {\r
+               if(gvar->mm.mmrover->useptr == baseptr)\r
+                       break;\r
+\r
+               gvar->mm.mmrover = gvar->mm.mmrover->next;\r
+\r
+               if(!gvar->mm.mmrover)\r
+                       gvar->mm.mmrover = gvar->mm.mmhead;\r
+               else if(gvar->mm.mmrover == start)\r
+               {\r
+#ifdef __DEBUG_PM__\r
+                       printf("\n\nstart->useptr       gvar->mm.mmhead->useptr\n");\r
+                       printf("        %Fp     %Fp\n", start->useptr, gvar->mm.mmhead->useptr);\r
+                       printf("&       %Fp     %Fp\n", &(start->useptr), &(gvar->mm.mmhead->useptr));\r
+                       printf("baseptr                 gvar->mm.mmrover->useptr\n");\r
+                       printf("        %Fp     %Fp\n", baseptr, gvar->mm.mmrover->useptr);\r
+                       printf("&       %Fp     %Fp\n", &(baseptr), &(gvar->mm.mmrover->useptr));\r
+                       printf("*       %Fp     %Fp\n", *(baseptr), *(gvar->mm.mmrover->useptr));\r
+                       printf("start                   gvar->mm.mmrover gvar->mm.mmrover->next\n");\r
+                       printf("        %Fp     %Fp     %Fp\n", start, gvar->mm.mmrover, gvar->mm.mmrover->next);\r
+                       printf("&       %Fp     %Fp     %Fp\n", &start, &gvar->mm.mmrover, gvar->mm.mmrover->next);\r
+                       getch();\r
+                       MM_ShowMemory(gvar);\r
+                       MM_DumpData(gvar);\r
+                       MM_Report_(gvar);\r
+                       getch();\r
+#endif\r
+                       Quit("MM_SetPurge: Block not found!");\r
+                       return;\r
+               }\r
+\r
+       } while(1);\r
+\r
+       gvar->mm.mmrover->attributes &= ~PURGEBITS;\r
+       gvar->mm.mmrover->attributes |= purge;\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= MM_SetLock\r
+=\r
+= Locks / unlocks the block\r
+=\r
+=====================\r
+*/\r
+\r
+void MM_SetLock(memptr *baseptr, boolean locked, global_game_variables_t *gvar)\r
+{\r
+       //huge mmblocktype huge *start;\r
+       mmblocktype far *start;\r
+\r
+       start = gvar->mm.mmrover;\r
+\r
+       do\r
+       {\r
+               if(gvar->mm.mmrover->useptr == baseptr)\r
+                       break;\r
+\r
+               gvar->mm.mmrover = gvar->mm.mmrover->next;\r
+\r
+               if(!gvar->mm.mmrover)\r
+                       gvar->mm.mmrover = gvar->mm.mmhead;\r
+               else if(gvar->mm.mmrover == start)\r
+               {\r
+                       Quit("MM_SetLock: Block not found!");\r
+                       //return;\r
+               }\r
+\r
+       } while(1);\r
+\r
+       gvar->mm.mmrover->attributes &= ~LOCKBIT;\r
+       gvar->mm.mmrover->attributes |= locked*LOCKBIT;\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= MM_SortMem\r
+=\r
+= Throws out all purgable stuff and compresses movable blocks\r
+=\r
+=====================\r
+*/\r
+\r
+void MM_SortMem(global_game_variables_t *gvar)\r
+{\r
+       //huge mmblocktype huge *scan,huge *last,huge *next;\r
+       mmblocktype far *scan,far *last,far *next;\r
+       unsigned        start,length,source,dest,oldborder;\r
+       int                     playing;\r
+\r
+       //\r
+       // lock down a currently playing sound\r
+       //\r
+/*++++ playing = SD_SoundPlaying ();\r
+       if(playing)\r
+       {\r
+               switch (SoundMode)\r
+               {\r
+               case sdm_PC:\r
+                       playing += STARTPCSOUNDS;\r
+                       break;\r
+               case sdm_AdLib:\r
+                       playing += STARTADLIBSOUNDS;\r
+                       break;\r
+               }\r
+               MM_SetLock(&(memptr)audiosegs[playing],true);\r
+       }\r
+\r
+\r
+       SD_StopSound();*/\r
+//     oldborder = bordercolor;\r
+//     VW_ColorBorder (15);\r
+\r
+       if(beforesort)\r
+               beforesort();\r
+\r
+       scan = gvar->mm.mmhead;\r
+\r
+       last = NULL;            // shut up compiler warning\r
+\r
+       while(scan)\r
+       {\r
+               if(scan->attributes & LOCKBIT)\r
+               {\r
+               //\r
+               // block is locked, so try to pile later blocks right after it\r
+               //\r
+                       start = scan->start + scan->length;\r
+               }\r
+               else\r
+               {\r
+                       if(scan->attributes & PURGEBITS)\r
+                       {\r
+                       //\r
+                       // throw out the purgable block\r
+                       //\r
+                               next = scan->next;\r
+                               FREEBLOCK(scan);\r
+                               //MM_FreeBlock(scan, gvar);\r
+                               last->next = next;\r
+                               scan = next;\r
+                               continue;\r
+                       }\r
+                       else\r
+                       {\r
+                       //\r
+                       // push the non purgable block on top of the last moved block\r
+                       //\r
+                               if(scan->start != start)\r
+                               {\r
+                                       length = scan->length;\r
+                                       source = scan->start;\r
+                                       dest = start;\r
+                                       while(length > 0xf00)\r
+                                       {\r
+                                               movedata(source,0,dest,0,0xf00*16);\r
+                                               length -= 0xf00;\r
+                                               source += 0xf00;\r
+                                               dest += 0xf00;\r
+                                       }\r
+                                       movedata(source,0,dest,0,length*16);\r
+\r
+                                       scan->start = start;\r
+                                       *(unsigned *)scan->useptr = start;\r
+                               }\r
+                               start = scan->start + scan->length;\r
+                       }\r
+               }\r
+\r
+               last = scan;\r
+               scan = scan->next;              // go to next block\r
+       }\r
+\r
+       gvar->mm.mmrover = gvar->mm.mmhead;\r
+\r
+       if(aftersort)\r
+               aftersort();\r
+\r
+//     VW_ColorBorder (oldborder);\r
+\r
+/*++++ if(playing)\r
+               MM_SetLock(&(memptr)audiosegs[playing],false);*/\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= MM_ShowMemory\r
+=\r
+=====================\r
+*/\r
+\r
+void MM_ShowMemory(global_game_variables_t *gvar)\r
+{\r
+       //huge mmblocktype huge *scan;\r
+       mmblocktype far *scan;\r
+       word temp;\r
+       sdword  end,owner;\r
+       //word chx,chy;\r
+       word w;\r
+       //dword wwww;\r
+       byte    scratch[160],scratch0[4096],scratch1[160],str[16];\r
+       //byte d = '#';\r
+//**** VW_SetDefaultColors();\r
+//**** VW_SetLineWidth(40);\r
+//++++mh       temp = bufferofs;\r
+//++++mh       bufferofs = 0;\r
+//**** VW_SetScreen (0,0);\r
+       scan = gvar->mm.mmhead;\r
+       end = -1;\r
+\r
+       CA_OpenDebug (gvar);\r
+       w=0;\r
+       while(scan)\r
+       {\r
+               strcpy(scratch, AARESET);\r
+               if(scan->attributes & PURGEBITS)\r
+                       strcpy(scratch0, AAMAGENTA);            // dark purple = purgable\r
+               else\r
+                       strcpy(scratch0, AABLUE);               // medium blue = non purgable\r
+               if(scan->attributes & LOCKBIT)\r
+                       strcpy(scratch0, AARED);                // red = locked\r
+               if(scan->start<=end)\r
+               {\r
+                       printf("\nend==%d\n\n", end);\r
+                       strcat(scratch, "MM_ShowMemory: Memory block order currupted!\n");\r
+                       strcat(scratch, "End's Size: ");\r
+                       ultoa (end,str,10);\r
+                       strcat (scratch,str);\r
+                       strcat(scratch, "\nscan->start's Size: ");\r
+                       ultoa (scan->start,str,10);\r
+                       strcat (scratch,str);\r
+                       write(gvar->handle.debughandle,scratch,strlen(scratch));\r
+                       //modexprint(&page, chx, chy, 1, 0, 24, "\nMM_ShowMemory: Memory block order currupted!\n");\r
+                       break;\r
+               }\r
+               end = scan->start+(scan->length)-1;\r
+//++++         chy = scan->start/320;\r
+//++++         chx = scan->start%320;\r
+                               //modexhlin(page, scan->start, (unsigned)end, chy, color);\r
+                               //for(chx=scan->start;chx+4>=(word)end;chx+=4)\r
+                               //{\r
+//++++                                 modexClearRegion(page, chx, chy, 4, 4, color);\r
+                               //}\r
+//++++         VW_Hlin(scan->start,(unsigned)end,0,color);\r
+               for(w=(scan->start)/80;w<=end/80;w++)\r
+               {\r
+                       //printf("+     %u      %lu\n", w, scan->length);\r
+                       strcat(scratch0, "+");\r
+               }\r
+               //++==++==optional strcat(scratch0, AARESET); strcat(scratch0, AAGREY); strcat(scratch0,"_");\r
+//++++         VW_Plot(scan->start,0,15);\r
+//++++                         modexClearRegion(page, chx, chy, 4, 4, 15);\r
+//++++                 VW_Hlin(end+1,scan->next->start,0,0);   // black = free\r
+\r
+               //wwww=(dword)(scan->next->start)-(dword)scan->start;\r
+               //wwww=(dword)scan->start+(dword)(scan->next->start);\r
+               if (scan->next && scan->next->start >= end+1)\r
+               {\r
+                       strcat(scratch0, AARESET);\r
+                       //++==++==optional strcat(scratch0, "\n");\r
+                       strcat(scratch0,AAGREEN);\r
+                       for(w=(end+1)/80;w<=((scan->next->start-scan->start)/80);w++)\r
+                       //for(w=(wwww)/80;w<=((end+1)/80);w++)\r
+                       //for(w=(end+1)/80;w<=((wwww)/80);w++)\r
+                       {\r
+                               //printf("0     %x      %u      %lu\n", scan->next->start, w, scan->length);\r
+                               strcat(scratch0,"0");\r
+                       }\r
+                       //printf("==================\n");\r
+                       //printf("w=%u  wwww=%lu        start=%04x      next=%04x       end=%lu\n", w/80, wwww/80, scan->start, (scan->next->start), end+1);\r
+                       //printf("==================\n");\r
+                       strcat(scratch0, "\n");\r
+                       //getch();\r
+               }/*else {//if(scan->next->start <= scan->start){\r
+                       scan->next->start=scan->start+0x1000;\r
+                       wwww=(dword)(scan->next->start)-(dword)scan->start;\r
+                       strcat(scratch0, AARESET);\r
+                       strcat(scratch0, "\n");\r
+                       strcat(scratch0,AAGREEN);\r
+                       for(w=(end+1);w<=(0x1000/80);w++)\r
+                       {\r
+                               //printf("0     %x      %x      %u\n", scan->start, w);\r
+                               strcat(scratch0,"0");\r
+                       }\r
+                       printf("================\n");\r
+                       printf("w=%x    start=%x        next=%x end=%u  %lu\n", w, scan->start, (scan->next->start), end+1, wwww);\r
+                       printf("================\n");\r
+                       getch();\r
+               }*/\r
+               strcat(scratch0, AARESET);\r
+               //strcat(scratch0,"\n");\r
+                       //for(chx=scan->next->start;chx+4>=(word)end+1;chx+=4)\r
+                       //{\r
+//                             chx+=scan->next->start;\r
+//                             modexClearRegion(page, chx, chy, 4, 4, 2);\r
+                       //}\r
+                                       //modexhlin(page, end+1,scan->next->start, chy, 0);\r
+/*             y = scan->start/320;\r
+               x = scan->start%320;\r
+               VW_Hlin(x,x+end,y,color);\r
+               VW_Plot(x,y,15);*/\r
+//++++                 VW_Hlin(x+end+1,x+(scan->next->start-scan->start),y,0); // black = free\r
+               strcat(scratch,"Seg:");\r
+               ultoa (scan->start,str,16);\r
+               strcat (scratch,str);\r
+               strcat (scratch,"\tSize:");\r
+               ultoa ((unsigned)scan->length,str,10);\r
+               strcat (scratch,str);\r
+               strcat (scratch,"\tOwner:0x");\r
+               owner = (unsigned)scan->useptr;\r
+               ultoa (owner,str,16);\r
+               strcat (scratch,str);\r
+               strcat (scratch,"\n");\r
+               write(gvar->handle.debughandle,scratch,strlen(scratch));\r
+               write(gvar->handle.debughandle,scratch0,strlen(scratch0));\r
+//modexprint(page, chx, chy, 1, 0, 24, &scratch);\r
+//++++chy+=4;\r
+//fprintf(stdout, "%s", scratch);\r
+\r
+               scan = scan->next;\r
+       }\r
+       /*strcpy(scratch1, AARESET);\r
+       strcat(scratch1, "========================================\n");\r
+       strcat(scratch1, "near=  ");\r
+       ultoa (*(gvar->mm.nearheap),str,10);\r
+       strcat (scratch1,str);\r
+       strcat(scratch1, "      far= ");\r
+       ultoa (*(gvar->mm.farheap),str,10);\r
+       strcat (scratch1,str);\r
+       strcat(scratch1, "\n");\r
+       //strcat(scratch1, "&near=      %Fp ", &(gvar->mm.nearheap));\r
+       //strcat(scratch1, "&far=       %Fp", &(gvar->mm.farheap));\r
+       //strcat(scratch1, "\n");\r
+       strcat(scratch1, "========================================\n");\r
+       write(gvar->handle.debughandle,scratch1,strlen(scratch1));*/\r
+\r
+\r
+       CA_CloseDebug (gvar);\r
+\r
+//++++mh       IN_Ack();\r
+//**** VW_SetLineWidth(64);\r
+//++++mh       bufferofs = temp;\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= MM_DumpData\r
+=\r
+=====================\r
+*/\r
+\r
+void MM_DumpData(global_game_variables_t *gvar)\r
+{\r
+       //huge mmblocktype huge *scan,huge *best;\r
+       mmblocktype far *scan,far *best;\r
+       long    lowest,oldlowest;\r
+       word    owner;\r
+       byte    lock,purge;\r
+       FILE    *dumpfile;\r
+\r
+       free(gvar->mm.nearheap);\r
+#ifdef __BORLANDC__\r
+               dumpfile = fopen ("mmdump.16b","w");\r
+#endif\r
+#ifdef __WATCOMC__\r
+               dumpfile = fopen ("mmdump.16w","w");\r
+#endif\r
+       if (!dumpfile){\r
+               printf("MM_DumpData: Couldn't open MMDUMP.16!\n");\r
+               return;\r
+       }\r
+\r
+       lowest = -1;\r
+       do\r
+       {\r
+               oldlowest = lowest;\r
+               lowest = 0xffff;\r
+\r
+               scan = gvar->mm.mmhead;\r
+               while (scan)\r
+               {\r
+                       owner = (unsigned)scan->useptr;\r
+\r
+                       if (owner && owner<lowest && owner > oldlowest)\r
+                       {\r
+                               best = scan;\r
+                               lowest = owner;\r
+                       }\r
+\r
+                       scan = scan->next;\r
+               }\r
+\r
+               if (lowest != 0xffff)\r
+               {\r
+                       if (best->attributes & PURGEBITS)\r
+                               purge = 'P';\r
+                       else\r
+                               purge = '-';\r
+                       if (best->attributes & LOCKBIT)\r
+                               lock = 'L';\r
+                       else\r
+                               lock = '-';\r
+                       fprintf (dumpfile,"0x%p (%c%c) = %u\n"\r
+                       ,(unsigned)lowest,lock,purge,best->length);\r
+               }\r
+\r
+       } while (lowest != 0xffff);\r
+\r
+       fclose(dumpfile);\r
+       printf("MMDUMP.16 created.\n");\r
+}\r
+\r
+//==========================================================================\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= MM_UnusedMemory\r
+=\r
+= Returns the total free space without purging\r
+=\r
+======================\r
+*/\r
+\r
+dword MM_UnusedMemory(global_game_variables_t *gvar)\r
+{\r
+       dword free;\r
+       //huge mmblocktype huge *scan;\r
+       mmblocktype far *scan;\r
+\r
+       free = 0;\r
+       scan = gvar->mm.mmhead;\r
+\r
+       while(scan->next)\r
+       {\r
+               free += scan->next->start - (scan->start + scan->length);\r
+               scan = scan->next;\r
+       }\r
+\r
+       return free*16lu;\r
+//     return free;\r
+}\r
+\r
+//==========================================================================\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= MM_TotalFree\r
+=\r
+= Returns the total free space with purging\r
+=\r
+======================\r
+*/\r
+\r
+dword MM_TotalFree(global_game_variables_t *gvar)\r
+{\r
+       dword free;\r
+       //huge mmblocktype huge *scan;\r
+       mmblocktype far *scan;\r
+\r
+       free = 0;\r
+       scan = gvar->mm.mmhead;\r
+\r
+       while(scan->next)\r
+       {\r
+               if((scan->attributes&PURGEBITS) && !(scan->attributes&LOCKBIT))\r
+                       free += scan->length;\r
+               free += scan->next->start - (scan->start + scan->length);\r
+               scan = scan->next;\r
+       }\r
+\r
+       return free*16lu;\r
+//     return free;\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= MM_Report\r
+=\r
+=====================\r
+*/\r
+\r
+void MM_Report_(global_game_variables_t *gvar)\r
+{\r
+       printf("========================================\n");\r
+       printf("                MM_Report\n");\r
+       printf("========================================\n");\r
+       if(MML_CheckForEMS())\r
+       {\r
+               printf("        LIMEMS\n");\r
+               printf("                EMM v%x.%x available\n", gvar->pm.emm.EMSVer>>4,gvar->pm.emm.EMSVer&0x0F);\r
+               printf("                totalEMSpages:  %u      ", gvar->pm.emm.totalEMSpages); printf("freeEMSpages:   %u\n", gvar->pm.emm.freeEMSpages);\r
+               printf("                EMSPageFrame:   %x\n", gvar->pm.emm.EMSPageFrame);\r
+       }\r
+       if(MML_CheckForXMS(gvar))\r
+       {\r
+               printf("        XMS\n");\r
+               printf("                XMSaddr:        %X\n", *XMSaddr);\r
+       }\r
+       printf("near:   %lu     ", gvar->mmi.nearheap); printf("far:    %lu\n", gvar->mmi.farheap); if(MML_CheckForEMS())\r
+       printf("EMSmem: %lu     ", gvar->mmi.EMSmem); if(MML_CheckForXMS(gvar)) printf("XMSmem: %lu", gvar->mmi.XMSmem); printf("\n");\r
+       //printf("mainmem:      %lu\n", gvar->mmi.mainmem);\r
+       printf("Total convmem:  %lu     ", gvar->mmi.mainmem); printf("TotalFree:       %lu     ", MM_TotalFree(gvar)); printf("TotalUsed:      %lu\n", gvar->mmi.mainmem+gvar->mmi.EMSmem+gvar->mmi.XMSmem+gvar->mmi.XMSmem);\r
+       printf("                        UnusedMemory:   %lu\n", MM_UnusedMemory(gvar));\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= MM_EMSerr\r
+=\r
+=====================\r
+*/\r
+\r
+void MM_EMSerr(byte *stri, byte err)\r
+{\r
+       //Returns a text string describing the error code in EMS.Error.\r
+       switch(err)\r
+       {\r
+               case 0x0:\r
+                       strcat(stri, "successful");\r
+               break;\r
+               case 0x80:\r
+                       strcat(stri, "internal error");\r
+               break;\r
+               case 0x81:\r
+                       strcat(stri, "hardware malfunction");\r
+               break;\r
+               case 0x82:\r
+                       strcat(stri, "busy .. retry later");\r
+               break;\r
+               case 0x83:\r
+                       strcat(stri, "invalid handle");\r
+               break;\r
+               case 0x84:\r
+                       strcat(stri, "undefined function requested by application");\r
+               break;\r
+               case 0x85:\r
+                       strcat(stri, "no more handles available");\r
+               break;\r
+               case 0x86:\r
+                       strcat(stri, "error in save or restore of mapping context");\r
+               break;\r
+               case 0x87:\r
+                       strcat(stri, "insufficient memory pages in system");\r
+               break;\r
+               case 0x88:\r
+                       strcat(stri, "insufficient memory pages available");\r
+               break;\r
+               case 0x89:\r
+                       strcat(stri, "zero pages requested");\r
+               break;\r
+               case 0x8A:\r
+                       strcat(stri, "invalid logical page number encountered");\r
+               break;\r
+               case 0x8B:\r
+                       strcat(stri, "invalid physical page number encountered");\r
+               break;\r
+               case 0x8C:\r
+                       strcat(stri, "page-mapping hardware state save area is full");\r
+               break;\r
+               case 0x8D:\r
+                       strcat(stri, "save of mapping context failed");\r
+               break;\r
+               case 0x8E:\r
+                       strcat(stri, "restore of mapping context failed");\r
+               break;\r
+               case 0x8F:\r
+                       strcat(stri, "undefined subfunction");\r
+               break;\r
+               case 0x90:\r
+                       strcat(stri, "undefined attribute type");\r
+               break;\r
+               case 0x91:\r
+                       strcat(stri, "feature not supported");\r
+               break;\r
+               case 0x92:\r
+                       strcat(stri, "successful, but a portion of the source region has been overwritten");\r
+               break;\r
+               case 0x93:\r
+                       strcat(stri, "length of source or destination region exceeds length of region allocated to either source or destination handle");\r
+               break;\r
+               case 0x94:\r
+                       strcat(stri, "conventional and expanded memory regions overlap");\r
+               break;\r
+               case 0x95:\r
+                       strcat(stri, "offset within logical page exceeds size of logical page");\r
+               break;\r
+               case 0x96:\r
+                       strcat(stri, "region length exceeds 1 MB");\r
+               break;\r
+               case 0x97:\r
+                       strcat(stri, "source and destination EMS regions have same handle and overlap");\r
+               break;\r
+               case 0x98:\r
+                       strcat(stri, "memory source or destination type undefined");\r
+               break;\r
+               case 0x9A:\r
+                       strcat(stri, "specified alternate map register or DMA register set not supported");\r
+               break;\r
+               case 0x9B:\r
+                       strcat(stri, "all alternate map register or DMA register sets currently allocated");\r
+               break;\r
+               case 0x9C:\r
+                       strcat(stri, "alternate map register or DMA register sets not supported");\r
+               break;\r
+               case 0x9D:\r
+                       strcat(stri, "undefined or unallocated alternate map register or DMA register set");\r
+               break;\r
+               case 0x9E:\r
+                       strcat(stri, "dedicated DMA channels not supported");\r
+               break;\r
+               case 0x9F:\r
+                       strcat(stri, "specified dedicated DMA channel not supported");\r
+               break;\r
+               case 0xA0:\r
+                       strcat(stri, "no such handle name");\r
+               break;\r
+               case 0xA1:\r
+                       strcat(stri, "a handle found had no name, or duplicate handle name");\r
+               break;\r
+               case 0xA2:\r
+                       strcat(stri, "attempted to wrap around 1M conventional address space");\r
+               break;\r
+               case 0xA3:\r
+                       strcat(stri, "source array corrupted");\r
+               break;\r
+               case 0xA4:\r
+                       strcat(stri, "operating system denied access");\r
+               break;\r
+               default:\r
+                       strcat(stri, "undefined error");\r
+       }\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= MM_BombOnError\r
+=\r
+=====================\r
+*/\r
+\r
+void MM_BombOnError(boolean bomb, global_game_variables_t *gvar)\r
+{\r
+       gvar->mm.bombonerror = bomb;\r
+}\r
+\r
+/*void MM_GetNewBlock(global_game_variables_t *gvar)\r
+{\r
+       if(!gvar->mm.mmfree)\r
+               MML_ClearBlock(gvar);\r
+       gvar->mm.mmnew=gvar->mm.mmfree;\r
+       gvar->mm.mmfree=gvar->mm.mmfree->next;\r
+       if(!(gvar->mm.mmnew=gvar->mm.mmfree))\r
+       {\r
+               printf("MM_GETNEWBLOCK: No free blocks!\n");\r
+               return;\r
+       }\r
+       gvar->mm.mmfree=gvar->mm.mmfree->next;\r
+}\r
+\r
+void MM_FreeBlock(mmblocktype *x, global_game_variables_t *gvar)\r
+{\r
+       x->useptr=NULL;\r
+       x->next=gvar->mm.mmfree;\r
+       gvar->mm.mmfree=x;\r
+}*/\r
+\r
+void   XMS_CALL(byte v, global_game_variables_t *gvar)\r
+{\r
+       XMSD;\r
+       //XMSDriver=gvar->pm.xmm.XMSDriver;\r
+       __asm {\r
+               mov v,ah\r
+               call [WORD PTR XMSDriver]\r
+       }\r
+}\r
+\r
+/*void MM_seguin(void)\r
+{\r
+       __asm {\r
+               push    ds\r
+               mov     ax,ds\r
+               inc             ax\r
+               mov     ds,ax\r
+       }\r
+}\r
+\r
+void MM_segude(void)\r
+{\r
+       __asm {\r
+               pop ds\r
+       }\r
+}*/\r
+\r
+/*\r
+pull data from far and put it into ds var\r
+mov ax,es:si\r
+mov x,ax\r
+*/\r
+/*\r
+ss stack segment\r
+sp top of stack\r
+bp bottem of stack\r
+*/\r
index 206a3c8b358d6b8f3b85930d1d14a0ff64f88bdc..d351abfa8f868a004be425755ce6f2f37a5910a5 100755 (executable)
-/* Catacomb Apocalypse Source Code
- * Copyright (C) 1993-2014 Flat Rock Software
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-// ID_MM.H
-
-#ifndef __16_EXMM__
-#define __16_EXMM__
-
-#include <string.h>
-#include <malloc.h>
-#include "src/lib/16_head.h"
-#include "src/lib/16_hc.h"
-#include "src/lib/16_lib.h"
-//++++mh       #include "src/lib/16_in.h"
-
-
-#ifdef __DEBUG__               // 1 == Debug/Dev  ;  0 == Production/final
-#define OUT_OF_MEM_MSG "MM_GetPtr: Out of memory!\nYou were short :%lu bytes\n"
-#else
-#define OUT_OF_MEM_MSG "\npee\n"
-#endif
-
-//#define GETNEWBLOCK {if(!(mmnew=mmfree))Quit("MM_GETNEWBLOCK: No free blocks!") ;mmfree=mmfree->next;}
-#define GETNEWBLOCK {if(!gvar->mm.mmfree)MML_ClearBlock(gvar);gvar->mm.mmnew=gvar->mm.mmfree;gvar->mm.mmfree=gvar->mm.mmfree->next;}
-
-#define FREEBLOCK(x) {*x->useptr=NULL;x->next=gvar->mm.mmfree;gvar->mm.mmfree=x;}
-
-#define SAVENEARHEAP   0x200           // space to leave in data segment
-#define SAVEFARHEAP    0//x400                 // space to leave in far heap
-
-#define        BUFFERSIZE              0x1000          // miscelanious, allways available buffer
-
-//moved to typdefst
-//#define MAXBLOCKS            1024
-
-
-
-//--------
-
-#define        EMS_INT                 0x67
-
-#define        EMS_STATUS              0x40
-#define        EMS_GETFRAME    0x41
-#define        EMS_GETPAGES    0x42
-#define        EMS_ALLOCPAGES  0x43
-#define        EMS_MAPPAGE             0x44
-#define        EMS_MAPXPAGE            0x50
-#define        EMS_FREEPAGES   0x45
-#define        EMS_VERSION             0x46
-
-//--------
-
-#define        XMS_INT                 0x2f
-#define        XMSD                    dword XMSDriver=gvar->pm.xmm.XMSDriver;
-inline void    XMS_CALL(byte v, global_game_variables_t *gvar)
-{
-       XMSD;
-       XMSDriver=gvar->pm.xmm.XMSDriver;
-       __asm {
-               mov v,ah
-               call [WORD PTR XMSDriver]
-       }
-}
-
-#define        XMS_VERSION             0x00
-
-#define        XMS_ALLOCHMA    0x01
-#define        XMS_FREEHMA             0x02
-
-#define        XMS_GENABLEA20  0x03
-#define        XMS_GDISABLEA20 0x04
-#define        XMS_LENABLEA20  0x05
-#define        XMS_LDISABLEA20 0x06
-#define        XMS_QUERYA20    0x07
-
-#define        XMS_QUERYFREE   0x08
-#define        XMS_ALLOC               0x09
-#define        XMS_FREE                0x0A
-#define        XMS_MOVE                0x0B
-#define        XMS_LOCK                0x0C
-#define        XMS_UNLOCK              0x0D
-#define        XMS_GETINFO             0x0E
-#define        XMS_RESIZE              0x0F
-
-#define        XMS_ALLOCUMB    0x10
-#define        XMS_FREEUMB             0x11
-
-//==========================================================================
-
-//moved to typdefst
-/*typedef struct
-{
-       dword   nearheap,farheap,EMSmem,XMSmem,mainmem;
-} mminfotype;*/
-
-//==========================================================================
-
-extern void            (* beforesort) (void);
-extern void            (* aftersort) (void);
-extern void            (* XMSaddr) (void);             // far pointer to XMS driver
-
-//==========================================================================
-
-/*
-=============================================================================
-
-                                                       LOCAL INFO
-
-=============================================================================
-*/
-
-#define LOCKBIT                0x80    // if set in attributes, block cannot be moved
-#define PURGEBITS      3               // 0-3 level, 0= unpurgable, 3= purge first
-#define PURGEMASK      0xfffc
-#define BASEATTRIBUTES 0       // unlocked, non purgable
-
-//moved to typedefst
-//#define MAXUMBS              12
-#define MAPPAGES               4//gvar->mm.EMSpagesmapped
-
-//moved to typdefst
-/*typedef struct mmblockstruct
-{
-       word    start,length;
-       //word  start;  dword length;
-       word    blob;   //for data larger than 64k
-       unsigned        attributes;
-       memptr          *useptr;        // pointer to the segment start
-       //huge struct mmblockstruct huge *next;
-       struct mmblockstruct far *next;
-} mmblocktype;
-
-
-typedef struct
-{
-       memptr bufferseg;
-       boolean         mmstarted, bombonerror, mmerror;
-       //huge void huge        *farheap;
-       void far        *farheap;
-#ifdef __BORLANDC__
-       void    *nearheap;
-#endif
-#ifdef __WATCOMC__
-       void __near     *nearheap;
-#endif
-       //byte          EMS_status;
-       unsigned        totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle;
-       unsigned int EMSVer;
-       word numUMBs,UMBbase[MAXUMBS];
-       //dword numUMBs,UMBbase[MAXUMBS];
-       //huge mmblocktype      huge mmblocks[MAXBLOCKS],huge *mmhead,huge *mmfree,huge *mmrover,huge *mmnew;
-       mmblocktype     far mmblocks[MAXBLOCKS],far *mmhead,far *mmfree,far *mmrover,far *mmnew;
-} mminfo_t;*/
-
-/*
-=============================================================================
-
-                                                GLOBAL VARIABLES
-
-=============================================================================
-*/
-
-
-/*
-=============================================================================
-
-                                                LOCAL VARIABLES
-
-=============================================================================
-*/
-
-//==========================================================================
-
-boolean MML_CheckForEMS(void);
-//byte MML_SetupEMS(mminfo_t *mm);
-//void MML_ShutdownEMS(mminfo_t *mm);
-byte MM_MapEMS(global_game_variables_t *gvar);
-byte MM_MapXEMS(global_game_variables_t *gvar);
-//boolean MML_CheckForXMS(mminfo_t *mm);
-//void MML_SetupXMS(mminfo_t *mm, mminfotype *mmi);
-//void MML_ShutdownXMS(mminfo_t *mm);
-void MML_UseSpace(word segstart, dword seglength, global_game_variables_t *gvar);
-void MML_ClearBlock(global_game_variables_t *gvar);
-
-void MM_Startup(global_game_variables_t *gvar);
-void MM_Shutdown(global_game_variables_t *gvar);
-
-void MM_GetPtr(memptr *baseptr,dword size, global_game_variables_t *gvar);
-void MM_FreePtr(memptr *baseptr, global_game_variables_t *gvar);
-void MM_SetPurge(memptr *baseptr, int purge, global_game_variables_t *gvar);
-void MM_SetLock(memptr *baseptr, boolean locked, global_game_variables_t *gvar);
-void MM_SortMem(global_game_variables_t *gvar);
-void MM_ShowMemory(global_game_variables_t *gvar);
-void MM_DumpData(global_game_variables_t *gvar);
-dword MM_UnusedMemory(global_game_variables_t *gvar);
-dword MM_TotalFree(global_game_variables_t *gvar);
-void MM_Report_(global_game_variables_t *gvar);
-/*static */void MM_EMSerr(byte *stri, byte err);
-void MM_BombOnError(boolean bomb, global_game_variables_t *gvar);
-//void MM_GetNewBlock(mminfo_t *mm);
-//void MM_FreeBlock(mmblocktype *x, mminfo_t *mm);
-
-//==========================================================================
-
-#endif
+/* Catacomb Apocalypse Source Code\r
+ * Copyright (C) 1993-2014 Flat Rock Software\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License along\r
+ * with this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+ */\r
+\r
+// ID_MM.H\r
+\r
+#ifndef __16_EXMM__\r
+#define __16_EXMM__\r
+\r
+#include <string.h>\r
+#include <malloc.h>\r
+#include "src/lib/16_head.h"\r
+#include "src/lib/16_hc.h"\r
+#include "src/lib/16_lib.h"\r
+//++++mh       #include "src/lib/16_in.h"\r
+\r
+\r
+#ifdef __DEBUG__               // 1 == Debug/Dev  ;  0 == Production/final\r
+#define OUT_OF_MEM_MSG "MM_GetPtr: Out of memory!\nYou were short :%lu bytes\n"\r
+#else\r
+#define OUT_OF_MEM_MSG "\npee\n"\r
+#endif\r
+\r
+//#define GETNEWBLOCK {if(!(mmnew=mmfree))Quit("MM_GETNEWBLOCK: No free blocks!") ;mmfree=mmfree->next;}\r
+#define GETNEWBLOCK {if(!gvar->mm.mmfree)MML_ClearBlock(gvar);gvar->mm.mmnew=gvar->mm.mmfree;gvar->mm.mmfree=gvar->mm.mmfree->next;}\r
+\r
+#define FREEBLOCK(x) {*x->useptr=NULL;x->next=gvar->mm.mmfree;gvar->mm.mmfree=x;}\r
+\r
+#define SAVENEARHEAP   0x200           // space to leave in data segment\r
+#define SAVEFARHEAP    0//x400                 // space to leave in far heap\r
+\r
+#define        BUFFERSIZE              0x1000          // miscelanious, allways available buffer\r
+\r
+//moved to typdefst\r
+//#define MAXBLOCKS            1024\r
+\r
+\r
+\r
+//--------\r
+\r
+#define        EMS_INT                 0x67\r
+\r
+#define        EMS_STATUS              0x40\r
+#define        EMS_GETFRAME    0x41\r
+#define        EMS_GETPAGES    0x42\r
+#define        EMS_ALLOCPAGES  0x43\r
+#define        EMS_MAPPAGE             0x44\r
+#define        EMS_MAPXPAGE            0x50\r
+#define        EMS_FREEPAGES   0x45\r
+#define        EMS_VERSION             0x46\r
+\r
+//--------\r
+\r
+#define        XMS_INT                 0x2f\r
+#define        XMSD                    dword XMSDriver=gvar->pm.xmm.XMSDriver;\r
+\r
+#define        XMS_VERSION             0x00\r
+\r
+#define        XMS_ALLOCHMA    0x01\r
+#define        XMS_FREEHMA             0x02\r
+\r
+#define        XMS_GENABLEA20  0x03\r
+#define        XMS_GDISABLEA20 0x04\r
+#define        XMS_LENABLEA20  0x05\r
+#define        XMS_LDISABLEA20 0x06\r
+#define        XMS_QUERYA20    0x07\r
+\r
+#define        XMS_QUERYFREE   0x08\r
+#define        XMS_ALLOC               0x09\r
+#define        XMS_FREE                0x0A\r
+#define        XMS_MOVE                0x0B\r
+#define        XMS_LOCK                0x0C\r
+#define        XMS_UNLOCK              0x0D\r
+#define        XMS_GETINFO             0x0E\r
+#define        XMS_RESIZE              0x0F\r
+\r
+#define        XMS_ALLOCUMB    0x10\r
+#define        XMS_FREEUMB             0x11\r
+\r
+//==========================================================================\r
+\r
+//moved to typdefst\r
+/*typedef struct\r
+{\r
+       dword   nearheap,farheap,EMSmem,XMSmem,mainmem;\r
+} mminfotype;*/\r
+\r
+//==========================================================================\r
+\r
+extern void            (* beforesort) (void);\r
+extern void            (* aftersort) (void);\r
+extern void            (* XMSaddr) (void);             // far pointer to XMS driver\r
+\r
+//==========================================================================\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                       LOCAL INFO\r
+\r
+=============================================================================\r
+*/\r
+\r
+#define LOCKBIT                0x80    // if set in attributes, block cannot be moved\r
+#define PURGEBITS      3               // 0-3 level, 0= unpurgable, 3= purge first\r
+#define PURGEMASK      0xfffc\r
+#define BASEATTRIBUTES 0       // unlocked, non purgable\r
+\r
+//moved to typedefst\r
+//#define MAXUMBS              12\r
+#define MAPPAGES               4//gvar->mm.EMSpagesmapped\r
+\r
+//moved to typdefst\r
+/*typedef struct mmblockstruct\r
+{\r
+       word    start,length;\r
+       //word  start;  dword length;\r
+       word    blob;   //for data larger than 64k\r
+       unsigned        attributes;\r
+       memptr          *useptr;        // pointer to the segment start\r
+       //huge struct mmblockstruct huge *next;\r
+       struct mmblockstruct far *next;\r
+} mmblocktype;\r
+\r
+\r
+typedef struct\r
+{\r
+       memptr bufferseg;\r
+       boolean         mmstarted, bombonerror, mmerror;\r
+       //huge void huge        *farheap;\r
+       void far        *farheap;\r
+#ifdef __BORLANDC__\r
+       void    *nearheap;\r
+#endif\r
+#ifdef __WATCOMC__\r
+       void __near     *nearheap;\r
+#endif\r
+       //byte          EMS_status;\r
+       unsigned        totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle;\r
+       unsigned int EMSVer;\r
+       word numUMBs,UMBbase[MAXUMBS];\r
+       //dword numUMBs,UMBbase[MAXUMBS];\r
+       //huge mmblocktype      huge mmblocks[MAXBLOCKS],huge *mmhead,huge *mmfree,huge *mmrover,huge *mmnew;\r
+       mmblocktype     far mmblocks[MAXBLOCKS],far *mmhead,far *mmfree,far *mmrover,far *mmnew;\r
+} mminfo_t;*/\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                GLOBAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                LOCAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+//==========================================================================\r
+\r
+boolean MML_CheckForEMS(void);\r
+//byte MML_SetupEMS(mminfo_t *mm);\r
+//void MML_ShutdownEMS(mminfo_t *mm);\r
+byte MM_MapEMS(global_game_variables_t *gvar);\r
+byte MM_MapXEMS(global_game_variables_t *gvar);\r
+//boolean MML_CheckForXMS(mminfo_t *mm);\r
+//void MML_SetupXMS(mminfo_t *mm, mminfotype *mmi);\r
+//void MML_ShutdownXMS(mminfo_t *mm);\r
+void MML_UseSpace(word segstart, dword seglength, global_game_variables_t *gvar);\r
+void MML_ClearBlock(global_game_variables_t *gvar);\r
+\r
+void MM_Startup(global_game_variables_t *gvar);\r
+void MM_Shutdown(global_game_variables_t *gvar);\r
+\r
+void MM_GetPtr(memptr *baseptr,dword size, global_game_variables_t *gvar);\r
+void MM_FreePtr(memptr *baseptr, global_game_variables_t *gvar);\r
+void MM_SetPurge(memptr *baseptr, int purge, global_game_variables_t *gvar);\r
+void MM_SetLock(memptr *baseptr, boolean locked, global_game_variables_t *gvar);\r
+void MM_SortMem(global_game_variables_t *gvar);\r
+void MM_ShowMemory(global_game_variables_t *gvar);\r
+void MM_DumpData(global_game_variables_t *gvar);\r
+dword MM_UnusedMemory(global_game_variables_t *gvar);\r
+dword MM_TotalFree(global_game_variables_t *gvar);\r
+void MM_Report_(global_game_variables_t *gvar);\r
+/*static */void MM_EMSerr(byte *stri, byte err);\r
+void MM_BombOnError(boolean bomb, global_game_variables_t *gvar);\r
+//void MM_GetNewBlock(mminfo_t *mm);\r
+//void MM_FreeBlock(mmblocktype *x, mminfo_t *mm);\r
+void   XMS_CALL(byte v, global_game_variables_t *gvar);\r
+\r
+//==========================================================================\r
+\r
+#endif\r
index 8ebf0ec000a94529bb03c5b4a14230a9d4a8434e..ea11ac488cca2b2dbc659ed4470f883268dd0763 100755 (executable)
@@ -137,62 +137,51 @@ PML_MapEMS(word logical, byte physical, global_game_variables_t *gvar)
 boolean\r
 PML_StartupEMS(global_game_variables_t *gvar)\r
 {\r
-       boolean emmcfems;\r
-\r
        int             i;\r
        long    size;\r
+       boolean errorflag;\r
 \r
        gvar->pm.emm.EMSPresent = false;                        // Assume that we'll fail\r
        gvar->pm.emm.EMSAvail = 0;\r
-       emmcfems=0;\r
+       errorflag=0;\r
 \r
+       _DX = (word)EMMDriverName;\r
+       _AX = 0x3d00;\r
+       geninterrupt(0x21);                     // try to open EMMXXXX0 device\r
        __asm {\r
-       //_DX = (word)EMMDriverName;\r
-       //_AX = 0x3d00;\r
-       //geninterrupt(0x21);                   // try to open EMMXXXX0 device\r
-               mov     dx,OFFSET EMMDriverName\r
-               mov     ax,0x3d00\r
-               int     0x21            // try to open EMMXXXX0 device\r
-               jnc     gothandle\r
-               //fail\r
-               mov     emmcfems,1\r
-               jmp             Aend\r
-#ifdef __BORLANDC__\r
+               jnc     gothandle\r
+               mov     errorflag,1\r
+               gothandle:\r
        }\r
-#endif\r
+       if(errorflag)\r
+               goto error;\r
 \r
-gothandle:\r
-#ifdef __BORLANDC__\r
+//gothandle:\r
+       _BX = _AX;\r
+       _AX = 0x4400;\r
+       geninterrupt(0x21);                     // get device info\r
        __asm {\r
-#endif\r
-       //_BX = _AX;\r
-       //_AX = 0x4400;\r
-       //geninterrupt(0x21);                   // get device info\r
-               mov     bx,ax\r
-               mov     ax,0x4400\r
-               int     0x21                    // get device info\r
                jnc     gotinfo\r
-               //fail\r
-               mov     emmcfems,1\r
-               jmp             Aend\r
-#ifdef __BORLANDC__\r
-       }\r
-#endif\r
-Aend:\r
-gotinfo:\r
-#ifndef __BORLANDC__\r
+               mov     errorflag,1\r
+               gotinfo:\r
        }\r
-#endif\r
-       if(emmcfems!=0) goto error;\r
-       __asm and       dx,0x80\r
+       if(errorflag)\r
+               goto error;\r
+\r
+//gotinfo:\r
+__asm  and     dx,0x80\r
        if (!_DX)\r
                goto error;\r
 \r
        _AX = 0x4407;\r
        geninterrupt(0x21);                     // get status\r
-       __asm mov       emmcfems,1\r
-       if(emmcfems!=0) goto error;\r
-\r
+       __asm {\r
+               jc      error\r
+               jmp     end\r
+               error:\r
+               mov     errorflag,1\r
+               end:\r
+       }\r
        if (!_AL)\r
                goto error;\r
 \r
@@ -256,11 +245,16 @@ error:
 void\r
 PML_ShutdownEMS(global_game_variables_t *gvar)\r
 {\r
+       word EMSHandle;\r
+       EMSHandle=gvar->pm.emm.EMSHandle;\r
+\r
        if (gvar->pm.emm.EMSPresent)\r
        {\r
-                       _AH=EMS_FREEPAGES;\r
-                       _AX=gvar->pm.emm.EMSHandle;\r
-                       geninterrupt(EMS_INT);\r
+               __asm {\r
+                       mov     ah,EMS_FREEPAGES\r
+                       mov     dx,[EMSHandle]\r
+                       int     EMS_INT\r
+               }\r
                if (_AH)\r
                {\r
                        Quit("PML_ShutdownEMS: Error freeing EMS\n");\r
@@ -435,8 +429,15 @@ PM_SetMainMemPurge(int level, global_game_variables_t *gvar)
        int     i;\r
 \r
        for (i = 0;i < PMMaxMainMem;i++)\r
+       {\r
+#ifdef __DEBUG_PM__\r
+               printf("PM_SetMainMemPurge()    info of gvar->pm.mm.MainMemPages[i]\n");\r
+               printf("        %Fp,    %Fp\n", gvar->pm.mm.MainMemPages[i],            (gvar->pm.mm.MainMemPages[i]));\r
+               printf("&       %Fp,    %Fp\n", &gvar->pm.mm.MainMemPages[i],   &(gvar->pm.mm.MainMemPages[i]));\r
+#endif\r
                if (gvar->pm.mm.MainMemPages[i])\r
-                       MM_SetPurge(&gvar->pm.mm.MainMemPages[i],level, gvar);\r
+                       MM_SetPurge((gvar->pm.mm.MainMemPages[i]),level, gvar);\r
+       }\r
 }\r
 \r
 //\r
index c5158dc5d318e6836808b20e366351a2cf9e9cd2..c59590cefe640158f0ac0ee4455574506b971d8d 100755 (executable)
-#include "src/lib/16_sprit.h"
-
-char* get_curr_anim_name(struct sprite *spri)
-{
-       // Retrive animation name list
-       struct vrs_header huge *vrs = spri->spritesheet->vrs_hdr;
-       uint32_t huge *anim_names_offsets =     (uint32_t huge *)
-                                               ((byte huge *)vrs +
-                                                vrs->offset_table[VRS_HEADER_OFFSET_ANIMATION_NAME_LIST]);
-
-       return (char *)(vrs + anim_names_offsets[spri->curr_anim]);
-}
-
-void init_anim(struct sprite *spri, int anim_index)
-{
-       struct vrs_header huge *vrs = spri->spritesheet->vrs_hdr;
-       uint32_t huge *anim_lists_offsets =     (uint32_t huge *)
-                                               ((byte huge *)vrs +
-                                                vrs->offset_table[VRS_HEADER_OFFSET_ANIMATION_LIST]);
-       struct vrs_animation_list_entry_t huge *anim_list =     (struct vrs_animation_list_entry_t huge *)
-                                                               ((byte huge *)vrs +
-                                                                anim_lists_offsets[anim_index]);
-
-       // Upon new animation, start from the first sprite in it
-       spri->curr_anim = anim_index;
-       spri->curr_anim_spri = 0;
-       spri->curr_spri_id = anim_list[0].sprite_id;
-       spri->delay = anim_list[0].delay;
-
-       spri->curr_anim_list = anim_list;
-}
-
-
-int set_anim_by_id(struct sprite *spri, int anim_id)
-{
-       int new_anim_index = 0;
-       int iter_id;
-       struct vrs_header huge *vrs = spri->spritesheet->vrs_hdr;
-       // Retruve animation ids list
-        uint16_t huge *anim_ids =      (uint16_t huge *)
-                                       ((byte huge *)vrs +
-                                        vrs->offset_table[VRS_HEADER_OFFSET_ANIMATION_ID_LIST]);
-
-       // Loop through animation id untill match or end of list
-       while(iter_id = anim_ids[new_anim_index])
-       {
-               // Return on successful match
-               if (iter_id == anim_id)
-               {
-                       init_anim(spri, new_anim_index);
-                       return 0;
-               }
-               new_anim_index++;
-       }
-       return -1;
-}
-
-void print_anim_ids(struct sprite *spri)
-{
-       int new_anim_index = 0;
-       int iter_id;
-       struct vrs_header huge *vrs = spri->spritesheet->vrs_hdr;
-       // Retruve animation ids list
-        uint16_t huge *anim_ids =      (uint16_t huge *)
-                                       ((byte huge *)vrs +
-                                        vrs->offset_table[VRS_HEADER_OFFSET_ANIMATION_ID_LIST]);
-
-       if(!anim_ids[new_anim_index])
-               exit(3);
-       // Loop through animation id untill match or end of list
-       while(iter_id = anim_ids[new_anim_index])
-       {
-               // Return on successful match
-               new_anim_index++;
-       }
-}
-
-
-void animate_spri(struct sprite *spri)
-{
-       int i;
-       // Events go here
-
-       // Draw sprite
-       i = get_vrl_by_id(spri->spritesheet, spri->curr_spri_id, spri->sprite_vrl_cont);
-       if(i < 0)
-       {
-               printf("Error retriving required sprite");
-               exit(-1);
-       }
-       draw_vrl1_vgax_modex(   spri->x, spri->y,
-                               spri->sprite_vrl_cont->vrl_header, spri->sprite_vrl_cont->line_offsets,
-                               spri->sprite_vrl_cont->buffer + sizeof(struct vrl1_vgax_header),
-                               spri->sprite_vrl_cont->data_size);
-
-       // Depending on delay, update indices
-       switch(spri->delay){
-               // Delay = 0 means that sprite should loop. Nothing to change here
-               case 0:
-                       break;
-
-               // Delay = 1 means that on next time unit sprite should be changed
-               case 1:
-                       spri->curr_anim_spri++;
-
-                       // If we hit the end of an animation sequence, restart it
-                       if(!(spri->curr_spri_id = spri->curr_anim_list[spri->curr_anim_spri].sprite_id)){
-                               spri->curr_anim_spri = 0;
-                               spri->curr_spri_id = spri->curr_anim_list[spri->curr_anim_spri].sprite_id;
-                       }
-                       spri->delay = spri->curr_anim_list[spri->curr_anim_spri].delay;
-
-               // Delay > 1 means that we should not change sprite yet. Decrease delay
-               default:
-                       spri->delay--;
-                       break;
-       }
-}
+#include "src/lib/16_sprit.h"\r
+\r
+char* get_curr_anim_name(struct sprite *spri)\r
+{\r
+       // Retrive animation name list\r
+       struct vrs_header huge *vrs = spri->spritesheet->vrs_hdr;\r
+       uint32_t huge *anim_names_offsets =     (uint32_t huge *)\r
+                                               ((byte huge *)vrs +\r
+                                                vrs->offset_table[VRS_HEADER_OFFSET_ANIMATION_NAME_LIST]);\r
+\r
+       return (char *)(vrs + anim_names_offsets[spri->curr_anim]);\r
+}\r
+\r
+void init_anim(struct sprite *spri, int anim_index)\r
+{\r
+       struct vrs_header huge *vrs = spri->spritesheet->vrs_hdr;\r
+       uint32_t huge *anim_lists_offsets =     (uint32_t huge *)\r
+                                               ((byte huge *)vrs +\r
+                                                vrs->offset_table[VRS_HEADER_OFFSET_ANIMATION_LIST]);\r
+       struct vrs_animation_list_entry_t huge *anim_list =     (struct vrs_animation_list_entry_t huge *)\r
+                                                               ((byte huge *)vrs +\r
+                                                                anim_lists_offsets[anim_index]);\r
+\r
+       // Upon new animation, start from the first sprite in it\r
+       spri->curr_anim = anim_index;\r
+       spri->curr_anim_spri = 0;\r
+       spri->curr_spri_id = anim_list[0].sprite_id;\r
+       spri->delay = anim_list[0].delay;\r
+\r
+       spri->curr_anim_list = anim_list;\r
+}\r
+\r
+\r
+int set_anim_by_id(struct sprite *spri, int anim_id)\r
+{\r
+       int new_anim_index = 0;\r
+       int iter_id;\r
+       struct vrs_header huge *vrs = spri->spritesheet->vrs_hdr;\r
+       // Retruve animation ids list\r
+        uint16_t huge *anim_ids =      (uint16_t huge *)\r
+                                       ((byte huge *)vrs +\r
+                                        vrs->offset_table[VRS_HEADER_OFFSET_ANIMATION_ID_LIST]);\r
+\r
+       // Loop through animation id untill match or end of list\r
+       while(iter_id = anim_ids[new_anim_index])\r
+       {\r
+               // Return on successful match\r
+               if (iter_id == anim_id)\r
+               {\r
+                       init_anim(spri, new_anim_index);\r
+                       return 0;\r
+               }\r
+               new_anim_index++;\r
+       }\r
+       return -1;\r
+}\r
+\r
+void print_anim_ids(struct sprite *spri)\r
+{\r
+       int new_anim_index = 0;\r
+       int iter_id;\r
+       struct vrs_header huge *vrs = spri->spritesheet->vrs_hdr;\r
+       // Retruve animation ids list\r
+        uint16_t huge *anim_ids =      (uint16_t huge *)\r
+                                       ((byte huge *)vrs +\r
+                                        vrs->offset_table[VRS_HEADER_OFFSET_ANIMATION_ID_LIST]);\r
+\r
+       if(!anim_ids[new_anim_index])\r
+               exit(3);\r
+       // Loop through animation id untill match or end of list\r
+       while(iter_id = anim_ids[new_anim_index])\r
+       {\r
+               // Return on successful match\r
+               new_anim_index++;\r
+       }\r
+}\r
+\r
+\r
+void animate_spri(struct sprite *spri)\r
+{\r
+       int i;\r
+       // Events go here\r
+\r
+       // Draw sprite\r
+       i = get_vrl_by_id(spri->spritesheet, spri->curr_spri_id, spri->sprite_vrl_cont);\r
+       if(i < 0)\r
+       {\r
+               printf("Error retriving required sprite");\r
+               exit(-1);\r
+       }\r
+       draw_vrl1_vgax_modex(   spri->x, spri->y,\r
+                               spri->sprite_vrl_cont->vrl_header, spri->sprite_vrl_cont->line_offsets,\r
+                               spri->sprite_vrl_cont->buffer + sizeof(struct vrl1_vgax_header),\r
+                               spri->sprite_vrl_cont->data_size);\r
+\r
+       // Depending on delay, update indices\r
+       switch(spri->delay){\r
+               // Delay = 0 means that sprite should loop. Nothing to change here\r
+               case 0:\r
+                       break;\r
+\r
+               // Delay = 1 means that on next time unit sprite should be changed\r
+               case 1:\r
+                       spri->curr_anim_spri++;\r
+\r
+                       // If we hit the end of an animation sequence, restart it\r
+                       if(!(spri->curr_spri_id = spri->curr_anim_list[spri->curr_anim_spri].sprite_id)){\r
+                               spri->curr_anim_spri = 0;\r
+                               spri->curr_spri_id = spri->curr_anim_list[spri->curr_anim_spri].sprite_id;\r
+                       }\r
+                       spri->delay = spri->curr_anim_list[spri->curr_anim_spri].delay;\r
+\r
+               // Delay > 1 means that we should not change sprite yet. Decrease delay\r
+               default:\r
+                       spri->delay--;\r
+                       break;\r
+       }\r
+}\r
index a93838ace685a54dd0c4aab65acbb50b0a79424b..555e8d1c67c5689743bf1d5e9db4cae8996f17f2 100755 (executable)
@@ -1,74 +1,74 @@
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-#ifndef __16_SPRI__
-#define __16_SPRI__
-
-#include "src/lib/16_vrs.h"
-#include "src/lib/typdefst.h"
-
-struct sprite
-{
-       // VRS container from which we will extract animation and image data
-       struct vrs_container *spritesheet;
-       // Container for a vrl sprite
-       struct vrl_container *sprite_vrl_cont;
-       // Current sprite id
-       int curr_spri_id;
-       // Index of a current sprite in an animation sequence
-       int curr_anim_spri;
-       // Current animation sequence
-       struct vrs_animation_list_entry_t *curr_anim_list;
-       // Index of current animation in relevant VRS offsets table
-       int curr_anim;
-       // Delay in time units untill we should change sprite
-       int delay;
-       // Position of sprite on screen
-       int x, y;
-};
-
-/* Retrive current animation name of sprite
-* In:
-* + struct sprite *spri - sprite to retrive current animation sequence name from
-* Out:
-* + char* - animation sequence name
-*/
-char* get_curr_anim_name(struct sprite *spri);
-
-/* Change sprite's current animation to the one given by id
- * In:
- * struct sprite *spri - sprite to manipulate on
- * int id - id of a new animation sequence of th sprite
- * Out:
- * int - 0 on success, -1 on error
- */
-int set_anim_by_id(struct sprite *spri, int id);
-
-/* Animate sprite, triggering any events and changing indices if necessary
- * NB: if you want to change animation sequence after a specific sprite is shown, you should call animate_spri first
- * In:
- * + struct sprite *spri - sprite to animate
- */
-void animate_spri(struct sprite *spri);
-
-void print_anim_ids(struct sprite *spri);
-
-#endif
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+#ifndef __16_SPRI__\r
+#define __16_SPRI__\r
+\r
+#include "src/lib/16_vrs.h"\r
+#include "src/lib/typdefst.h"\r
+\r
+struct sprite\r
+{\r
+       // VRS container from which we will extract animation and image data\r
+       struct vrs_container *spritesheet;\r
+       // Container for a vrl sprite\r
+       struct vrl_container *sprite_vrl_cont;\r
+       // Current sprite id\r
+       int curr_spri_id;\r
+       // Index of a current sprite in an animation sequence\r
+       int curr_anim_spri;\r
+       // Current animation sequence\r
+       struct vrs_animation_list_entry_t *curr_anim_list;\r
+       // Index of current animation in relevant VRS offsets table\r
+       int curr_anim;\r
+       // Delay in time units untill we should change sprite\r
+       int delay;\r
+       // Position of sprite on screen\r
+       int x, y;\r
+};\r
+\r
+/* Retrive current animation name of sprite\r
+* In:\r
+* + struct sprite *spri - sprite to retrive current animation sequence name from\r
+* Out:\r
+* + char* - animation sequence name\r
+*/\r
+char* get_curr_anim_name(struct sprite *spri);\r
+\r
+/* Change sprite's current animation to the one given by id\r
+ * In:\r
+ * struct sprite *spri - sprite to manipulate on\r
+ * int id - id of a new animation sequence of th sprite\r
+ * Out:\r
+ * int - 0 on success, -1 on error\r
+ */\r
+int set_anim_by_id(struct sprite *spri, int id);\r
+\r
+/* Animate sprite, triggering any events and changing indices if necessary\r
+ * NB: if you want to change animation sequence after a specific sprite is shown, you should call animate_spri first\r
+ * In:\r
+ * + struct sprite *spri - sprite to animate\r
+ */\r
+void animate_spri(struct sprite *spri);\r
+\r
+void print_anim_ids(struct sprite *spri);\r
+\r
+#endif\r
index 5dc525e15d39c237e6783525de42f6538eed733b..595489d69fe760f647ba7de213369a4aa2625e5b 100755 (executable)
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-#include "src/lib/16_vrs.h"
-#include "src/lib/typdefst.h"
-
-// Read .vrs file into far memory
-int read_vrs(global_game_variables_t *gvar, char *filename, struct vrs_container *vrs_cont){
-       int fd;
-       dword size;
-#ifdef __WATCOMC__
-       __segment seg;
-       void __based(seg)* bigbuffer;
-#endif
-#ifdef __BORLANDC__
-       memptr bigbuffer;
-#endif
-       byte huge *buffer;
-       vrl1_vgax_offset_t **vrl_line_offsets;
-       uint32_t huge *vrl_headers_offsets;
-       uint16_t huge *vrl_id_iter;
-       uint32_t vrl_size;
-       int num_of_vrl, i;
-       struct vrl1_vgax_header huge *curr_vrl;
-       int success;
-
-       // Open filename, get size of file,
-       // populate the vrs_container if all tests pass
-       fd = open(filename, O_RDONLY|O_BINARY);
-       // Insert sanity cheks later
-       size = lseek(fd, 0, SEEK_END);
-       buffer = malloc(size);
-       lseek(fd, 0, SEEK_SET);
-       read(fd, buffer, size);
-       close(fd);
-       if(!success)
-       {
-               fprintf(stderr, "Unablee to load file");
-               exit(3);
-       }
-       vrs_cont->data_size = size - sizeof(struct vrs_header);
-       vrs_cont->buffer = buffer;
-
-       // Calculate vrl offsets
-       
-       // Count sprites
-       vrl_id_iter = (uint16_t huge *)(buffer + vrs_cont->vrs_hdr->offset_table[VRS_HEADER_OFFSET_SPRITE_ID_LIST]);
-       while(vrl_id_iter[num_of_vrl]){
-               num_of_vrl++;
-       }
-       // Allocate memory for vrl line offsets table
-       vrl_line_offsets = malloc(sizeof(vrl1_vgax_offset_t *)*num_of_vrl);
-
-       vrl_headers_offsets = (uint32_t huge *)(buffer + vrs_cont->vrs_hdr->offset_table[VRS_HEADER_OFFSET_VRS_LIST]);
-       // Calculate line offsets for each vrl
-       for(i = 0; i < num_of_vrl; i++){
-               curr_vrl = (struct vrl1_vgax_header huge *)(buffer + vrl_headers_offsets[i]);
-
-               // Calc. vrl size as (next_offset - curr_offset)
-               if (i != num_of_vrl - 1){
-                       vrl_size = vrl_headers_offsets[i+1] - vrl_headers_offsets[i] - sizeof(struct vrl1_vgax_header);
-               }
-               // If it's the last vrl, size is (next_vrs_struct_offset - curr_offset)
-               else{
-                       vrl_size = vrs_cont->vrs_hdr->offset_table[VRS_HEADER_OFFSET_SPRITE_ID_LIST] - vrl_headers_offsets[i] - sizeof(struct vrl1_vgax_header);
-               }
-               vrl_line_offsets[i] = vrl1_vgax_genlineoffsets(curr_vrl, (byte *)curr_vrl + sizeof(struct vrl1_vgax_header), vrl_size);
-       }
-       vrs_cont->vrl_line_offsets = vrl_line_offsets;
-       return 0;
-}
-
-// Seek and return a specified .vrl blob from .vrs blob in far memory
-int get_vrl_by_id(struct vrs_container /*huge*/ *vrs_cont, uint16_t id, struct vrl_container *vrl_cont){
-       uint16_t huge *ids;
-       uint32_t huge *vrl_offs_list;
-       int counter = 0;
-
-       // If id is invalid, return -1
-       if(id == 0){
-               // Probably add an error message?
-               return -1;
-       }
-
-       // Get id list from .vrs blob (base + offset)
-       ids = (uint16_t huge*)(vrs_cont->buffer + 
-               vrs_cont->vrs_hdr->offset_table[VRS_HEADER_OFFSET_SPRITE_ID_LIST]);
-
-       // Loop through the id list until we found the right one or hit the end of the list
-       // Counter is keeping track of the offset(in ids/vrl blobs)
-       while(ids[counter] != id && ids[counter]){
-               counter++;
-       }
-       // Return -2 if we couldn't find the requested id
-       if(!ids[counter]){
-               // Error message?
-               return -2;
-       }
-
-       // Get vrl offsets list from .vrs blob (base + offset)
-       vrl_offs_list = (uint32_t huge *)(vrs_cont->buffer +
-                                       vrs_cont->vrs_hdr->offset_table[VRS_HEADER_OFFSET_VRS_LIST]);
-
-       // Get vrl_header from .vrs (base + offset from vrl_list)
-       // Counter is number of vrls to skip (ids and vrls are aligned according to the .vrs specification)
-       vrl_cont->vrl_header = (struct vrl1_vgax_header huge *)(vrs_cont->buffer + vrl_offs_list[counter]);
-
-       // Get .vrl size by integer arithmetics (next vrl offset - current vrl offset)
-       if(ids[counter+1]){
-               vrl_cont->data_size = vrl_offs_list[counter+1] - vrl_offs_list[counter] - sizeof(struct vrl1_vgax_header);
-       }
-       // If we are retriving the last vrl, size is ids_list offset - current vrl offset, as next vrl offs is 0
-       else{
-               vrl_cont->data_size = vrs_cont->vrs_hdr->offset_table[VRS_HEADER_OFFSET_SPRITE_ID_LIST] - vrl_offs_list[counter] - sizeof(struct vrl1_vgax_header);
-       }
-
-       // Retrive line offsets form .vrs
-       vrl_cont->line_offsets = vrs_cont->vrl_line_offsets[counter];
-
-       return 0;
-}
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+#include "src/lib/16_vrs.h"\r
+#include "src/lib/typdefst.h"\r
+\r
+// Read .vrs file into far memory\r
+int read_vrs(global_game_variables_t *gvar, char *filename, struct vrs_container *vrs_cont){\r
+       int fd;\r
+       dword size;\r
+#ifdef __WATCOMC__\r
+       __segment seg;\r
+       void __based(seg)* bigbuffer;\r
+#endif\r
+#ifdef __BORLANDC__\r
+       memptr bigbuffer;\r
+#endif\r
+       byte huge *buffer;\r
+       vrl1_vgax_offset_t **vrl_line_offsets;\r
+       uint32_t huge *vrl_headers_offsets;\r
+       uint16_t huge *vrl_id_iter;\r
+       uint32_t vrl_size;\r
+       int num_of_vrl, i;\r
+       struct vrl1_vgax_header huge *curr_vrl;\r
+       int success;\r
+\r
+       // Open filename, get size of file,\r
+       // populate the vrs_container if all tests pass\r
+       fd = open(filename, O_RDONLY|O_BINARY);\r
+       // Insert sanity cheks later\r
+       size = lseek(fd, 0, SEEK_END);\r
+       buffer = malloc(size);\r
+       lseek(fd, 0, SEEK_SET);\r
+       read(fd, buffer, size);\r
+       close(fd);\r
+       if(!success)\r
+       {\r
+               fprintf(stderr, "Unablee to load file");\r
+               exit(3);\r
+       }\r
+       vrs_cont->data_size = size - sizeof(struct vrs_header);\r
+       vrs_cont->buffer = buffer;\r
+\r
+       // Calculate vrl offsets\r
+       \r
+       // Count sprites\r
+       vrl_id_iter = (uint16_t huge *)(buffer + vrs_cont->vrs_hdr->offset_table[VRS_HEADER_OFFSET_SPRITE_ID_LIST]);\r
+       while(vrl_id_iter[num_of_vrl]){\r
+               num_of_vrl++;\r
+       }\r
+       // Allocate memory for vrl line offsets table\r
+       vrl_line_offsets = malloc(sizeof(vrl1_vgax_offset_t *)*num_of_vrl);\r
+\r
+       vrl_headers_offsets = (uint32_t huge *)(buffer + vrs_cont->vrs_hdr->offset_table[VRS_HEADER_OFFSET_VRS_LIST]);\r
+       // Calculate line offsets for each vrl\r
+       for(i = 0; i < num_of_vrl; i++){\r
+               curr_vrl = (struct vrl1_vgax_header huge *)(buffer + vrl_headers_offsets[i]);\r
+\r
+               // Calc. vrl size as (next_offset - curr_offset)\r
+               if (i != num_of_vrl - 1){\r
+                       vrl_size = vrl_headers_offsets[i+1] - vrl_headers_offsets[i] - sizeof(struct vrl1_vgax_header);\r
+               }\r
+               // If it's the last vrl, size is (next_vrs_struct_offset - curr_offset)\r
+               else{\r
+                       vrl_size = vrs_cont->vrs_hdr->offset_table[VRS_HEADER_OFFSET_SPRITE_ID_LIST] - vrl_headers_offsets[i] - sizeof(struct vrl1_vgax_header);\r
+               }\r
+               vrl_line_offsets[i] = vrl1_vgax_genlineoffsets(curr_vrl, (byte *)curr_vrl + sizeof(struct vrl1_vgax_header), vrl_size);\r
+       }\r
+       vrs_cont->vrl_line_offsets = vrl_line_offsets;\r
+       return 0;\r
+}\r
+\r
+// Seek and return a specified .vrl blob from .vrs blob in far memory\r
+int get_vrl_by_id(struct vrs_container /*huge*/ *vrs_cont, uint16_t id, struct vrl_container *vrl_cont){\r
+       uint16_t huge *ids;\r
+       uint32_t huge *vrl_offs_list;\r
+       int counter = 0;\r
+\r
+       // If id is invalid, return -1\r
+       if(id == 0){\r
+               // Probably add an error message?\r
+               return -1;\r
+       }\r
+\r
+       // Get id list from .vrs blob (base + offset)\r
+       ids = (uint16_t huge*)(vrs_cont->buffer + \r
+               vrs_cont->vrs_hdr->offset_table[VRS_HEADER_OFFSET_SPRITE_ID_LIST]);\r
+\r
+       // Loop through the id list until we found the right one or hit the end of the list\r
+       // Counter is keeping track of the offset(in ids/vrl blobs)\r
+       while(ids[counter] != id && ids[counter]){\r
+               counter++;\r
+       }\r
+       // Return -2 if we couldn't find the requested id\r
+       if(!ids[counter]){\r
+               // Error message?\r
+               return -2;\r
+       }\r
+\r
+       // Get vrl offsets list from .vrs blob (base + offset)\r
+       vrl_offs_list = (uint32_t huge *)(vrs_cont->buffer +\r
+                                       vrs_cont->vrs_hdr->offset_table[VRS_HEADER_OFFSET_VRS_LIST]);\r
+\r
+       // Get vrl_header from .vrs (base + offset from vrl_list)\r
+       // Counter is number of vrls to skip (ids and vrls are aligned according to the .vrs specification)\r
+       vrl_cont->vrl_header = (struct vrl1_vgax_header huge *)(vrs_cont->buffer + vrl_offs_list[counter]);\r
+\r
+       // Get .vrl size by integer arithmetics (next vrl offset - current vrl offset)\r
+       if(ids[counter+1]){\r
+               vrl_cont->data_size = vrl_offs_list[counter+1] - vrl_offs_list[counter] - sizeof(struct vrl1_vgax_header);\r
+       }\r
+       // If we are retriving the last vrl, size is ids_list offset - current vrl offset, as next vrl offs is 0\r
+       else{\r
+               vrl_cont->data_size = vrs_cont->vrs_hdr->offset_table[VRS_HEADER_OFFSET_SPRITE_ID_LIST] - vrl_offs_list[counter] - sizeof(struct vrl1_vgax_header);\r
+       }\r
+\r
+       // Retrive line offsets form .vrs\r
+       vrl_cont->line_offsets = vrs_cont->vrl_line_offsets[counter];\r
+\r
+       return 0;\r
+}\r
index 381b7108dbea75e39c4be851a361960a46d64456..cdeb81a0cf74a1cdfa97abff15bacb9c76857419 100755 (executable)
@@ -1,78 +1,78 @@
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-#ifndef __16_VRS__
-#define __16_VRS__
-
-#include "src/lib/modex16.h"
-#include "src/lib/typdefst.h"
-//#include <hw/cpu/cpu.h>
-//#include <hw/dos/dos.h>
-#include <hw/vga/vrl.h>
-#include "src/lib/16_ca.h"
-
-struct vrs_container{
-       // Size of a .vrs lob in memory
-       // minus header
-       dword data_size;
-       union{
-               byte huge *buffer;
-               struct vrs_header huge *vrs_hdr;
-       };
-       // Array of corresponding vrl line offsets
-       vrl1_vgax_offset_t **vrl_line_offsets;
-};
-
-struct vrl_container{
-       // Size of a .vrl blob in memory
-       // minus header
-       dword data_size;
-       union{
-               byte huge *buffer;
-               struct vrl1_vgax_header huge *vrl_header;
-       };
-       // Pointer to a corresponding vrl line offsets struct
-       vrl1_vgax_offset_t *line_offsets;
-};
-
-/* Read .vrs file into memory
-* In:
-* + char *filename - name of the file to load
-* + struct vrs_container *vrs_cont - pointer to the vrs_container
-* to load the file into
-* Out:
-* + int - 0 on succes, 1 on failure
-*/
-int read_vrs(global_game_variables_t *gvar, char *filename, struct vrs_container *vrs_cont);
-
-/* Seek and return a specified .vrl blob from .vrs blob in memory
-* In:
-* + struct vrs_container *vrs_cont - pointer to the vrs_container
-* with a loaded .vrs file
-* + uint16_t id - id of the vrl to retrive
-* + struct vrl_container * vrl_cont - pointer to vrl_container to load to
-* Out:
-* int - operation status
-* to the requested .vrl blob
-*/
-int get_vrl_by_id(struct vrs_container *vrs_cont, uint16_t id, struct vrl_container * vrl_cont);
-
-#endif
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+#ifndef __16_VRS__\r
+#define __16_VRS__\r
+\r
+#include "src/lib/modex16.h"\r
+#include "src/lib/typdefst.h"\r
+//#include <hw/cpu/cpu.h>\r
+//#include <hw/dos/dos.h>\r
+#include <hw/vga/vrl.h>\r
+#include "src/lib/16_ca.h"\r
+\r
+struct vrs_container{\r
+       // Size of a .vrs lob in memory\r
+       // minus header\r
+       dword data_size;\r
+       union{\r
+               byte huge *buffer;\r
+               struct vrs_header huge *vrs_hdr;\r
+       };\r
+       // Array of corresponding vrl line offsets\r
+       vrl1_vgax_offset_t **vrl_line_offsets;\r
+};\r
+\r
+struct vrl_container{\r
+       // Size of a .vrl blob in memory\r
+       // minus header\r
+       dword data_size;\r
+       union{\r
+               byte huge *buffer;\r
+               struct vrl1_vgax_header huge *vrl_header;\r
+       };\r
+       // Pointer to a corresponding vrl line offsets struct\r
+       vrl1_vgax_offset_t *line_offsets;\r
+};\r
+\r
+/* Read .vrs file into memory\r
+* In:\r
+* + char *filename - name of the file to load\r
+* + struct vrs_container *vrs_cont - pointer to the vrs_container\r
+* to load the file into\r
+* Out:\r
+* + int - 0 on succes, 1 on failure\r
+*/\r
+int read_vrs(global_game_variables_t *gvar, char *filename, struct vrs_container *vrs_cont);\r
+\r
+/* Seek and return a specified .vrl blob from .vrs blob in memory\r
+* In:\r
+* + struct vrs_container *vrs_cont - pointer to the vrs_container\r
+* with a loaded .vrs file\r
+* + uint16_t id - id of the vrl to retrive\r
+* + struct vrl_container * vrl_cont - pointer to vrl_container to load to\r
+* Out:\r
+* int - operation status\r
+* to the requested .vrl blob\r
+*/\r
+int get_vrl_by_id(struct vrs_container *vrs_cont, uint16_t id, struct vrl_container * vrl_cont);\r
+\r
+#endif\r
index 2dc6f5aa088258665dcebda37c6610007a39d171..e152ce18fc08b460687c050a7cf815793e5d8975 100755 (executable)
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-/*
-       scroll16 library~
-*/
-#include "src/lib/scroll16.h"
-#include "src/lib/16_sprite.h"
-
-void walk(map_view_t *pip, player_t *player, word pn)
-{
-       #define INC_PER_FRAME if(player[pn].q&1) player[pn].persist_aniframe++; if(player[pn].persist_aniframe>4) player[pn].persist_aniframe = 1;
-       //printf("player[%d].d=%d\n", pn, player[pn].d);
-       switch(player[pn].d)
-       {
-               //no direction
-               case 2:
-                       //0000pip[0].video->startclk = (*clockw);
-               break;
-               //right movement
-               case 3:
-                       //printf("pip[0].page->tilesw=%d        ", pip[0].page->tilesw); printf("pip[0].page->tw=%d\n", pip[0].page->tw);
-                       if(pip[0].tx >= 0 && pip[0].tx+pip[0].page->tw < pip[0].map->width && player[pn].tx == pip[0].tx+pip[0].page->tilemidposscreenx &&
-                       !(pip[0].map->data[(player[pn].tx)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx+1 == TRIGGX && player[pn].ty == TRIGGY))      //collision detection!
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       animatePlayer(pip, player, pn, 1);
-                                       ScrollRight(pip, player, 3, pn);
-                                       ScrollRight(pip, player, 2, pn);
-                                       mapScrollRight(pip, player, !(pip[0].video->p), pn);
-                                       mapScrollRight(pip, player, (pip[0].video->p), pn);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx++; }
-                       }
-                       else if(player[pn].tx < pip[0].map->width && !(pip[0].map->data[(player[pn].tx)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx+1 == TRIGGX && player[pn].ty == TRIGGY))
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       player[pn].x+=(player[pn].speed);
-                                       animatePlayer(pip, player, pn, 0);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx++; }
-                       }
-                       else
-                       {
-                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 16, 32);
-#ifdef SPRITE
-                               //PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 16, 32, 16, 32, PLAYERBMPDATA);
-                               animate_spri(player[pn].spri);
-#else
-                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 16, 32, 14);
-#endif
-                               if(!pageflipflop) modexShowPage(pip[1].page);
-                               player[pn].d = 2;
-                       }
-                       player[pn].triggerx = player[pn].tx+1;
-                       player[pn].triggery = player[pn].ty;
-               break;
-
-               //left movement
-               case 1:
-                       if(pip[0].tx > 0 && pip[0].tx+pip[0].page->tw <= pip[0].map->width && player[pn].tx == pip[0].tx+pip[0].page->tilemidposscreenx &&
-                       !(pip[0].map->data[(player[pn].tx-2)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx-1 == TRIGGX && player[pn].ty == TRIGGY))    //collision detection!
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       animatePlayer(pip, player, pn, 1);
-                                       ScrollLeft(pip, player, 3, pn);
-                                       ScrollLeft(pip, player, 2, pn);
-                                       mapScrollLeft(pip, player, !(pip[0].video->p), pn);
-                                       mapScrollLeft(pip, player, (pip[0].video->p), pn);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx--; }
-                       }
-                       else if(player[pn].tx > 1 && !(pip[0].map->data[(player[pn].tx-2)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx-1 == TRIGGX && player[pn].ty == TRIGGY))
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       player[pn].x-=(player[pn].speed);
-                                       animatePlayer(pip, player, pn, 0);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx--; }
-                       }
-                       else
-                       {
-                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 16, 32);
-#ifdef SPRITE
-                               //PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 16, 96, 16, 32, PLAYERBMPDATA);
-                               animate_spri(player[pn].spri);
-#else
-                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 16, 32, 10);
-#endif
-                               if(!pageflipflop) modexShowPage(pip[1].page);
-                               player[pn].d = 2;
-                       }
-                       player[pn].triggerx = player[pn].tx-1;
-                       player[pn].triggery = player[pn].ty;
-               break;
-
-               //down movement
-               case 4:
-                       if(pip[0].ty >= 0 && pip[0].ty+pip[0].page->th < pip[0].map->height && player[pn].ty == pip[0].ty+pip[0].page->tilemidposscreeny &&
-                       !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty))] == 0))//!(player[pn].tx == TRIGGX && player[pn].ty+1 == TRIGGY))      //collision detection!
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       animatePlayer(pip, player, pn, 1);
-                                       ScrollDown(pip, player, 3, pn);
-                                       ScrollDown(pip, player, 2, pn);
-                                       mapScrollDown(pip, player, !(pip[0].video->p), pn);
-                                       mapScrollDown(pip, player, (pip[0].video->p), pn);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty++; }
-                       }
-                       else if(player[pn].ty < pip[0].map->height && !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty))] == 0))//!(player[pn].tx == TRIGGX && player[pn].ty+1 == TRIGGY))
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       player[pn].y+=(player[pn].speed);
-                                       animatePlayer(pip, player, pn, 0);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty++; }
-                       }
-                       else
-                       {
-                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 16, 32);
-#ifdef SPRITE
-                               //PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 16, 64, 16, 32, PLAYERBMPDATA);
-                               animate_spri(player[pn].spri);
-#else
-                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 16, 32, 9);
-#endif
-                               if(!pageflipflop) modexShowPage(pip[1].page);
-                               player[pn].d = 2;
-                       }
-                       player[pn].triggerx = player[pn].tx;
-                       player[pn].triggery = player[pn].ty+1;
-               break;
-
-               //up movement
-               case 0:
-                       if(pip[0].ty > 0 && pip[0].ty+pip[0].page->th <= pip[0].map->height && player[pn].ty == pip[0].ty+pip[0].page->tilemidposscreeny &&
-                       !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty-2))] == 0))//!(player[pn].tx == TRIGGX && player[pn].ty-1 == TRIGGY))    //collision detection!
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       animatePlayer(pip, player, pn, 1);
-                                       ScrollUp(pip, player, 3, pn);
-                                       ScrollUp(pip, player, 2, pn);
-                                       mapScrollUp(pip, player, !(pip[0].video->p), pn);
-                                       mapScrollUp(pip, player, (pip[0].video->p), pn);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty--; }
-                       }
-                       else if(player[pn].ty > 1 && !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty-2))] == 0))//!(player[pn].tx == TRIGGX &&  player[pn].ty-1 == TRIGGY))
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       player[pn].y-=(player[pn].speed);
-                                       animatePlayer(pip, player, 0, pn);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty--; }
-                       }
-                       else
-                       {
-                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 16, 32);
-#ifdef SPRITE
-                               //PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 16, 0, 16, 32, PLAYERBMPDATA);
-                               animate_spri(player[pn].spri);
-#else
-                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 16, 32, 12);
-#endif
-                               if(!pageflipflop) modexShowPage(pip[1].page);
-                               player[pn].d = 2;
-                       }
-                       player[pn].triggerx = player[pn].tx;
-                       player[pn].triggery = player[pn].ty-1;
-               break;
-       }
-}
-
-//panning page
-void panpagemanual(map_view_t *pip, player_t *player, word pn)
-{
-       switch(player[pn].d)
-       {
-               //right movement
-               case 3:
-                       if(pip[pip[0].pan->pn].tx >= 0 && pip[pip[0].pan->pn].tx+pip[pip[0].pan->pn].page->tw < pip[pip[0].pan->pn].page->tilesw)
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       pip[pip[0].pan->pn].page->dx+=4;
-                                       modexShowPage(pip[pip[0].pan->pn].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].tx++; }
-                       }
-               break;
-
-               //left movement
-               case 1:
-                       if(pip[pip[0].pan->pn].tx > 0 && pip[pip[0].pan->pn].tx+pip[pip[0].pan->pn].page->tw <= pip[pip[0].pan->pn].page->tilesw)
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       pip[pip[0].pan->pn].page->dx-=4;
-                                       modexShowPage(pip[pip[0].pan->pn].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].tx--; }
-                       }
-               break;
-
-               //down movement
-               case 4:
-                       if(pip[pip[0].pan->pn].ty >= 0 && pip[pip[0].pan->pn].ty+pip[pip[0].pan->pn].page->th < pip[pip[0].pan->pn].page->tilesh)
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       pip[pip[0].pan->pn].page->dy+=4;
-                                       modexShowPage(pip[pip[0].pan->pn].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].ty++; }
-                       }
-               break;
-
-               //up movement
-               case 0:
-                       if(pip[pip[0].pan->pn].ty > 0 && pip[pip[0].pan->pn].ty+pip[pip[0].pan->pn].page->th <= pip[pip[0].pan->pn].page->tilesh)
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       pip[pip[0].pan->pn].page->dy-=4;
-                                       modexShowPage(pip[pip[0].pan->pn].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].ty--; }
-                       }
-                       break;
-       }
-       //if (player[pn].d!=2) printf("player[%u].d=%u player[%u].q=%u\n", pn, player[pn].d, pn, player[pn].q);
-}
-
-/*map_t
-allocMap(int w, int h) {
-       map_t result;
-
-       result.width =w;
-       result.height=h;
-       result.data = malloc(sizeof(byte) * w * h);
-       //result.data = (byte *)alloc_emem(((int)sizeof(byte) * w * h)/1024);
-       if(isEMS() || checkEMS())
-       {
-               XMOVE mm;
-               //emmhandle = mallocEMS(coretotalEMS());//alloc_emem((int)sizeof(map))
-               mm.length=sizeof(result);
-               mm.sourceH=0;
-               mm.sourceOff=ptr2long(&result);
-               mm.destH=emmhandle;
-               mm.destOff=0;
-               ist = move_emem(&mm);
-               if(!ist){ dealloc_emem(emmhandle); exit(5); }
-               printf("%d\n", coretotalEMS());
-       }
-
-       return result;
-}*/
-
-/*void
-initMap(map_t *map) {
-       // just a place holder to fill out an alternating pattern
-       int x, y, xx, yy;
-       int i, q;
-//     int tile = 1;
-       //if(!isEMS() || !checkEMS())
-//             map->tiles = malloc(sizeof(tiles_t));
-       //else
-       //      map->tiles = (tiles_t *)alloc_emem(sizeof(tiles_t));
-
-        //create the tile set
-       //if(!isEMS() || !checkEMS())
-//             map->tiles->data = malloc(sizeof(bitmap_t));
-       //else
-       //      map->tiles->data = (bitmap_t *)alloc_emem(sizeof(bitmap_t));
-//     map->tiles->data->width = (TILEWH);
-//     map->tiles->data->height= TILEWH;
-       //if(!isEMS() || !checkEMS())
-//             map->tiles->data->data = malloc((TILEWH*2)*TILEWH);
-       //else
-       //      map->tiles->data->data = (byte *)alloc_emem((TILEWH*2)*TILEWH);
-//     map->tiles->tileHeight = TILEWH;
-//     map->tiles->tileWidth =TILEWH;
-//     map->tiles->rows = 1;
-//     map->tiles->cols = 1;//2;
-
-       q=0;
-       //for(y=0; y<map->height; y++) {
-       //for(x=0; x<map->width; x++) {
-       i=0;
-       for(yy=0; yy<TILEWH; yy++) {
-       for(xx=0; xx<(TILEWH); xx++) {
-               //if(x<TILEWH){
-                 map->tiles->data->data[i+1] = map->data[q];//28;//0x24;
-//               printf("[%d]", map->tiles->data->data[i]);
-               //}else{
-                 //map->tiles->data->data[i] = map->data[q];//0;//0x34;
-                 //printf("]%d[==[%d]", i, map->tiles->data->data[i]);
-               //}
-               i++;
-       }
-//     printf("\n");
-       }
-//     printf("[%d]", map->data[q]);
-       q++;
-//     }
-       //printf("\n\n");
-//     }
-
-       i=0;
-       for(y=0; y<map->height; y++) {
-               for(x=0; x<map->width; x++) {
-//                     map->data[i]=255;
-                       printf("[%d]", map->data[i]);
-                       //tile = tile ? 0 : 1;
-                       i++;
-               }
-               //tile = tile ? 0 : 1;
-       }
-}*/
-
-void near mapScrollRight(map_view_t *mv, player_t *player, word id, word plid)
-{
-       word x, y;  /* coordinate for drawing */
-
-       /* increment the pixel position and update the page */
-       mv[id].page->dx += player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dx >= mv[id].dxThresh )
-       {
-       /* go forward one tile */
-       mv[id].tx++;
-       /* Snap the origin forward */
-       mv[id].page->data += 4;
-
-       mv[id].page->dx = mv[id].map->tiles->tileWidth;
-       }
-
-       /* draw the next column */
-       x= mv[0].page->sw + mv[id].map->tiles->tileWidth;
-       if(player[plid].q%4)
-               if(id==0)
-                       mapDrawCol(&mv[0], mv[0].tx + mv[0].page->tw, mv[0].ty-1, x, player, mv->page->dx);
-               else
-                       if(!pageflipflop && !pageploop)
-                               modexCopyPageRegion(mv[id].page, mv[0].page, x, 0, x, 0, mv[id].map->tiles->tileWidth, mv[id].map->tiles->tileHeight*(mv[0].page->th+2));
-       mv[0].video->r=1;
-}
-
-
-void near mapScrollLeft(map_view_t *mv, player_t *player, word id, word plid)
-{
-       word x, y;  /* coordinate for drawing */
-
-       /* decrement the pixel position and update the page */
-       mv[id].page->dx -= player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dx == 0)
-       {
-       /* go backward one tile */
-       mv[id].tx--;
-       /* Snap the origin backward */
-       mv[id].page->data -= 4;
-
-       mv[id].page->dx = mv[id].map->tiles->tileWidth;
-       }
-
-       /* draw the next column */
-       x= 0;
-       if(player[plid].q%4)
-               if(id==0)
-                       mapDrawCol(&mv[0], mv[0].tx - 1, mv[0].ty-1, x, player, mv->page->dx);
-               else
-                       if(!pageflipflop && !pageploop)
-                               modexCopyPageRegion(mv[id].page, mv[0].page, x, 0, x, 0, mv[id].map->tiles->tileWidth, mv[id].map->tiles->tileHeight*(mv[0].page->th+2));
-       mv[0].video->r=1;
-}
-
-
-void near mapScrollUp(map_view_t *mv, player_t *player, word id, word plid)
-{
-       word x, y;  /* coordinate for drawing */
-
-       /* decrement the pixel position and update the page */
-       mv[id].page->dy -= player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dy == 0 )
-       {
-       /* go down one tile */
-       mv[id].ty--;
-       /* Snap the origin downward */
-       mv[id].page->data -= mv[id].page->pi;
-
-       mv[id].page->dy = mv[id].map->tiles->tileHeight;
-       }
-
-       /* draw the next row */
-       y= 0;
-       if(player[plid].q%3)
-               if(id==0)
-                       mapDrawRow(&mv[0], mv[0].tx - 1, mv[0].ty-1, y, player, mv->page->dy);
-               else
-                       if(!pageflipflop && !pageploop)
-                               modexCopyPageRegion(mv[id].page, mv[0].page, 0, y, 0, y, mv[id].map->tiles->tileWidth*(mv[0].page->tw+2), mv[id].map->tiles->tileHeight);
-       mv[0].video->r=1;
-}
-
-void near mapScrollDown(map_view_t *mv, player_t *player, word id, word plid)
-{
-       word x, y;  /* coordinate for drawing */
-
-       /* increment the pixel position and update the page */
-       mv[id].page->dy += player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dy >= mv[id].dyThresh )
-       {
-       /* go down one tile */
-       mv[id].ty++;
-       /* Snap the origin downward */
-       mv[id].page->data += mv[id].page->pi;
-
-       mv[id].page->dy = mv[id].map->tiles->tileHeight;
-       }
-
-       /* draw the next row */
-       y= mv[0].page->sh + mv[id].map->tiles->tileHeight;
-       if(player[plid].q%3)
-               if(id==0)
-                       mapDrawRow(&mv[0], mv[0].tx - 1, mv[0].ty+mv[0].page->th, y, player, mv->page->dy);
-               else
-                       if(!pageflipflop && !pageploop)
-                               modexCopyPageRegion(mv[id].page, mv[0].page, 0, y, 0, y, mv[id].map->tiles->tileWidth*(mv[0].page->tw+2), mv[id].map->tiles->tileHeight);
-       mv[0].video->r=1;
-}
-
-
-//TODO finish this wwww
-void near ScrollRight(map_view_t *mv, player_t *player, word id, word plid)
-{
-       /* increment the pixel position and update the page */
-       mv[id].page->dx += player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dx >= mv[0].dxThresh )
-       {
-//             vga_setup_wm1_block_copy();
-//             _fmemmove(mv[id].page->data+4, mv[id].page->data, mv[id].page->pagesize);
-//             vga_restore_rm0wm0();
-               /* Snap the origin forward */
-               mv[id].page->data += 4;
-               mv[id].page->dx = mv[0].map->tiles->tileWidth;
-       }
-}
-
-void near ScrollLeft(map_view_t *mv, player_t *player, word id, word plid)
-{
-       /* decrement the pixel position and update the page */
-       mv[id].page->dx -= player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dx == 0)
-       {
-//             vga_setup_wm1_block_copy();
-//             _fmemmove(mv[id].page->data-4, mv[id].page->data, mv[id].page->pagesize);
-//             vga_restore_rm0wm0();
-               /* Snap the origin backward */
-               mv[id].page->data -= 4;
-               mv[id].page->dx = mv[0].map->tiles->tileWidth;
-       }
-}
-
-void near ScrollUp(map_view_t *mv, player_t *player, word id, word plid)
-{
-       /* decrement the pixel position and update the page */
-       mv[id].page->dy -= player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dy == 0)
-       {
-//             vga_setup_wm1_block_copy();
-//             _fmemmove(mv[id].page->data-mv[id].page->pi, mv[id].page->data, mv[id].page->pagesize);
-//             vga_restore_rm0wm0();
-               /* Snap the origin backward */
-               mv[id].page->data -= mv[id].page->pi;
-               mv[id].page->dy = mv[0].map->tiles->tileWidth;
-       }
-}
-
-void near ScrollDown(map_view_t *mv, player_t *player, word id, word plid)
-{
-       /* increment the pixel position and update the page */
-       mv[id].page->dy += player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dy >= mv[0].dxThresh )
-       {
-//             vga_setup_wm1_block_copy();
-//             _fmemmove(mv[id].page->data+mv[id].page->pi, mv[id].page->data, mv[id].page->pagesize);
-//             vga_restore_rm0wm0();
-               /* Snap the origin forward */
-               mv[id].page->data += mv[id].page->pi;
-               mv[id].page->dy = mv[0].map->tiles->tileWidth;
-       }
-}
-
-sword chkmap(map_t *map, word q)
-{
-//     bitmap_t bp;
-       static byte x[(MAPW*MAPH)+1] =
-{ 1, 2, 3, 4, 0, 3, 3, 3, 3, 3, 3, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 11, 12, 4, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 0, 1, 1, 1, 5, 8, 1, 11, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 4, 0, 0, 0, 0, 0, 8, 8, 1, 11, 11, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 2, 3, 4, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 5, 6, 7, 8, 6, 6, 6, 6, 6, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 9, 10, 11, 12, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10 };
-/*1,   2,      3,      4,      0,      3,      3,      3,      3,      3,      3,      3,      3,      4,      1,      1,      1,      1,      1,      1,      \
-5,     6,      7,      8,      0,      1,      0,      1,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-9,     10,     11,     12,     4,      1,      0,      1,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-13,    14,     15,     16,     0,      1,      1,      1,      5,      8,      1,      11,     11,     1,      1,      1,      1,      1,      1,      1,      \
-0,     0,      4,      0,      0,      0,      0,      0,      8,      8,      1,      11,     11,     3,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      0,      0,      0,      0,      8,      8,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      0,      0,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      0,      0,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      3,      3,      3,      1,      2,      3,      4 };*/
-       //check for failed to load map
-       if((map->width == map->height == 0) && (q>0))
-       {
-               //initiate a null map!
-               map->width=MAPW;///2;
-               map->height=MAPH;///2;
-//             map->data = malloc(((map->width*map->height)+1)*sizeof(byte));
-               map->data = &x;
-               map->tiles = malloc(sizeof(tiles_t));
-               //fix this to be far~
-//             bp = bitmapLoadPcx("data/ed.pcx");
-//             map->tiles->data = &bp;
-               map->tiles->debug_data = map->data;
-               map->tiles->tileHeight = 16;
-               map->tiles->tileWidth = 16;
-               map->tiles->rows = 1;
-               map->tiles->cols = 1;
-               map->tiles->debug_text = true;
-       }
-       else map->tiles->debug_text = false;
-       return 0;
-}
-
-//TODO: player position here
-void mapGoTo(map_view_t *mv, int tx, int ty)
-{
-       int px, py;
-       unsigned int i;
-
-       /* set up the coordinates */
-       mv[0].tx = mv[1].tx = tx;
-       mv[0].ty = mv[1].ty = ty;
-       mv[0].page->dx = mv[1].page->dx = mv[2].page->dx = mv[3].page->dx = mv->map->tiles->tileWidth;
-       mv[0].page->dy = mv[1].page->dy = mv[2].page->dy = mv[3].page->dy = mv->map->tiles->tileHeight;
-
-       /* set up the thresholds */
-       mv[0].dxThresh = mv[1].dxThresh = mv[2].dxThresh = mv[3].dxThresh = mv->map->tiles->tileWidth * 2;
-       mv[0].dyThresh = mv[1].dyThresh = mv[2].dxThresh = mv[3].dxThresh = mv->map->tiles->tileHeight * 2;
-
-       /* draw the tiles */
-       modexClearRegion(mv[0].page, 0, 0, mv[0].page->width, mv[0].page->height, 0);
-       py=0;
-       i=mv[0].ty * mv[0].map->width + mv[0].tx;
-       for(ty=mv[0].ty-1; py < mv[0].page->sh+mv->dyThresh && ty < mv[0].map->height; ty++, py+=mv[0].map->tiles->tileHeight) {
-               mapDrawWRow(&mv[0], tx-1, ty, py);
-       i+=mv->map->width - tx;
-       }
-       if(!pageploop) modexCopyPageRegion(mv[1].page, mv[0].page, 0, 0, 0, 0, mv[0].page->width, mv[0].page->height);
-//     {
-//             unsigned int k,j,o;
-//             /* fill screen with a distinctive pattern */
-//             for (k=0;k < vga_state.vga_width;k++) {
-//                     o = k >> 2;
-//                     vga_write_sequencer(0x02/*map mask*/,1 << (k&3));
-//                             for (j=0;j < (mv[0].page->height)+(mv[1].page->height)+(mv[2].page->height)+(mv[3].page->height);j++,o += vga_state.vga_stride)
-//                                     vga_state.vga_graphics_ram[o] = (k^j)&15; // VRL samples put all colors in first 15!
-//             }
-//     }
-       modexCopyPageRegion(mv[3].page, mv[0].page, 0/**/, 0/**/, 0, 0, 16, 32);
-}
-
-void near
-mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y)
-{
-       word rx;
-       word ry;
-       word textx=0;
-       word texty=0;
-       //if(i==0) i=2;
-       if(i==0)
-       {
-               //wwww
-               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, 0); //currently the over scan color!
-       }
-       else
-       {
-               rx = (((i-1) % ((t->data->width)/t->tileWidth)) * t->tileWidth);
-               ry = (((i-1) / ((t->data->height)/t->tileHeight)) * t->tileHeight);
-////0000printf("i=%d\n", i);
-               switch(t->debug_text)
-               {
-                       case 0:
-#ifndef TILERENDER
-                               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, ((t->debug_data[i])+1));
-                               //modexprint(page, x, y, 1, 15, 0, (char const *)(t->debug_data[i]));
-#else
-                               PBUFBFUN                (page, x, y, rx, ry, t->tileWidth, t->tileHeight, (t->data));
-                               /* then the sprite. note modding ram ptr means we just draw to (x&3,0) */
-                               //draw_vrl1_vgax_modex(x-rx,y-ry,vrl_header,vrl_lineoffs,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));
-                               //modexDrawBmpRegion    (page, x, y, rx, ry, t->tileWidth, t->tileHeight, (t->data));
-#endif
-                       break;
-                       case 1:
-                               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, (t->debug_data[i])+1);
-                               //modexprintbig(page, x, y, 1, 15, 0, (t->debug_data));
-                               /*for(texty=0; texty<2; texty++)
-                               {
-                                       for(textx=0; textx<2; textx++)
-                                       {*/
-//                                             modexprint(page, x+(textx*8), y+(texty*8), 1, (word)(t->debug_data), 0, (t->debug_data));
-/*                                     }
-                               }*/
-                       break;
-               }
-       }
-}
-
-void near mapDrawRow(map_view_t *mv, int tx, int ty, word y, player_t *p, word poopoffset)
-{
-       word x;
-       int i;
-       poopoffset%=p[0].speed;
-//printf("y: %d\n", poopoffset);
-       /* the position within the map array */
-       i=ty * mv->map->width + tx;
-       for(x=poopoffset; x<(mv->page->sw+mv->dxThresh)/(poopoffset+1) && tx < mv->map->width; x+=mv->map->tiles->tileWidth, tx++) {
-       if(i>=0) {
-               /* we are in the map, so copy! */
-               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);
-       }
-       i++; /* next! */
-       }
-}
-
-void near mapDrawCol(map_view_t *mv, int tx, int ty, word x, player_t *p, word poopoffset)
-{
-       int y;
-       int i;
-       poopoffset%=p[0].speed;
-//printf("x: %d\n", poopoffset);
-       /* location in the map array */
-       i=ty * mv->map->width + tx;
-
-       /* We'll copy all of the columns in the screen,
-          i + 1 row above and one below */
-       for(y=poopoffset; y<(mv->page->sh+mv->dyThresh)/(poopoffset+1) && ty < mv->map->height; y+=mv->map->tiles->tileHeight, ty++) {
-       if(i>=0) {
-               /* we are in the map, so copy away! */
-               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);
-       }
-       i += mv->map->width;
-       }
-}
-
-void mapDrawWRow(map_view_t *mv, int tx, int ty, word y)
-{
-       word x;
-       int i;
-
-       /* the position within the map array */
-       i=ty * mv->map->width + tx;
-       for(x=0; x<mv->page->sw+mv->dxThresh && tx < mv->map->width; x+=mv->map->tiles->tileWidth, tx++) {
-       if(i>=0) {
-               /* we are in the map, so copy! */
-               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);
-       }
-       i++; /* next! */
-       }
-}
-
-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,
-          i + 1 row above and one below */
-       for(y=0; y<mv->page->sh+mv->dyThresh && ty < mv->map->height; y+=mv->map->tiles->tileHeight, ty++) {
-       if(i>=0) {
-               /* we are in the map, so copy away! */
-               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);
-       }
-       i += mv->map->width;
-       }
-}
-
-/*void qclean()
-{
-       //setkb(0);
-}*/
-
-unsigned char shinku_fps_indicator_page = 2;
-boolean pageflipflop = 1;
-boolean pageploop = 1;
-
-/*     sync    */
-void shinku(global_game_variables_t *gv)
-{
-       word x = (0) + gv->video.page[/*!*/(gv->video.p)].dx; // follow the screen
-       word y = (0) + gv->video.page[/*!*/(gv->video.p)].dy; // follow the screen
-       word w = 64, h = 8, col = 7, bgcol = 0, type = 1;
-       byte o,o2,i;
-       //modexCopyPageRegion(pip[1].page, pip[2].page, 16, 16, 16, 16, (14*8)+4, 8+4);
-       /* block copy to visible RAM from offscreen */
-//     vga_setup_wm1_block_copy();
-//     modexCopyPageRegion(&(gv->video.page[shinku_fps_indicator_page]), &(gv->video.page[!shinku_fps_indicator_page]), x, y, x+w, 0, w, h);
-//     o =     *(gv->video.page[2].data); // source offscreen
-//     o2 =    *(gv->video.page[shinku_fps_indicator_page].data)+(y * vga_state.vga_stride) + (x >> 2); // dest visible (original stride)
-//     for (i=0;i < h;i++,o += vga_state.vga_draw_stride,o2 += vga_state.vga_stride) vga_wm1_mem_block_copy(o2,o,w >> 2);
-       /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */
-//     vga_restore_rm0wm0();
-       if(elapsed_timer(gv) >= (1.0 / gv->kurokku.frames_per_second))
-       {
-               sprintf(gv->pee, "%.0f fps", (double)gv->kurokku.tiku/ticktock(gv));
-               //modexClearRegion(&(gv->video.page[shinku_fps_indicator_page]), x, y, w, h, 45);
-               modexprint(&(gv->video.page[/*!*/(gv->video.p)]), x, y, type, col, bgcol, gv->pee);
-               gv->kurokku.tiku=0;
-               /* block copy to visible RAM from offscreen */
-//             vga_setup_wm1_block_copy();
-//             o =     *(gv->video.page[shinku_fps_indicator_page].data); // source offscreen
-//             o2 =    *(gv->video.page[2].data)+(y * vga_state.vga_stride) + (x >> 2); // dest visible (original stride)
-//             for (i=0;i < h;i++,o += vga_state.vga_draw_stride,o2 += vga_state.vga_stride) vga_wm1_mem_block_copy(o2,o,w >> 2);
-//             modexCopyPageRegion(&(gv->video.page[shinku_fps_indicator_page]), &(gv->video.page[!shinku_fps_indicator_page]), x, y, x, 0, w, h);
-               /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */
-//             vga_restore_rm0wm0();
-       }else //copy dat sheet
-       gv->kurokku.tiku++;
-
-       switch(gv->kurokku.fpscap)
-       {
-               case 0:
-                       //modexprint(&(gv->video.page[shinku_fps_indicator_page]), x, y+8, type, col, bgcol, "sanic!");
-                       gv->kurokku.frames_per_second=1;
-               break;
-               case 1:
-                       //turn this off if XT
-                       //modexWaitBorder();
-                       vga_wait_for_vsync();
-                       gv->kurokku.frames_per_second=60;
-               break;
-       }
-       if(pageflipflop){
-       if(gv->video.r){
-               //vga_setup_wm1_block_copy();
-               //_fmemcpy((gv->video.page[(gv->video.p)]).data, (gv->video.page[(!gv->video.p)]).data, gv->video.page[(!gv->video.p)].pagesize);
-               //vga_restore_rm0wm0();
-               if(!pageploop) modexCopyPageRegion(&(gv->video.page[(gv->video.p)]), &(gv->video.page[(!gv->video.p)]), 0, 0, 0, 0, gv->video.page[gv->video.p].width, gv->video.page[!gv->video.p].height);
-               modexShowPage(&(gv->video.page[gv->video.p]));
-               if(!pageploop) gv->video.p=!gv->video.p;
-               gv->video.r=!gv->video.r;
-               //0000gv->video.tickclk = ((*clockw)-gv->video.startclk)/18.2;
-       }
-       }
-}
-
-void near animatePlayer(map_view_t *pip, player_t *player, word pn, sword scrollswitch)
-{
-       sword x = player[pn].x;
-       sword y = player[pn].y;
-       sword bx = x+16;        //buffer's x
-       sword by = y+16;        //buffer's y
-       word dire=32; //direction
-       sword qq; //scroll offset
-       word ls = player[pn].persist_aniframe;
-
-       switch(scrollswitch)
-       {
-               case 0:
-                       qq = 0;
-               break;
-               default:
-                       qq = ((player[pn].q)*(player[pn].speed));
-               break;
-       }
-       //x-=4;
-       y-=pip[0].map->tiles->tileHeight;
-       switch (player[pn].d)
-       {
-               case 0:
-                       //up
-                       dire*=player[pn].d;
-                       y-=qq;
-                       by-=4;
-               break;
-               case 3:
-                       // right
-                       dire*=(player[pn].d-2);
-                       x+=qq;
-                       bx+=4;
-               break;
-               case 2:
-               break;
-               case 4:
-                       //down
-                       dire*=(player[pn].d-2);
-                       y+=qq;
-                       by+=4;
-               break;
-               case 1:
-                       //left
-                       dire*=(player[pn].d+2);
-                       x-=qq;
-                       bx-=4;
-               break;
-       }
-
-#ifdef SPRITE
-//#define FRAME1 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 32, dire, 16, 32,      PLAYERBMPDATA);
-//#define FRAME2 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 16, dire, 16, 32,      PLAYERBMPDATA);
-//#define FRAME3 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 0, dire, 16, 32,       PLAYERBMPDATA);
-//#define FRAME4 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 16, dire, 16, 32,      PLAYERBMPDATA);
-#define FRAME1 animate_spri(player[pn].spri);
-#define FRAME2 animate_spri(player[pn].spri);
-#define FRAME3 animate_spri(player[pn].spri);
-#define FRAME4 animate_spri(player[pn].spri);
-#else
-#define FRAME1 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 16, 32, 2+dire);
-#define FRAME2 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 16, 32, 1+dire);
-#define FRAME3 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 16, 32, dire);
-#define FRAME4 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 16, 32, 1+dire);
-#endif
-       if(!pageflipflop)
-               modexCopyPageRegion(pip[1].page, pip[0].page, x-4, y-4, x-4, y-4, 28, 36);
-       else{
-               //copy old bg to page0
-               //modexCopyPageRegion(pip[3].page, pip[0].page, bx, by, 0, 0,   20, 36);
-               //update buffer
-               //modexCopyPageRegion(pip[0].page, pip[3].page, 0, 0,   x, y,   20, 36);
-       }
-//modexCopyPageRegion(page_t *dest, page_t *src, word sx, word sy, word dx, word dy, word width, word height);
-       //modexCopyPageRegion(pip[3].page, pip[!(pip->video->p)].page, x-4, y-4, 0, 128, 28, 36);
-       /*modexCopyPageRegion(pip[pip->video->p].page,
- pip[!(pip->video->p)].page, x-4, y-4, x-4, y-4, 28, 36);*/
-//     else modexCopyPageRegion(pip[1].page, pip[0].page, x-4, y-4, x-4, y-4, 28, 40);
-       switch(ls)
-       {
-               case 1:
-                       FRAME1
-               break;
-               case 2:
-                       FRAME2
-               break;
-               case 3:
-                       FRAME3
-               break;
-               case 4:
-                       FRAME4
-               break;
-       }
-//     if(2>ls && ls>=1) { FRAME1 }else
-//     if(3>ls && ls>=2) { FRAME2 }else
-//     if(4>ls && ls>=3) { FRAME3 }else
-//     if(5>ls && ls>=4) { FRAME4 }
-       //modexCopyPageRegion(pip[0].page, pip[3].page, 0, 0, x, y, 16, 32);
-       //printf("x=%d  y=%d    bx=%d           by=%d\n", x, y, bx, by);
-       pip->video->r=1;
-}
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+/*\r
+       scroll16 library~\r
+*/\r
+#include "src/lib/scroll16.h"\r
+#include "src/lib/16_sprite.h"\r
+\r
+void walk(map_view_t *pip, player_t *player, word pn)\r
+{\r
+       #define INC_PER_FRAME if(player[pn].q&1) player[pn].persist_aniframe++; if(player[pn].persist_aniframe>4) player[pn].persist_aniframe = 1;\r
+       //printf("player[%d].d=%d\n", pn, player[pn].d);\r
+       switch(player[pn].d)\r
+       {\r
+               //no direction\r
+               case 2:\r
+                       //0000pip[0].video->startclk = (*clockw);\r
+               break;\r
+               //right movement\r
+               case 3:\r
+                       //printf("pip[0].page->tilesw=%d        ", pip[0].page->tilesw); printf("pip[0].page->tw=%d\n", pip[0].page->tw);\r
+                       if(pip[0].tx >= 0 && pip[0].tx+pip[0].page->tw < pip[0].map->width && player[pn].tx == pip[0].tx+pip[0].page->tilemidposscreenx &&\r
+                       !(pip[0].map->data[(player[pn].tx)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx+1 == TRIGGX && player[pn].ty == TRIGGY))      //collision detection!\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       animatePlayer(pip, player, pn, 1);\r
+                                       ScrollRight(pip, player, 3, pn);\r
+                                       ScrollRight(pip, player, 2, pn);\r
+                                       mapScrollRight(pip, player, !(pip[0].video->p), pn);\r
+                                       mapScrollRight(pip, player, (pip[0].video->p), pn);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx++; }\r
+                       }\r
+                       else if(player[pn].tx < pip[0].map->width && !(pip[0].map->data[(player[pn].tx)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx+1 == TRIGGX && player[pn].ty == TRIGGY))\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       player[pn].x+=(player[pn].speed);\r
+                                       animatePlayer(pip, player, pn, 0);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx++; }\r
+                       }\r
+                       else\r
+                       {\r
+                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 16, 32);\r
+#ifdef SPRITE\r
+                               //PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 16, 32, 16, 32, PLAYERBMPDATA);\r
+                               animate_spri(player[pn].spri);\r
+#else\r
+                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 16, 32, 14);\r
+#endif\r
+                               if(!pageflipflop) modexShowPage(pip[1].page);\r
+                               player[pn].d = 2;\r
+                       }\r
+                       player[pn].triggerx = player[pn].tx+1;\r
+                       player[pn].triggery = player[pn].ty;\r
+               break;\r
+\r
+               //left movement\r
+               case 1:\r
+                       if(pip[0].tx > 0 && pip[0].tx+pip[0].page->tw <= pip[0].map->width && player[pn].tx == pip[0].tx+pip[0].page->tilemidposscreenx &&\r
+                       !(pip[0].map->data[(player[pn].tx-2)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx-1 == TRIGGX && player[pn].ty == TRIGGY))    //collision detection!\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       animatePlayer(pip, player, pn, 1);\r
+                                       ScrollLeft(pip, player, 3, pn);\r
+                                       ScrollLeft(pip, player, 2, pn);\r
+                                       mapScrollLeft(pip, player, !(pip[0].video->p), pn);\r
+                                       mapScrollLeft(pip, player, (pip[0].video->p), pn);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx--; }\r
+                       }\r
+                       else if(player[pn].tx > 1 && !(pip[0].map->data[(player[pn].tx-2)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx-1 == TRIGGX && player[pn].ty == TRIGGY))\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       player[pn].x-=(player[pn].speed);\r
+                                       animatePlayer(pip, player, pn, 0);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx--; }\r
+                       }\r
+                       else\r
+                       {\r
+                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 16, 32);\r
+#ifdef SPRITE\r
+                               //PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 16, 96, 16, 32, PLAYERBMPDATA);\r
+                               animate_spri(player[pn].spri);\r
+#else\r
+                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 16, 32, 10);\r
+#endif\r
+                               if(!pageflipflop) modexShowPage(pip[1].page);\r
+                               player[pn].d = 2;\r
+                       }\r
+                       player[pn].triggerx = player[pn].tx-1;\r
+                       player[pn].triggery = player[pn].ty;\r
+               break;\r
+\r
+               //down movement\r
+               case 4:\r
+                       if(pip[0].ty >= 0 && pip[0].ty+pip[0].page->th < pip[0].map->height && player[pn].ty == pip[0].ty+pip[0].page->tilemidposscreeny &&\r
+                       !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty))] == 0))//!(player[pn].tx == TRIGGX && player[pn].ty+1 == TRIGGY))      //collision detection!\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       animatePlayer(pip, player, pn, 1);\r
+                                       ScrollDown(pip, player, 3, pn);\r
+                                       ScrollDown(pip, player, 2, pn);\r
+                                       mapScrollDown(pip, player, !(pip[0].video->p), pn);\r
+                                       mapScrollDown(pip, player, (pip[0].video->p), pn);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty++; }\r
+                       }\r
+                       else if(player[pn].ty < pip[0].map->height && !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty))] == 0))//!(player[pn].tx == TRIGGX && player[pn].ty+1 == TRIGGY))\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       player[pn].y+=(player[pn].speed);\r
+                                       animatePlayer(pip, player, pn, 0);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty++; }\r
+                       }\r
+                       else\r
+                       {\r
+                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 16, 32);\r
+#ifdef SPRITE\r
+                               //PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 16, 64, 16, 32, PLAYERBMPDATA);\r
+                               animate_spri(player[pn].spri);\r
+#else\r
+                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 16, 32, 9);\r
+#endif\r
+                               if(!pageflipflop) modexShowPage(pip[1].page);\r
+                               player[pn].d = 2;\r
+                       }\r
+                       player[pn].triggerx = player[pn].tx;\r
+                       player[pn].triggery = player[pn].ty+1;\r
+               break;\r
+\r
+               //up movement\r
+               case 0:\r
+                       if(pip[0].ty > 0 && pip[0].ty+pip[0].page->th <= pip[0].map->height && player[pn].ty == pip[0].ty+pip[0].page->tilemidposscreeny &&\r
+                       !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty-2))] == 0))//!(player[pn].tx == TRIGGX && player[pn].ty-1 == TRIGGY))    //collision detection!\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       animatePlayer(pip, player, pn, 1);\r
+                                       ScrollUp(pip, player, 3, pn);\r
+                                       ScrollUp(pip, player, 2, pn);\r
+                                       mapScrollUp(pip, player, !(pip[0].video->p), pn);\r
+                                       mapScrollUp(pip, player, (pip[0].video->p), pn);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty--; }\r
+                       }\r
+                       else if(player[pn].ty > 1 && !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty-2))] == 0))//!(player[pn].tx == TRIGGX &&  player[pn].ty-1 == TRIGGY))\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       player[pn].y-=(player[pn].speed);\r
+                                       animatePlayer(pip, player, 0, pn);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty--; }\r
+                       }\r
+                       else\r
+                       {\r
+                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 16, 32);\r
+#ifdef SPRITE\r
+                               //PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 16, 0, 16, 32, PLAYERBMPDATA);\r
+                               animate_spri(player[pn].spri);\r
+#else\r
+                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 16, 32, 12);\r
+#endif\r
+                               if(!pageflipflop) modexShowPage(pip[1].page);\r
+                               player[pn].d = 2;\r
+                       }\r
+                       player[pn].triggerx = player[pn].tx;\r
+                       player[pn].triggery = player[pn].ty-1;\r
+               break;\r
+       }\r
+}\r
+\r
+//panning page\r
+void panpagemanual(map_view_t *pip, player_t *player, word pn)\r
+{\r
+       switch(player[pn].d)\r
+       {\r
+               //right movement\r
+               case 3:\r
+                       if(pip[pip[0].pan->pn].tx >= 0 && pip[pip[0].pan->pn].tx+pip[pip[0].pan->pn].page->tw < pip[pip[0].pan->pn].page->tilesw)\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       pip[pip[0].pan->pn].page->dx+=4;\r
+                                       modexShowPage(pip[pip[0].pan->pn].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].tx++; }\r
+                       }\r
+               break;\r
+\r
+               //left movement\r
+               case 1:\r
+                       if(pip[pip[0].pan->pn].tx > 0 && pip[pip[0].pan->pn].tx+pip[pip[0].pan->pn].page->tw <= pip[pip[0].pan->pn].page->tilesw)\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       pip[pip[0].pan->pn].page->dx-=4;\r
+                                       modexShowPage(pip[pip[0].pan->pn].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].tx--; }\r
+                       }\r
+               break;\r
+\r
+               //down movement\r
+               case 4:\r
+                       if(pip[pip[0].pan->pn].ty >= 0 && pip[pip[0].pan->pn].ty+pip[pip[0].pan->pn].page->th < pip[pip[0].pan->pn].page->tilesh)\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       pip[pip[0].pan->pn].page->dy+=4;\r
+                                       modexShowPage(pip[pip[0].pan->pn].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].ty++; }\r
+                       }\r
+               break;\r
+\r
+               //up movement\r
+               case 0:\r
+                       if(pip[pip[0].pan->pn].ty > 0 && pip[pip[0].pan->pn].ty+pip[pip[0].pan->pn].page->th <= pip[pip[0].pan->pn].page->tilesh)\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       pip[pip[0].pan->pn].page->dy-=4;\r
+                                       modexShowPage(pip[pip[0].pan->pn].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].ty--; }\r
+                       }\r
+                       break;\r
+       }\r
+       //if (player[pn].d!=2) printf("player[%u].d=%u player[%u].q=%u\n", pn, player[pn].d, pn, player[pn].q);\r
+}\r
+\r
+/*map_t\r
+allocMap(int w, int h) {\r
+       map_t result;\r
+\r
+       result.width =w;\r
+       result.height=h;\r
+       result.data = malloc(sizeof(byte) * w * h);\r
+       //result.data = (byte *)alloc_emem(((int)sizeof(byte) * w * h)/1024);\r
+       if(isEMS() || checkEMS())\r
+       {\r
+               XMOVE mm;\r
+               //emmhandle = mallocEMS(coretotalEMS());//alloc_emem((int)sizeof(map))\r
+               mm.length=sizeof(result);\r
+               mm.sourceH=0;\r
+               mm.sourceOff=ptr2long(&result);\r
+               mm.destH=emmhandle;\r
+               mm.destOff=0;\r
+               ist = move_emem(&mm);\r
+               if(!ist){ dealloc_emem(emmhandle); exit(5); }\r
+               printf("%d\n", coretotalEMS());\r
+       }\r
+\r
+       return result;\r
+}*/\r
+\r
+/*void\r
+initMap(map_t *map) {\r
+       // just a place holder to fill out an alternating pattern\r
+       int x, y, xx, yy;\r
+       int i, q;\r
+//     int tile = 1;\r
+       //if(!isEMS() || !checkEMS())\r
+//             map->tiles = malloc(sizeof(tiles_t));\r
+       //else\r
+       //      map->tiles = (tiles_t *)alloc_emem(sizeof(tiles_t));\r
+\r
+        //create the tile set\r
+       //if(!isEMS() || !checkEMS())\r
+//             map->tiles->data = malloc(sizeof(bitmap_t));\r
+       //else\r
+       //      map->tiles->data = (bitmap_t *)alloc_emem(sizeof(bitmap_t));\r
+//     map->tiles->data->width = (TILEWH);\r
+//     map->tiles->data->height= TILEWH;\r
+       //if(!isEMS() || !checkEMS())\r
+//             map->tiles->data->data = malloc((TILEWH*2)*TILEWH);\r
+       //else\r
+       //      map->tiles->data->data = (byte *)alloc_emem((TILEWH*2)*TILEWH);\r
+//     map->tiles->tileHeight = TILEWH;\r
+//     map->tiles->tileWidth =TILEWH;\r
+//     map->tiles->rows = 1;\r
+//     map->tiles->cols = 1;//2;\r
+\r
+       q=0;\r
+       //for(y=0; y<map->height; y++) {\r
+       //for(x=0; x<map->width; x++) {\r
+       i=0;\r
+       for(yy=0; yy<TILEWH; yy++) {\r
+       for(xx=0; xx<(TILEWH); xx++) {\r
+               //if(x<TILEWH){\r
+                 map->tiles->data->data[i+1] = map->data[q];//28;//0x24;\r
+//               printf("[%d]", map->tiles->data->data[i]);\r
+               //}else{\r
+                 //map->tiles->data->data[i] = map->data[q];//0;//0x34;\r
+                 //printf("]%d[==[%d]", i, map->tiles->data->data[i]);\r
+               //}\r
+               i++;\r
+       }\r
+//     printf("\n");\r
+       }\r
+//     printf("[%d]", map->data[q]);\r
+       q++;\r
+//     }\r
+       //printf("\n\n");\r
+//     }\r
+\r
+       i=0;\r
+       for(y=0; y<map->height; y++) {\r
+               for(x=0; x<map->width; x++) {\r
+//                     map->data[i]=255;\r
+                       printf("[%d]", map->data[i]);\r
+                       //tile = tile ? 0 : 1;\r
+                       i++;\r
+               }\r
+               //tile = tile ? 0 : 1;\r
+       }\r
+}*/\r
+\r
+void near mapScrollRight(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       word x, y;  /* coordinate for drawing */\r
+\r
+       /* increment the pixel position and update the page */\r
+       mv[id].page->dx += player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dx >= mv[id].dxThresh )\r
+       {\r
+       /* go forward one tile */\r
+       mv[id].tx++;\r
+       /* Snap the origin forward */\r
+       mv[id].page->data += 4;\r
+\r
+       mv[id].page->dx = mv[id].map->tiles->tileWidth;\r
+       }\r
+\r
+       /* draw the next column */\r
+       x= mv[0].page->sw + mv[id].map->tiles->tileWidth;\r
+       if(player[plid].q%4)\r
+               if(id==0)\r
+                       mapDrawCol(&mv[0], mv[0].tx + mv[0].page->tw, mv[0].ty-1, x, player, mv->page->dx);\r
+               else\r
+                       if(!pageflipflop && !pageploop)\r
+                               modexCopyPageRegion(mv[id].page, mv[0].page, x, 0, x, 0, mv[id].map->tiles->tileWidth, mv[id].map->tiles->tileHeight*(mv[0].page->th+2));\r
+       mv[0].video->r=1;\r
+}\r
+\r
+\r
+void near mapScrollLeft(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       word x, y;  /* coordinate for drawing */\r
+\r
+       /* decrement the pixel position and update the page */\r
+       mv[id].page->dx -= player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dx == 0)\r
+       {\r
+       /* go backward one tile */\r
+       mv[id].tx--;\r
+       /* Snap the origin backward */\r
+       mv[id].page->data -= 4;\r
+\r
+       mv[id].page->dx = mv[id].map->tiles->tileWidth;\r
+       }\r
+\r
+       /* draw the next column */\r
+       x= 0;\r
+       if(player[plid].q%4)\r
+               if(id==0)\r
+                       mapDrawCol(&mv[0], mv[0].tx - 1, mv[0].ty-1, x, player, mv->page->dx);\r
+               else\r
+                       if(!pageflipflop && !pageploop)\r
+                               modexCopyPageRegion(mv[id].page, mv[0].page, x, 0, x, 0, mv[id].map->tiles->tileWidth, mv[id].map->tiles->tileHeight*(mv[0].page->th+2));\r
+       mv[0].video->r=1;\r
+}\r
+\r
+\r
+void near mapScrollUp(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       word x, y;  /* coordinate for drawing */\r
+\r
+       /* decrement the pixel position and update the page */\r
+       mv[id].page->dy -= player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dy == 0 )\r
+       {\r
+       /* go down one tile */\r
+       mv[id].ty--;\r
+       /* Snap the origin downward */\r
+       mv[id].page->data -= mv[id].page->pi;\r
+\r
+       mv[id].page->dy = mv[id].map->tiles->tileHeight;\r
+       }\r
+\r
+       /* draw the next row */\r
+       y= 0;\r
+       if(player[plid].q%3)\r
+               if(id==0)\r
+                       mapDrawRow(&mv[0], mv[0].tx - 1, mv[0].ty-1, y, player, mv->page->dy);\r
+               else\r
+                       if(!pageflipflop && !pageploop)\r
+                               modexCopyPageRegion(mv[id].page, mv[0].page, 0, y, 0, y, mv[id].map->tiles->tileWidth*(mv[0].page->tw+2), mv[id].map->tiles->tileHeight);\r
+       mv[0].video->r=1;\r
+}\r
+\r
+void near mapScrollDown(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       word x, y;  /* coordinate for drawing */\r
+\r
+       /* increment the pixel position and update the page */\r
+       mv[id].page->dy += player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dy >= mv[id].dyThresh )\r
+       {\r
+       /* go down one tile */\r
+       mv[id].ty++;\r
+       /* Snap the origin downward */\r
+       mv[id].page->data += mv[id].page->pi;\r
+\r
+       mv[id].page->dy = mv[id].map->tiles->tileHeight;\r
+       }\r
+\r
+       /* draw the next row */\r
+       y= mv[0].page->sh + mv[id].map->tiles->tileHeight;\r
+       if(player[plid].q%3)\r
+               if(id==0)\r
+                       mapDrawRow(&mv[0], mv[0].tx - 1, mv[0].ty+mv[0].page->th, y, player, mv->page->dy);\r
+               else\r
+                       if(!pageflipflop && !pageploop)\r
+                               modexCopyPageRegion(mv[id].page, mv[0].page, 0, y, 0, y, mv[id].map->tiles->tileWidth*(mv[0].page->tw+2), mv[id].map->tiles->tileHeight);\r
+       mv[0].video->r=1;\r
+}\r
+\r
+\r
+//TODO finish this wwww\r
+void near ScrollRight(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       /* increment the pixel position and update the page */\r
+       mv[id].page->dx += player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dx >= mv[0].dxThresh )\r
+       {\r
+//             vga_setup_wm1_block_copy();\r
+//             _fmemmove(mv[id].page->data+4, mv[id].page->data, mv[id].page->pagesize);\r
+//             vga_restore_rm0wm0();\r
+               /* Snap the origin forward */\r
+               mv[id].page->data += 4;\r
+               mv[id].page->dx = mv[0].map->tiles->tileWidth;\r
+       }\r
+}\r
+\r
+void near ScrollLeft(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       /* decrement the pixel position and update the page */\r
+       mv[id].page->dx -= player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dx == 0)\r
+       {\r
+//             vga_setup_wm1_block_copy();\r
+//             _fmemmove(mv[id].page->data-4, mv[id].page->data, mv[id].page->pagesize);\r
+//             vga_restore_rm0wm0();\r
+               /* Snap the origin backward */\r
+               mv[id].page->data -= 4;\r
+               mv[id].page->dx = mv[0].map->tiles->tileWidth;\r
+       }\r
+}\r
+\r
+void near ScrollUp(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       /* decrement the pixel position and update the page */\r
+       mv[id].page->dy -= player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dy == 0)\r
+       {\r
+//             vga_setup_wm1_block_copy();\r
+//             _fmemmove(mv[id].page->data-mv[id].page->pi, mv[id].page->data, mv[id].page->pagesize);\r
+//             vga_restore_rm0wm0();\r
+               /* Snap the origin backward */\r
+               mv[id].page->data -= mv[id].page->pi;\r
+               mv[id].page->dy = mv[0].map->tiles->tileWidth;\r
+       }\r
+}\r
+\r
+void near ScrollDown(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       /* increment the pixel position and update the page */\r
+       mv[id].page->dy += player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dy >= mv[0].dxThresh )\r
+       {\r
+//             vga_setup_wm1_block_copy();\r
+//             _fmemmove(mv[id].page->data+mv[id].page->pi, mv[id].page->data, mv[id].page->pagesize);\r
+//             vga_restore_rm0wm0();\r
+               /* Snap the origin forward */\r
+               mv[id].page->data += mv[id].page->pi;\r
+               mv[id].page->dy = mv[0].map->tiles->tileWidth;\r
+       }\r
+}\r
+\r
+sword chkmap(map_t *map, word q)\r
+{\r
+//     bitmap_t bp;\r
+       static byte x[(MAPW*MAPH)+1] =\r
+{ 1, 2, 3, 4, 0, 3, 3, 3, 3, 3, 3, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 11, 12, 4, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 0, 1, 1, 1, 5, 8, 1, 11, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 4, 0, 0, 0, 0, 0, 8, 8, 1, 11, 11, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 2, 3, 4, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 5, 6, 7, 8, 6, 6, 6, 6, 6, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 9, 10, 11, 12, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10 };\r
+/*1,   2,      3,      4,      0,      3,      3,      3,      3,      3,      3,      3,      3,      4,      1,      1,      1,      1,      1,      1,      \\r
+5,     6,      7,      8,      0,      1,      0,      1,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+9,     10,     11,     12,     4,      1,      0,      1,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+13,    14,     15,     16,     0,      1,      1,      1,      5,      8,      1,      11,     11,     1,      1,      1,      1,      1,      1,      1,      \\r
+0,     0,      4,      0,      0,      0,      0,      0,      8,      8,      1,      11,     11,     3,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      0,      0,      0,      0,      8,      8,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      0,      0,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      0,      0,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      3,      3,      3,      1,      2,      3,      4 };*/\r
+       //check for failed to load map\r
+       if((map->width == map->height == 0) && (q>0))\r
+       {\r
+               //initiate a null map!\r
+               map->width=MAPW;///2;\r
+               map->height=MAPH;///2;\r
+//             map->data = malloc(((map->width*map->height)+1)*sizeof(byte));\r
+               map->data = &x;\r
+               map->tiles = malloc(sizeof(tiles_t));\r
+               //fix this to be far~\r
+//             bp = bitmapLoadPcx("data/ed.pcx");\r
+//             map->tiles->data = &bp;\r
+               map->tiles->debug_data = map->data;\r
+               map->tiles->tileHeight = 16;\r
+               map->tiles->tileWidth = 16;\r
+               map->tiles->rows = 1;\r
+               map->tiles->cols = 1;\r
+               map->tiles->debug_text = true;\r
+       }\r
+       else map->tiles->debug_text = false;\r
+       return 0;\r
+}\r
+\r
+//TODO: player position here\r
+void mapGoTo(map_view_t *mv, int tx, int ty)\r
+{\r
+       int px, py;\r
+       unsigned int i;\r
+\r
+       /* set up the coordinates */\r
+       mv[0].tx = mv[1].tx = tx;\r
+       mv[0].ty = mv[1].ty = ty;\r
+       mv[0].page->dx = mv[1].page->dx = mv[2].page->dx = mv[3].page->dx = mv->map->tiles->tileWidth;\r
+       mv[0].page->dy = mv[1].page->dy = mv[2].page->dy = mv[3].page->dy = mv->map->tiles->tileHeight;\r
+\r
+       /* set up the thresholds */\r
+       mv[0].dxThresh = mv[1].dxThresh = mv[2].dxThresh = mv[3].dxThresh = mv->map->tiles->tileWidth * 2;\r
+       mv[0].dyThresh = mv[1].dyThresh = mv[2].dxThresh = mv[3].dxThresh = mv->map->tiles->tileHeight * 2;\r
+\r
+       /* draw the tiles */\r
+       modexClearRegion(mv[0].page, 0, 0, mv[0].page->width, mv[0].page->height, 0);\r
+       py=0;\r
+       i=mv[0].ty * mv[0].map->width + mv[0].tx;\r
+       for(ty=mv[0].ty-1; py < mv[0].page->sh+mv->dyThresh && ty < mv[0].map->height; ty++, py+=mv[0].map->tiles->tileHeight) {\r
+               mapDrawWRow(&mv[0], tx-1, ty, py);\r
+       i+=mv->map->width - tx;\r
+       }\r
+       if(!pageploop) modexCopyPageRegion(mv[1].page, mv[0].page, 0, 0, 0, 0, mv[0].page->width, mv[0].page->height);\r
+//     {\r
+//             unsigned int k,j,o;\r
+//             /* fill screen with a distinctive pattern */\r
+//             for (k=0;k < vga_state.vga_width;k++) {\r
+//                     o = k >> 2;\r
+//                     vga_write_sequencer(0x02/*map mask*/,1 << (k&3));\r
+//                             for (j=0;j < (mv[0].page->height)+(mv[1].page->height)+(mv[2].page->height)+(mv[3].page->height);j++,o += vga_state.vga_stride)\r
+//                                     vga_state.vga_graphics_ram[o] = (k^j)&15; // VRL samples put all colors in first 15!\r
+//             }\r
+//     }\r
+       modexCopyPageRegion(mv[3].page, mv[0].page, 0/**/, 0/**/, 0, 0, 16, 32);\r
+}\r
+\r
+void near\r
+mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y)\r
+{\r
+       word rx;\r
+       word ry;\r
+       word textx=0;\r
+       word texty=0;\r
+       //if(i==0) i=2;\r
+       if(i==0)\r
+       {\r
+               //wwww\r
+               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, 0); //currently the over scan color!\r
+       }\r
+       else\r
+       {\r
+               rx = (((i-1) % ((t->data->width)/t->tileWidth)) * t->tileWidth);\r
+               ry = (((i-1) / ((t->data->height)/t->tileHeight)) * t->tileHeight);\r
+////0000printf("i=%d\n", i);\r
+               switch(t->debug_text)\r
+               {\r
+                       case 0:\r
+#ifndef TILERENDER\r
+                               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, ((t->debug_data[i])+1));\r
+                               //modexprint(page, x, y, 1, 15, 0, (char const *)(t->debug_data[i]));\r
+#else\r
+                               PBUFBFUN                (page, x, y, rx, ry, t->tileWidth, t->tileHeight, (t->data));\r
+                               /* then the sprite. note modding ram ptr means we just draw to (x&3,0) */\r
+                               //draw_vrl1_vgax_modex(x-rx,y-ry,vrl_header,vrl_lineoffs,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));\r
+                               //modexDrawBmpRegion    (page, x, y, rx, ry, t->tileWidth, t->tileHeight, (t->data));\r
+#endif\r
+                       break;\r
+                       case 1:\r
+                               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, (t->debug_data[i])+1);\r
+                               //modexprintbig(page, x, y, 1, 15, 0, (t->debug_data));\r
+                               /*for(texty=0; texty<2; texty++)\r
+                               {\r
+                                       for(textx=0; textx<2; textx++)\r
+                                       {*/\r
+//                                             modexprint(page, x+(textx*8), y+(texty*8), 1, (word)(t->debug_data), 0, (t->debug_data));\r
+/*                                     }\r
+                               }*/\r
+                       break;\r
+               }\r
+       }\r
+}\r
+\r
+void near mapDrawRow(map_view_t *mv, int tx, int ty, word y, player_t *p, word poopoffset)\r
+{\r
+       word x;\r
+       int i;\r
+       poopoffset%=p[0].speed;\r
+//printf("y: %d\n", poopoffset);\r
+       /* the position within the map array */\r
+       i=ty * mv->map->width + tx;\r
+       for(x=poopoffset; x<(mv->page->sw+mv->dxThresh)/(poopoffset+1) && tx < mv->map->width; x+=mv->map->tiles->tileWidth, tx++) {\r
+       if(i>=0) {\r
+               /* we are in the map, so copy! */\r
+               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);\r
+       }\r
+       i++; /* next! */\r
+       }\r
+}\r
+\r
+void near mapDrawCol(map_view_t *mv, int tx, int ty, word x, player_t *p, word poopoffset)\r
+{\r
+       int y;\r
+       int i;\r
+       poopoffset%=p[0].speed;\r
+//printf("x: %d\n", poopoffset);\r
+       /* location in the map array */\r
+       i=ty * mv->map->width + tx;\r
+\r
+       /* We'll copy all of the columns in the screen,\r
+          i + 1 row above and one below */\r
+       for(y=poopoffset; y<(mv->page->sh+mv->dyThresh)/(poopoffset+1) && ty < mv->map->height; y+=mv->map->tiles->tileHeight, ty++) {\r
+       if(i>=0) {\r
+               /* we are in the map, so copy away! */\r
+               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);\r
+       }\r
+       i += mv->map->width;\r
+       }\r
+}\r
+\r
+void mapDrawWRow(map_view_t *mv, int tx, int ty, word y)\r
+{\r
+       word x;\r
+       int i;\r
+\r
+       /* the position within the map array */\r
+       i=ty * mv->map->width + tx;\r
+       for(x=0; x<mv->page->sw+mv->dxThresh && tx < mv->map->width; x+=mv->map->tiles->tileWidth, tx++) {\r
+       if(i>=0) {\r
+               /* we are in the map, so copy! */\r
+               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);\r
+       }\r
+       i++; /* next! */\r
+       }\r
+}\r
+\r
+void mapDrawWCol(map_view_t *mv, int tx, int ty, word x)\r
+{\r
+       int y;\r
+       int i;\r
+\r
+       /* location in the map array */\r
+       i=ty * mv->map->width + tx;\r
+\r
+       /* We'll copy all of the columns in the screen,\r
+          i + 1 row above and one below */\r
+       for(y=0; y<mv->page->sh+mv->dyThresh && ty < mv->map->height; y+=mv->map->tiles->tileHeight, ty++) {\r
+       if(i>=0) {\r
+               /* we are in the map, so copy away! */\r
+               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);\r
+       }\r
+       i += mv->map->width;\r
+       }\r
+}\r
+\r
+/*void qclean()\r
+{\r
+       //setkb(0);\r
+}*/\r
+\r
+unsigned char shinku_fps_indicator_page = 2;\r
+boolean pageflipflop = 1;\r
+boolean pageploop = 1;\r
+\r
+/*     sync    */\r
+void shinku(global_game_variables_t *gv)\r
+{\r
+       word x = (0) + gv->video.page[/*!*/(gv->video.p)].dx; // follow the screen\r
+       word y = (0) + gv->video.page[/*!*/(gv->video.p)].dy; // follow the screen\r
+       word w = 64, h = 8, col = 7, bgcol = 0, type = 1;\r
+       byte o,o2,i;\r
+       //modexCopyPageRegion(pip[1].page, pip[2].page, 16, 16, 16, 16, (14*8)+4, 8+4);\r
+       /* block copy to visible RAM from offscreen */\r
+//     vga_setup_wm1_block_copy();\r
+//     modexCopyPageRegion(&(gv->video.page[shinku_fps_indicator_page]), &(gv->video.page[!shinku_fps_indicator_page]), x, y, x+w, 0, w, h);\r
+//     o =     *(gv->video.page[2].data); // source offscreen\r
+//     o2 =    *(gv->video.page[shinku_fps_indicator_page].data)+(y * vga_state.vga_stride) + (x >> 2); // dest visible (original stride)\r
+//     for (i=0;i < h;i++,o += vga_state.vga_draw_stride,o2 += vga_state.vga_stride) vga_wm1_mem_block_copy(o2,o,w >> 2);\r
+       /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */\r
+//     vga_restore_rm0wm0();\r
+       if(elapsed_timer(gv) >= (1.0 / gv->kurokku.frames_per_second))\r
+       {\r
+               sprintf(gv->pee, "%.0f fps", (double)gv->kurokku.tiku/ticktock(gv));\r
+               //modexClearRegion(&(gv->video.page[shinku_fps_indicator_page]), x, y, w, h, 45);\r
+               modexprint(&(gv->video.page[/*!*/(gv->video.p)]), x, y, type, col, bgcol, gv->pee);\r
+               gv->kurokku.tiku=0;\r
+               /* block copy to visible RAM from offscreen */\r
+//             vga_setup_wm1_block_copy();\r
+//             o =     *(gv->video.page[shinku_fps_indicator_page].data); // source offscreen\r
+//             o2 =    *(gv->video.page[2].data)+(y * vga_state.vga_stride) + (x >> 2); // dest visible (original stride)\r
+//             for (i=0;i < h;i++,o += vga_state.vga_draw_stride,o2 += vga_state.vga_stride) vga_wm1_mem_block_copy(o2,o,w >> 2);\r
+//             modexCopyPageRegion(&(gv->video.page[shinku_fps_indicator_page]), &(gv->video.page[!shinku_fps_indicator_page]), x, y, x, 0, w, h);\r
+               /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */\r
+//             vga_restore_rm0wm0();\r
+       }else //copy dat sheet\r
+       gv->kurokku.tiku++;\r
+\r
+       switch(gv->kurokku.fpscap)\r
+       {\r
+               case 0:\r
+                       //modexprint(&(gv->video.page[shinku_fps_indicator_page]), x, y+8, type, col, bgcol, "sanic!");\r
+                       gv->kurokku.frames_per_second=1;\r
+               break;\r
+               case 1:\r
+                       //turn this off if XT\r
+                       //modexWaitBorder();\r
+                       vga_wait_for_vsync();\r
+                       gv->kurokku.frames_per_second=60;\r
+               break;\r
+       }\r
+       if(pageflipflop){\r
+       if(gv->video.r){\r
+               //vga_setup_wm1_block_copy();\r
+               //_fmemcpy((gv->video.page[(gv->video.p)]).data, (gv->video.page[(!gv->video.p)]).data, gv->video.page[(!gv->video.p)].pagesize);\r
+               //vga_restore_rm0wm0();\r
+               if(!pageploop) modexCopyPageRegion(&(gv->video.page[(gv->video.p)]), &(gv->video.page[(!gv->video.p)]), 0, 0, 0, 0, gv->video.page[gv->video.p].width, gv->video.page[!gv->video.p].height);\r
+               modexShowPage(&(gv->video.page[gv->video.p]));\r
+               if(!pageploop) gv->video.p=!gv->video.p;\r
+               gv->video.r=!gv->video.r;\r
+               //0000gv->video.tickclk = ((*clockw)-gv->video.startclk)/18.2;\r
+       }\r
+       }\r
+}\r
+\r
+void near animatePlayer(map_view_t *pip, player_t *player, word pn, sword scrollswitch)\r
+{\r
+       sword x = player[pn].x;\r
+       sword y = player[pn].y;\r
+       sword bx = x+16;        //buffer's x\r
+       sword by = y+16;        //buffer's y\r
+       word dire=32; //direction\r
+       sword qq; //scroll offset\r
+       word ls = player[pn].persist_aniframe;\r
+\r
+       switch(scrollswitch)\r
+       {\r
+               case 0:\r
+                       qq = 0;\r
+               break;\r
+               default:\r
+                       qq = ((player[pn].q)*(player[pn].speed));\r
+               break;\r
+       }\r
+       //x-=4;\r
+       y-=pip[0].map->tiles->tileHeight;\r
+       switch (player[pn].d)\r
+       {\r
+               case 0:\r
+                       //up\r
+                       dire*=player[pn].d;\r
+                       y-=qq;\r
+                       by-=4;\r
+               break;\r
+               case 3:\r
+                       // right\r
+                       dire*=(player[pn].d-2);\r
+                       x+=qq;\r
+                       bx+=4;\r
+               break;\r
+               case 2:\r
+               break;\r
+               case 4:\r
+                       //down\r
+                       dire*=(player[pn].d-2);\r
+                       y+=qq;\r
+                       by+=4;\r
+               break;\r
+               case 1:\r
+                       //left\r
+                       dire*=(player[pn].d+2);\r
+                       x-=qq;\r
+                       bx-=4;\r
+               break;\r
+       }\r
+\r
+#ifdef SPRITE\r
+//#define FRAME1 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 32, dire, 16, 32,      PLAYERBMPDATA);\r
+//#define FRAME2 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 16, dire, 16, 32,      PLAYERBMPDATA);\r
+//#define FRAME3 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 0, dire, 16, 32,       PLAYERBMPDATA);\r
+//#define FRAME4 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 16, dire, 16, 32,      PLAYERBMPDATA);\r
+#define FRAME1 animate_spri(player[pn].spri);\r
+#define FRAME2 animate_spri(player[pn].spri);\r
+#define FRAME3 animate_spri(player[pn].spri);\r
+#define FRAME4 animate_spri(player[pn].spri);\r
+#else\r
+#define FRAME1 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 16, 32, 2+dire);\r
+#define FRAME2 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 16, 32, 1+dire);\r
+#define FRAME3 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 16, 32, dire);\r
+#define FRAME4 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 16, 32, 1+dire);\r
+#endif\r
+       if(!pageflipflop)\r
+               modexCopyPageRegion(pip[1].page, pip[0].page, x-4, y-4, x-4, y-4, 28, 36);\r
+       else{\r
+               //copy old bg to page0\r
+               //modexCopyPageRegion(pip[3].page, pip[0].page, bx, by, 0, 0,   20, 36);\r
+               //update buffer\r
+               //modexCopyPageRegion(pip[0].page, pip[3].page, 0, 0,   x, y,   20, 36);\r
+       }\r
+//modexCopyPageRegion(page_t *dest, page_t *src, word sx, word sy, word dx, word dy, word width, word height);\r
+       //modexCopyPageRegion(pip[3].page, pip[!(pip->video->p)].page, x-4, y-4, 0, 128, 28, 36);\r
+       /*modexCopyPageRegion(pip[pip->video->p].page,\r
+ pip[!(pip->video->p)].page, x-4, y-4, x-4, y-4, 28, 36);*/\r
+//     else modexCopyPageRegion(pip[1].page, pip[0].page, x-4, y-4, x-4, y-4, 28, 40);\r
+       switch(ls)\r
+       {\r
+               case 1:\r
+                       FRAME1\r
+               break;\r
+               case 2:\r
+                       FRAME2\r
+               break;\r
+               case 3:\r
+                       FRAME3\r
+               break;\r
+               case 4:\r
+                       FRAME4\r
+               break;\r
+       }\r
+//     if(2>ls && ls>=1) { FRAME1 }else\r
+//     if(3>ls && ls>=2) { FRAME2 }else\r
+//     if(4>ls && ls>=3) { FRAME3 }else\r
+//     if(5>ls && ls>=4) { FRAME4 }\r
+       //modexCopyPageRegion(pip[0].page, pip[3].page, 0, 0, x, y, 16, 32);\r
+       //printf("x=%d  y=%d    bx=%d           by=%d\n", x, y, bx, by);\r
+       pip->video->r=1;\r
+}\r
index 3f8ab3e51b28c1f8fbbed1601e838b154fee7773..ee209e361eb3a5897e72c2933877d4546558d488 100755 (executable)
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "src/lib/bakapee.h"
-
-/* clrstdin() clear any leftover chars tha may be in stdin stream */
-void clrstdin()
-{
-   int ch = 0;
-   while( ( ch = getchar() ) != '\n' && ch != EOF );
-}
-
-//color \82Ä\82·\82Æ
-void colortest(page_t *page, bakapee_t *pee)
-{
-       //if(pee->coor < 256)
-       //{
-               modexcls(page, pee->coor, VGA);
-               pee->coor++;
-       //}else pee->coor = 0;
-}
-
-//color \82Ä\82·\82Æ
-void colorz(page_t *page, bakapee_t *pee)
-{
-       if(pee->coor <= HGQ)
-       {
-               modexcls(page, pee->coor, VGA);
-               pee->coor++;
-       }else pee->coor = LGQ;
-}
-
-//slow spectrum down
-void ssd(page_t *page, bakapee_t *pee, word svq)
-{
-       if(pee->sy < page->sh+1)
-       {
-               if(pee->sx < page->sw+1)
-               {
-                       //mxPutPixel(sx, sy, coor);
-                       //printf("%d %d %d %d\n", pee->sx, pee->sy, svq, pee->coor);
-                       dingpp(page, pee);
-                       pee->sx++;
-               }else pee->sx = 0;
-               if(pee->sx == page->sw)
-               {
-                       pee->sy++;
-                       if(svq == 7) pee->coor++;
-                       if(pee->sy == page->sh && svq == 8) pee->coor = rand()%256;
-               }
-       }else pee->sy = 0;
-}
-
-//plot pixel or plot tile
-void dingpp(page_t *page, bakapee_t *pee)
-{
-       if(pee->tile)
-       {
-#ifndef MXLIB
-       //fill_block(pee->xx, pee->yy, pee->xx+TILEWH, pee->yy+TILEWH, pee->coor);
-               mxFillBox(pee->xx, pee->yy, TILEWH, TILEWH, pee->coor, OP_SET);
-#else
-               modexClearRegion(page, pee->xx, pee->yy, TILEWH, TILEWH, pee->coor);
-#endif
-       }
-       else
-               modexputPixel(page, pee->xx, pee->yy, pee->coor);
-}
-
-void dingo(page_t *page, bakapee_t *pee)
-{
-       if(pee->tile)
-       {
-               if(pee->xx<0) pee->xx=(page->sw-TILEWH);
-               if(pee->yy<0) pee->yy=(page->sh-TILEWH);
-               if(pee->xx>(page->sw-TILEWH)) pee->xx=0;
-               if(pee->yy>(page->sh-TILEWH)/*+(TILEWH*BUFFMX)*/) pee->yy=0;
-       }
-               else
-       {
-               if(pee->xx<0) pee->xx=page->sw;
-               if(pee->yy<0) pee->yy=page->sh;
-               if(pee->xx>page->sw) pee->xx=0;
-               if(pee->yy>page->sh) pee->yy=0;
-       }
-}
-
-//assigning values from randomizer
-void dingas(bakapee_t *pee)
-{
-       if(pee->gq == BONK) dingu(pee);
-       if(!pee->bakax)
-       {
-               if(pee->tile)
-               pee->xx-=TILEWH;
-               else pee->xx--;
-       }
-       else if(pee->bakax>1)
-       {
-               if(pee->tile)
-               pee->xx+=TILEWH;
-               else pee->xx++;
-       }
-       if(!pee->bakay)
-       {
-               if(pee->tile)
-               pee->yy-=TILEWH;
-               else pee->yy--;
-       }
-       else if(pee->bakay>1)
-       {
-               if(pee->tile)
-               pee->yy+=TILEWH;
-               else pee->yy++;
-       }
-}
-
-void dingu(bakapee_t *pee)
-{
-       if(pee->coor < HGQ && pee->coor < LGQ) pee->coor = LGQ;
-       if(pee->coor < HGQ)
-       {
-               pee->coor++;
-       }else{
-               pee->coor = LGQ;
-       }
-}
-
-//randomizer
-void dingq(bakapee_t *pee)
-{
-       if(pee->gq<BONK)
-       {
-               pee->gq++;
-       }
-       else
-       {
-               dingu(pee);
-               pee->gq = 0;
-       }
-       pee->bakax = rand()%3; pee->bakay = rand()%3;
-}
-
-/*-----------ding-------------*/
-void ding(page_t *page, bakapee_t *pee, word q)
-{
-       word d3y, tx=0,ty=0;
-
-//++++  if(q <= 4 && q!=2 && gq == BONK-1) coor = rand()%HGQ;
-       switch(q)
-       {
-               case 1:
-                       dingq(pee);
-                       if(pee->xx==page->sw){pee->bakax=0;}
-                       if(pee->xx==0){pee->bakax=1;}
-                       if(pee->yy==page->sh){pee->bakay=0;}
-                       if(pee->yy==0){pee->bakay=1;}
-               break;
-               case 2:
-                       dingq(pee);
-                       dingas(pee);
-                       dingo(page, pee);
-                       dingpp(page, pee);      //plot the pixel/tile
-                       if(pee->tile)
-                       modexClearRegion(page, (rand()*TILEWH)%page->width, (rand()*TILEWH)%(page->height), TILEWH, TILEWH, 0);
-                       else
-                       modexputPixel(page, rand()%page->width, rand()%page->height, 0);
-               break;
-               case 3:
-                       dingq(pee);
-                       if(pee->xx!=page->sw||pee->yy!=page->sh)
-                       {
-                               if(pee->xx==0){pee->bakax=1;pee->bakay=-1;d3y=1;}
-                               if(pee->yy==0){pee->bakax=1;pee->bakay=0;d3y=1;}
-                               if(pee->xx==page->sw){pee->bakax=-1;pee->bakay=-1;d3y=1;}
-                               if(pee->yy==page->sh){pee->bakax=1;pee->bakay=0;d3y=1;}
-                       }else if(pee->xx==page->sw&&pee->yy==page->sh) pee->xx=pee->yy=0;
-                       if(d3y)
-                       {
-                               if(pee->bakay<0)
-                               {
-                                       pee->yy--;
-                                       d3y--;
-                               }else
-                               if(pee->bakay>0)
-                               {
-                                       pee->yy++;
-                                       d3y--;
-                               }
-                       }
-                       if(pee->bakax<0)
-                       {
-                               pee->xx--;
-                       }else
-                       if(pee->bakax>0)
-                       {
-                               pee->xx++;
-                       }
-                       dingpp(page, pee);      //plot the pixel/tile
-               break;
-               case 4:
-                       dingq(pee);
-                       dingas(pee);
-                       dingo(page, pee);
-                       dingpp(page, pee);      //plot the pixel/tile
-               break;
-               case 5:
-                       colortest(page, pee);
-               break;
-               case 6:
-                       pee->coor = rand()%256;
-                       modexcls(page, pee->coor, VGA);
-               break;
-               case 7:
-                       if(pee->coor <= HGQ)
-                       {
-                               ssd(page, pee, q);
-                               pee->coor++;
-                       }else pee->coor = LGQ;
-               break;
-               case 8:
-                       colorz(page, pee);
-                       modexprint(page, page->sw/2, page->sh/2, 1, 47, 0, "bakapi");
-               break;
-               case 9:
-                       if(pee->coor <= HGQ)
-                       {
-                               ssd(page, pee, q);
-                               pee->coor++;
-                       }else pee->coor = LGQ;
-               break;
-               case 10:
-                       ssd(page, pee, q); /*printf("%d\n", pee->coor);*/
-               break;
-               case 11:
-                       colorz(page, pee); delay(100);
-               break;
-
-               case 16:        //interesting effects
-                       dingq(pee);
-                       if(!pee->bakax){ pee->xx--;}
-                       else if(pee->bakax>0){ pee->xx++; }
-                       if(!pee->bakay){ pee->yy--;}
-                       else if(pee->bakay>0){ pee->yy++; }
-                       dingas(pee);
-                       tx+=pee->xx+TILEWH+4;
-                       ty+=pee->yy+TILEWH+4;
-                       modexClearRegion(page, tx, ty, 4, 4, pee->coor);
-                       if(pee->tile)
-                       modexClearRegion(page, (rand()*4)%page->width, (rand()*4)%(page->height), 4, 4, 0);
-                       else
-                       modexputPixel(page, rand()%page->width, rand()%(page->height), 0);
-                       //printf("%d %d %d %d %d %d\n", pee->xx, pee->yy, tx, ty, TILEWH);
-               break;
-               default:
-               break;
-       }
-       //pee->coor++;
-}
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+\r
+#include "src/lib/bakapee.h"\r
+\r
+/* clrstdin() clear any leftover chars tha may be in stdin stream */\r
+void clrstdin()\r
+{\r
+   int ch = 0;\r
+   while( ( ch = getchar() ) != '\n' && ch != EOF );\r
+}\r
+\r
+//color \82Ä\82·\82Æ\r
+void colortest(page_t *page, bakapee_t *pee)\r
+{\r
+       //if(pee->coor < 256)\r
+       //{\r
+               modexcls(page, pee->coor, VGA);\r
+               pee->coor++;\r
+       //}else pee->coor = 0;\r
+}\r
+\r
+//color \82Ä\82·\82Æ\r
+void colorz(page_t *page, bakapee_t *pee)\r
+{\r
+       if(pee->coor <= HGQ)\r
+       {\r
+               modexcls(page, pee->coor, VGA);\r
+               pee->coor++;\r
+       }else pee->coor = LGQ;\r
+}\r
+\r
+//slow spectrum down\r
+void ssd(page_t *page, bakapee_t *pee, word svq)\r
+{\r
+       if(pee->sy < page->sh+1)\r
+       {\r
+               if(pee->sx < page->sw+1)\r
+               {\r
+                       //mxPutPixel(sx, sy, coor);\r
+                       //printf("%d %d %d %d\n", pee->sx, pee->sy, svq, pee->coor);\r
+                       dingpp(page, pee);\r
+                       pee->sx++;\r
+               }else pee->sx = 0;\r
+               if(pee->sx == page->sw)\r
+               {\r
+                       pee->sy++;\r
+                       if(svq == 7) pee->coor++;\r
+                       if(pee->sy == page->sh && svq == 8) pee->coor = rand()%256;\r
+               }\r
+       }else pee->sy = 0;\r
+}\r
+\r
+//plot pixel or plot tile\r
+void dingpp(page_t *page, bakapee_t *pee)\r
+{\r
+       if(pee->tile)\r
+       {\r
+#ifndef MXLIB\r
+       //fill_block(pee->xx, pee->yy, pee->xx+TILEWH, pee->yy+TILEWH, pee->coor);\r
+               mxFillBox(pee->xx, pee->yy, TILEWH, TILEWH, pee->coor, OP_SET);\r
+#else\r
+               modexClearRegion(page, pee->xx, pee->yy, TILEWH, TILEWH, pee->coor);\r
+#endif\r
+       }\r
+       else\r
+               modexputPixel(page, pee->xx, pee->yy, pee->coor);\r
+}\r
+\r
+void dingo(page_t *page, bakapee_t *pee)\r
+{\r
+       if(pee->tile)\r
+       {\r
+               if(pee->xx<0) pee->xx=(page->sw-TILEWH);\r
+               if(pee->yy<0) pee->yy=(page->sh-TILEWH);\r
+               if(pee->xx>(page->sw-TILEWH)) pee->xx=0;\r
+               if(pee->yy>(page->sh-TILEWH)/*+(TILEWH*BUFFMX)*/) pee->yy=0;\r
+       }\r
+               else\r
+       {\r
+               if(pee->xx<0) pee->xx=page->sw;\r
+               if(pee->yy<0) pee->yy=page->sh;\r
+               if(pee->xx>page->sw) pee->xx=0;\r
+               if(pee->yy>page->sh) pee->yy=0;\r
+       }\r
+}\r
+\r
+//assigning values from randomizer\r
+void dingas(bakapee_t *pee)\r
+{\r
+       if(pee->gq == BONK) dingu(pee);\r
+       if(!pee->bakax)\r
+       {\r
+               if(pee->tile)\r
+               pee->xx-=TILEWH;\r
+               else pee->xx--;\r
+       }\r
+       else if(pee->bakax>1)\r
+       {\r
+               if(pee->tile)\r
+               pee->xx+=TILEWH;\r
+               else pee->xx++;\r
+       }\r
+       if(!pee->bakay)\r
+       {\r
+               if(pee->tile)\r
+               pee->yy-=TILEWH;\r
+               else pee->yy--;\r
+       }\r
+       else if(pee->bakay>1)\r
+       {\r
+               if(pee->tile)\r
+               pee->yy+=TILEWH;\r
+               else pee->yy++;\r
+       }\r
+}\r
+\r
+void dingu(bakapee_t *pee)\r
+{\r
+       if(pee->coor < HGQ && pee->coor < LGQ) pee->coor = LGQ;\r
+       if(pee->coor < HGQ)\r
+       {\r
+               pee->coor++;\r
+       }else{\r
+               pee->coor = LGQ;\r
+       }\r
+}\r
+\r
+//randomizer\r
+void dingq(bakapee_t *pee)\r
+{\r
+       if(pee->gq<BONK)\r
+       {\r
+               pee->gq++;\r
+       }\r
+       else\r
+       {\r
+               dingu(pee);\r
+               pee->gq = 0;\r
+       }\r
+       pee->bakax = rand()%3; pee->bakay = rand()%3;\r
+}\r
+\r
+/*-----------ding-------------*/\r
+void ding(page_t *page, bakapee_t *pee, word q)\r
+{\r
+       word d3y, tx=0,ty=0;\r
+\r
+//++++  if(q <= 4 && q!=2 && gq == BONK-1) coor = rand()%HGQ;\r
+       switch(q)\r
+       {\r
+               case 1:\r
+                       dingq(pee);\r
+                       if(pee->xx==page->sw){pee->bakax=0;}\r
+                       if(pee->xx==0){pee->bakax=1;}\r
+                       if(pee->yy==page->sh){pee->bakay=0;}\r
+                       if(pee->yy==0){pee->bakay=1;}\r
+               break;\r
+               case 2:\r
+                       dingq(pee);\r
+                       dingas(pee);\r
+                       dingo(page, pee);\r
+                       dingpp(page, pee);      //plot the pixel/tile\r
+                       if(pee->tile)\r
+                       modexClearRegion(page, (rand()*TILEWH)%page->width, (rand()*TILEWH)%(page->height), TILEWH, TILEWH, 0);\r
+                       else\r
+                       modexputPixel(page, rand()%page->width, rand()%page->height, 0);\r
+               break;\r
+               case 3:\r
+                       dingq(pee);\r
+                       if(pee->xx!=page->sw||pee->yy!=page->sh)\r
+                       {\r
+                               if(pee->xx==0){pee->bakax=1;pee->bakay=-1;d3y=1;}\r
+                               if(pee->yy==0){pee->bakax=1;pee->bakay=0;d3y=1;}\r
+                               if(pee->xx==page->sw){pee->bakax=-1;pee->bakay=-1;d3y=1;}\r
+                               if(pee->yy==page->sh){pee->bakax=1;pee->bakay=0;d3y=1;}\r
+                       }else if(pee->xx==page->sw&&pee->yy==page->sh) pee->xx=pee->yy=0;\r
+                       if(d3y)\r
+                       {\r
+                               if(pee->bakay<0)\r
+                               {\r
+                                       pee->yy--;\r
+                                       d3y--;\r
+                               }else\r
+                               if(pee->bakay>0)\r
+                               {\r
+                                       pee->yy++;\r
+                                       d3y--;\r
+                               }\r
+                       }\r
+                       if(pee->bakax<0)\r
+                       {\r
+                               pee->xx--;\r
+                       }else\r
+                       if(pee->bakax>0)\r
+                       {\r
+                               pee->xx++;\r
+                       }\r
+                       dingpp(page, pee);      //plot the pixel/tile\r
+               break;\r
+               case 4:\r
+                       dingq(pee);\r
+                       dingas(pee);\r
+                       dingo(page, pee);\r
+                       dingpp(page, pee);      //plot the pixel/tile\r
+               break;\r
+               case 5:\r
+                       colortest(page, pee);\r
+               break;\r
+               case 6:\r
+                       pee->coor = rand()%256;\r
+                       modexcls(page, pee->coor, VGA);\r
+               break;\r
+               case 7:\r
+                       if(pee->coor <= HGQ)\r
+                       {\r
+                               ssd(page, pee, q);\r
+                               pee->coor++;\r
+                       }else pee->coor = LGQ;\r
+               break;\r
+               case 8:\r
+                       colorz(page, pee);\r
+                       modexprint(page, page->sw/2, page->sh/2, 1, 47, 0, "bakapi");\r
+               break;\r
+               case 9:\r
+                       if(pee->coor <= HGQ)\r
+                       {\r
+                               ssd(page, pee, q);\r
+                               pee->coor++;\r
+                       }else pee->coor = LGQ;\r
+               break;\r
+               case 10:\r
+                       ssd(page, pee, q); /*printf("%d\n", pee->coor);*/\r
+               break;\r
+               case 11:\r
+                       colorz(page, pee); delay(100);\r
+               break;\r
+\r
+               case 16:        //interesting effects\r
+                       dingq(pee);\r
+                       if(!pee->bakax){ pee->xx--;}\r
+                       else if(pee->bakax>0){ pee->xx++; }\r
+                       if(!pee->bakay){ pee->yy--;}\r
+                       else if(pee->bakay>0){ pee->yy++; }\r
+                       dingas(pee);\r
+                       tx+=pee->xx+TILEWH+4;\r
+                       ty+=pee->yy+TILEWH+4;\r
+                       modexClearRegion(page, tx, ty, 4, 4, pee->coor);\r
+                       if(pee->tile)\r
+                       modexClearRegion(page, (rand()*4)%page->width, (rand()*4)%(page->height), 4, 4, 0);\r
+                       else\r
+                       modexputPixel(page, rand()%page->width, rand()%(page->height), 0);\r
+                       //printf("%d %d %d %d %d %d\n", pee->xx, pee->yy, tx, ty, TILEWH);\r
+               break;\r
+               default:\r
+               break;\r
+       }\r
+       //pee->coor++;\r
+}\r
index 9d371053163e67e8049bde8e0b4bbc33c7bf10ce..4bbfefd6b4ac880a4246c11e0bd8ec2c0dafe45d 100755 (executable)
@@ -1,5 +1,5 @@
-/*
-
+/*\r
+\r
                    THE IBM PC PROGRAMMER'S GUIDE TO C\r
                                     \r
                                     \r
@@ -21,8 +21,8 @@ proviso that credit is given to the author. Sections of this work may be
 used and distributed without payment under the proviso that credit is\r
 given to both this work and the author. Source code occuring in this work\r
 may be used within commercial and non-commercial applications without\r
-charge and without reference to the author.
-*/
+charge and without reference to the author.\r
+*/\r
      /*\r
      Various functions for using Expanded memory\r
      */\r
@@ -178,4 +178,4 @@ charge and without reference to the author.
           regs.x.dx = handle;\r
           int86(EMM,&regs,&regs);\r
           return (regs.h.ah == 0);\r
-     }
+     }\r
index b288a548ac6a70cca3f29d616e5aeeb023413257..33d24d06ad7de53f264bcfd1c3f90dd984336073 100755 (executable)
@@ -1,5 +1,5 @@
-/*
-
+/*\r
+\r
                    THE IBM PC PROGRAMMER'S GUIDE TO C\r
                                     \r
                                     \r
@@ -21,24 +21,24 @@ proviso that credit is given to the author. Sections of this work may be
 used and distributed without payment under the proviso that credit is\r
 given to both this work and the author. Source code occuring in this work\r
 may be used within commercial and non-commercial applications without\r
-charge and without reference to the author.
- */
-
-#ifndef __EMS_H_
-#define __EMS_H_
-
+charge and without reference to the author.\r
+ */\r
+\r
+#ifndef __EMS_H_\r
+#define __EMS_H_\r
+\r
 #include <dos.h>\r
 #define   EMM  0x67\r
      \r
-char far *emmbase;
-
-emmtest();
-emmok();
-long emmavail();
-long emmalloc(int n);
-emmmap(long handle, int phys, int page);
-void emmmove(int page, char *str, int n);
-void emmget(int page, char *str, int n);
-emmclose(long handle);
-
-#endif __EMS_H_
+char far *emmbase;\r
+\r
+emmtest();\r
+emmok();\r
+long emmavail();\r
+long emmalloc(int n);\r
+emmmap(long handle, int phys, int page);\r
+void emmmove(int page, char *str, int n);\r
+void emmget(int page, char *str, int n);\r
+emmclose(long handle);\r
+\r
+#endif __EMS_H_\r
index 8a8d5d87396c62a3eff362fd3036459522949446..5421d9dd8a57cf37a23cbdc42006859b24117b06 100755 (executable)
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "src/lib/mapread.h"
-
-int jsoneq(const char *json, jsmntok_t *tok, const char *s) {
-       if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start &&
-                       strncmp(json + tok->start, s, tok->end - tok->start) == 0) {
-               return 0;
-       }
-       return -1;
-}
-
-//this function is quite messy ^^; sorry! it is a quick and dirty fix~
-word dump(const char *js, jsmntok_t *t, size_t count, word indent, char *js_sv, map_t *map, dword q) {
-       dword i;
-       word j;//, k;
-       bitmap_t bp;
-       #ifdef DEBUG_JS
-       if(indent==0)
-       {
-               fprintf(stdout, "%s\n", js);
-               fprintf(stdout, "\n");
-       }
-       #endif
-       #ifdef DEBUG_DUMPVARS
-       fprintf(stdout, "t->size=[%d]   ", t->size);
-       fprintf(stdout, "q=[%d] ", q);
-       fprintf(stdout, "indent= [%d]   ", indent);
-       fprintf(stdout, "js_sv= [%s]\n", js_sv);
-       #endif
-       if (count == 0) {
-               return 0;
-       }
-       /* We may want to do strtol() here to get numeric value */
-//0000fprintf(stderr, "t->type=%d\n", t->type);
-       if (t->type == JSMN_PRIMITIVE) {
-               if(strstr(js_sv, "data"))
-               {
-                       /*
-                               here we should recursivly call dump again here to skip over the array until we get the facking width of the map.
-                               so we can initiate the map which allocates the facking map->tiles->data->data properly and THEN we can return
-                               here to read the data.... That is my design for this... wwww
-
-                               FUCK well i am stuck.... wwww
-                       */
-                       map->data[q] = (byte)atoi(js+t->start);
-                       #ifdef DEBUG_MAPDATA
-                               fprintf(stdout, "%d[%d]", q, map->data[q]);
-                       #endif
-               }
-               else
-               if(strstr(js_sv, "height"))
-               {
-                       map->height = atoi(js+t->start);
-                       #ifdef DEBUG_MAPVAR
-                       fprintf(stdout, "indent= [%d]   ", indent);
-                       fprintf(stdout, "h:[%d]\n", map->height);
-                       #endif
-               }else if(strstr(js_sv, "width"))
-               {
-                       map->width = atoi(js+t->start);
-                       #ifdef DEBUG_MAPVAR
-                       fprintf(stdout, "indent= [%d]   ", indent);
-                       fprintf(stdout, "w:[%d]\n", map->width);
-                       #endif
-               }
-               return 1;
-               /* We may use strndup() to fetch string value */
-       } else if (t->type == JSMN_STRING) {
-               if(jsoneq(js, t, "data") == 0)
-               {
-//                     fprintf(stdout, "[[[[%d|%d]]]]\n", &(t+1)->size, (t+1)->size);
-//                     fprintf(stdout, "\n%.*s[xx[%d|%d]xx]\n", (t+1)->end - (t+1)->start, js+(t+1)->start, &(t+1)->size, (t+1)->size);
-                       map->data = malloc(sizeof(byte) * (t+1)->size);
-                       map->tiles = malloc(sizeof(tiles_t));
-                       map->tiles->btdata = malloc(sizeof(bitmap_t));
-                       //fix this to be far~
-                       bp = bitmapLoadPcx("data/ed.pcx");
-//                     bp = bitmapLoadPcx("data/koishi^^.pcx");
-                       map->tiles->btdata = &bp;
-//----                 map->tiles->data = planar_buf_from_bitmap(&bp);
-                       //map->tiles->data->data = malloc((16/**2*/)*16);
-                       //map->tiles->data->width = (16/**2*/);
-                       //map->tiles->data->height= 16;
-                       map->tiles->tileHeight = 16;
-                       map->tiles->tileWidth = 16;
-                       map->tiles->rows = 1;
-                       map->tiles->cols = 1;
-                       map->tiles->debug_text=false;
-                       strcpy(js_sv, "data");//strdup(js+t->start);//, t->end - t->start);
-               }
-               else
-               if (jsoneq(js, t, "height") == 0 && indent<=1)
-               {
-                       strcpy(js_sv, "height");//strdup(js+t->start);//, t->end - t->start);
-               }else
-               if(jsoneq(js, t, "width") == 0 && indent<=1)
-               {
-                       strcpy(js_sv, "width");//strdup(js+t->start);//, t->end - t->start);
-               }else strcpy(js_sv, "\0");
-               return 1;
-       } else if (t->type == JSMN_OBJECT) {
-               //fprintf(stdout, "\n");
-               j = 0;
-               for (i = 0; i < t->size; i++) {
-                       //for (k = 0; k < indent; k++) fprintf(stdout, "\t");
-                       j += dump(js, t+1+j, count-j, indent+1, js_sv, map, i);
-                       //fprintf(stdout, ": ");
-                       j += dump(js, t+1+j, count-j, indent+1, js_sv, map, i);
-                       //fprintf(stdout, "\n");
-               }
-               return j+1;
-       } else if (t->type == JSMN_ARRAY) {
-               j = 0;
-               //fprintf(stdout, "==\n");
-               for (i = 0; i < t->size; i++) {
-                       //for (k = 0; k < indent-1; k++) fprintf(stdout, "\t");
-                       //fprintf(stdout, "\t-");
-                       j += dump(js, t+1+j, count-j, indent+1, js_sv, map, i);
-                       //fprintf(stdout, "==\n");
-               }
-               return j+1;
-       }
-       return 0;
-}
-
-int loadmap(char *mn, map_t *map)
-{
-       int r;
-       static word incr=0;
-       int eof_expected = 0;
-       char *js = NULL;
-       size_t jslen = 0;
-       char buf[BUFSIZ];
-       static char js_ss[16];
-
-       jsmn_parser p;
-       jsmntok_t *tok;
-       size_t tokcount = 2;
-
-       FILE *fh = fopen(mn, "r");
-
-       /* Prepare parser */
-       jsmn_init(&p);
-
-       /* Allocate some tokens as a start */
-//0000fprintf(stderr, "tok malloc\n");
-       tok = malloc(sizeof(*tok) * tokcount);
-       if (tok == NULL) {
-               fprintf(stderr, "malloc(): errno=%d\n", errno);
-               return 3;
-       }
-
-       for (;;) {
-               /* Read another chunk */
-//0000fprintf(stderr, "read\n");
-               r = fread(buf, 1, sizeof(buf), fh);
-               if (r < 0) {
-                       fprintf(stderr, "fread(): %d, errno=%d\n", r, errno);
-                       return 1;
-               }
-               if (r == 0) {
-                       if (eof_expected != 0) {
-                               return 0;
-                       } else {
-                               fprintf(stderr, "fread(): unexpected EOF\n");
-                               return 2;
-                       }
-               }
-//0000fprintf(stdout, "r=      [%d]    BUFSIZ=%d\n", r, BUFSIZ);
-//0000fprintf(stderr, "js alloc~\n");
-               js = realloc(js, jslen + r + 1);
-               if (js == NULL) {
-                       fprintf(stderr, "*js=%Fp\n", *js);
-                       fprintf(stderr, "realloc(): errno = %d\n", errno);
-                       return 3;
-               }
-               strncpy(js + jslen, buf, r);
-               jslen = jslen + r;
-
-again:
-//0000fprintf(stdout, "        parse~ tok=%zu  jslen=%zu       r=%d    _memavl()=%u    BUFSIZ=%d~\n", tokcount, jslen, r, _memavl(), BUFSIZ);
-//0000fprintf(stdout, "p=[%u]  [%u]    [%d]\n", p.pos, p.toknext, p.toksuper);
-/*
-               I think it crashes on the line below when it tries to parse the data of huge maps... wwww this is a jsmn problem wwww
-*/
-               r = jsmn_parse(&p, js, jslen, tok, tokcount);
-//0000fprintf(stdout, "r=      [%d]\n", r);
-               if (r < 0) {
-                       if (r == JSMN_ERROR_NOMEM) {
-                               tokcount = tokcount * 2;
-//0000fprintf(stderr, "tok realloc~ %zu\n", tokcount);
-                               tok = realloc(tok, sizeof(*tok) * tokcount);
-                               if (tok == NULL) {
-                                       fprintf(stderr, "realloc(): errno=%d\n", errno);
-                                       return 3;
-                               }
-                               goto again;
-                       }
-               } else {
-                       //printf("js=%Fp\n", (js));
-                       //printf("*js=%Fp\n", (*(js)));
-                       //printf("&*js=%s\n", &(*(js)));
-                       //printf("&buf=[%Fp]\n", &buf);
-                       //printf("&buf_seg=[%x]\n", FP_SEG(&buf));
-                       //printf("&buf_off=[%x]\n", FP_OFF(&buf));
-                       //printf("&buf_fp=[%Fp]\n", MK_FP(FP_SEG(&buf), FP_OFF(&buf)));
-                       //printf("buf=[\n%s\n]\n", buf);
-                       //printf("buff=[%Fp]\n", buff);
-                       //printf("(*buff)=[%Fp]\n", (*buff));
-                       //printf("&(*buff)=[\n%s\n]\n", &(*buff));
-                       #ifdef DEBUG_DUMPVARS
-                       fprintf(stdout, "running dump~\n");
-                       #endif
-                       dump(js, tok, p.toknext, incr, &js_ss, map, 0);
-                       eof_expected = 1;
-               }
-       }
-
-       free(js);
-       free(tok);
-       fclose(fh);
-
-       return 0;
-}
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+\r
+#include "src/lib/mapread.h"\r
+\r
+int jsoneq(const char *json, jsmntok_t *tok, const char *s) {\r
+       if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start &&\r
+                       strncmp(json + tok->start, s, tok->end - tok->start) == 0) {\r
+               return 0;\r
+       }\r
+       return -1;\r
+}\r
+\r
+//this function is quite messy ^^; sorry! it is a quick and dirty fix~\r
+word dump(const char *js, jsmntok_t *t, size_t count, word indent, char *js_sv, map_t *map, dword q) {\r
+       dword i;\r
+       word j;//, k;\r
+       bitmap_t bp;\r
+       #ifdef DEBUG_JS\r
+       if(indent==0)\r
+       {\r
+               fprintf(stdout, "%s\n", js);\r
+               fprintf(stdout, "\n");\r
+       }\r
+       #endif\r
+       #ifdef DEBUG_DUMPVARS\r
+       fprintf(stdout, "t->size=[%d]   ", t->size);\r
+       fprintf(stdout, "q=[%d] ", q);\r
+       fprintf(stdout, "indent= [%d]   ", indent);\r
+       fprintf(stdout, "js_sv= [%s]\n", js_sv);\r
+       #endif\r
+       if (count == 0) {\r
+               return 0;\r
+       }\r
+       /* We may want to do strtol() here to get numeric value */\r
+//0000fprintf(stderr, "t->type=%d\n", t->type);\r
+       if (t->type == JSMN_PRIMITIVE) {\r
+               if(strstr(js_sv, "data"))\r
+               {\r
+                       /*\r
+                               here we should recursivly call dump again here to skip over the array until we get the facking width of the map.\r
+                               so we can initiate the map which allocates the facking map->tiles->data->data properly and THEN we can return\r
+                               here to read the data.... That is my design for this... wwww\r
+\r
+                               FUCK well i am stuck.... wwww\r
+                       */\r
+                       map->data[q] = (byte)atoi(js+t->start);\r
+                       #ifdef DEBUG_MAPDATA\r
+                               fprintf(stdout, "%d[%d]", q, map->data[q]);\r
+                       #endif\r
+               }\r
+               else\r
+               if(strstr(js_sv, "height"))\r
+               {\r
+                       map->height = atoi(js+t->start);\r
+                       #ifdef DEBUG_MAPVAR\r
+                       fprintf(stdout, "indent= [%d]   ", indent);\r
+                       fprintf(stdout, "h:[%d]\n", map->height);\r
+                       #endif\r
+               }else if(strstr(js_sv, "width"))\r
+               {\r
+                       map->width = atoi(js+t->start);\r
+                       #ifdef DEBUG_MAPVAR\r
+                       fprintf(stdout, "indent= [%d]   ", indent);\r
+                       fprintf(stdout, "w:[%d]\n", map->width);\r
+                       #endif\r
+               }\r
+               return 1;\r
+               /* We may use strndup() to fetch string value */\r
+       } else if (t->type == JSMN_STRING) {\r
+               if(jsoneq(js, t, "data") == 0)\r
+               {\r
+//                     fprintf(stdout, "[[[[%d|%d]]]]\n", &(t+1)->size, (t+1)->size);\r
+//                     fprintf(stdout, "\n%.*s[xx[%d|%d]xx]\n", (t+1)->end - (t+1)->start, js+(t+1)->start, &(t+1)->size, (t+1)->size);\r
+                       map->data = malloc(sizeof(byte) * (t+1)->size);\r
+                       map->tiles = malloc(sizeof(tiles_t));\r
+                       map->tiles->btdata = malloc(sizeof(bitmap_t));\r
+                       //fix this to be far~\r
+                       bp = bitmapLoadPcx("data/ed.pcx");\r
+//                     bp = bitmapLoadPcx("data/koishi^^.pcx");\r
+                       map->tiles->btdata = &bp;\r
+//----                 map->tiles->data = planar_buf_from_bitmap(&bp);\r
+                       //map->tiles->data->data = malloc((16/**2*/)*16);\r
+                       //map->tiles->data->width = (16/**2*/);\r
+                       //map->tiles->data->height= 16;\r
+                       map->tiles->tileHeight = 16;\r
+                       map->tiles->tileWidth = 16;\r
+                       map->tiles->rows = 1;\r
+                       map->tiles->cols = 1;\r
+                       map->tiles->debug_text=false;\r
+                       strcpy(js_sv, "data");//strdup(js+t->start);//, t->end - t->start);\r
+               }\r
+               else\r
+               if (jsoneq(js, t, "height") == 0 && indent<=1)\r
+               {\r
+                       strcpy(js_sv, "height");//strdup(js+t->start);//, t->end - t->start);\r
+               }else\r
+               if(jsoneq(js, t, "width") == 0 && indent<=1)\r
+               {\r
+                       strcpy(js_sv, "width");//strdup(js+t->start);//, t->end - t->start);\r
+               }else strcpy(js_sv, "\0");\r
+               return 1;\r
+       } else if (t->type == JSMN_OBJECT) {\r
+               //fprintf(stdout, "\n");\r
+               j = 0;\r
+               for (i = 0; i < t->size; i++) {\r
+                       //for (k = 0; k < indent; k++) fprintf(stdout, "\t");\r
+                       j += dump(js, t+1+j, count-j, indent+1, js_sv, map, i);\r
+                       //fprintf(stdout, ": ");\r
+                       j += dump(js, t+1+j, count-j, indent+1, js_sv, map, i);\r
+                       //fprintf(stdout, "\n");\r
+               }\r
+               return j+1;\r
+       } else if (t->type == JSMN_ARRAY) {\r
+               j = 0;\r
+               //fprintf(stdout, "==\n");\r
+               for (i = 0; i < t->size; i++) {\r
+                       //for (k = 0; k < indent-1; k++) fprintf(stdout, "\t");\r
+                       //fprintf(stdout, "\t-");\r
+                       j += dump(js, t+1+j, count-j, indent+1, js_sv, map, i);\r
+                       //fprintf(stdout, "==\n");\r
+               }\r
+               return j+1;\r
+       }\r
+       return 0;\r
+}\r
+\r
+int loadmap(char *mn, map_t *map)\r
+{\r
+       int r;\r
+       static word incr=0;\r
+       int eof_expected = 0;\r
+       char *js = NULL;\r
+       size_t jslen = 0;\r
+       char buf[BUFSIZ];\r
+       static char js_ss[16];\r
+\r
+       jsmn_parser p;\r
+       jsmntok_t *tok;\r
+       size_t tokcount = 2;\r
+\r
+       FILE *fh = fopen(mn, "r");\r
+\r
+       /* Prepare parser */\r
+       jsmn_init(&p);\r
+\r
+       /* Allocate some tokens as a start */\r
+//0000fprintf(stderr, "tok malloc\n");\r
+       tok = malloc(sizeof(*tok) * tokcount);\r
+       if (tok == NULL) {\r
+               fprintf(stderr, "malloc(): errno=%d\n", errno);\r
+               return 3;\r
+       }\r
+\r
+       for (;;) {\r
+               /* Read another chunk */\r
+//0000fprintf(stderr, "read\n");\r
+               r = fread(buf, 1, sizeof(buf), fh);\r
+               if (r < 0) {\r
+                       fprintf(stderr, "fread(): %d, errno=%d\n", r, errno);\r
+                       return 1;\r
+               }\r
+               if (r == 0) {\r
+                       if (eof_expected != 0) {\r
+                               return 0;\r
+                       } else {\r
+                               fprintf(stderr, "fread(): unexpected EOF\n");\r
+                               return 2;\r
+                       }\r
+               }\r
+//0000fprintf(stdout, "r=      [%d]    BUFSIZ=%d\n", r, BUFSIZ);\r
+//0000fprintf(stderr, "js alloc~\n");\r
+               js = realloc(js, jslen + r + 1);\r
+               if (js == NULL) {\r
+                       fprintf(stderr, "*js=%Fp\n", *js);\r
+                       fprintf(stderr, "realloc(): errno = %d\n", errno);\r
+                       return 3;\r
+               }\r
+               strncpy(js + jslen, buf, r);\r
+               jslen = jslen + r;\r
+\r
+again:\r
+//0000fprintf(stdout, "        parse~ tok=%zu  jslen=%zu       r=%d    _memavl()=%u    BUFSIZ=%d~\n", tokcount, jslen, r, _memavl(), BUFSIZ);\r
+//0000fprintf(stdout, "p=[%u]  [%u]    [%d]\n", p.pos, p.toknext, p.toksuper);\r
+/*\r
+               I think it crashes on the line below when it tries to parse the data of huge maps... wwww this is a jsmn problem wwww\r
+*/\r
+               r = jsmn_parse(&p, js, jslen, tok, tokcount);\r
+//0000fprintf(stdout, "r=      [%d]\n", r);\r
+               if (r < 0) {\r
+                       if (r == JSMN_ERROR_NOMEM) {\r
+                               tokcount = tokcount * 2;\r
+//0000fprintf(stderr, "tok realloc~ %zu\n", tokcount);\r
+                               tok = realloc(tok, sizeof(*tok) * tokcount);\r
+                               if (tok == NULL) {\r
+                                       fprintf(stderr, "realloc(): errno=%d\n", errno);\r
+                                       return 3;\r
+                               }\r
+                               goto again;\r
+                       }\r
+               } else {\r
+                       //printf("js=%Fp\n", (js));\r
+                       //printf("*js=%Fp\n", (*(js)));\r
+                       //printf("&*js=%s\n", &(*(js)));\r
+                       //printf("&buf=[%Fp]\n", &buf);\r
+                       //printf("&buf_seg=[%x]\n", FP_SEG(&buf));\r
+                       //printf("&buf_off=[%x]\n", FP_OFF(&buf));\r
+                       //printf("&buf_fp=[%Fp]\n", MK_FP(FP_SEG(&buf), FP_OFF(&buf)));\r
+                       //printf("buf=[\n%s\n]\n", buf);\r
+                       //printf("buff=[%Fp]\n", buff);\r
+                       //printf("(*buff)=[%Fp]\n", (*buff));\r
+                       //printf("&(*buff)=[\n%s\n]\n", &(*buff));\r
+                       #ifdef DEBUG_DUMPVARS\r
+                       fprintf(stdout, "running dump~\n");\r
+                       #endif\r
+                       dump(js, tok, p.toknext, incr, &js_ss, map, 0);\r
+                       eof_expected = 1;\r
+               }\r
+       }\r
+\r
+       free(js);\r
+       free(tok);\r
+       fclose(fh);\r
+\r
+       return 0;\r
+}\r
index 760906c87681b9c38a28b379a066f7ca6be47c97..7e6ac1c5ac07776ba505f195d72d742b0b9ab3be 100755 (executable)
-/* midi.c
- *
- * Adlib OPL2/OPL3 FM synthesizer chipset test program.
- * Play MIDI file using the OPLx synthesizer (well, poorly anyway)
- * (C) 2010-2012 Jonathan Campbell.
- * Hackipedia DOS library.
- *
- * This code is licensed under the LGPL.
- * <insert LGPL legal text here>
- *
- * Compiles for intended target environments:
- *   - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]
- */
-
-#include "src/lib/midi.h"
-
-static unsigned int            midi_trk_count=0;
-struct midi_note               midi_notes[ADLIB_FM_VOICES];
-struct midi_channel            midi_ch[MIDI_MAX_CHANNELS];
-struct midi_track              midi_trk[MIDI_MAX_TRACKS];
-
-/* MIDI params. Nobody ever said it was a straightforward standard!
- * NTS: These are for reading reference. Internally we convert everything to 100Hz time base. */
-static unsigned int ticks_per_quarter_note=0;  /* "Ticks per beat" */
-
-#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))
-static inline unsigned long farptr2phys(unsigned char far *p) { /* take 16:16 pointer convert to physical memory address */
-       return ((unsigned long)FP_SEG(p) << 4UL) + ((unsigned long)FP_OFF(p));
-}
-#endif
-
-static inline unsigned char midi_trk_read(struct midi_track *t) {
-       unsigned char c;
-
-       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */
-       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence) {
-               t->eof = 1;
-               return 0xFF;
-       }
-
-       c = *(t->read);
-#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))
-       if (FP_OFF(t->read) >= 0xF) /* 16:16 far pointer aware (NTS: Programs reassigning this pointer MUST normalize the FAR pointer) */
-               t->read = MK_FP(FP_SEG(t->read)+0x1,0);
-       else
-               t->read++;
-#else
-       t->read++;
-#endif
-       return c;
-}
-
-void midi_trk_end(struct midi_track *t) {
-       t->wait = ~0UL;
-       t->read = t->fence;
-}
-
-void midi_trk_skip(struct midi_track *t,unsigned long len) {
-       unsigned long rem;
-
-       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */
-       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence)
-               return;
-
-       if (len > 0xFFF0UL) {
-               midi_trk_end(t);
-               return;
-       }
-#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))
-       {
-               unsigned long tt;
-
-               tt = farptr2phys(t->read);
-               rem = farptr2phys(t->fence) - tt;
-               if (rem > len) rem = len;
-               tt += rem;
-               t->read = MK_FP(tt>>4,tt&0xF);
-       }
-#else
-       rem = (unsigned long)(t->fence - t->read);
-       if (len > rem) len = rem;
-       t->read += len;
-#endif
-}
-
-static const uint32_t midikeys_freqs[0x80] = {
-       0x00082d01,     /* key 0 = 8.17579891564371Hz */
-       0x0008a976,     /* key 1 = 8.66195721802725Hz */
-       0x00092d51,     /* key 2 = 9.17702399741899Hz */
-       0x0009b904,     /* key 3 = 9.72271824131503Hz */
-       0x000a4d05,     /* key 4 = 10.3008611535272Hz */
-       0x000ae9d3,     /* key 5 = 10.9133822322814Hz */
-       0x000b8ff4,     /* key 6 = 11.5623257097386Hz */
-       0x000c3ff6,     /* key 7 = 12.2498573744297Hz */
-       0x000cfa70,     /* key 8 = 12.9782717993733Hz */
-       0x000dc000,     /* key 9 = 13.75Hz */
-       0x000e914f,     /* key 10 = 14.5676175474403Hz */
-       0x000f6f11,     /* key 11 = 15.4338531642539Hz */
-       0x00105a02,     /* key 12 = 16.3515978312874Hz */
-       0x001152ec,     /* key 13 = 17.3239144360545Hz */
-       0x00125aa2,     /* key 14 = 18.354047994838Hz */
-       0x00137208,     /* key 15 = 19.4454364826301Hz */
-       0x00149a0a,     /* key 16 = 20.6017223070544Hz */
-       0x0015d3a6,     /* key 17 = 21.8267644645627Hz */
-       0x00171fe9,     /* key 18 = 23.1246514194771Hz */
-       0x00187fed,     /* key 19 = 24.4997147488593Hz */
-       0x0019f4e0,     /* key 20 = 25.9565435987466Hz */
-       0x001b8000,     /* key 21 = 27.5Hz */
-       0x001d229e,     /* key 22 = 29.1352350948806Hz */
-       0x001ede22,     /* key 23 = 30.8677063285078Hz */
-       0x0020b404,     /* key 24 = 32.7031956625748Hz */
-       0x0022a5d8,     /* key 25 = 34.647828872109Hz */
-       0x0024b545,     /* key 26 = 36.7080959896759Hz */
-       0x0026e410,     /* key 27 = 38.8908729652601Hz */
-       0x00293414,     /* key 28 = 41.2034446141087Hz */
-       0x002ba74d,     /* key 29 = 43.6535289291255Hz */
-       0x002e3fd2,     /* key 30 = 46.2493028389543Hz */
-       0x0030ffda,     /* key 31 = 48.9994294977187Hz */
-       0x0033e9c0,     /* key 32 = 51.9130871974931Hz */
-       0x00370000,     /* key 33 = 55Hz */
-       0x003a453d,     /* key 34 = 58.2704701897612Hz */
-       0x003dbc44,     /* key 35 = 61.7354126570155Hz */
-       0x00416809,     /* key 36 = 65.4063913251497Hz */
-       0x00454bb0,     /* key 37 = 69.295657744218Hz */
-       0x00496a8b,     /* key 38 = 73.4161919793519Hz */
-       0x004dc820,     /* key 39 = 77.7817459305202Hz */
-       0x00526829,     /* key 40 = 82.4068892282175Hz */
-       0x00574e9b,     /* key 41 = 87.307057858251Hz */
-       0x005c7fa4,     /* key 42 = 92.4986056779086Hz */
-       0x0061ffb5,     /* key 43 = 97.9988589954373Hz */
-       0x0067d380,     /* key 44 = 103.826174394986Hz */
-       0x006e0000,     /* key 45 = 110Hz */
-       0x00748a7b,     /* key 46 = 116.540940379522Hz */
-       0x007b7888,     /* key 47 = 123.470825314031Hz */
-       0x0082d012,     /* key 48 = 130.812782650299Hz */
-       0x008a9760,     /* key 49 = 138.591315488436Hz */
-       0x0092d517,     /* key 50 = 146.832383958704Hz */
-       0x009b9041,     /* key 51 = 155.56349186104Hz */
-       0x00a4d053,     /* key 52 = 164.813778456435Hz */
-       0x00ae9d36,     /* key 53 = 174.614115716502Hz */
-       0x00b8ff49,     /* key 54 = 184.997211355817Hz */
-       0x00c3ff6a,     /* key 55 = 195.997717990875Hz */
-       0x00cfa700,     /* key 56 = 207.652348789973Hz */
-       0x00dc0000,     /* key 57 = 220Hz */
-       0x00e914f6,     /* key 58 = 233.081880759045Hz */
-       0x00f6f110,     /* key 59 = 246.941650628062Hz */
-       0x0105a025,     /* key 60 = 261.625565300599Hz */
-       0x01152ec0,     /* key 61 = 277.182630976872Hz */
-       0x0125aa2e,     /* key 62 = 293.664767917408Hz */
-       0x01372082,     /* key 63 = 311.126983722081Hz */
-       0x0149a0a7,     /* key 64 = 329.62755691287Hz */
-       0x015d3a6d,     /* key 65 = 349.228231433004Hz */
-       0x0171fe92,     /* key 66 = 369.994422711634Hz */
-       0x0187fed4,     /* key 67 = 391.995435981749Hz */
-       0x019f4e00,     /* key 68 = 415.304697579945Hz */
-       0x01b80000,     /* key 69 = 440Hz */
-       0x01d229ec,     /* key 70 = 466.16376151809Hz */
-       0x01ede220,     /* key 71 = 493.883301256124Hz */
-       0x020b404a,     /* key 72 = 523.251130601197Hz */
-       0x022a5d81,     /* key 73 = 554.365261953744Hz */
-       0x024b545c,     /* key 74 = 587.329535834815Hz */
-       0x026e4104,     /* key 75 = 622.253967444162Hz */
-       0x0293414f,     /* key 76 = 659.25511382574Hz */
-       0x02ba74da,     /* key 77 = 698.456462866008Hz */
-       0x02e3fd24,     /* key 78 = 739.988845423269Hz */
-       0x030ffda9,     /* key 79 = 783.990871963499Hz */
-       0x033e9c01,     /* key 80 = 830.60939515989Hz */
-       0x03700000,     /* key 81 = 880Hz */
-       0x03a453d8,     /* key 82 = 932.32752303618Hz */
-       0x03dbc440,     /* key 83 = 987.766602512248Hz */
-       0x04168094,     /* key 84 = 1046.50226120239Hz */
-       0x0454bb03,     /* key 85 = 1108.73052390749Hz */
-       0x0496a8b8,     /* key 86 = 1174.65907166963Hz */
-       0x04dc8208,     /* key 87 = 1244.50793488832Hz */
-       0x0526829e,     /* key 88 = 1318.51022765148Hz */
-       0x0574e9b5,     /* key 89 = 1396.91292573202Hz */
-       0x05c7fa49,     /* key 90 = 1479.97769084654Hz */
-       0x061ffb53,     /* key 91 = 1567.981743927Hz */
-       0x067d3802,     /* key 92 = 1661.21879031978Hz */
-       0x06e00000,     /* key 93 = 1760Hz */
-       0x0748a7b1,     /* key 94 = 1864.65504607236Hz */
-       0x07b78880,     /* key 95 = 1975.5332050245Hz */
-       0x082d0128,     /* key 96 = 2093.00452240479Hz */
-       0x08a97607,     /* key 97 = 2217.46104781498Hz */
-       0x092d5171,     /* key 98 = 2349.31814333926Hz */
-       0x09b90410,     /* key 99 = 2489.01586977665Hz */
-       0x0a4d053c,     /* key 100 = 2637.02045530296Hz */
-       0x0ae9d36b,     /* key 101 = 2793.82585146403Hz */
-       0x0b8ff493,     /* key 102 = 2959.95538169308Hz */
-       0x0c3ff6a7,     /* key 103 = 3135.96348785399Hz */
-       0x0cfa7005,     /* key 104 = 3322.43758063956Hz */
-       0x0dc00000,     /* key 105 = 3520Hz */
-       0x0e914f62,     /* key 106 = 3729.31009214472Hz */
-       0x0f6f1100,     /* key 107 = 3951.06641004899Hz */
-       0x105a0250,     /* key 108 = 4186.00904480958Hz */
-       0x1152ec0e,     /* key 109 = 4434.92209562995Hz */
-       0x125aa2e3,     /* key 110 = 4698.63628667852Hz */
-       0x13720820,     /* key 111 = 4978.03173955329Hz */
-       0x149a0a79,     /* key 112 = 5274.04091060592Hz */
-       0x15d3a6d6,     /* key 113 = 5587.65170292806Hz */
-       0x171fe927,     /* key 114 = 5919.91076338615Hz */
-       0x187fed4e,     /* key 115 = 6271.92697570799Hz */
-       0x19f4e00a,     /* key 116 = 6644.87516127912Hz */
-       0x1b800000,     /* key 117 = 7040Hz */
-       0x1d229ec4,     /* key 118 = 7458.62018428944Hz */
-       0x1ede2200,     /* key 119 = 7902.13282009799Hz */
-       0x20b404a1,     /* key 120 = 8372.01808961916Hz */
-       0x22a5d81c,     /* key 121 = 8869.84419125991Hz */
-       0x24b545c7,     /* key 122 = 9397.27257335704Hz */
-       0x26e41040,     /* key 123 = 9956.06347910659Hz */
-       0x293414f2,     /* key 124 = 10548.0818212118Hz */
-       0x2ba74dac,     /* key 125 = 11175.3034058561Hz */
-       0x2e3fd24f,     /* key 126 = 11839.8215267723Hz */
-       0x30ffda9c      /* key 127 = 12543.853951416Hz */
-};
-
-static uint32_t midi_note_freq(struct midi_channel *ch,unsigned char key) {
-       return midikeys_freqs[key&0x7F];
-}
-
-static struct midi_note *get_fm_note(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char do_alloc) {
-       unsigned int tch = (unsigned int)(t - midi_trk); /* pointer math */
-       unsigned int ach = (unsigned int)(ch - midi_ch); /* pointer math */
-       unsigned int i,freen=~0;
-
-       for (i=0;i < ADLIB_FM_VOICES;i++) {
-               if (midi_notes[i].busy) {
-                       if (midi_notes[i].note_channel == ach && midi_notes[i].note_track == tch && midi_notes[i].note_number == key)
-                               return &midi_notes[i];
-               }
-               else {
-                       if (freen == ~0) freen = i;
-               }
-       }
-
-       if (do_alloc && freen != ~0) return &midi_notes[freen];
-       return NULL;
-}
-
-static void drop_fm_note(struct midi_channel *ch,unsigned char key) {
-       unsigned int ach = (unsigned int)(ch - midi_ch); /* pointer math */
-       unsigned int i;
-
-       for (i=0;i < ADLIB_FM_VOICES;i++) {
-               if (midi_notes[i].busy && midi_notes[i].note_channel == ach) {
-                       midi_notes[i].busy = 0;
-                       break;
-               }
-       }
-}
-
-static inline void on_key_aftertouch(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {
-       struct midi_note *note = get_fm_note(t,ch,key,/*do_alloc*/0);
-       uint32_t freq = midi_note_freq(ch,key);
-       unsigned int ach;
-
-       if (note == NULL) return;
-
-       note->busy = 1;
-       note->note_number = key;
-       note->note_velocity = vel;
-       note->note_track = (unsigned int)(t - midi_trk);
-       note->note_channel = (unsigned int)(ch - midi_ch);
-       ach = (unsigned int)(note - midi_notes); /* which FM channel? */
-       adlib_freq_to_fm_op(&adlib_fm[ach].mod,(double)freq / 65536);
-       adlib_fm[ach].mod.attack_rate = vel >> 3; /* 0-127 to 0-15 */
-       adlib_fm[ach].mod.sustain_level = vel >> 3;
-       adlib_fm[ach].mod.key_on = 1;
-       adlib_update_groupA0(ach,&adlib_fm[ach]);
-}
-
-static inline void on_key_on(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {
-       struct midi_note *note = get_fm_note(t,ch,key,/*do_alloc*/1);
-       uint32_t freq = midi_note_freq(ch,key);
-       unsigned int ach;
-
-       /* HACK: Ignore percussion */
-       if ((ch->program >= 8 && ch->program <= 15)/*Chromatic percussion*/ ||
-               (ch->program >= 112 && ch->program <= 119)/*Percussive*/ ||
-               ch == &midi_ch[9]/*MIDI channel 10 (DAMN YOU 1-BASED COUNTING)*/)
-               return;
-
-       if (note == NULL) {
-               /* then we'll have to knock one off to make room */
-               drop_fm_note(ch,key);
-               note = get_fm_note(t,ch,key,1);
-               if (note == NULL) return;
-       }
-
-       note->busy = 1;
-       note->note_number = key;
-       note->note_velocity = vel;
-       note->note_track = (unsigned int)(t - midi_trk);
-       note->note_channel = (unsigned int)(ch - midi_ch);
-       ach = (unsigned int)(note - midi_notes); /* which FM channel? */
-       adlib_freq_to_fm_op(&adlib_fm[ach].mod,(double)freq / 65536);
-       adlib_fm[ach].mod.attack_rate = vel >> 3; /* 0-127 to 0-15 */
-       adlib_fm[ach].mod.sustain_level = vel >> 3;
-       adlib_fm[ach].mod.key_on = 1;
-       adlib_update_groupA0(ach,&adlib_fm[ach]);
-}
-
-static inline void on_key_off(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {
-       struct midi_note *note = get_fm_note(t,ch,key,/*do_alloc*/0);
-       uint32_t freq = midi_note_freq(ch,key);
-       unsigned int ach;
-
-       if (note == NULL) return;
-
-       note->busy = 0;
-       ach = (unsigned int)(note - midi_notes); /* which FM channel? */
-       adlib_freq_to_fm_op(&adlib_fm[ach].mod,(double)freq / 65536);
-       adlib_fm[ach].mod.attack_rate = vel >> 3; /* 0-127 to 0-15 */
-       adlib_fm[ach].mod.sustain_level = vel >> 3;
-       adlib_fm[ach].mod.key_on = 0;
-       adlib_update_groupA0(ach,&adlib_fm[ach]);
-}
-
-static inline void on_control_change(struct midi_track *t,struct midi_channel *ch,unsigned char num,unsigned char val) {
-}
-
-static inline void on_program_change(struct midi_track *t,struct midi_channel *ch,unsigned char inst) {
-       ch->program = inst;
-}
-
-static inline void on_channel_aftertouch(struct midi_track *t,struct midi_channel *ch,unsigned char velocity) {
-}
-
-static inline void on_pitch_bend(struct midi_track *t,struct midi_channel *ch,int bend/*-8192 to 8192*/) {
-}
-
-unsigned long midi_trk_read_delta(struct midi_track *t) {
-       unsigned long tc = 0;
-       unsigned char c = 0,b;
-
-       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */
-       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence)
-               return tc;
-
-       while (c < 4) {
-               b = midi_trk_read(t);
-               tc = (tc << 7UL) + (unsigned long)(b&0x7F);
-               if (!(b&0x80)) break;
-               c++;
-       }
-
-       return tc;
-}
-
-void midi_tick_track(unsigned int i) {
-       struct midi_track *t = midi_trk + i;
-       struct midi_channel *ch;
-       unsigned char b,c,d;
-       int cnt=0;
-
-       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */
-       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence) {
-               t->eof = 1;
-               return;
-       }
-
-       t->us_tick_cnt_mtpq += 10000UL * (unsigned long)ticks_per_quarter_note;
-       while (t->us_tick_cnt_mtpq >= t->us_per_quarter_note) {
-               t->us_tick_cnt_mtpq -= t->us_per_quarter_note;
-               cnt++;
-
-               while (t->wait == 0) {
-                       if ((unsigned long)t->read >= (unsigned long)t->fence) {
-                               t->eof = 1;
-                               break;
-                       }
-
-                       /* read pointer should be pointing at MIDI event bytes, just after the time delay */
-                       b = midi_trk_read(t);
-                       if (b&0x80) {
-                               if (b < 0xF8) {
-                                       if (b >= 0xF0)
-                                               t->last_status = 0;
-                                       else
-                                               t->last_status = b;
-                               }
-                               if (b != 0x00 && ((b&0xF8) != 0xF0))
-                                       c = midi_trk_read(t);
-                       }
-                       else {
-                               /* blegh. last status */
-                               c = b;
-                               b = t->last_status;
-                       }
-                       switch (b>>4) {
-                               case 0x8: { /* note off */
-                                       d = midi_trk_read(t);
-                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */
-                                       on_key_off(t,ch,c,d);
-                                       } break;
-                               case 0x9: { /* note on */
-                                       d = midi_trk_read(t);
-                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */
-                                       if (d != 0) on_key_on(t,ch,c,d); /* "A Note On with a velocity of 0 is actually a note off" Bleh, really? */
-                                       else on_key_off(t,ch,c,d);
-                                       } break;
-                               case 0xA: { /* polyphonic aftertouch */
-                                       d = midi_trk_read(t);
-                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */
-                                       on_key_aftertouch(t,ch,c,d);
-                                       } break;
-                               case 0xB: { /* control change */
-                                       d = midi_trk_read(t);
-                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */
-                                       on_control_change(t,ch,c,d);
-                                       } break;
-                               case 0xC: { /* program change */
-                                       on_program_change(t,ch,c); /* c=instrument d=not used */
-                                       } break;
-                               case 0xD: { /* channel aftertouch */
-                                       on_channel_aftertouch(t,ch,c); /* c=velocity d=not used */
-                                       } break;
-                               case 0xE: { /* pitch bend */
-                                       d = midi_trk_read(t);
-                                       on_pitch_bend(t,ch,((c&0x7F)|((d&0x7F)<<7))-8192); /* c=LSB d=MSB */
-                                       } break;
-                               case 0xF: { /* event */
-                                       if (b == 0xFF) {
-                                               if (c == 0x7F) { /* c=type d=len */
-                                                       unsigned long len = midi_trk_read_delta(t);
-//====
-                                                       fprintf(stderr,"Type 0x7F len=%lu %p/%p/%p\n",len,t->raw,t->read,t->fence);
-//====
-                                                       if (len < 512UL) {
-                                                               /* unknown */
-                                                               midi_trk_skip(t,len);
-                                                       }
-                                                       else {
-                                                               midi_trk_end(t);
-                                                       }
-                                               }
-                                               else if (c < 0x7F) {
-                                                       d = midi_trk_read(t);
-
-                                                       if (c == 0x51 && d >= 3) {
-                                                               d -= 3;
-                                                               t->us_per_quarter_note = ((unsigned long)midi_trk_read(t)<<16UL)+
-                                                                       ((unsigned long)midi_trk_read(t)<<8UL)+
-                                                                       ((unsigned long)midi_trk_read(t)<<0UL);
-
-                                                               if (1/*TODO: If format 0 or format 1*/) {
-                                                                       /* Ugh. Unless format 2, the tempo applies to all tracks */
-                                                                       int j;
-
-                                                                       for (j=0;j < midi_trk_count;j++) {
-                                                                               if (j != i) midi_trk[j].us_per_quarter_note =
-                                                                                       t->us_per_quarter_note;
-                                                                       }
-                                                               }
-                                                       }
-                                                       else {
-//====
-                                                               fprintf(stderr,"Type 0x%02x len=%lu %p/%p/%p\n",c,d,t->raw,t->read,t->fence);
-//====
-                                                       }
-
-                                                       midi_trk_skip(t,d);
-                                               }
-                                               else {
-                                                       fprintf(stderr,"t=%u Unknown MIDI f message 0x%02x 0x%02x %p/%p/%p\n",i,b,c,t->raw,t->read,t->fence);
-                                               }
-                                       }
-                                       else {
-                                               unsigned long len = midi_trk_read_delta(t);
-//====
-                                               fprintf(stderr,"Sysex len=%lu %p/%p/%p\n",len,t->raw,t->read,t->fence);
-//====
-                                               midi_trk_skip(t,len);
-                                       }
-                                       } break;
-                               default:
-                                       if (b != 0x00) {
-                                               fprintf(stderr,"t=%u Unknown MIDI message 0x%02x at %p/%p/%p\n",i,b,t->raw,t->read,t->fence);
-                                               midi_trk_end(t);
-                                       }
-                                       break;
-                       };
-
-                       /* and then read the next event */
-                       t->wait = midi_trk_read_delta(t);
-               }
-               if (t->wait != 0) {
-                       t->wait--;
-               }
-       }
-}
-
-//void adlib_shut_up();
-void midi_reset_tracks();
-void midi_reset_channels();
-
-void midi_tick() {
-       if (midi_playing) {
-               unsigned int i;
-               int eof=0;
-
-               for (i=0;i < midi_trk_count;i++) {
-                       midi_tick_track(i);
-                       eof += midi_trk[i].eof?1:0;
-               }
-
-               if (eof >= midi_trk_count) {
-                       adlib_shut_up();
-                       midi_reset_tracks();
-                       midi_reset_channels();
-               }
-       }
-}
-
-/* WARNING: subroutine call in interrupt handler. make sure you compile with -zu flag for large/compact memory models */
-void interrupt irq0() {
-//     midi_tick();
-       irq0_ticks++;
-       if ((irq0_cnt += irq0_add) >= irq0_max) {
-               irq0_cnt -= irq0_max;
-               old_irq0();
-       }
-       else {
-               p8259_OCW2(0,P8259_OCW2_NON_SPECIFIC_EOI);
-       }
-}
-
-void adlib_shut_up() {
-       int i;
-
-       memset(adlib_fm,0,sizeof(adlib_fm));
-       memset(&adlib_reg_bd,0,sizeof(adlib_reg_bd));
-       for (i=0;i < adlib_fm_voices;i++) {
-               struct adlib_fm_operator *f;
-               f = &adlib_fm[i].mod;
-               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;
-               f = &adlib_fm[i].car;
-               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;
-       }
-
-       for (i=0;i < adlib_fm_voices;i++) {
-               struct adlib_fm_operator *f;
-
-               midi_notes[i].busy = 0;
-               midi_notes[i].note_channel = 0;
-
-               f = &adlib_fm[i].mod;
-               f->mod_multiple = 1;
-               f->total_level = 63 - 16;
-               f->attack_rate = 15;
-               f->decay_rate = 4;
-               f->sustain_level = 0;
-               f->release_rate = 8;
-               f->f_number = 400;
-               f->sustain = 1;
-               f->octave = 4;
-               f->key_on = 0;
-
-               f = &adlib_fm[i].car;
-               f->mod_multiple = 1;
-               f->total_level = 63 - 16;
-               f->attack_rate = 15;
-               f->decay_rate = 4;
-               f->sustain_level = 0;
-               f->release_rate = 8;
-               f->f_number = 0;
-               f->sustain = 1;
-               f->octave = 0;
-               f->key_on = 0;
-       }
-
-       adlib_apply_all();
-}
-
-void midi_reset_track(unsigned int i) {
-       struct midi_track *t;
-
-       if (i >= MIDI_MAX_TRACKS) return;
-       t = &midi_trk[i];
-       t->eof = 0;
-       t->last_status = 0;
-       t->us_tick_cnt_mtpq = 0;
-       t->us_per_quarter_note = (60000000UL / 120UL); /* 120BPM */
-       t->read = midi_trk[i].raw;
-       t->wait = midi_trk_read_delta(t); /* and then the read pointer will point at the MIDI event when wait counts down */
-}
-
-void midi_reset_tracks() {
-       int i;
-
-       for (i=0;i < midi_trk_count;i++)
-               midi_reset_track(i);
-}
-
-void midi_reset_channels() {
-       int i;
-
-       for (i=0;i < MIDI_MAX_CHANNELS;i++) {
-               midi_ch[i].program = 0;
-       }
-}
-
-int load_midi_file(const char *path) {
-       unsigned char tmp[256];
-       unsigned int tracks=0;
-       unsigned int tracki=0;
-       int fd;
-
-       fd = open(path,O_RDONLY|O_BINARY);
-       if (fd < 0) {
-               printf("Failed to load file %s\n",path);
-               return 0;
-       }
-
-       ticks_per_quarter_note = 0;
-       while (read(fd,tmp,8) == 8) {
-               uint32_t sz;
-
-               sz =    ((uint32_t)tmp[4] << (uint32_t)24) |
-                       ((uint32_t)tmp[5] << (uint32_t)16) |
-                       ((uint32_t)tmp[6] << (uint32_t)8) |
-                       ((uint32_t)tmp[7] << (uint32_t)0);
-               if (!memcmp(tmp,"MThd",4)) {
-                       unsigned short t,tdiv;
-
-                       if (sz < 6 || sz > 255) {
-                               fprintf(stderr,"Invalid MThd size %lu\n",(unsigned long)sz);
-                               goto err;
-                       }
-                       if (read(fd,tmp,(int)sz) != (int)sz) {
-                               fprintf(stderr,"MThd read error\n");
-                               goto err;
-                       }
-
-                       /* byte 0-1 = format type (0,1 or 2) */
-                       /* byte 2-3 = number of tracks */
-                       /* byte 4-5 = time divison */
-                       t = tmp[1] | (tmp[0] << 8);
-                       if (t > 1) {
-                               fprintf(stderr,"MThd type %u not supported\n",t);
-                               goto err; /* we only take type 0 or 1, don't support 2 */
-                       }
-                       tracks = tmp[3] | (tmp[2] << 8);
-                       if (tracks > MIDI_MAX_TRACKS) {
-                               fprintf(stderr,"MThd too many (%u) tracks\n",tracks);
-                               goto err;
-                       }
-                       tdiv = tmp[5] | (tmp[4] << 8);
-                       if (tdiv & 0x8000) {
-                               fprintf(stderr,"MThd SMPTE time division not supported\n");
-                               goto err; /* we do not support the SMPTE form */
-                       }
-                       if (tdiv == 0) {
-                               fprintf(stderr,"MThd time division == 0\n");
-                               goto err;
-                       }
-                       ticks_per_quarter_note = tdiv;
-               }
-               else if (!memcmp(tmp,"MTrk",4)) {
-                       if (sz == 0UL) continue;
-#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))
-                       if (sz > (640UL << 10UL)) goto err; /* 640KB */
-#elif TARGET_MSDOS == 32
-                       if (sz > (1UL << 20UL)) goto err; /* 1MB */
-#else
-                       if (sz > (60UL << 10UL)) goto err; /* 60KB */
-#endif
-                       if (tracki >= MIDI_MAX_TRACKS) goto err;
-#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))
-                       {
-                               unsigned segv;
-
-                               /* NTS: _fmalloc() is still limited to 64KB sizes */
-                               if (_dos_allocmem((unsigned)((sz+15UL)>>4UL),&segv) != 0) goto err;
-                               midi_trk[tracki].raw = MK_FP(segv,0);
-                       }
-#else
-                       midi_trk[tracki].raw = malloc(sz);
-#endif
-                       if (midi_trk[tracki].raw == NULL) goto err;
-                       midi_trk[tracki].read = midi_trk[tracki].raw;
-#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))
-                       {
-                               unsigned char far *p = midi_trk[tracki].raw;
-                               unsigned long rem = (unsigned long)sz;
-                               unsigned long cando;
-                               unsigned read;
-
-                               while (rem != 0UL) {
-                                       read = 0;
-
-                                       cando = 0x10000UL - (unsigned long)FP_OFF(p);
-                                       if (cando > rem) cando = rem;
-                                       if (cando > 0xFFFFUL) cando = 0xFFFFUL; /* we're limited to 64KB-1 of reading */
-
-                                       if (_dos_read(fd,p,(unsigned)cando,&read) != 0) goto err;
-                                       if (read != (unsigned)cando) goto err;
-
-                                       rem -= cando;
-                                       if ((((unsigned long)FP_OFF(p))+cando) == 0x10000UL)
-                                               p = MK_FP(FP_SEG(p)+0x1000,0);
-                                       else
-                                               p += (unsigned)cando;
-                               }
-
-                               cando = farptr2phys(p);
-                               midi_trk[tracki].fence = MK_FP(cando>>4,cando&0xF);
-                       }
-#else
-                       midi_trk[tracki].fence = midi_trk[tracki].raw + (unsigned)sz;
-                       if (read(fd,midi_trk[tracki].raw,(unsigned)sz) != (int)sz) goto err;
-#endif
-                       tracki++;
-               }
-               else {
-                       fprintf(stderr,"Unknown MIDI chunk %c%c%c%c\n",tmp[0],tmp[1],tmp[2],tmp[3]);
-                       goto err;
-               }
-       }
-       if (tracki == 0 || ticks_per_quarter_note == 0) goto err;
-       midi_trk_count = tracki;
-
-       fprintf(stderr,"Ticks per quarter note: %u\n",ticks_per_quarter_note);
-
-       close(fd);
-       return 1;
-err:
-       close(fd);
-       return 0;
-}
+/* midi.c\r
+ *\r
+ * Adlib OPL2/OPL3 FM synthesizer chipset test program.\r
+ * Play MIDI file using the OPLx synthesizer (well, poorly anyway)\r
+ * (C) 2010-2012 Jonathan Campbell.\r
+ * Hackipedia DOS library.\r
+ *\r
+ * This code is licensed under the LGPL.\r
+ * <insert LGPL legal text here>\r
+ *\r
+ * Compiles for intended target environments:\r
+ *   - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]\r
+ */\r
+\r
+#include "src/lib/midi.h"\r
+\r
+static unsigned int            midi_trk_count=0;\r
+struct midi_note               midi_notes[ADLIB_FM_VOICES];\r
+struct midi_channel            midi_ch[MIDI_MAX_CHANNELS];\r
+struct midi_track              midi_trk[MIDI_MAX_TRACKS];\r
+\r
+/* MIDI params. Nobody ever said it was a straightforward standard!\r
+ * NTS: These are for reading reference. Internally we convert everything to 100Hz time base. */\r
+static unsigned int ticks_per_quarter_note=0;  /* "Ticks per beat" */\r
+\r
+#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))\r
+static inline unsigned long farptr2phys(unsigned char far *p) { /* take 16:16 pointer convert to physical memory address */\r
+       return ((unsigned long)FP_SEG(p) << 4UL) + ((unsigned long)FP_OFF(p));\r
+}\r
+#endif\r
+\r
+static inline unsigned char midi_trk_read(struct midi_track *t) {\r
+       unsigned char c;\r
+\r
+       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */\r
+       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence) {\r
+               t->eof = 1;\r
+               return 0xFF;\r
+       }\r
+\r
+       c = *(t->read);\r
+#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))\r
+       if (FP_OFF(t->read) >= 0xF) /* 16:16 far pointer aware (NTS: Programs reassigning this pointer MUST normalize the FAR pointer) */\r
+               t->read = MK_FP(FP_SEG(t->read)+0x1,0);\r
+       else\r
+               t->read++;\r
+#else\r
+       t->read++;\r
+#endif\r
+       return c;\r
+}\r
+\r
+void midi_trk_end(struct midi_track *t) {\r
+       t->wait = ~0UL;\r
+       t->read = t->fence;\r
+}\r
+\r
+void midi_trk_skip(struct midi_track *t,unsigned long len) {\r
+       unsigned long rem;\r
+\r
+       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */\r
+       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence)\r
+               return;\r
+\r
+       if (len > 0xFFF0UL) {\r
+               midi_trk_end(t);\r
+               return;\r
+       }\r
+#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))\r
+       {\r
+               unsigned long tt;\r
+\r
+               tt = farptr2phys(t->read);\r
+               rem = farptr2phys(t->fence) - tt;\r
+               if (rem > len) rem = len;\r
+               tt += rem;\r
+               t->read = MK_FP(tt>>4,tt&0xF);\r
+       }\r
+#else\r
+       rem = (unsigned long)(t->fence - t->read);\r
+       if (len > rem) len = rem;\r
+       t->read += len;\r
+#endif\r
+}\r
+\r
+static const uint32_t midikeys_freqs[0x80] = {\r
+       0x00082d01,     /* key 0 = 8.17579891564371Hz */\r
+       0x0008a976,     /* key 1 = 8.66195721802725Hz */\r
+       0x00092d51,     /* key 2 = 9.17702399741899Hz */\r
+       0x0009b904,     /* key 3 = 9.72271824131503Hz */\r
+       0x000a4d05,     /* key 4 = 10.3008611535272Hz */\r
+       0x000ae9d3,     /* key 5 = 10.9133822322814Hz */\r
+       0x000b8ff4,     /* key 6 = 11.5623257097386Hz */\r
+       0x000c3ff6,     /* key 7 = 12.2498573744297Hz */\r
+       0x000cfa70,     /* key 8 = 12.9782717993733Hz */\r
+       0x000dc000,     /* key 9 = 13.75Hz */\r
+       0x000e914f,     /* key 10 = 14.5676175474403Hz */\r
+       0x000f6f11,     /* key 11 = 15.4338531642539Hz */\r
+       0x00105a02,     /* key 12 = 16.3515978312874Hz */\r
+       0x001152ec,     /* key 13 = 17.3239144360545Hz */\r
+       0x00125aa2,     /* key 14 = 18.354047994838Hz */\r
+       0x00137208,     /* key 15 = 19.4454364826301Hz */\r
+       0x00149a0a,     /* key 16 = 20.6017223070544Hz */\r
+       0x0015d3a6,     /* key 17 = 21.8267644645627Hz */\r
+       0x00171fe9,     /* key 18 = 23.1246514194771Hz */\r
+       0x00187fed,     /* key 19 = 24.4997147488593Hz */\r
+       0x0019f4e0,     /* key 20 = 25.9565435987466Hz */\r
+       0x001b8000,     /* key 21 = 27.5Hz */\r
+       0x001d229e,     /* key 22 = 29.1352350948806Hz */\r
+       0x001ede22,     /* key 23 = 30.8677063285078Hz */\r
+       0x0020b404,     /* key 24 = 32.7031956625748Hz */\r
+       0x0022a5d8,     /* key 25 = 34.647828872109Hz */\r
+       0x0024b545,     /* key 26 = 36.7080959896759Hz */\r
+       0x0026e410,     /* key 27 = 38.8908729652601Hz */\r
+       0x00293414,     /* key 28 = 41.2034446141087Hz */\r
+       0x002ba74d,     /* key 29 = 43.6535289291255Hz */\r
+       0x002e3fd2,     /* key 30 = 46.2493028389543Hz */\r
+       0x0030ffda,     /* key 31 = 48.9994294977187Hz */\r
+       0x0033e9c0,     /* key 32 = 51.9130871974931Hz */\r
+       0x00370000,     /* key 33 = 55Hz */\r
+       0x003a453d,     /* key 34 = 58.2704701897612Hz */\r
+       0x003dbc44,     /* key 35 = 61.7354126570155Hz */\r
+       0x00416809,     /* key 36 = 65.4063913251497Hz */\r
+       0x00454bb0,     /* key 37 = 69.295657744218Hz */\r
+       0x00496a8b,     /* key 38 = 73.4161919793519Hz */\r
+       0x004dc820,     /* key 39 = 77.7817459305202Hz */\r
+       0x00526829,     /* key 40 = 82.4068892282175Hz */\r
+       0x00574e9b,     /* key 41 = 87.307057858251Hz */\r
+       0x005c7fa4,     /* key 42 = 92.4986056779086Hz */\r
+       0x0061ffb5,     /* key 43 = 97.9988589954373Hz */\r
+       0x0067d380,     /* key 44 = 103.826174394986Hz */\r
+       0x006e0000,     /* key 45 = 110Hz */\r
+       0x00748a7b,     /* key 46 = 116.540940379522Hz */\r
+       0x007b7888,     /* key 47 = 123.470825314031Hz */\r
+       0x0082d012,     /* key 48 = 130.812782650299Hz */\r
+       0x008a9760,     /* key 49 = 138.591315488436Hz */\r
+       0x0092d517,     /* key 50 = 146.832383958704Hz */\r
+       0x009b9041,     /* key 51 = 155.56349186104Hz */\r
+       0x00a4d053,     /* key 52 = 164.813778456435Hz */\r
+       0x00ae9d36,     /* key 53 = 174.614115716502Hz */\r
+       0x00b8ff49,     /* key 54 = 184.997211355817Hz */\r
+       0x00c3ff6a,     /* key 55 = 195.997717990875Hz */\r
+       0x00cfa700,     /* key 56 = 207.652348789973Hz */\r
+       0x00dc0000,     /* key 57 = 220Hz */\r
+       0x00e914f6,     /* key 58 = 233.081880759045Hz */\r
+       0x00f6f110,     /* key 59 = 246.941650628062Hz */\r
+       0x0105a025,     /* key 60 = 261.625565300599Hz */\r
+       0x01152ec0,     /* key 61 = 277.182630976872Hz */\r
+       0x0125aa2e,     /* key 62 = 293.664767917408Hz */\r
+       0x01372082,     /* key 63 = 311.126983722081Hz */\r
+       0x0149a0a7,     /* key 64 = 329.62755691287Hz */\r
+       0x015d3a6d,     /* key 65 = 349.228231433004Hz */\r
+       0x0171fe92,     /* key 66 = 369.994422711634Hz */\r
+       0x0187fed4,     /* key 67 = 391.995435981749Hz */\r
+       0x019f4e00,     /* key 68 = 415.304697579945Hz */\r
+       0x01b80000,     /* key 69 = 440Hz */\r
+       0x01d229ec,     /* key 70 = 466.16376151809Hz */\r
+       0x01ede220,     /* key 71 = 493.883301256124Hz */\r
+       0x020b404a,     /* key 72 = 523.251130601197Hz */\r
+       0x022a5d81,     /* key 73 = 554.365261953744Hz */\r
+       0x024b545c,     /* key 74 = 587.329535834815Hz */\r
+       0x026e4104,     /* key 75 = 622.253967444162Hz */\r
+       0x0293414f,     /* key 76 = 659.25511382574Hz */\r
+       0x02ba74da,     /* key 77 = 698.456462866008Hz */\r
+       0x02e3fd24,     /* key 78 = 739.988845423269Hz */\r
+       0x030ffda9,     /* key 79 = 783.990871963499Hz */\r
+       0x033e9c01,     /* key 80 = 830.60939515989Hz */\r
+       0x03700000,     /* key 81 = 880Hz */\r
+       0x03a453d8,     /* key 82 = 932.32752303618Hz */\r
+       0x03dbc440,     /* key 83 = 987.766602512248Hz */\r
+       0x04168094,     /* key 84 = 1046.50226120239Hz */\r
+       0x0454bb03,     /* key 85 = 1108.73052390749Hz */\r
+       0x0496a8b8,     /* key 86 = 1174.65907166963Hz */\r
+       0x04dc8208,     /* key 87 = 1244.50793488832Hz */\r
+       0x0526829e,     /* key 88 = 1318.51022765148Hz */\r
+       0x0574e9b5,     /* key 89 = 1396.91292573202Hz */\r
+       0x05c7fa49,     /* key 90 = 1479.97769084654Hz */\r
+       0x061ffb53,     /* key 91 = 1567.981743927Hz */\r
+       0x067d3802,     /* key 92 = 1661.21879031978Hz */\r
+       0x06e00000,     /* key 93 = 1760Hz */\r
+       0x0748a7b1,     /* key 94 = 1864.65504607236Hz */\r
+       0x07b78880,     /* key 95 = 1975.5332050245Hz */\r
+       0x082d0128,     /* key 96 = 2093.00452240479Hz */\r
+       0x08a97607,     /* key 97 = 2217.46104781498Hz */\r
+       0x092d5171,     /* key 98 = 2349.31814333926Hz */\r
+       0x09b90410,     /* key 99 = 2489.01586977665Hz */\r
+       0x0a4d053c,     /* key 100 = 2637.02045530296Hz */\r
+       0x0ae9d36b,     /* key 101 = 2793.82585146403Hz */\r
+       0x0b8ff493,     /* key 102 = 2959.95538169308Hz */\r
+       0x0c3ff6a7,     /* key 103 = 3135.96348785399Hz */\r
+       0x0cfa7005,     /* key 104 = 3322.43758063956Hz */\r
+       0x0dc00000,     /* key 105 = 3520Hz */\r
+       0x0e914f62,     /* key 106 = 3729.31009214472Hz */\r
+       0x0f6f1100,     /* key 107 = 3951.06641004899Hz */\r
+       0x105a0250,     /* key 108 = 4186.00904480958Hz */\r
+       0x1152ec0e,     /* key 109 = 4434.92209562995Hz */\r
+       0x125aa2e3,     /* key 110 = 4698.63628667852Hz */\r
+       0x13720820,     /* key 111 = 4978.03173955329Hz */\r
+       0x149a0a79,     /* key 112 = 5274.04091060592Hz */\r
+       0x15d3a6d6,     /* key 113 = 5587.65170292806Hz */\r
+       0x171fe927,     /* key 114 = 5919.91076338615Hz */\r
+       0x187fed4e,     /* key 115 = 6271.92697570799Hz */\r
+       0x19f4e00a,     /* key 116 = 6644.87516127912Hz */\r
+       0x1b800000,     /* key 117 = 7040Hz */\r
+       0x1d229ec4,     /* key 118 = 7458.62018428944Hz */\r
+       0x1ede2200,     /* key 119 = 7902.13282009799Hz */\r
+       0x20b404a1,     /* key 120 = 8372.01808961916Hz */\r
+       0x22a5d81c,     /* key 121 = 8869.84419125991Hz */\r
+       0x24b545c7,     /* key 122 = 9397.27257335704Hz */\r
+       0x26e41040,     /* key 123 = 9956.06347910659Hz */\r
+       0x293414f2,     /* key 124 = 10548.0818212118Hz */\r
+       0x2ba74dac,     /* key 125 = 11175.3034058561Hz */\r
+       0x2e3fd24f,     /* key 126 = 11839.8215267723Hz */\r
+       0x30ffda9c      /* key 127 = 12543.853951416Hz */\r
+};\r
+\r
+static uint32_t midi_note_freq(struct midi_channel *ch,unsigned char key) {\r
+       return midikeys_freqs[key&0x7F];\r
+}\r
+\r
+static struct midi_note *get_fm_note(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char do_alloc) {\r
+       unsigned int tch = (unsigned int)(t - midi_trk); /* pointer math */\r
+       unsigned int ach = (unsigned int)(ch - midi_ch); /* pointer math */\r
+       unsigned int i,freen=~0;\r
+\r
+       for (i=0;i < ADLIB_FM_VOICES;i++) {\r
+               if (midi_notes[i].busy) {\r
+                       if (midi_notes[i].note_channel == ach && midi_notes[i].note_track == tch && midi_notes[i].note_number == key)\r
+                               return &midi_notes[i];\r
+               }\r
+               else {\r
+                       if (freen == ~0) freen = i;\r
+               }\r
+       }\r
+\r
+       if (do_alloc && freen != ~0) return &midi_notes[freen];\r
+       return NULL;\r
+}\r
+\r
+static void drop_fm_note(struct midi_channel *ch,unsigned char key) {\r
+       unsigned int ach = (unsigned int)(ch - midi_ch); /* pointer math */\r
+       unsigned int i;\r
+\r
+       for (i=0;i < ADLIB_FM_VOICES;i++) {\r
+               if (midi_notes[i].busy && midi_notes[i].note_channel == ach) {\r
+                       midi_notes[i].busy = 0;\r
+                       break;\r
+               }\r
+       }\r
+}\r
+\r
+static inline void on_key_aftertouch(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {\r
+       struct midi_note *note = get_fm_note(t,ch,key,/*do_alloc*/0);\r
+       uint32_t freq = midi_note_freq(ch,key);\r
+       unsigned int ach;\r
+\r
+       if (note == NULL) return;\r
+\r
+       note->busy = 1;\r
+       note->note_number = key;\r
+       note->note_velocity = vel;\r
+       note->note_track = (unsigned int)(t - midi_trk);\r
+       note->note_channel = (unsigned int)(ch - midi_ch);\r
+       ach = (unsigned int)(note - midi_notes); /* which FM channel? */\r
+       adlib_freq_to_fm_op(&adlib_fm[ach].mod,(double)freq / 65536);\r
+       adlib_fm[ach].mod.attack_rate = vel >> 3; /* 0-127 to 0-15 */\r
+       adlib_fm[ach].mod.sustain_level = vel >> 3;\r
+       adlib_fm[ach].mod.key_on = 1;\r
+       adlib_update_groupA0(ach,&adlib_fm[ach]);\r
+}\r
+\r
+static inline void on_key_on(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {\r
+       struct midi_note *note = get_fm_note(t,ch,key,/*do_alloc*/1);\r
+       uint32_t freq = midi_note_freq(ch,key);\r
+       unsigned int ach;\r
+\r
+       /* HACK: Ignore percussion */\r
+       if ((ch->program >= 8 && ch->program <= 15)/*Chromatic percussion*/ ||\r
+               (ch->program >= 112 && ch->program <= 119)/*Percussive*/ ||\r
+               ch == &midi_ch[9]/*MIDI channel 10 (DAMN YOU 1-BASED COUNTING)*/)\r
+               return;\r
+\r
+       if (note == NULL) {\r
+               /* then we'll have to knock one off to make room */\r
+               drop_fm_note(ch,key);\r
+               note = get_fm_note(t,ch,key,1);\r
+               if (note == NULL) return;\r
+       }\r
+\r
+       note->busy = 1;\r
+       note->note_number = key;\r
+       note->note_velocity = vel;\r
+       note->note_track = (unsigned int)(t - midi_trk);\r
+       note->note_channel = (unsigned int)(ch - midi_ch);\r
+       ach = (unsigned int)(note - midi_notes); /* which FM channel? */\r
+       adlib_freq_to_fm_op(&adlib_fm[ach].mod,(double)freq / 65536);\r
+       adlib_fm[ach].mod.attack_rate = vel >> 3; /* 0-127 to 0-15 */\r
+       adlib_fm[ach].mod.sustain_level = vel >> 3;\r
+       adlib_fm[ach].mod.key_on = 1;\r
+       adlib_update_groupA0(ach,&adlib_fm[ach]);\r
+}\r
+\r
+static inline void on_key_off(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {\r
+       struct midi_note *note = get_fm_note(t,ch,key,/*do_alloc*/0);\r
+       uint32_t freq = midi_note_freq(ch,key);\r
+       unsigned int ach;\r
+\r
+       if (note == NULL) return;\r
+\r
+       note->busy = 0;\r
+       ach = (unsigned int)(note - midi_notes); /* which FM channel? */\r
+       adlib_freq_to_fm_op(&adlib_fm[ach].mod,(double)freq / 65536);\r
+       adlib_fm[ach].mod.attack_rate = vel >> 3; /* 0-127 to 0-15 */\r
+       adlib_fm[ach].mod.sustain_level = vel >> 3;\r
+       adlib_fm[ach].mod.key_on = 0;\r
+       adlib_update_groupA0(ach,&adlib_fm[ach]);\r
+}\r
+\r
+static inline void on_control_change(struct midi_track *t,struct midi_channel *ch,unsigned char num,unsigned char val) {\r
+}\r
+\r
+static inline void on_program_change(struct midi_track *t,struct midi_channel *ch,unsigned char inst) {\r
+       ch->program = inst;\r
+}\r
+\r
+static inline void on_channel_aftertouch(struct midi_track *t,struct midi_channel *ch,unsigned char velocity) {\r
+}\r
+\r
+static inline void on_pitch_bend(struct midi_track *t,struct midi_channel *ch,int bend/*-8192 to 8192*/) {\r
+}\r
+\r
+unsigned long midi_trk_read_delta(struct midi_track *t) {\r
+       unsigned long tc = 0;\r
+       unsigned char c = 0,b;\r
+\r
+       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */\r
+       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence)\r
+               return tc;\r
+\r
+       while (c < 4) {\r
+               b = midi_trk_read(t);\r
+               tc = (tc << 7UL) + (unsigned long)(b&0x7F);\r
+               if (!(b&0x80)) break;\r
+               c++;\r
+       }\r
+\r
+       return tc;\r
+}\r
+\r
+void midi_tick_track(unsigned int i) {\r
+       struct midi_track *t = midi_trk + i;\r
+       struct midi_channel *ch;\r
+       unsigned char b,c,d;\r
+       int cnt=0;\r
+\r
+       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */\r
+       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence) {\r
+               t->eof = 1;\r
+               return;\r
+       }\r
+\r
+       t->us_tick_cnt_mtpq += 10000UL * (unsigned long)ticks_per_quarter_note;\r
+       while (t->us_tick_cnt_mtpq >= t->us_per_quarter_note) {\r
+               t->us_tick_cnt_mtpq -= t->us_per_quarter_note;\r
+               cnt++;\r
+\r
+               while (t->wait == 0) {\r
+                       if ((unsigned long)t->read >= (unsigned long)t->fence) {\r
+                               t->eof = 1;\r
+                               break;\r
+                       }\r
+\r
+                       /* read pointer should be pointing at MIDI event bytes, just after the time delay */\r
+                       b = midi_trk_read(t);\r
+                       if (b&0x80) {\r
+                               if (b < 0xF8) {\r
+                                       if (b >= 0xF0)\r
+                                               t->last_status = 0;\r
+                                       else\r
+                                               t->last_status = b;\r
+                               }\r
+                               if (b != 0x00 && ((b&0xF8) != 0xF0))\r
+                                       c = midi_trk_read(t);\r
+                       }\r
+                       else {\r
+                               /* blegh. last status */\r
+                               c = b;\r
+                               b = t->last_status;\r
+                       }\r
+                       switch (b>>4) {\r
+                               case 0x8: { /* note off */\r
+                                       d = midi_trk_read(t);\r
+                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */\r
+                                       on_key_off(t,ch,c,d);\r
+                                       } break;\r
+                               case 0x9: { /* note on */\r
+                                       d = midi_trk_read(t);\r
+                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */\r
+                                       if (d != 0) on_key_on(t,ch,c,d); /* "A Note On with a velocity of 0 is actually a note off" Bleh, really? */\r
+                                       else on_key_off(t,ch,c,d);\r
+                                       } break;\r
+                               case 0xA: { /* polyphonic aftertouch */\r
+                                       d = midi_trk_read(t);\r
+                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */\r
+                                       on_key_aftertouch(t,ch,c,d);\r
+                                       } break;\r
+                               case 0xB: { /* control change */\r
+                                       d = midi_trk_read(t);\r
+                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */\r
+                                       on_control_change(t,ch,c,d);\r
+                                       } break;\r
+                               case 0xC: { /* program change */\r
+                                       on_program_change(t,ch,c); /* c=instrument d=not used */\r
+                                       } break;\r
+                               case 0xD: { /* channel aftertouch */\r
+                                       on_channel_aftertouch(t,ch,c); /* c=velocity d=not used */\r
+                                       } break;\r
+                               case 0xE: { /* pitch bend */\r
+                                       d = midi_trk_read(t);\r
+                                       on_pitch_bend(t,ch,((c&0x7F)|((d&0x7F)<<7))-8192); /* c=LSB d=MSB */\r
+                                       } break;\r
+                               case 0xF: { /* event */\r
+                                       if (b == 0xFF) {\r
+                                               if (c == 0x7F) { /* c=type d=len */\r
+                                                       unsigned long len = midi_trk_read_delta(t);\r
+//====\r
+                                                       fprintf(stderr,"Type 0x7F len=%lu %p/%p/%p\n",len,t->raw,t->read,t->fence);\r
+//====\r
+                                                       if (len < 512UL) {\r
+                                                               /* unknown */\r
+                                                               midi_trk_skip(t,len);\r
+                                                       }\r
+                                                       else {\r
+                                                               midi_trk_end(t);\r
+                                                       }\r
+                                               }\r
+                                               else if (c < 0x7F) {\r
+                                                       d = midi_trk_read(t);\r
+\r
+                                                       if (c == 0x51 && d >= 3) {\r
+                                                               d -= 3;\r
+                                                               t->us_per_quarter_note = ((unsigned long)midi_trk_read(t)<<16UL)+\r
+                                                                       ((unsigned long)midi_trk_read(t)<<8UL)+\r
+                                                                       ((unsigned long)midi_trk_read(t)<<0UL);\r
+\r
+                                                               if (1/*TODO: If format 0 or format 1*/) {\r
+                                                                       /* Ugh. Unless format 2, the tempo applies to all tracks */\r
+                                                                       int j;\r
+\r
+                                                                       for (j=0;j < midi_trk_count;j++) {\r
+                                                                               if (j != i) midi_trk[j].us_per_quarter_note =\r
+                                                                                       t->us_per_quarter_note;\r
+                                                                       }\r
+                                                               }\r
+                                                       }\r
+                                                       else {\r
+//====\r
+                                                               fprintf(stderr,"Type 0x%02x len=%lu %p/%p/%p\n",c,d,t->raw,t->read,t->fence);\r
+//====\r
+                                                       }\r
+\r
+                                                       midi_trk_skip(t,d);\r
+                                               }\r
+                                               else {\r
+                                                       fprintf(stderr,"t=%u Unknown MIDI f message 0x%02x 0x%02x %p/%p/%p\n",i,b,c,t->raw,t->read,t->fence);\r
+                                               }\r
+                                       }\r
+                                       else {\r
+                                               unsigned long len = midi_trk_read_delta(t);\r
+//====\r
+                                               fprintf(stderr,"Sysex len=%lu %p/%p/%p\n",len,t->raw,t->read,t->fence);\r
+//====\r
+                                               midi_trk_skip(t,len);\r
+                                       }\r
+                                       } break;\r
+                               default:\r
+                                       if (b != 0x00) {\r
+                                               fprintf(stderr,"t=%u Unknown MIDI message 0x%02x at %p/%p/%p\n",i,b,t->raw,t->read,t->fence);\r
+                                               midi_trk_end(t);\r
+                                       }\r
+                                       break;\r
+                       };\r
+\r
+                       /* and then read the next event */\r
+                       t->wait = midi_trk_read_delta(t);\r
+               }\r
+               if (t->wait != 0) {\r
+                       t->wait--;\r
+               }\r
+       }\r
+}\r
+\r
+//void adlib_shut_up();\r
+void midi_reset_tracks();\r
+void midi_reset_channels();\r
+\r
+void midi_tick() {\r
+       if (midi_playing) {\r
+               unsigned int i;\r
+               int eof=0;\r
+\r
+               for (i=0;i < midi_trk_count;i++) {\r
+                       midi_tick_track(i);\r
+                       eof += midi_trk[i].eof?1:0;\r
+               }\r
+\r
+               if (eof >= midi_trk_count) {\r
+                       adlib_shut_up();\r
+                       midi_reset_tracks();\r
+                       midi_reset_channels();\r
+               }\r
+       }\r
+}\r
+\r
+/* WARNING: subroutine call in interrupt handler. make sure you compile with -zu flag for large/compact memory models */\r
+void interrupt irq0() {\r
+//     midi_tick();\r
+       irq0_ticks++;\r
+       if ((irq0_cnt += irq0_add) >= irq0_max) {\r
+               irq0_cnt -= irq0_max;\r
+               old_irq0();\r
+       }\r
+       else {\r
+               p8259_OCW2(0,P8259_OCW2_NON_SPECIFIC_EOI);\r
+       }\r
+}\r
+\r
+void adlib_shut_up() {\r
+       int i;\r
+\r
+       memset(adlib_fm,0,sizeof(adlib_fm));\r
+       memset(&adlib_reg_bd,0,sizeof(adlib_reg_bd));\r
+       for (i=0;i < adlib_fm_voices;i++) {\r
+               struct adlib_fm_operator *f;\r
+               f = &adlib_fm[i].mod;\r
+               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;\r
+               f = &adlib_fm[i].car;\r
+               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;\r
+       }\r
+\r
+       for (i=0;i < adlib_fm_voices;i++) {\r
+               struct adlib_fm_operator *f;\r
+\r
+               midi_notes[i].busy = 0;\r
+               midi_notes[i].note_channel = 0;\r
+\r
+               f = &adlib_fm[i].mod;\r
+               f->mod_multiple = 1;\r
+               f->total_level = 63 - 16;\r
+               f->attack_rate = 15;\r
+               f->decay_rate = 4;\r
+               f->sustain_level = 0;\r
+               f->release_rate = 8;\r
+               f->f_number = 400;\r
+               f->sustain = 1;\r
+               f->octave = 4;\r
+               f->key_on = 0;\r
+\r
+               f = &adlib_fm[i].car;\r
+               f->mod_multiple = 1;\r
+               f->total_level = 63 - 16;\r
+               f->attack_rate = 15;\r
+               f->decay_rate = 4;\r
+               f->sustain_level = 0;\r
+               f->release_rate = 8;\r
+               f->f_number = 0;\r
+               f->sustain = 1;\r
+               f->octave = 0;\r
+               f->key_on = 0;\r
+       }\r
+\r
+       adlib_apply_all();\r
+}\r
+\r
+void midi_reset_track(unsigned int i) {\r
+       struct midi_track *t;\r
+\r
+       if (i >= MIDI_MAX_TRACKS) return;\r
+       t = &midi_trk[i];\r
+       t->eof = 0;\r
+       t->last_status = 0;\r
+       t->us_tick_cnt_mtpq = 0;\r
+       t->us_per_quarter_note = (60000000UL / 120UL); /* 120BPM */\r
+       t->read = midi_trk[i].raw;\r
+       t->wait = midi_trk_read_delta(t); /* and then the read pointer will point at the MIDI event when wait counts down */\r
+}\r
+\r
+void midi_reset_tracks() {\r
+       int i;\r
+\r
+       for (i=0;i < midi_trk_count;i++)\r
+               midi_reset_track(i);\r
+}\r
+\r
+void midi_reset_channels() {\r
+       int i;\r
+\r
+       for (i=0;i < MIDI_MAX_CHANNELS;i++) {\r
+               midi_ch[i].program = 0;\r
+       }\r
+}\r
+\r
+int load_midi_file(const char *path) {\r
+       unsigned char tmp[256];\r
+       unsigned int tracks=0;\r
+       unsigned int tracki=0;\r
+       int fd;\r
+\r
+       fd = open(path,O_RDONLY|O_BINARY);\r
+       if (fd < 0) {\r
+               printf("Failed to load file %s\n",path);\r
+               return 0;\r
+       }\r
+\r
+       ticks_per_quarter_note = 0;\r
+       while (read(fd,tmp,8) == 8) {\r
+               uint32_t sz;\r
+\r
+               sz =    ((uint32_t)tmp[4] << (uint32_t)24) |\r
+                       ((uint32_t)tmp[5] << (uint32_t)16) |\r
+                       ((uint32_t)tmp[6] << (uint32_t)8) |\r
+                       ((uint32_t)tmp[7] << (uint32_t)0);\r
+               if (!memcmp(tmp,"MThd",4)) {\r
+                       unsigned short t,tdiv;\r
+\r
+                       if (sz < 6 || sz > 255) {\r
+                               fprintf(stderr,"Invalid MThd size %lu\n",(unsigned long)sz);\r
+                               goto err;\r
+                       }\r
+                       if (read(fd,tmp,(int)sz) != (int)sz) {\r
+                               fprintf(stderr,"MThd read error\n");\r
+                               goto err;\r
+                       }\r
+\r
+                       /* byte 0-1 = format type (0,1 or 2) */\r
+                       /* byte 2-3 = number of tracks */\r
+                       /* byte 4-5 = time divison */\r
+                       t = tmp[1] | (tmp[0] << 8);\r
+                       if (t > 1) {\r
+                               fprintf(stderr,"MThd type %u not supported\n",t);\r
+                               goto err; /* we only take type 0 or 1, don't support 2 */\r
+                       }\r
+                       tracks = tmp[3] | (tmp[2] << 8);\r
+                       if (tracks > MIDI_MAX_TRACKS) {\r
+                               fprintf(stderr,"MThd too many (%u) tracks\n",tracks);\r
+                               goto err;\r
+                       }\r
+                       tdiv = tmp[5] | (tmp[4] << 8);\r
+                       if (tdiv & 0x8000) {\r
+                               fprintf(stderr,"MThd SMPTE time division not supported\n");\r
+                               goto err; /* we do not support the SMPTE form */\r
+                       }\r
+                       if (tdiv == 0) {\r
+                               fprintf(stderr,"MThd time division == 0\n");\r
+                               goto err;\r
+                       }\r
+                       ticks_per_quarter_note = tdiv;\r
+               }\r
+               else if (!memcmp(tmp,"MTrk",4)) {\r
+                       if (sz == 0UL) continue;\r
+#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))\r
+                       if (sz > (640UL << 10UL)) goto err; /* 640KB */\r
+#elif TARGET_MSDOS == 32\r
+                       if (sz > (1UL << 20UL)) goto err; /* 1MB */\r
+#else\r
+                       if (sz > (60UL << 10UL)) goto err; /* 60KB */\r
+#endif\r
+                       if (tracki >= MIDI_MAX_TRACKS) goto err;\r
+#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))\r
+                       {\r
+                               unsigned segv;\r
+\r
+                               /* NTS: _fmalloc() is still limited to 64KB sizes */\r
+                               if (_dos_allocmem((unsigned)((sz+15UL)>>4UL),&segv) != 0) goto err;\r
+                               midi_trk[tracki].raw = MK_FP(segv,0);\r
+                       }\r
+#else\r
+                       midi_trk[tracki].raw = malloc(sz);\r
+#endif\r
+                       if (midi_trk[tracki].raw == NULL) goto err;\r
+                       midi_trk[tracki].read = midi_trk[tracki].raw;\r
+#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))\r
+                       {\r
+                               unsigned char far *p = midi_trk[tracki].raw;\r
+                               unsigned long rem = (unsigned long)sz;\r
+                               unsigned long cando;\r
+                               unsigned read;\r
+\r
+                               while (rem != 0UL) {\r
+                                       read = 0;\r
+\r
+                                       cando = 0x10000UL - (unsigned long)FP_OFF(p);\r
+                                       if (cando > rem) cando = rem;\r
+                                       if (cando > 0xFFFFUL) cando = 0xFFFFUL; /* we're limited to 64KB-1 of reading */\r
+\r
+                                       if (_dos_read(fd,p,(unsigned)cando,&read) != 0) goto err;\r
+                                       if (read != (unsigned)cando) goto err;\r
+\r
+                                       rem -= cando;\r
+                                       if ((((unsigned long)FP_OFF(p))+cando) == 0x10000UL)\r
+                                               p = MK_FP(FP_SEG(p)+0x1000,0);\r
+                                       else\r
+                                               p += (unsigned)cando;\r
+                               }\r
+\r
+                               cando = farptr2phys(p);\r
+                               midi_trk[tracki].fence = MK_FP(cando>>4,cando&0xF);\r
+                       }\r
+#else\r
+                       midi_trk[tracki].fence = midi_trk[tracki].raw + (unsigned)sz;\r
+                       if (read(fd,midi_trk[tracki].raw,(unsigned)sz) != (int)sz) goto err;\r
+#endif\r
+                       tracki++;\r
+               }\r
+               else {\r
+                       fprintf(stderr,"Unknown MIDI chunk %c%c%c%c\n",tmp[0],tmp[1],tmp[2],tmp[3]);\r
+                       goto err;\r
+               }\r
+       }\r
+       if (tracki == 0 || ticks_per_quarter_note == 0) goto err;\r
+       midi_trk_count = tracki;\r
+\r
+       fprintf(stderr,"Ticks per quarter note: %u\n",ticks_per_quarter_note);\r
+\r
+       close(fd);\r
+       return 1;\r
+err:\r
+       close(fd);\r
+       return 0;\r
+}\r
index ac740c809d5ce036a09a24bf994adc19a0232add..356255d24c992ab1001af18c86458e21dda9cd41 100755 (executable)
@@ -1,83 +1,83 @@
-/* midi.h
- *
- * Adlib OPL2/OPL3 FM synthesizer chipset test program.
- * Play MIDI file using the OPLx synthesizer (well, poorly anyway)
- * (C) 2010-2012 Jonathan Campbell.
- * Hackipedia DOS library.
- *
- * This code is licensed under the LGPL.
- * <insert LGPL legal text here>
- *
- * Compiles for intended target environments:
- *   - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]
- */
-
+/* midi.h\r
+ *\r
+ * Adlib OPL2/OPL3 FM synthesizer chipset test program.\r
+ * Play MIDI file using the OPLx synthesizer (well, poorly anyway)\r
+ * (C) 2010-2012 Jonathan Campbell.\r
+ * Hackipedia DOS library.\r
+ *\r
+ * This code is licensed under the LGPL.\r
+ * <insert LGPL legal text here>\r
+ *\r
+ * Compiles for intended target environments:\r
+ *   - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]\r
+ */\r
+\r
 #ifndef        __MIDI__\r
-#define        __MIDI__
-
-#include <stdio.h>
-#include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <malloc.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <math.h>
-#include <dos.h>
-
-//#include "src/lib/doslib/vga.h"
-#include "src/lib/doslib/dos.h"
-#include "src/lib/16_head.h"
-#include "src/lib/doslib/8254.h"               /* 8254 timer */
-#include "src/lib/doslib/8259.h"
-//#include "src/lib/doslib/vgagui.h"
-//#include "src/lib/doslib/vgatty.h"
-#include "src/lib/doslib/adlib.h"
-
-/* one per OPL channel */
-struct midi_note {
-       unsigned char           note_number;
-       unsigned char           note_velocity;
-       unsigned char           note_track;     /* from what MIDI track */
-       unsigned char           note_channel;   /* from what MIDI channel */
-       unsigned int            busy:1;         /* if occupied */
-};
-
-struct midi_channel {
-       unsigned char           program;
-};
-
-struct midi_track {
-       /* track data, raw */
-       unsigned char*          raw;            /* raw data base */
-       unsigned char*          fence;          /* raw data end (last byte + 1) */
-       unsigned char*          read;           /* raw data read ptr */
-       /* state */
-       unsigned long           us_per_quarter_note; /* Microseconds per quarter note (def 120 BPM) */
-       unsigned long           us_tick_cnt_mtpq; /* Microseconds advanced (up to 10000 us or one unit at 100Hz) x ticks per quarter note */
-       unsigned long           wait;
-       unsigned char           last_status;    /* MIDI last status byte */
-       unsigned int            eof:1;          /* we hit the end of the track */
-};
-
-#define MIDI_MAX_CHANNELS      16
-#define MIDI_MAX_TRACKS                64
-
-extern struct midi_note                midi_notes[ADLIB_FM_VOICES];
-extern struct midi_channel             midi_ch[MIDI_MAX_CHANNELS];
-extern struct midi_track               midi_trk[MIDI_MAX_TRACKS];
-
-static void (interrupt *old_irq0)();
-static volatile unsigned long irq0_ticks=0;
-static volatile unsigned int irq0_cnt=0,irq0_add=0,irq0_max=0;
-static volatile unsigned char  midi_playing=0;
-
-int load_midi_file(const char *path);
-void interrupt irq0();
-void adlib_shut_up();
-void midi_reset_tracks();
-void midi_reset_channels();
-void midi_tick();
-
-#endif /* __MIDI__ */
+#define        __MIDI__\r
+\r
+#include <stdio.h>\r
+#include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+#include <malloc.h>\r
+#include <ctype.h>\r
+#include <fcntl.h>\r
+#include <math.h>\r
+#include <dos.h>\r
+\r
+//#include "src/lib/doslib/vga.h"\r
+#include "src/lib/doslib/dos.h"\r
+#include "src/lib/16_head.h"\r
+#include "src/lib/doslib/8254.h"               /* 8254 timer */\r
+#include "src/lib/doslib/8259.h"\r
+//#include "src/lib/doslib/vgagui.h"\r
+//#include "src/lib/doslib/vgatty.h"\r
+#include "src/lib/doslib/adlib.h"\r
+\r
+/* one per OPL channel */\r
+struct midi_note {\r
+       unsigned char           note_number;\r
+       unsigned char           note_velocity;\r
+       unsigned char           note_track;     /* from what MIDI track */\r
+       unsigned char           note_channel;   /* from what MIDI channel */\r
+       unsigned int            busy:1;         /* if occupied */\r
+};\r
+\r
+struct midi_channel {\r
+       unsigned char           program;\r
+};\r
+\r
+struct midi_track {\r
+       /* track data, raw */\r
+       unsigned char*          raw;            /* raw data base */\r
+       unsigned char*          fence;          /* raw data end (last byte + 1) */\r
+       unsigned char*          read;           /* raw data read ptr */\r
+       /* state */\r
+       unsigned long           us_per_quarter_note; /* Microseconds per quarter note (def 120 BPM) */\r
+       unsigned long           us_tick_cnt_mtpq; /* Microseconds advanced (up to 10000 us or one unit at 100Hz) x ticks per quarter note */\r
+       unsigned long           wait;\r
+       unsigned char           last_status;    /* MIDI last status byte */\r
+       unsigned int            eof:1;          /* we hit the end of the track */\r
+};\r
+\r
+#define MIDI_MAX_CHANNELS      16\r
+#define MIDI_MAX_TRACKS                64\r
+\r
+extern struct midi_note                midi_notes[ADLIB_FM_VOICES];\r
+extern struct midi_channel             midi_ch[MIDI_MAX_CHANNELS];\r
+extern struct midi_track               midi_trk[MIDI_MAX_TRACKS];\r
+\r
+static void (interrupt *old_irq0)();\r
+static volatile unsigned long irq0_ticks=0;\r
+static volatile unsigned int irq0_cnt=0,irq0_add=0,irq0_max=0;\r
+static volatile unsigned char  midi_playing=0;\r
+\r
+int load_midi_file(const char *path);\r
+void interrupt irq0();\r
+void adlib_shut_up();\r
+void midi_reset_tracks();\r
+void midi_reset_channels();\r
+void midi_tick();\r
+\r
+#endif /* __MIDI__ */\r
index 23202f2d50508828ebd4243f91a5b7b3096c59c6..3467a77dd3487169751b90b5ad516b025c6d8b26 100755 (executable)
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-/*
- * Functions for handling modex and doing other basic graphics stuff.
- */
-#ifndef MODEX16_H
-#define MODEX16_H
-
-#include "src/lib/16_head.h"
-#include "src/lib/bitmap.h"
-//#include "src/lib/planar.h"
-//#include "src/lib/modex16/16planar.h"
-#include "src/lib/16text.h"
-#include "src/lib/16render.h"
-////#include "src/lib/modex16/320x240.h"
-// #include "src/lib/modex16/320x200.h"
-// #include "src/lib/modex16/256x192.h"
-// #include "src/lib/modex16/192x144_.h"
-// #include "src/lib/modex16/160x120.h"
-
-#ifdef __WATCOMC__
-#include <hw/cpu/cpu.h>
-#include <hw/dos/dos.h>
-#include <hw/vga/vga.h>
-#include <hw/vga/vrl.h>
-#include <hw/vga/vrs.h>
-#endif
-
-static struct pcxHeader {
-       byte id;
-       byte version;
-       byte encoding;
-       byte bpp;
-       word xmin;
-       word ymin;
-       word xmax;
-       word ymax;
-       word hres;
-       word vres;
-       byte pal16[48];
-       byte res1;
-       word bpplane;
-       word palType;
-       word hScreenSize;
-       word vScreenSize;
-       byte padding[54];
-} head;
-
-//320x240 = 20x15
-//192x144 = 12x9
-
-//temp defines
-#define TILEWH 16
-#define TILEWHD        TILEWH*2
-#define QUADWH                 TILEWH/2
-
-/* -========================== Types & Macros ==========================- */
-#define PAGE_OFFSET(x,y) (((y)<<6)+((y)<<4)+((x)>>2))
-#define PLANE(x) (1 << ((x) & 3))
-#define SELECT_ALL_PLANES() outpw(0x03c4, 0xff02)
-#define     PALSIZE            768
-
-typedef union
-{
-       byte red;
-       byte green;
-       byte blue;
-} rgb_t;
-
-/* -======================= Constants & Vars ==========================- */
-extern byte far*  VGA;  /* The VGA Memory */
-#define SCREEN_SEG             0xa000
-#define VIDEO_INT              0x10
-#define SET_MODE               0x00
-#define VGA_256_COLOR_MODE     0x13
-#define TEXT_MODE              0x03
-
-#define AC_INDEX               0x03c0
-#define SC_INDEX               0x03c4
-#define SC_DATA                        0x03c5
-#define CRTC_INDEX             0x03d4
-#define CRTC_DATA              0x03d5
-#define GC_INDEX               0x03ce
-#define MISC_OUTPUT            0x03c2
-#define HIGH_ADDRESS           0x0C
-#define LOW_ADDRESS            0x0D
-#define VRETRACE               0x08
-//#define INPUT_STATUS_1               0x03da  defined in 16_head
-#define DISPLAY_ENABLE         0x01
-#define MAP_MASK               0x02
-#define PAL_READ_REG                   0x03C7   /* Color register, read address */
-#define PAL_WRITE_REG             0x03C8   /* Color register, write address */
-#define PAL_DATA_REG                   0x03C9   /* Color register, data port */
-#define PAL_SIZE                               (256 * 3)
-
-/* -============================ Functions =============================- */
-/* mode switching, page, and plane functions */
-void VGAmodeX(sword vq, boolean cmem, global_game_variables_t *gv);
-void modexEnter(sword vq, boolean cmem, global_game_variables_t *gv);
-byte vgaGetMode();
-void modexLeave();
-void modexsetBaseXMode();
-page_t modexDefaultPage(page_t *p);
-page_t modexNextPage(page_t *p);
-page_t modexNextPageFlexibleSize(page_t *p, word x, word y);
-void modexCalcVmemRemain(video_t *video);
-void modexHiganbanaPageSetup(video_t *video);
-void modexShowPage(page_t *page);
-void modexPanPage(page_t *page, int dx, int dy);
-void modexSelectPlane(byte plane);
-void modexClearRegion(page_t *page, int x, int y, int w, int h, byte color);
-/* moved to src/lib/modex16/16render.c */
-void modexCopyPageRegion(page_t *dest, page_t *src, word sx, word sy, word dx, word dy, word width, word height);
-
-/* Palette fade and flash effects */
-void modexFadeOn(word fade, byte *palette);
-void modexFadeOff(word fade, byte *palette);
-void modexFlashOn(word fade, byte *palette);
-void modexFlashOff(word fade, byte *palette);
-
-/* palette loading and saving */
-void modexPalSave(byte *palette);
-byte *modexNewPal();
-void modexLoadPalFile(char *filename, byte **palette);
-void modexSavePalFile(char *filename, byte *palette);
-
-/* fixed palette functions */
-void modexPalBlack();
-void modexPalWhite();
-
-/* utility functions */
-void modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset);
-void modexPalUpdate1(byte *p);
-void modexPalUpdate0(byte *p);
-void modexPalOverscan(word col);
-void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/);
-void modexputPixel(page_t *page, int x, int y, byte color);
-byte modexgetPixel(page_t *page, int x, int y);
-
-#if 0 // not needed anymore. maybe good for reference purposes though.
-static inline void modexwritepixel(page_t *page, int x, int y, word addr, byte color)
-{
-       /* Each address accesses four neighboring pixels, so set
-          Write Plane Enable according to which pixel we want
-          to modify.  The plane is determined by the two least
-          significant bits of the x-coordinate: */
-       modexSelectPlane(PLANE(x));
-       //outp(SC_INDEX, 0x02);
-       //outp(SC_DATA, 0x01 << (x & 3));
-
-       /* The offset of the pixel into the video segment is
-          offset = (width * y + x) / 4, and write the given
-          color to the plane we selected above.  Heed the active
-          page start selection. */
-       vga_state.vga_graphics_ram[addr] = color;
-}
-static inline byte modexreadPixel(page_t *page, int x, int y, word addr)
-{
-       /* Select the plane from which we must read the pixel color: */
-       outpw(GC_INDEX, 0x04);
-       outpw(GC_INDEX+1, x & 3);
-       return vga_state.vga_graphics_ram[addr];
-}
-#endif
-
-void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str);
-void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str);
-void modexpdump(page_t *pee);
-void modexcls(page_t *page, byte color, byte *Where);
-void modexWaitBorder();
-void modexprintmeminfo(video_t *v);
-
-#endif
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+/*\r
+ * Functions for handling modex and doing other basic graphics stuff.\r
+ */\r
+#ifndef MODEX16_H\r
+#define MODEX16_H\r
+\r
+#include "src/lib/16_head.h"\r
+#include "src/lib/bitmap.h"\r
+//#include "src/lib/planar.h"\r
+//#include "src/lib/modex16/16planar.h"\r
+#include "src/lib/16text.h"\r
+#include "src/lib/16render.h"\r
+////#include "src/lib/modex16/320x240.h"\r
+// #include "src/lib/modex16/320x200.h"\r
+// #include "src/lib/modex16/256x192.h"\r
+// #include "src/lib/modex16/192x144_.h"\r
+// #include "src/lib/modex16/160x120.h"\r
+\r
+#ifdef __WATCOMC__\r
+#include <hw/cpu/cpu.h>\r
+#include <hw/dos/dos.h>\r
+#include <hw/vga/vga.h>\r
+#include <hw/vga/vrl.h>\r
+#include <hw/vga/vrs.h>\r
+#endif\r
+\r
+static struct pcxHeader {\r
+       byte id;\r
+       byte version;\r
+       byte encoding;\r
+       byte bpp;\r
+       word xmin;\r
+       word ymin;\r
+       word xmax;\r
+       word ymax;\r
+       word hres;\r
+       word vres;\r
+       byte pal16[48];\r
+       byte res1;\r
+       word bpplane;\r
+       word palType;\r
+       word hScreenSize;\r
+       word vScreenSize;\r
+       byte padding[54];\r
+} head;\r
+\r
+//320x240 = 20x15\r
+//192x144 = 12x9\r
+\r
+//temp defines\r
+#define TILEWH 16\r
+#define TILEWHD        TILEWH*2\r
+#define QUADWH                 TILEWH/2\r
+\r
+/* -========================== Types & Macros ==========================- */\r
+#define PAGE_OFFSET(x,y) (((y)<<6)+((y)<<4)+((x)>>2))\r
+#define PLANE(x) (1 << ((x) & 3))\r
+#define SELECT_ALL_PLANES() outpw(0x03c4, 0xff02)\r
+#define     PALSIZE            768\r
+\r
+typedef union\r
+{\r
+       byte red;\r
+       byte green;\r
+       byte blue;\r
+} rgb_t;\r
+\r
+/* -======================= Constants & Vars ==========================- */\r
+extern byte far*  VGA;  /* The VGA Memory */\r
+#define SCREEN_SEG             0xa000\r
+#define VIDEO_INT              0x10\r
+#define SET_MODE               0x00\r
+#define VGA_256_COLOR_MODE     0x13\r
+#define TEXT_MODE              0x03\r
+\r
+#define AC_INDEX               0x03c0\r
+#define SC_INDEX               0x03c4\r
+#define SC_DATA                        0x03c5\r
+#define CRTC_INDEX             0x03d4\r
+#define CRTC_DATA              0x03d5\r
+#define GC_INDEX               0x03ce\r
+#define MISC_OUTPUT            0x03c2\r
+#define HIGH_ADDRESS           0x0C\r
+#define LOW_ADDRESS            0x0D\r
+#define VRETRACE               0x08\r
+//#define INPUT_STATUS_1               0x03da  defined in 16_head\r
+#define DISPLAY_ENABLE         0x01\r
+#define MAP_MASK               0x02\r
+#define PAL_READ_REG                   0x03C7   /* Color register, read address */\r
+#define PAL_WRITE_REG             0x03C8   /* Color register, write address */\r
+#define PAL_DATA_REG                   0x03C9   /* Color register, data port */\r
+#define PAL_SIZE                               (256 * 3)\r
+\r
+/* -============================ Functions =============================- */\r
+/* mode switching, page, and plane functions */\r
+void VGAmodeX(sword vq, boolean cmem, global_game_variables_t *gv);\r
+void modexEnter(sword vq, boolean cmem, global_game_variables_t *gv);\r
+byte vgaGetMode();\r
+void modexLeave();\r
+void modexsetBaseXMode();\r
+page_t modexDefaultPage(page_t *p);\r
+page_t modexNextPage(page_t *p);\r
+page_t modexNextPageFlexibleSize(page_t *p, word x, word y);\r
+void modexCalcVmemRemain(video_t *video);\r
+void modexHiganbanaPageSetup(video_t *video);\r
+void modexShowPage(page_t *page);\r
+void modexPanPage(page_t *page, int dx, int dy);\r
+void modexSelectPlane(byte plane);\r
+void modexClearRegion(page_t *page, int x, int y, int w, int h, byte color);\r
+/* moved to src/lib/modex16/16render.c */\r
+void modexCopyPageRegion(page_t *dest, page_t *src, word sx, word sy, word dx, word dy, word width, word height);\r
+\r
+/* Palette fade and flash effects */\r
+void modexFadeOn(word fade, byte *palette);\r
+void modexFadeOff(word fade, byte *palette);\r
+void modexFlashOn(word fade, byte *palette);\r
+void modexFlashOff(word fade, byte *palette);\r
+\r
+/* palette loading and saving */\r
+void modexPalSave(byte *palette);\r
+byte *modexNewPal();\r
+void modexLoadPalFile(char *filename, byte **palette);\r
+void modexSavePalFile(char *filename, byte *palette);\r
+\r
+/* fixed palette functions */\r
+void modexPalBlack();\r
+void modexPalWhite();\r
+\r
+/* utility functions */\r
+void modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset);\r
+void modexPalUpdate1(byte *p);\r
+void modexPalUpdate0(byte *p);\r
+void modexPalOverscan(word col);\r
+void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/);\r
+void modexputPixel(page_t *page, int x, int y, byte color);\r
+byte modexgetPixel(page_t *page, int x, int y);\r
+\r
+#if 0 // not needed anymore. maybe good for reference purposes though.\r
+static inline void modexwritepixel(page_t *page, int x, int y, word addr, byte color)\r
+{\r
+       /* Each address accesses four neighboring pixels, so set\r
+          Write Plane Enable according to which pixel we want\r
+          to modify.  The plane is determined by the two least\r
+          significant bits of the x-coordinate: */\r
+       modexSelectPlane(PLANE(x));\r
+       //outp(SC_INDEX, 0x02);\r
+       //outp(SC_DATA, 0x01 << (x & 3));\r
+\r
+       /* The offset of the pixel into the video segment is\r
+          offset = (width * y + x) / 4, and write the given\r
+          color to the plane we selected above.  Heed the active\r
+          page start selection. */\r
+       vga_state.vga_graphics_ram[addr] = color;\r
+}\r
+static inline byte modexreadPixel(page_t *page, int x, int y, word addr)\r
+{\r
+       /* Select the plane from which we must read the pixel color: */\r
+       outpw(GC_INDEX, 0x04);\r
+       outpw(GC_INDEX+1, x & 3);\r
+       return vga_state.vga_graphics_ram[addr];\r
+}\r
+#endif\r
+\r
+void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str);\r
+void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str);\r
+void modexpdump(page_t *pee);\r
+void modexcls(page_t *page, byte color, byte *Where);\r
+void modexWaitBorder();\r
+void modexprintmeminfo(video_t *v);\r
+\r
+#endif\r
index eca613a8ccfbc1bdf60f5a4a0b837813c3dc3953..b94e768a77c1a8d4813111caa3e2bdae39c36cf3 100755 (executable)
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-/*
-       scroll16 library~
-*/
-#include "src/lib/scroll16.h"
-
-void walk(map_view_t *pip, player_t *player, word pn)
-{
-       #define INC_PER_FRAME if(player[pn].q&1) player[pn].persist_aniframe++; if(player[pn].persist_aniframe>4) player[pn].persist_aniframe = 1;
-       //printf("player[%d].d=%d\n", pn, player[pn].d);
-       switch(player[pn].d)
-       {
-               //no direction
-               case 2:
-                       //0000pip[0].video->startclk = (*clockw);
-               break;
-               //right movement
-               case 3:
-                       //printf("pip[0].page->tilesw=%d        ", pip[0].page->tilesw); printf("pip[0].page->tw=%d\n", pip[0].page->tw);
-                       if(pip[0].tx >= 0 && pip[0].tx+pip[0].page->tw < pip[0].map->width && player[pn].tx == pip[0].tx+pip[0].page->tilemidposscreenx &&
-                       !(pip[0].map->data[(player[pn].tx)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx+1 == TRIGGX && player[pn].ty == TRIGGY))      //collision detection!
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       animatePlayer(pip, player, pn, 1);
-                                       ScrollRight(pip, player, 3, pn);
-                                       ScrollRight(pip, player, 2, pn);
-                                       mapScrollRight(pip, player, !(pip[0].video->p), pn);
-                                       mapScrollRight(pip, player, (pip[0].video->p), pn);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx++; }
-                       }
-                       else if(player[pn].tx < pip[0].map->width && !(pip[0].map->data[(player[pn].tx)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx+1 == TRIGGX && player[pn].ty == TRIGGY))
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       player[pn].x+=(player[pn].speed);
-                                       animatePlayer(pip, player, pn, 0);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx++; }
-                       }
-                       else
-                       {
-                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 24, 32);
-#ifdef SPRITE
-                               PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 24, 32, 24, 32, PLAYERBMPDATA);
-#else
-                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 24, 32, 14);
-#endif
-                               if(!pageflipflop) modexShowPage(pip[1].page);
-                               player[pn].d = 2;
-                       }
-                       player[pn].triggerx = player[pn].tx+1;
-                       player[pn].triggery = player[pn].ty;
-               break;
-
-               //left movement
-               case 1:
-                       if(pip[0].tx > 0 && pip[0].tx+pip[0].page->tw <= pip[0].map->width && player[pn].tx == pip[0].tx+pip[0].page->tilemidposscreenx &&
-                       !(pip[0].map->data[(player[pn].tx-2)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx-1 == TRIGGX && player[pn].ty == TRIGGY))    //collision detection!
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       animatePlayer(pip, player, pn, 1);
-                                       ScrollLeft(pip, player, 3, pn);
-                                       ScrollLeft(pip, player, 2, pn);
-                                       mapScrollLeft(pip, player, !(pip[0].video->p), pn);
-                                       mapScrollLeft(pip, player, (pip[0].video->p), pn);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx--; }
-                       }
-                       else if(player[pn].tx > 1 && !(pip[0].map->data[(player[pn].tx-2)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx-1 == TRIGGX && player[pn].ty == TRIGGY))
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       player[pn].x-=(player[pn].speed);
-                                       animatePlayer(pip, player, pn, 0);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx--; }
-                       }
-                       else
-                       {
-                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 24, 32);
-#ifdef SPRITE
-                               PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 24, 96, 24, 32, PLAYERBMPDATA);
-#else
-                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 24, 32, 10);
-#endif
-                               if(!pageflipflop) modexShowPage(pip[1].page);
-                               player[pn].d = 2;
-                       }
-                       player[pn].triggerx = player[pn].tx-1;
-                       player[pn].triggery = player[pn].ty;
-               break;
-
-               //down movement
-               case 4:
-                       if(pip[0].ty >= 0 && pip[0].ty+pip[0].page->th < pip[0].map->height && player[pn].ty == pip[0].ty+pip[0].page->tilemidposscreeny &&
-                       !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty))] == 0))//!(player[pn].tx == TRIGGX && player[pn].ty+1 == TRIGGY))      //collision detection!
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       animatePlayer(pip, player, pn, 1);
-                                       ScrollDown(pip, player, 3, pn);
-                                       ScrollDown(pip, player, 2, pn);
-                                       mapScrollDown(pip, player, !(pip[0].video->p), pn);
-                                       mapScrollDown(pip, player, (pip[0].video->p), pn);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty++; }
-                       }
-                       else if(player[pn].ty < pip[0].map->height && !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty))] == 0))//!(player[pn].tx == TRIGGX && player[pn].ty+1 == TRIGGY))
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       player[pn].y+=(player[pn].speed);
-                                       animatePlayer(pip, player, pn, 0);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty++; }
-                       }
-                       else
-                       {
-                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 24, 32);
-#ifdef SPRITE
-                               PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 24, 64, 24, 32, PLAYERBMPDATA);
-#else
-                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 24, 32, 9);
-#endif
-                               if(!pageflipflop) modexShowPage(pip[1].page);
-                               player[pn].d = 2;
-                       }
-                       player[pn].triggerx = player[pn].tx;
-                       player[pn].triggery = player[pn].ty+1;
-               break;
-
-               //up movement
-               case 0:
-                       if(pip[0].ty > 0 && pip[0].ty+pip[0].page->th <= pip[0].map->height && player[pn].ty == pip[0].ty+pip[0].page->tilemidposscreeny &&
-                       !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty-2))] == 0))//!(player[pn].tx == TRIGGX && player[pn].ty-1 == TRIGGY))    //collision detection!
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       animatePlayer(pip, player, pn, 1);
-                                       ScrollUp(pip, player, 3, pn);
-                                       ScrollUp(pip, player, 2, pn);
-                                       mapScrollUp(pip, player, !(pip[0].video->p), pn);
-                                       mapScrollUp(pip, player, (pip[0].video->p), pn);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty--; }
-                       }
-                       else if(player[pn].ty > 1 && !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty-2))] == 0))//!(player[pn].tx == TRIGGX &&  player[pn].ty-1 == TRIGGY))
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       INC_PER_FRAME;
-                                       player[pn].y-=(player[pn].speed);
-                                       animatePlayer(pip, player, 0, pn);
-                                       if(!pageflipflop) modexShowPage(pip[1].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty--; }
-                       }
-                       else
-                       {
-                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 24, 32);
-#ifdef SPRITE
-                               PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 24, 0, 24, 32, PLAYERBMPDATA);
-#else
-                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 24, 32, 12);
-#endif
-                               if(!pageflipflop) modexShowPage(pip[1].page);
-                               player[pn].d = 2;
-                       }
-                       player[pn].triggerx = player[pn].tx;
-                       player[pn].triggery = player[pn].ty-1;
-               break;
-       }
-}
-
-//panning page
-void panpagemanual(map_view_t *pip, player_t *player, word pn)
-{
-       switch(player[pn].d)
-       {
-               //right movement
-               case 3:
-                       if(pip[pip[0].pan->pn].tx >= 0 && pip[pip[0].pan->pn].tx+pip[pip[0].pan->pn].page->tw < pip[pip[0].pan->pn].page->tilesw)
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       pip[pip[0].pan->pn].page->dx+=4;
-                                       modexShowPage(pip[pip[0].pan->pn].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].tx++; }
-                       }
-               break;
-
-               //left movement
-               case 1:
-                       if(pip[pip[0].pan->pn].tx > 0 && pip[pip[0].pan->pn].tx+pip[pip[0].pan->pn].page->tw <= pip[pip[0].pan->pn].page->tilesw)
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       pip[pip[0].pan->pn].page->dx-=4;
-                                       modexShowPage(pip[pip[0].pan->pn].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].tx--; }
-                       }
-               break;
-
-               //down movement
-               case 4:
-                       if(pip[pip[0].pan->pn].ty >= 0 && pip[pip[0].pan->pn].ty+pip[pip[0].pan->pn].page->th < pip[pip[0].pan->pn].page->tilesh)
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       pip[pip[0].pan->pn].page->dy+=4;
-                                       modexShowPage(pip[pip[0].pan->pn].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].ty++; }
-                       }
-               break;
-
-               //up movement
-               case 0:
-                       if(pip[pip[0].pan->pn].ty > 0 && pip[pip[0].pan->pn].ty+pip[pip[0].pan->pn].page->th <= pip[pip[0].pan->pn].page->tilesh)
-                       {
-                               if(player[pn].q<=player[pn].spt)
-                               {
-                                       pip[pip[0].pan->pn].page->dy-=4;
-                                       modexShowPage(pip[pip[0].pan->pn].page);
-                                       player[pn].q++;
-                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].ty--; }
-                       }
-                       break;
-       }
-       //if (player[pn].d!=2) printf("player[%u].d=%u player[%u].q=%u\n", pn, player[pn].d, pn, player[pn].q);
-}
-
-/*map_t
-allocMap(int w, int h) {
-       map_t result;
-
-       result.width =w;
-       result.height=h;
-       result.data = malloc(sizeof(byte) * w * h);
-       //result.data = (byte *)alloc_emem(((int)sizeof(byte) * w * h)/1024);
-       if(isEMS() || checkEMS())
-       {
-               XMOVE mm;
-               //emmhandle = mallocEMS(coretotalEMS());//alloc_emem((int)sizeof(map))
-               mm.length=sizeof(result);
-               mm.sourceH=0;
-               mm.sourceOff=ptr2long(&result);
-               mm.destH=emmhandle;
-               mm.destOff=0;
-               ist = move_emem(&mm);
-               if(!ist){ dealloc_emem(emmhandle); exit(5); }
-               printf("%d\n", coretotalEMS());
-       }
-
-       return result;
-}*/
-
-/*void
-initMap(map_t *map) {
-       // just a place holder to fill out an alternating pattern
-       int x, y, xx, yy;
-       int i, q;
-//     int tile = 1;
-       //if(!isEMS() || !checkEMS())
-//             map->tiles = malloc(sizeof(tiles_t));
-       //else
-       //      map->tiles = (tiles_t *)alloc_emem(sizeof(tiles_t));
-
-        //create the tile set
-       //if(!isEMS() || !checkEMS())
-//             map->tiles->data = malloc(sizeof(bitmap_t));
-       //else
-       //      map->tiles->data = (bitmap_t *)alloc_emem(sizeof(bitmap_t));
-//     map->tiles->data->width = (TILEWH);
-//     map->tiles->data->height= TILEWH;
-       //if(!isEMS() || !checkEMS())
-//             map->tiles->data->data = malloc((TILEWH*2)*TILEWH);
-       //else
-       //      map->tiles->data->data = (byte *)alloc_emem((TILEWH*2)*TILEWH);
-//     map->tiles->tileHeight = TILEWH;
-//     map->tiles->tileWidth =TILEWH;
-//     map->tiles->rows = 1;
-//     map->tiles->cols = 1;//2;
-
-       q=0;
-       //for(y=0; y<map->height; y++) {
-       //for(x=0; x<map->width; x++) {
-       i=0;
-       for(yy=0; yy<TILEWH; yy++) {
-       for(xx=0; xx<(TILEWH); xx++) {
-               //if(x<TILEWH){
-                 map->tiles->data->data[i+1] = map->data[q];//28;//0x24;
-//               printf("[%d]", map->tiles->data->data[i]);
-               //}else{
-                 //map->tiles->data->data[i] = map->data[q];//0;//0x34;
-                 //printf("]%d[==[%d]", i, map->tiles->data->data[i]);
-               //}
-               i++;
-       }
-//     printf("\n");
-       }
-//     printf("[%d]", map->data[q]);
-       q++;
-//     }
-       //printf("\n\n");
-//     }
-
-       i=0;
-       for(y=0; y<map->height; y++) {
-               for(x=0; x<map->width; x++) {
-//                     map->data[i]=255;
-                       printf("[%d]", map->data[i]);
-                       //tile = tile ? 0 : 1;
-                       i++;
-               }
-               //tile = tile ? 0 : 1;
-       }
-}*/
-
-void near mapScrollRight(map_view_t *mv, player_t *player, word id, word plid)
-{
-       word x, y;  /* coordinate for drawing */
-
-       /* increment the pixel position and update the page */
-       mv[id].page->dx += player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dx >= mv[id].dxThresh )
-       {
-       /* go forward one tile */
-       mv[id].tx++;
-       /* Snap the origin forward */
-       mv[id].page->data += 4;
-
-       mv[id].page->dx = mv[id].map->tiles->tileWidth;
-       }
-
-       /* draw the next column */
-       x= mv[0].page->sw + mv[id].map->tiles->tileWidth;
-       if(player[plid].q%4)
-               if(id==0)
-                       mapDrawCol(&mv[0], mv[0].tx + mv[0].page->tw, mv[0].ty-1, x, player, mv->page->dx);
-               else
-                       if(!pageflipflop && !pageploop)
-                               modexCopyPageRegion(mv[id].page, mv[0].page, x, 0, x, 0, mv[id].map->tiles->tileWidth, mv[id].map->tiles->tileHeight*(mv[0].page->th+2));
-       mv[0].video->r=1;
-}
-
-
-void near mapScrollLeft(map_view_t *mv, player_t *player, word id, word plid)
-{
-       word x, y;  /* coordinate for drawing */
-
-       /* decrement the pixel position and update the page */
-       mv[id].page->dx -= player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dx == 0)
-       {
-       /* go backward one tile */
-       mv[id].tx--;
-       /* Snap the origin backward */
-       mv[id].page->data -= 4;
-
-       mv[id].page->dx = mv[id].map->tiles->tileWidth;
-       }
-
-       /* draw the next column */
-       x= 0;
-       if(player[plid].q%4)
-               if(id==0)
-                       mapDrawCol(&mv[0], mv[0].tx - 1, mv[0].ty-1, x, player, mv->page->dx);
-               else
-                       if(!pageflipflop && !pageploop)
-                               modexCopyPageRegion(mv[id].page, mv[0].page, x, 0, x, 0, mv[id].map->tiles->tileWidth, mv[id].map->tiles->tileHeight*(mv[0].page->th+2));
-       mv[0].video->r=1;
-}
-
-
-void near mapScrollUp(map_view_t *mv, player_t *player, word id, word plid)
-{
-       word x, y;  /* coordinate for drawing */
-
-       /* decrement the pixel position and update the page */
-       mv[id].page->dy -= player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dy == 0 )
-       {
-       /* go down one tile */
-       mv[id].ty--;
-       /* Snap the origin downward */
-       mv[id].page->data -= mv[id].page->pi;
-
-       mv[id].page->dy = mv[id].map->tiles->tileHeight;
-       }
-
-       /* draw the next row */
-       y= 0;
-       if(player[plid].q%3)
-               if(id==0)
-                       mapDrawRow(&mv[0], mv[0].tx - 1, mv[0].ty-1, y, player, mv->page->dy);
-               else
-                       if(!pageflipflop && !pageploop)
-                               modexCopyPageRegion(mv[id].page, mv[0].page, 0, y, 0, y, mv[id].map->tiles->tileWidth*(mv[0].page->tw+2), mv[id].map->tiles->tileHeight);
-       mv[0].video->r=1;
-}
-
-void near mapScrollDown(map_view_t *mv, player_t *player, word id, word plid)
-{
-       word x, y;  /* coordinate for drawing */
-
-       /* increment the pixel position and update the page */
-       mv[id].page->dy += player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dy >= mv[id].dyThresh )
-       {
-       /* go down one tile */
-       mv[id].ty++;
-       /* Snap the origin downward */
-       mv[id].page->data += mv[id].page->pi;
-
-       mv[id].page->dy = mv[id].map->tiles->tileHeight;
-       }
-
-       /* draw the next row */
-       y= mv[0].page->sh + mv[id].map->tiles->tileHeight;
-       if(player[plid].q%3)
-               if(id==0)
-                       mapDrawRow(&mv[0], mv[0].tx - 1, mv[0].ty+mv[0].page->th, y, player, mv->page->dy);
-               else
-                       if(!pageflipflop && !pageploop)
-                               modexCopyPageRegion(mv[id].page, mv[0].page, 0, y, 0, y, mv[id].map->tiles->tileWidth*(mv[0].page->tw+2), mv[id].map->tiles->tileHeight);
-       mv[0].video->r=1;
-}
-
-
-//TODO finish this wwww
-void near ScrollRight(map_view_t *mv, player_t *player, word id, word plid)
-{
-       /* increment the pixel position and update the page */
-       mv[id].page->dx += player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dx >= mv[0].dxThresh )
-       {
-//             vga_setup_wm1_block_copy();
-//             _fmemmove(mv[id].page->data+4, mv[id].page->data, mv[id].page->pagesize);
-//             vga_restore_rm0wm0();
-               /* Snap the origin forward */
-               mv[id].page->data += 4;
-               mv[id].page->dx = mv[0].map->tiles->tileWidth;
-       }
-}
-
-void near ScrollLeft(map_view_t *mv, player_t *player, word id, word plid)
-{
-       /* decrement the pixel position and update the page */
-       mv[id].page->dx -= player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dx == 0)
-       {
-//             vga_setup_wm1_block_copy();
-//             _fmemmove(mv[id].page->data-4, mv[id].page->data, mv[id].page->pagesize);
-//             vga_restore_rm0wm0();
-               /* Snap the origin backward */
-               mv[id].page->data -= 4;
-               mv[id].page->dx = mv[0].map->tiles->tileWidth;
-       }
-}
-
-void near ScrollUp(map_view_t *mv, player_t *player, word id, word plid)
-{
-       /* decrement the pixel position and update the page */
-       mv[id].page->dy -= player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dy == 0)
-       {
-//             vga_setup_wm1_block_copy();
-//             _fmemmove(mv[id].page->data-mv[id].page->pi, mv[id].page->data, mv[id].page->pagesize);
-//             vga_restore_rm0wm0();
-               /* Snap the origin backward */
-               mv[id].page->data -= mv[id].page->pi;
-               mv[id].page->dy = mv[0].map->tiles->tileWidth;
-       }
-}
-
-void near ScrollDown(map_view_t *mv, player_t *player, word id, word plid)
-{
-       /* increment the pixel position and update the page */
-       mv[id].page->dy += player[plid].speed;
-
-       /* check to see if this changes the tile */
-       if(mv[id].page->dy >= mv[0].dxThresh )
-       {
-//             vga_setup_wm1_block_copy();
-//             _fmemmove(mv[id].page->data+mv[id].page->pi, mv[id].page->data, mv[id].page->pagesize);
-//             vga_restore_rm0wm0();
-               /* Snap the origin forward */
-               mv[id].page->data += mv[id].page->pi;
-               mv[id].page->dy = mv[0].map->tiles->tileWidth;
-       }
-}
-
-sword chkmap(map_t *map, word q)
-{
-//     bitmap_t bp;
-       static byte x[(MAPW*MAPH)+1] =
-{ 1, 2, 3, 4, 0, 3, 3, 3, 3, 3, 3, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 11, 12, 4, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 0, 1, 1, 1, 5, 8, 1, 11, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 4, 0, 0, 0, 0, 0, 8, 8, 1, 11, 11, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 2, 3, 4, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 5, 6, 7, 8, 6, 6, 6, 6, 6, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 9, 10, 11, 12, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10 };
-/*1,   2,      3,      4,      0,      3,      3,      3,      3,      3,      3,      3,      3,      4,      1,      1,      1,      1,      1,      1,      \
-5,     6,      7,      8,      0,      1,      0,      1,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-9,     10,     11,     12,     4,      1,      0,      1,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-13,    14,     15,     16,     0,      1,      1,      1,      5,      8,      1,      11,     11,     1,      1,      1,      1,      1,      1,      1,      \
-0,     0,      4,      0,      0,      0,      0,      0,      8,      8,      1,      11,     11,     3,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      0,      0,      0,      0,      8,      8,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      0,      0,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      0,      0,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      3,      3,      3,      1,      2,      3,      4 };*/
-       //check for failed to load map
-       if((map->width == map->height == 0) && (q>0))
-       {
-               //initiate a null map!
-               map->width=MAPW;///2;
-               map->height=MAPH;///2;
-//             map->data = malloc(((map->width*map->height)+1)*sizeof(byte));
-               map->data = &x;
-               map->tiles = malloc(sizeof(tiles_t));
-               //fix this to be far~
-//             bp = bitmapLoadPcx("data/ed.pcx");
-//             map->tiles->data = &bp;
-               map->tiles->debug_data = map->data;
-               map->tiles->tileHeight = 16;
-               map->tiles->tileWidth = 16;
-               map->tiles->rows = 1;
-               map->tiles->cols = 1;
-               map->tiles->debug_text = true;
-       }
-       else map->tiles->debug_text = false;
-       return 0;
-}
-
-//TODO: player position here
-void mapGoTo(map_view_t *mv, int tx, int ty)
-{
-       int px, py;
-       unsigned int i;
-
-       /* set up the coordinates */
-       mv[0].tx = mv[1].tx = tx;
-       mv[0].ty = mv[1].ty = ty;
-       mv[0].page->dx = mv[1].page->dx = mv[2].page->dx = mv[3].page->dx = mv->map->tiles->tileWidth;
-       mv[0].page->dy = mv[1].page->dy = mv[2].page->dy = mv[3].page->dy = mv->map->tiles->tileHeight;
-
-       /* set up the thresholds */
-       mv[0].dxThresh = mv[1].dxThresh = mv[2].dxThresh = mv[3].dxThresh = mv->map->tiles->tileWidth * 2;
-       mv[0].dyThresh = mv[1].dyThresh = mv[2].dxThresh = mv[3].dxThresh = mv->map->tiles->tileHeight * 2;
-
-       /* draw the tiles */
-       modexClearRegion(mv[0].page, 0, 0, mv[0].page->width, mv[0].page->height, 0);
-       py=0;
-       i=mv[0].ty * mv[0].map->width + mv[0].tx;
-       for(ty=mv[0].ty-1; py < mv[0].page->sh+mv->dyThresh && ty < mv[0].map->height; ty++, py+=mv[0].map->tiles->tileHeight) {
-               mapDrawWRow(&mv[0], tx-1, ty, py);
-       i+=mv->map->width - tx;
-       }
-       if(!pageploop) modexCopyPageRegion(mv[1].page, mv[0].page, 0, 0, 0, 0, mv[0].page->width, mv[0].page->height);
-//     {
-//             unsigned int k,j,o;
-//             /* fill screen with a distinctive pattern */
-//             for (k=0;k < vga_state.vga_width;k++) {
-//                     o = k >> 2;
-//                     vga_write_sequencer(0x02/*map mask*/,1 << (k&3));
-//                             for (j=0;j < (mv[0].page->height)+(mv[1].page->height)+(mv[2].page->height)+(mv[3].page->height);j++,o += vga_state.vga_stride)
-//                                     vga_state.vga_graphics_ram[o] = (k^j)&15; // VRL samples put all colors in first 15!
-//             }
-//     }
-       modexCopyPageRegion(mv[3].page, mv[0].page, 0/**/, 0/**/, 0, 0, 24, 32);
-}
-
-void near
-mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y)
-{
-       word rx;
-       word ry;
-       word textx=0;
-       word texty=0;
-       //if(i==0) i=2;
-       if(i==0)
-       {
-               //wwww
-               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, 0); //currently the over scan color!
-       }
-       else
-       {
-               rx = (((i-1) % ((t->data->width)/t->tileWidth)) * t->tileWidth);
-               ry = (((i-1) / ((t->data->height)/t->tileHeight)) * t->tileHeight);
-////0000printf("i=%d\n", i);
-               switch(t->debug_text)
-               {
-                       case 0:
-#ifndef TILERENDER
-                               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, ((t->debug_data[i])+1));
-                               //modexprint(page, x, y, 1, 15, 0, (char const *)(t->debug_data[i]));
-#else
-                               PBUFBFUN                (page, x, y, rx, ry, t->tileWidth, t->tileHeight, (t->data));
-                               /* then the sprite. note modding ram ptr means we just draw to (x&3,0) */
-                               //draw_vrl1_vgax_modex(x-rx,y-ry,vrl_header,vrl_lineoffs,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));
-                               //modexDrawBmpRegion    (page, x, y, rx, ry, t->tileWidth, t->tileHeight, (t->data));
-#endif
-                       break;
-                       case 1:
-                               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, (t->debug_data[i])+1);
-                               //modexprintbig(page, x, y, 1, 15, 0, (t->debug_data));
-                               /*for(texty=0; texty<2; texty++)
-                               {
-                                       for(textx=0; textx<2; textx++)
-                                       {*/
-//                                             modexprint(page, x+(textx*8), y+(texty*8), 1, (word)(t->debug_data), 0, (t->debug_data));
-/*                                     }
-                               }*/
-                       break;
-               }
-       }
-}
-
-void near mapDrawRow(map_view_t *mv, int tx, int ty, word y, player_t *p, word poopoffset)
-{
-       word x;
-       int i;
-       poopoffset%=p[0].speed;
-//printf("y: %d\n", poopoffset);
-       /* the position within the map array */
-       i=ty * mv->map->width + tx;
-       for(x=poopoffset; x<(mv->page->sw+mv->dxThresh)/(poopoffset+1) && tx < mv->map->width; x+=mv->map->tiles->tileWidth, tx++) {
-       if(i>=0) {
-               /* we are in the map, so copy! */
-               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);
-       }
-       i++; /* next! */
-       }
-}
-
-void near mapDrawCol(map_view_t *mv, int tx, int ty, word x, player_t *p, word poopoffset)
-{
-       int y;
-       int i;
-       poopoffset%=p[0].speed;
-//printf("x: %d\n", poopoffset);
-       /* location in the map array */
-       i=ty * mv->map->width + tx;
-
-       /* We'll copy all of the columns in the screen,
-          i + 1 row above and one below */
-       for(y=poopoffset; y<(mv->page->sh+mv->dyThresh)/(poopoffset+1) && ty < mv->map->height; y+=mv->map->tiles->tileHeight, ty++) {
-       if(i>=0) {
-               /* we are in the map, so copy away! */
-               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);
-       }
-       i += mv->map->width;
-       }
-}
-
-void mapDrawWRow(map_view_t *mv, int tx, int ty, word y)
-{
-       word x;
-       int i;
-
-       /* the position within the map array */
-       i=ty * mv->map->width + tx;
-       for(x=0; x<mv->page->sw+mv->dxThresh && tx < mv->map->width; x+=mv->map->tiles->tileWidth, tx++) {
-       if(i>=0) {
-               /* we are in the map, so copy! */
-               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);
-       }
-       i++; /* next! */
-       }
-}
-
-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,
-          i + 1 row above and one below */
-       for(y=0; y<mv->page->sh+mv->dyThresh && ty < mv->map->height; y+=mv->map->tiles->tileHeight, ty++) {
-       if(i>=0) {
-               /* we are in the map, so copy away! */
-               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);
-       }
-       i += mv->map->width;
-       }
-}
-
-/*void qclean()
-{
-       //setkb(0);
-}*/
-
-unsigned char shinku_fps_indicator_page = 2;
-boolean pageflipflop = 1;
-boolean pageploop = 1;
-
-/*     sync    */
-void shinku(global_game_variables_t *gv)
-{
-       word x = (0) + gv->video.page[/*!*/(gv->video.p)].dx; // follow the screen
-       word y = (0) + gv->video.page[/*!*/(gv->video.p)].dy; // follow the screen
-       word w = 64, h = 8, col = 7, bgcol = 0, type = 1;
-       byte o,o2,i;
-       //modexCopyPageRegion(pip[1].page, pip[2].page, 16, 16, 16, 16, (14*8)+4, 8+4);
-       /* block copy to visible RAM from offscreen */
-//     vga_setup_wm1_block_copy();
-//     modexCopyPageRegion(&(gv->video.page[shinku_fps_indicator_page]), &(gv->video.page[!shinku_fps_indicator_page]), x, y, x+w, 0, w, h);
-//     o =     *(gv->video.page[2].data); // source offscreen
-//     o2 =    *(gv->video.page[shinku_fps_indicator_page].data)+(y * vga_state.vga_stride) + (x >> 2); // dest visible (original stride)
-//     for (i=0;i < h;i++,o += vga_state.vga_draw_stride,o2 += vga_state.vga_stride) vga_wm1_mem_block_copy(o2,o,w >> 2);
-       /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */
-//     vga_restore_rm0wm0();
-       if(elapsed_timer(gv) >= (1.0 / gv->kurokku.frames_per_second))
-       {
-               sprintf(gv->pee, "%.0f fps", (double)gv->kurokku.tiku/ticktock(gv));
-               //modexClearRegion(&(gv->video.page[shinku_fps_indicator_page]), x, y, w, h, 45);
-               modexprint(&(gv->video.page[/*!*/(gv->video.p)]), x, y, type, col, bgcol, gv->pee);
-               gv->kurokku.tiku=0;
-               /* block copy to visible RAM from offscreen */
-//             vga_setup_wm1_block_copy();
-//             o =     *(gv->video.page[shinku_fps_indicator_page].data); // source offscreen
-//             o2 =    *(gv->video.page[2].data)+(y * vga_state.vga_stride) + (x >> 2); // dest visible (original stride)
-//             for (i=0;i < h;i++,o += vga_state.vga_draw_stride,o2 += vga_state.vga_stride) vga_wm1_mem_block_copy(o2,o,w >> 2);
-//             modexCopyPageRegion(&(gv->video.page[shinku_fps_indicator_page]), &(gv->video.page[!shinku_fps_indicator_page]), x, y, x, 0, w, h);
-               /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */
-//             vga_restore_rm0wm0();
-       }else //copy dat sheet
-       gv->kurokku.tiku++;
-
-       switch(gv->kurokku.fpscap)
-       {
-               case 0:
-                       //modexprint(&(gv->video.page[shinku_fps_indicator_page]), x, y+8, type, col, bgcol, "sanic!");
-                       gv->kurokku.frames_per_second=1;
-               break;
-               case 1:
-                       //turn this off if XT
-                       //modexWaitBorder();
-                       vga_wait_for_vsync();
-                       gv->kurokku.frames_per_second=60;
-               break;
-       }
-       if(pageflipflop){
-       if(gv->video.r){
-               //vga_setup_wm1_block_copy();
-               //_fmemcpy((gv->video.page[(gv->video.p)]).data, (gv->video.page[(!gv->video.p)]).data, gv->video.page[(!gv->video.p)].pagesize);
-               //vga_restore_rm0wm0();
-               if(!pageploop) modexCopyPageRegion(&(gv->video.page[(gv->video.p)]), &(gv->video.page[(!gv->video.p)]), 0, 0, 0, 0, gv->video.page[gv->video.p].width, gv->video.page[!gv->video.p].height);
-               modexShowPage(&(gv->video.page[gv->video.p]));
-               if(!pageploop) gv->video.p=!gv->video.p;
-               gv->video.r=!gv->video.r;
-               //0000gv->video.tickclk = ((*clockw)-gv->video.startclk)/18.2;
-       }
-       }
-}
-
-void near animatePlayer(map_view_t *pip, player_t *player, word pn, sword scrollswitch)
-{
-       sword x = player[pn].x;
-       sword y = player[pn].y;
-       sword bx = x+16;        //buffer's x
-       sword by = y+16;        //buffer's y
-       word dire=32; //direction
-       sword qq; //scroll offset
-       word ls = player[pn].persist_aniframe;
-
-       switch(scrollswitch)
-       {
-               case 0:
-                       qq = 0;
-               break;
-               default:
-                       qq = ((player[pn].q)*(player[pn].speed));
-               break;
-       }
-       //x-=4;
-       y-=pip[0].map->tiles->tileHeight;
-       switch (player[pn].d)
-       {
-               case 0:
-                       //up
-                       dire*=player[pn].d;
-                       y-=qq;
-                       by-=4;
-               break;
-               case 3:
-                       // right
-                       dire*=(player[pn].d-2);
-                       x+=qq;
-                       bx+=4;
-               break;
-               case 2:
-               break;
-               case 4:
-                       //down
-                       dire*=(player[pn].d-2);
-                       y+=qq;
-                       by+=4;
-               break;
-               case 1:
-                       //left
-                       dire*=(player[pn].d+2);
-                       x-=qq;
-                       bx-=4;
-               break;
-       }
-
-#ifdef SPRITE
-#define FRAME1 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 48, dire, 24, 32,        PLAYERBMPDATA);
-#define FRAME2 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 24, dire, 24, 32,        PLAYERBMPDATA);
-#define FRAME3 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 0, dire, 24, 32, PLAYERBMPDATA);
-#define FRAME4 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 24, dire, 24, 32,        PLAYERBMPDATA);
-#else
-#define FRAME1 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, 2+dire);
-#define FRAME2 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, 1+dire);
-#define FRAME3 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, dire);
-#define FRAME4 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, 1+dire);
-#endif
-       if(!pageflipflop)
-               modexCopyPageRegion(pip[1].page, pip[0].page, x-4, y-4, x-4, y-4, 28, 36);
-       else{
-               //copy old bg to page0
-               //modexCopyPageRegion(pip[3].page, pip[0].page, bx, by, 0, 0,   20, 36);
-               //update buffer
-               //modexCopyPageRegion(pip[0].page, pip[3].page, 0, 0,   x, y,   20, 36);
-       }
-//modexCopyPageRegion(page_t *dest, page_t *src, word sx, word sy, word dx, word dy, word width, word height);
-       //modexCopyPageRegion(pip[3].page, pip[!(pip->video->p)].page, x-4, y-4, 0, 128, 28, 36);
-       /*modexCopyPageRegion(pip[pip->video->p].page,
- pip[!(pip->video->p)].page, x-4, y-4, x-4, y-4, 28, 36);*/
-//     else modexCopyPageRegion(pip[1].page, pip[0].page, x-4, y-4, x-4, y-4, 28, 40);
-       switch(ls)
-       {
-               case 1:
-                       FRAME1
-               break;
-               case 2:
-                       FRAME2
-               break;
-               case 3:
-                       FRAME3
-               break;
-               case 4:
-                       FRAME4
-               break;
-       }
-//     if(2>ls && ls>=1) { FRAME1 }else
-//     if(3>ls && ls>=2) { FRAME2 }else
-//     if(4>ls && ls>=3) { FRAME3 }else
-//     if(5>ls && ls>=4) { FRAME4 }
-       //modexCopyPageRegion(pip[0].page, pip[3].page, 0, 0, x, y, 24, 32);
-       //printf("x=%d  y=%d    bx=%d           by=%d\n", x, y, bx, by);
-       pip->video->r=1;
-}
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+/*\r
+       scroll16 library~\r
+*/\r
+#include "src/lib/scroll16.h"\r
+\r
+void walk(map_view_t *pip, player_t *player, word pn)\r
+{\r
+       #define INC_PER_FRAME if(player[pn].q&1) player[pn].persist_aniframe++; if(player[pn].persist_aniframe>4) player[pn].persist_aniframe = 1;\r
+       //printf("player[%d].d=%d\n", pn, player[pn].d);\r
+       switch(player[pn].d)\r
+       {\r
+               //no direction\r
+               case 2:\r
+                       //0000pip[0].video->startclk = (*clockw);\r
+               break;\r
+               //right movement\r
+               case 3:\r
+                       //printf("pip[0].page->tilesw=%d        ", pip[0].page->tilesw); printf("pip[0].page->tw=%d\n", pip[0].page->tw);\r
+                       if(pip[0].tx >= 0 && pip[0].tx+pip[0].page->tw < pip[0].map->width && player[pn].tx == pip[0].tx+pip[0].page->tilemidposscreenx &&\r
+                       !(pip[0].map->data[(player[pn].tx)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx+1 == TRIGGX && player[pn].ty == TRIGGY))      //collision detection!\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       animatePlayer(pip, player, pn, 1);\r
+                                       ScrollRight(pip, player, 3, pn);\r
+                                       ScrollRight(pip, player, 2, pn);\r
+                                       mapScrollRight(pip, player, !(pip[0].video->p), pn);\r
+                                       mapScrollRight(pip, player, (pip[0].video->p), pn);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx++; }\r
+                       }\r
+                       else if(player[pn].tx < pip[0].map->width && !(pip[0].map->data[(player[pn].tx)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx+1 == TRIGGX && player[pn].ty == TRIGGY))\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       player[pn].x+=(player[pn].speed);\r
+                                       animatePlayer(pip, player, pn, 0);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx++; }\r
+                       }\r
+                       else\r
+                       {\r
+                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 24, 32);\r
+#ifdef SPRITE\r
+                               PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 24, 32, 24, 32, PLAYERBMPDATA);\r
+#else\r
+                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 24, 32, 14);\r
+#endif\r
+                               if(!pageflipflop) modexShowPage(pip[1].page);\r
+                               player[pn].d = 2;\r
+                       }\r
+                       player[pn].triggerx = player[pn].tx+1;\r
+                       player[pn].triggery = player[pn].ty;\r
+               break;\r
+\r
+               //left movement\r
+               case 1:\r
+                       if(pip[0].tx > 0 && pip[0].tx+pip[0].page->tw <= pip[0].map->width && player[pn].tx == pip[0].tx+pip[0].page->tilemidposscreenx &&\r
+                       !(pip[0].map->data[(player[pn].tx-2)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx-1 == TRIGGX && player[pn].ty == TRIGGY))    //collision detection!\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       animatePlayer(pip, player, pn, 1);\r
+                                       ScrollLeft(pip, player, 3, pn);\r
+                                       ScrollLeft(pip, player, 2, pn);\r
+                                       mapScrollLeft(pip, player, !(pip[0].video->p), pn);\r
+                                       mapScrollLeft(pip, player, (pip[0].video->p), pn);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx--; }\r
+                       }\r
+                       else if(player[pn].tx > 1 && !(pip[0].map->data[(player[pn].tx-2)+(pip[0].map->width*(player[pn].ty-1))] == 0))//!(player[pn].tx-1 == TRIGGX && player[pn].ty == TRIGGY))\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       player[pn].x-=(player[pn].speed);\r
+                                       animatePlayer(pip, player, pn, 0);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].tx--; }\r
+                       }\r
+                       else\r
+                       {\r
+                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 24, 32);\r
+#ifdef SPRITE\r
+                               PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 24, 96, 24, 32, PLAYERBMPDATA);\r
+#else\r
+                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 24, 32, 10);\r
+#endif\r
+                               if(!pageflipflop) modexShowPage(pip[1].page);\r
+                               player[pn].d = 2;\r
+                       }\r
+                       player[pn].triggerx = player[pn].tx-1;\r
+                       player[pn].triggery = player[pn].ty;\r
+               break;\r
+\r
+               //down movement\r
+               case 4:\r
+                       if(pip[0].ty >= 0 && pip[0].ty+pip[0].page->th < pip[0].map->height && player[pn].ty == pip[0].ty+pip[0].page->tilemidposscreeny &&\r
+                       !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty))] == 0))//!(player[pn].tx == TRIGGX && player[pn].ty+1 == TRIGGY))      //collision detection!\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       animatePlayer(pip, player, pn, 1);\r
+                                       ScrollDown(pip, player, 3, pn);\r
+                                       ScrollDown(pip, player, 2, pn);\r
+                                       mapScrollDown(pip, player, !(pip[0].video->p), pn);\r
+                                       mapScrollDown(pip, player, (pip[0].video->p), pn);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty++; }\r
+                       }\r
+                       else if(player[pn].ty < pip[0].map->height && !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty))] == 0))//!(player[pn].tx == TRIGGX && player[pn].ty+1 == TRIGGY))\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       player[pn].y+=(player[pn].speed);\r
+                                       animatePlayer(pip, player, pn, 0);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty++; }\r
+                       }\r
+                       else\r
+                       {\r
+                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 24, 32);\r
+#ifdef SPRITE\r
+                               PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 24, 64, 24, 32, PLAYERBMPDATA);\r
+#else\r
+                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 24, 32, 9);\r
+#endif\r
+                               if(!pageflipflop) modexShowPage(pip[1].page);\r
+                               player[pn].d = 2;\r
+                       }\r
+                       player[pn].triggerx = player[pn].tx;\r
+                       player[pn].triggery = player[pn].ty+1;\r
+               break;\r
+\r
+               //up movement\r
+               case 0:\r
+                       if(pip[0].ty > 0 && pip[0].ty+pip[0].page->th <= pip[0].map->height && player[pn].ty == pip[0].ty+pip[0].page->tilemidposscreeny &&\r
+                       !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty-2))] == 0))//!(player[pn].tx == TRIGGX && player[pn].ty-1 == TRIGGY))    //collision detection!\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       animatePlayer(pip, player, pn, 1);\r
+                                       ScrollUp(pip, player, 3, pn);\r
+                                       ScrollUp(pip, player, 2, pn);\r
+                                       mapScrollUp(pip, player, !(pip[0].video->p), pn);\r
+                                       mapScrollUp(pip, player, (pip[0].video->p), pn);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                                       //0000pip[0].video->clk = ((*clockw)-pip[0].video->startclk)/18.2;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty--; }\r
+                       }\r
+                       else if(player[pn].ty > 1 && !(pip[0].map->data[(player[pn].tx-1)+(pip[0].map->width*(player[pn].ty-2))] == 0))//!(player[pn].tx == TRIGGX &&  player[pn].ty-1 == TRIGGY))\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       INC_PER_FRAME;\r
+                                       player[pn].y-=(player[pn].speed);\r
+                                       animatePlayer(pip, player, 0, pn);\r
+                                       if(!pageflipflop) modexShowPage(pip[1].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; player[pn].ty--; }\r
+                       }\r
+                       else\r
+                       {\r
+                               if(!pageflipflop) modexCopyPageRegion(pip[1].page, pip[0].page, player[pn].x, player[pn].y-TILEWH, player[pn].x, player[pn].y-TILEWH, 24, 32);\r
+#ifdef SPRITE\r
+                               PBUFSFUN(pip[0].page, player[pn].x, player[pn].y-TILEWH, 24, 0, 24, 32, PLAYERBMPDATA);\r
+#else\r
+                               modexClearRegion(pip[1].page, player[pn].x, player[pn].y-TILEWH, 24, 32, 12);\r
+#endif\r
+                               if(!pageflipflop) modexShowPage(pip[1].page);\r
+                               player[pn].d = 2;\r
+                       }\r
+                       player[pn].triggerx = player[pn].tx;\r
+                       player[pn].triggery = player[pn].ty-1;\r
+               break;\r
+       }\r
+}\r
+\r
+//panning page\r
+void panpagemanual(map_view_t *pip, player_t *player, word pn)\r
+{\r
+       switch(player[pn].d)\r
+       {\r
+               //right movement\r
+               case 3:\r
+                       if(pip[pip[0].pan->pn].tx >= 0 && pip[pip[0].pan->pn].tx+pip[pip[0].pan->pn].page->tw < pip[pip[0].pan->pn].page->tilesw)\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       pip[pip[0].pan->pn].page->dx+=4;\r
+                                       modexShowPage(pip[pip[0].pan->pn].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].tx++; }\r
+                       }\r
+               break;\r
+\r
+               //left movement\r
+               case 1:\r
+                       if(pip[pip[0].pan->pn].tx > 0 && pip[pip[0].pan->pn].tx+pip[pip[0].pan->pn].page->tw <= pip[pip[0].pan->pn].page->tilesw)\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       pip[pip[0].pan->pn].page->dx-=4;\r
+                                       modexShowPage(pip[pip[0].pan->pn].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].tx--; }\r
+                       }\r
+               break;\r
+\r
+               //down movement\r
+               case 4:\r
+                       if(pip[pip[0].pan->pn].ty >= 0 && pip[pip[0].pan->pn].ty+pip[pip[0].pan->pn].page->th < pip[pip[0].pan->pn].page->tilesh)\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       pip[pip[0].pan->pn].page->dy+=4;\r
+                                       modexShowPage(pip[pip[0].pan->pn].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].ty++; }\r
+                       }\r
+               break;\r
+\r
+               //up movement\r
+               case 0:\r
+                       if(pip[pip[0].pan->pn].ty > 0 && pip[pip[0].pan->pn].ty+pip[pip[0].pan->pn].page->th <= pip[pip[0].pan->pn].page->tilesh)\r
+                       {\r
+                               if(player[pn].q<=player[pn].spt)\r
+                               {\r
+                                       pip[pip[0].pan->pn].page->dy-=4;\r
+                                       modexShowPage(pip[pip[0].pan->pn].page);\r
+                                       player[pn].q++;\r
+                               } else { player[pn].q = 1; player[pn].d = 2; pip[pip[0].pan->pn].ty--; }\r
+                       }\r
+                       break;\r
+       }\r
+       //if (player[pn].d!=2) printf("player[%u].d=%u player[%u].q=%u\n", pn, player[pn].d, pn, player[pn].q);\r
+}\r
+\r
+/*map_t\r
+allocMap(int w, int h) {\r
+       map_t result;\r
+\r
+       result.width =w;\r
+       result.height=h;\r
+       result.data = malloc(sizeof(byte) * w * h);\r
+       //result.data = (byte *)alloc_emem(((int)sizeof(byte) * w * h)/1024);\r
+       if(isEMS() || checkEMS())\r
+       {\r
+               XMOVE mm;\r
+               //emmhandle = mallocEMS(coretotalEMS());//alloc_emem((int)sizeof(map))\r
+               mm.length=sizeof(result);\r
+               mm.sourceH=0;\r
+               mm.sourceOff=ptr2long(&result);\r
+               mm.destH=emmhandle;\r
+               mm.destOff=0;\r
+               ist = move_emem(&mm);\r
+               if(!ist){ dealloc_emem(emmhandle); exit(5); }\r
+               printf("%d\n", coretotalEMS());\r
+       }\r
+\r
+       return result;\r
+}*/\r
+\r
+/*void\r
+initMap(map_t *map) {\r
+       // just a place holder to fill out an alternating pattern\r
+       int x, y, xx, yy;\r
+       int i, q;\r
+//     int tile = 1;\r
+       //if(!isEMS() || !checkEMS())\r
+//             map->tiles = malloc(sizeof(tiles_t));\r
+       //else\r
+       //      map->tiles = (tiles_t *)alloc_emem(sizeof(tiles_t));\r
+\r
+        //create the tile set\r
+       //if(!isEMS() || !checkEMS())\r
+//             map->tiles->data = malloc(sizeof(bitmap_t));\r
+       //else\r
+       //      map->tiles->data = (bitmap_t *)alloc_emem(sizeof(bitmap_t));\r
+//     map->tiles->data->width = (TILEWH);\r
+//     map->tiles->data->height= TILEWH;\r
+       //if(!isEMS() || !checkEMS())\r
+//             map->tiles->data->data = malloc((TILEWH*2)*TILEWH);\r
+       //else\r
+       //      map->tiles->data->data = (byte *)alloc_emem((TILEWH*2)*TILEWH);\r
+//     map->tiles->tileHeight = TILEWH;\r
+//     map->tiles->tileWidth =TILEWH;\r
+//     map->tiles->rows = 1;\r
+//     map->tiles->cols = 1;//2;\r
+\r
+       q=0;\r
+       //for(y=0; y<map->height; y++) {\r
+       //for(x=0; x<map->width; x++) {\r
+       i=0;\r
+       for(yy=0; yy<TILEWH; yy++) {\r
+       for(xx=0; xx<(TILEWH); xx++) {\r
+               //if(x<TILEWH){\r
+                 map->tiles->data->data[i+1] = map->data[q];//28;//0x24;\r
+//               printf("[%d]", map->tiles->data->data[i]);\r
+               //}else{\r
+                 //map->tiles->data->data[i] = map->data[q];//0;//0x34;\r
+                 //printf("]%d[==[%d]", i, map->tiles->data->data[i]);\r
+               //}\r
+               i++;\r
+       }\r
+//     printf("\n");\r
+       }\r
+//     printf("[%d]", map->data[q]);\r
+       q++;\r
+//     }\r
+       //printf("\n\n");\r
+//     }\r
+\r
+       i=0;\r
+       for(y=0; y<map->height; y++) {\r
+               for(x=0; x<map->width; x++) {\r
+//                     map->data[i]=255;\r
+                       printf("[%d]", map->data[i]);\r
+                       //tile = tile ? 0 : 1;\r
+                       i++;\r
+               }\r
+               //tile = tile ? 0 : 1;\r
+       }\r
+}*/\r
+\r
+void near mapScrollRight(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       word x, y;  /* coordinate for drawing */\r
+\r
+       /* increment the pixel position and update the page */\r
+       mv[id].page->dx += player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dx >= mv[id].dxThresh )\r
+       {\r
+       /* go forward one tile */\r
+       mv[id].tx++;\r
+       /* Snap the origin forward */\r
+       mv[id].page->data += 4;\r
+\r
+       mv[id].page->dx = mv[id].map->tiles->tileWidth;\r
+       }\r
+\r
+       /* draw the next column */\r
+       x= mv[0].page->sw + mv[id].map->tiles->tileWidth;\r
+       if(player[plid].q%4)\r
+               if(id==0)\r
+                       mapDrawCol(&mv[0], mv[0].tx + mv[0].page->tw, mv[0].ty-1, x, player, mv->page->dx);\r
+               else\r
+                       if(!pageflipflop && !pageploop)\r
+                               modexCopyPageRegion(mv[id].page, mv[0].page, x, 0, x, 0, mv[id].map->tiles->tileWidth, mv[id].map->tiles->tileHeight*(mv[0].page->th+2));\r
+       mv[0].video->r=1;\r
+}\r
+\r
+\r
+void near mapScrollLeft(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       word x, y;  /* coordinate for drawing */\r
+\r
+       /* decrement the pixel position and update the page */\r
+       mv[id].page->dx -= player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dx == 0)\r
+       {\r
+       /* go backward one tile */\r
+       mv[id].tx--;\r
+       /* Snap the origin backward */\r
+       mv[id].page->data -= 4;\r
+\r
+       mv[id].page->dx = mv[id].map->tiles->tileWidth;\r
+       }\r
+\r
+       /* draw the next column */\r
+       x= 0;\r
+       if(player[plid].q%4)\r
+               if(id==0)\r
+                       mapDrawCol(&mv[0], mv[0].tx - 1, mv[0].ty-1, x, player, mv->page->dx);\r
+               else\r
+                       if(!pageflipflop && !pageploop)\r
+                               modexCopyPageRegion(mv[id].page, mv[0].page, x, 0, x, 0, mv[id].map->tiles->tileWidth, mv[id].map->tiles->tileHeight*(mv[0].page->th+2));\r
+       mv[0].video->r=1;\r
+}\r
+\r
+\r
+void near mapScrollUp(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       word x, y;  /* coordinate for drawing */\r
+\r
+       /* decrement the pixel position and update the page */\r
+       mv[id].page->dy -= player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dy == 0 )\r
+       {\r
+       /* go down one tile */\r
+       mv[id].ty--;\r
+       /* Snap the origin downward */\r
+       mv[id].page->data -= mv[id].page->pi;\r
+\r
+       mv[id].page->dy = mv[id].map->tiles->tileHeight;\r
+       }\r
+\r
+       /* draw the next row */\r
+       y= 0;\r
+       if(player[plid].q%3)\r
+               if(id==0)\r
+                       mapDrawRow(&mv[0], mv[0].tx - 1, mv[0].ty-1, y, player, mv->page->dy);\r
+               else\r
+                       if(!pageflipflop && !pageploop)\r
+                               modexCopyPageRegion(mv[id].page, mv[0].page, 0, y, 0, y, mv[id].map->tiles->tileWidth*(mv[0].page->tw+2), mv[id].map->tiles->tileHeight);\r
+       mv[0].video->r=1;\r
+}\r
+\r
+void near mapScrollDown(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       word x, y;  /* coordinate for drawing */\r
+\r
+       /* increment the pixel position and update the page */\r
+       mv[id].page->dy += player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dy >= mv[id].dyThresh )\r
+       {\r
+       /* go down one tile */\r
+       mv[id].ty++;\r
+       /* Snap the origin downward */\r
+       mv[id].page->data += mv[id].page->pi;\r
+\r
+       mv[id].page->dy = mv[id].map->tiles->tileHeight;\r
+       }\r
+\r
+       /* draw the next row */\r
+       y= mv[0].page->sh + mv[id].map->tiles->tileHeight;\r
+       if(player[plid].q%3)\r
+               if(id==0)\r
+                       mapDrawRow(&mv[0], mv[0].tx - 1, mv[0].ty+mv[0].page->th, y, player, mv->page->dy);\r
+               else\r
+                       if(!pageflipflop && !pageploop)\r
+                               modexCopyPageRegion(mv[id].page, mv[0].page, 0, y, 0, y, mv[id].map->tiles->tileWidth*(mv[0].page->tw+2), mv[id].map->tiles->tileHeight);\r
+       mv[0].video->r=1;\r
+}\r
+\r
+\r
+//TODO finish this wwww\r
+void near ScrollRight(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       /* increment the pixel position and update the page */\r
+       mv[id].page->dx += player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dx >= mv[0].dxThresh )\r
+       {\r
+//             vga_setup_wm1_block_copy();\r
+//             _fmemmove(mv[id].page->data+4, mv[id].page->data, mv[id].page->pagesize);\r
+//             vga_restore_rm0wm0();\r
+               /* Snap the origin forward */\r
+               mv[id].page->data += 4;\r
+               mv[id].page->dx = mv[0].map->tiles->tileWidth;\r
+       }\r
+}\r
+\r
+void near ScrollLeft(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       /* decrement the pixel position and update the page */\r
+       mv[id].page->dx -= player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dx == 0)\r
+       {\r
+//             vga_setup_wm1_block_copy();\r
+//             _fmemmove(mv[id].page->data-4, mv[id].page->data, mv[id].page->pagesize);\r
+//             vga_restore_rm0wm0();\r
+               /* Snap the origin backward */\r
+               mv[id].page->data -= 4;\r
+               mv[id].page->dx = mv[0].map->tiles->tileWidth;\r
+       }\r
+}\r
+\r
+void near ScrollUp(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       /* decrement the pixel position and update the page */\r
+       mv[id].page->dy -= player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dy == 0)\r
+       {\r
+//             vga_setup_wm1_block_copy();\r
+//             _fmemmove(mv[id].page->data-mv[id].page->pi, mv[id].page->data, mv[id].page->pagesize);\r
+//             vga_restore_rm0wm0();\r
+               /* Snap the origin backward */\r
+               mv[id].page->data -= mv[id].page->pi;\r
+               mv[id].page->dy = mv[0].map->tiles->tileWidth;\r
+       }\r
+}\r
+\r
+void near ScrollDown(map_view_t *mv, player_t *player, word id, word plid)\r
+{\r
+       /* increment the pixel position and update the page */\r
+       mv[id].page->dy += player[plid].speed;\r
+\r
+       /* check to see if this changes the tile */\r
+       if(mv[id].page->dy >= mv[0].dxThresh )\r
+       {\r
+//             vga_setup_wm1_block_copy();\r
+//             _fmemmove(mv[id].page->data+mv[id].page->pi, mv[id].page->data, mv[id].page->pagesize);\r
+//             vga_restore_rm0wm0();\r
+               /* Snap the origin forward */\r
+               mv[id].page->data += mv[id].page->pi;\r
+               mv[id].page->dy = mv[0].map->tiles->tileWidth;\r
+       }\r
+}\r
+\r
+sword chkmap(map_t *map, word q)\r
+{\r
+//     bitmap_t bp;\r
+       static byte x[(MAPW*MAPH)+1] =\r
+{ 1, 2, 3, 4, 0, 3, 3, 3, 3, 3, 3, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 11, 12, 4, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 0, 1, 1, 1, 5, 8, 1, 11, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 4, 0, 0, 0, 0, 0, 8, 8, 1, 11, 11, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 2, 3, 4, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 5, 6, 7, 8, 6, 6, 6, 6, 6, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 9, 10, 11, 12, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10 };\r
+/*1,   2,      3,      4,      0,      3,      3,      3,      3,      3,      3,      3,      3,      4,      1,      1,      1,      1,      1,      1,      \\r
+5,     6,      7,      8,      0,      1,      0,      1,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+9,     10,     11,     12,     4,      1,      0,      1,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+13,    14,     15,     16,     0,      1,      1,      1,      5,      8,      1,      11,     11,     1,      1,      1,      1,      1,      1,      1,      \\r
+0,     0,      4,      0,      0,      0,      0,      0,      8,      8,      1,      11,     11,     3,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      0,      0,      0,      0,      8,      8,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      0,      0,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      0,      0,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      3,      3,      3,      1,      2,      3,      4 };*/\r
+       //check for failed to load map\r
+       if((map->width == map->height == 0) && (q>0))\r
+       {\r
+               //initiate a null map!\r
+               map->width=MAPW;///2;\r
+               map->height=MAPH;///2;\r
+//             map->data = malloc(((map->width*map->height)+1)*sizeof(byte));\r
+               map->data = &x;\r
+               map->tiles = malloc(sizeof(tiles_t));\r
+               //fix this to be far~\r
+//             bp = bitmapLoadPcx("data/ed.pcx");\r
+//             map->tiles->data = &bp;\r
+               map->tiles->debug_data = map->data;\r
+               map->tiles->tileHeight = 16;\r
+               map->tiles->tileWidth = 16;\r
+               map->tiles->rows = 1;\r
+               map->tiles->cols = 1;\r
+               map->tiles->debug_text = true;\r
+       }\r
+       else map->tiles->debug_text = false;\r
+       return 0;\r
+}\r
+\r
+//TODO: player position here\r
+void mapGoTo(map_view_t *mv, int tx, int ty)\r
+{\r
+       int px, py;\r
+       unsigned int i;\r
+\r
+       /* set up the coordinates */\r
+       mv[0].tx = mv[1].tx = tx;\r
+       mv[0].ty = mv[1].ty = ty;\r
+       mv[0].page->dx = mv[1].page->dx = mv[2].page->dx = mv[3].page->dx = mv->map->tiles->tileWidth;\r
+       mv[0].page->dy = mv[1].page->dy = mv[2].page->dy = mv[3].page->dy = mv->map->tiles->tileHeight;\r
+\r
+       /* set up the thresholds */\r
+       mv[0].dxThresh = mv[1].dxThresh = mv[2].dxThresh = mv[3].dxThresh = mv->map->tiles->tileWidth * 2;\r
+       mv[0].dyThresh = mv[1].dyThresh = mv[2].dxThresh = mv[3].dxThresh = mv->map->tiles->tileHeight * 2;\r
+\r
+       /* draw the tiles */\r
+       modexClearRegion(mv[0].page, 0, 0, mv[0].page->width, mv[0].page->height, 0);\r
+       py=0;\r
+       i=mv[0].ty * mv[0].map->width + mv[0].tx;\r
+       for(ty=mv[0].ty-1; py < mv[0].page->sh+mv->dyThresh && ty < mv[0].map->height; ty++, py+=mv[0].map->tiles->tileHeight) {\r
+               mapDrawWRow(&mv[0], tx-1, ty, py);\r
+       i+=mv->map->width - tx;\r
+       }\r
+       if(!pageploop) modexCopyPageRegion(mv[1].page, mv[0].page, 0, 0, 0, 0, mv[0].page->width, mv[0].page->height);\r
+//     {\r
+//             unsigned int k,j,o;\r
+//             /* fill screen with a distinctive pattern */\r
+//             for (k=0;k < vga_state.vga_width;k++) {\r
+//                     o = k >> 2;\r
+//                     vga_write_sequencer(0x02/*map mask*/,1 << (k&3));\r
+//                             for (j=0;j < (mv[0].page->height)+(mv[1].page->height)+(mv[2].page->height)+(mv[3].page->height);j++,o += vga_state.vga_stride)\r
+//                                     vga_state.vga_graphics_ram[o] = (k^j)&15; // VRL samples put all colors in first 15!\r
+//             }\r
+//     }\r
+       modexCopyPageRegion(mv[3].page, mv[0].page, 0/**/, 0/**/, 0, 0, 24, 32);\r
+}\r
+\r
+void near\r
+mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y)\r
+{\r
+       word rx;\r
+       word ry;\r
+       word textx=0;\r
+       word texty=0;\r
+       //if(i==0) i=2;\r
+       if(i==0)\r
+       {\r
+               //wwww\r
+               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, 0); //currently the over scan color!\r
+       }\r
+       else\r
+       {\r
+               rx = (((i-1) % ((t->data->width)/t->tileWidth)) * t->tileWidth);\r
+               ry = (((i-1) / ((t->data->height)/t->tileHeight)) * t->tileHeight);\r
+////0000printf("i=%d\n", i);\r
+               switch(t->debug_text)\r
+               {\r
+                       case 0:\r
+#ifndef TILERENDER\r
+                               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, ((t->debug_data[i])+1));\r
+                               //modexprint(page, x, y, 1, 15, 0, (char const *)(t->debug_data[i]));\r
+#else\r
+                               PBUFBFUN                (page, x, y, rx, ry, t->tileWidth, t->tileHeight, (t->data));\r
+                               /* then the sprite. note modding ram ptr means we just draw to (x&3,0) */\r
+                               //draw_vrl1_vgax_modex(x-rx,y-ry,vrl_header,vrl_lineoffs,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));\r
+                               //modexDrawBmpRegion    (page, x, y, rx, ry, t->tileWidth, t->tileHeight, (t->data));\r
+#endif\r
+                       break;\r
+                       case 1:\r
+                               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, (t->debug_data[i])+1);\r
+                               //modexprintbig(page, x, y, 1, 15, 0, (t->debug_data));\r
+                               /*for(texty=0; texty<2; texty++)\r
+                               {\r
+                                       for(textx=0; textx<2; textx++)\r
+                                       {*/\r
+//                                             modexprint(page, x+(textx*8), y+(texty*8), 1, (word)(t->debug_data), 0, (t->debug_data));\r
+/*                                     }\r
+                               }*/\r
+                       break;\r
+               }\r
+       }\r
+}\r
+\r
+void near mapDrawRow(map_view_t *mv, int tx, int ty, word y, player_t *p, word poopoffset)\r
+{\r
+       word x;\r
+       int i;\r
+       poopoffset%=p[0].speed;\r
+//printf("y: %d\n", poopoffset);\r
+       /* the position within the map array */\r
+       i=ty * mv->map->width + tx;\r
+       for(x=poopoffset; x<(mv->page->sw+mv->dxThresh)/(poopoffset+1) && tx < mv->map->width; x+=mv->map->tiles->tileWidth, tx++) {\r
+       if(i>=0) {\r
+               /* we are in the map, so copy! */\r
+               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);\r
+       }\r
+       i++; /* next! */\r
+       }\r
+}\r
+\r
+void near mapDrawCol(map_view_t *mv, int tx, int ty, word x, player_t *p, word poopoffset)\r
+{\r
+       int y;\r
+       int i;\r
+       poopoffset%=p[0].speed;\r
+//printf("x: %d\n", poopoffset);\r
+       /* location in the map array */\r
+       i=ty * mv->map->width + tx;\r
+\r
+       /* We'll copy all of the columns in the screen,\r
+          i + 1 row above and one below */\r
+       for(y=poopoffset; y<(mv->page->sh+mv->dyThresh)/(poopoffset+1) && ty < mv->map->height; y+=mv->map->tiles->tileHeight, ty++) {\r
+       if(i>=0) {\r
+               /* we are in the map, so copy away! */\r
+               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);\r
+       }\r
+       i += mv->map->width;\r
+       }\r
+}\r
+\r
+void mapDrawWRow(map_view_t *mv, int tx, int ty, word y)\r
+{\r
+       word x;\r
+       int i;\r
+\r
+       /* the position within the map array */\r
+       i=ty * mv->map->width + tx;\r
+       for(x=0; x<mv->page->sw+mv->dxThresh && tx < mv->map->width; x+=mv->map->tiles->tileWidth, tx++) {\r
+       if(i>=0) {\r
+               /* we are in the map, so copy! */\r
+               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);\r
+       }\r
+       i++; /* next! */\r
+       }\r
+}\r
+\r
+void mapDrawWCol(map_view_t *mv, int tx, int ty, word x)\r
+{\r
+       int y;\r
+       int i;\r
+\r
+       /* location in the map array */\r
+       i=ty * mv->map->width + tx;\r
+\r
+       /* We'll copy all of the columns in the screen,\r
+          i + 1 row above and one below */\r
+       for(y=0; y<mv->page->sh+mv->dyThresh && ty < mv->map->height; y+=mv->map->tiles->tileHeight, ty++) {\r
+       if(i>=0) {\r
+               /* we are in the map, so copy away! */\r
+               mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y);\r
+       }\r
+       i += mv->map->width;\r
+       }\r
+}\r
+\r
+/*void qclean()\r
+{\r
+       //setkb(0);\r
+}*/\r
+\r
+unsigned char shinku_fps_indicator_page = 2;\r
+boolean pageflipflop = 1;\r
+boolean pageploop = 1;\r
+\r
+/*     sync    */\r
+void shinku(global_game_variables_t *gv)\r
+{\r
+       word x = (0) + gv->video.page[/*!*/(gv->video.p)].dx; // follow the screen\r
+       word y = (0) + gv->video.page[/*!*/(gv->video.p)].dy; // follow the screen\r
+       word w = 64, h = 8, col = 7, bgcol = 0, type = 1;\r
+       byte o,o2,i;\r
+       //modexCopyPageRegion(pip[1].page, pip[2].page, 16, 16, 16, 16, (14*8)+4, 8+4);\r
+       /* block copy to visible RAM from offscreen */\r
+//     vga_setup_wm1_block_copy();\r
+//     modexCopyPageRegion(&(gv->video.page[shinku_fps_indicator_page]), &(gv->video.page[!shinku_fps_indicator_page]), x, y, x+w, 0, w, h);\r
+//     o =     *(gv->video.page[2].data); // source offscreen\r
+//     o2 =    *(gv->video.page[shinku_fps_indicator_page].data)+(y * vga_state.vga_stride) + (x >> 2); // dest visible (original stride)\r
+//     for (i=0;i < h;i++,o += vga_state.vga_draw_stride,o2 += vga_state.vga_stride) vga_wm1_mem_block_copy(o2,o,w >> 2);\r
+       /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */\r
+//     vga_restore_rm0wm0();\r
+       if(elapsed_timer(gv) >= (1.0 / gv->kurokku.frames_per_second))\r
+       {\r
+               sprintf(gv->pee, "%.0f fps", (double)gv->kurokku.tiku/ticktock(gv));\r
+               //modexClearRegion(&(gv->video.page[shinku_fps_indicator_page]), x, y, w, h, 45);\r
+               modexprint(&(gv->video.page[/*!*/(gv->video.p)]), x, y, type, col, bgcol, gv->pee);\r
+               gv->kurokku.tiku=0;\r
+               /* block copy to visible RAM from offscreen */\r
+//             vga_setup_wm1_block_copy();\r
+//             o =     *(gv->video.page[shinku_fps_indicator_page].data); // source offscreen\r
+//             o2 =    *(gv->video.page[2].data)+(y * vga_state.vga_stride) + (x >> 2); // dest visible (original stride)\r
+//             for (i=0;i < h;i++,o += vga_state.vga_draw_stride,o2 += vga_state.vga_stride) vga_wm1_mem_block_copy(o2,o,w >> 2);\r
+//             modexCopyPageRegion(&(gv->video.page[shinku_fps_indicator_page]), &(gv->video.page[!shinku_fps_indicator_page]), x, y, x, 0, w, h);\r
+               /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */\r
+//             vga_restore_rm0wm0();\r
+       }else //copy dat sheet\r
+       gv->kurokku.tiku++;\r
+\r
+       switch(gv->kurokku.fpscap)\r
+       {\r
+               case 0:\r
+                       //modexprint(&(gv->video.page[shinku_fps_indicator_page]), x, y+8, type, col, bgcol, "sanic!");\r
+                       gv->kurokku.frames_per_second=1;\r
+               break;\r
+               case 1:\r
+                       //turn this off if XT\r
+                       //modexWaitBorder();\r
+                       vga_wait_for_vsync();\r
+                       gv->kurokku.frames_per_second=60;\r
+               break;\r
+       }\r
+       if(pageflipflop){\r
+       if(gv->video.r){\r
+               //vga_setup_wm1_block_copy();\r
+               //_fmemcpy((gv->video.page[(gv->video.p)]).data, (gv->video.page[(!gv->video.p)]).data, gv->video.page[(!gv->video.p)].pagesize);\r
+               //vga_restore_rm0wm0();\r
+               if(!pageploop) modexCopyPageRegion(&(gv->video.page[(gv->video.p)]), &(gv->video.page[(!gv->video.p)]), 0, 0, 0, 0, gv->video.page[gv->video.p].width, gv->video.page[!gv->video.p].height);\r
+               modexShowPage(&(gv->video.page[gv->video.p]));\r
+               if(!pageploop) gv->video.p=!gv->video.p;\r
+               gv->video.r=!gv->video.r;\r
+               //0000gv->video.tickclk = ((*clockw)-gv->video.startclk)/18.2;\r
+       }\r
+       }\r
+}\r
+\r
+void near animatePlayer(map_view_t *pip, player_t *player, word pn, sword scrollswitch)\r
+{\r
+       sword x = player[pn].x;\r
+       sword y = player[pn].y;\r
+       sword bx = x+16;        //buffer's x\r
+       sword by = y+16;        //buffer's y\r
+       word dire=32; //direction\r
+       sword qq; //scroll offset\r
+       word ls = player[pn].persist_aniframe;\r
+\r
+       switch(scrollswitch)\r
+       {\r
+               case 0:\r
+                       qq = 0;\r
+               break;\r
+               default:\r
+                       qq = ((player[pn].q)*(player[pn].speed));\r
+               break;\r
+       }\r
+       //x-=4;\r
+       y-=pip[0].map->tiles->tileHeight;\r
+       switch (player[pn].d)\r
+       {\r
+               case 0:\r
+                       //up\r
+                       dire*=player[pn].d;\r
+                       y-=qq;\r
+                       by-=4;\r
+               break;\r
+               case 3:\r
+                       // right\r
+                       dire*=(player[pn].d-2);\r
+                       x+=qq;\r
+                       bx+=4;\r
+               break;\r
+               case 2:\r
+               break;\r
+               case 4:\r
+                       //down\r
+                       dire*=(player[pn].d-2);\r
+                       y+=qq;\r
+                       by+=4;\r
+               break;\r
+               case 1:\r
+                       //left\r
+                       dire*=(player[pn].d+2);\r
+                       x-=qq;\r
+                       bx-=4;\r
+               break;\r
+       }\r
+\r
+#ifdef SPRITE\r
+#define FRAME1 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 48, dire, 24, 32,        PLAYERBMPDATA);\r
+#define FRAME2 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 24, dire, 24, 32,        PLAYERBMPDATA);\r
+#define FRAME3 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 0, dire, 24, 32, PLAYERBMPDATA);\r
+#define FRAME4 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 24, dire, 24, 32,        PLAYERBMPDATA);\r
+#else\r
+#define FRAME1 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, 2+dire);\r
+#define FRAME2 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, 1+dire);\r
+#define FRAME3 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, dire);\r
+#define FRAME4 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, 1+dire);\r
+#endif\r
+       if(!pageflipflop)\r
+               modexCopyPageRegion(pip[1].page, pip[0].page, x-4, y-4, x-4, y-4, 28, 36);\r
+       else{\r
+               //copy old bg to page0\r
+               //modexCopyPageRegion(pip[3].page, pip[0].page, bx, by, 0, 0,   20, 36);\r
+               //update buffer\r
+               //modexCopyPageRegion(pip[0].page, pip[3].page, 0, 0,   x, y,   20, 36);\r
+       }\r
+//modexCopyPageRegion(page_t *dest, page_t *src, word sx, word sy, word dx, word dy, word width, word height);\r
+       //modexCopyPageRegion(pip[3].page, pip[!(pip->video->p)].page, x-4, y-4, 0, 128, 28, 36);\r
+       /*modexCopyPageRegion(pip[pip->video->p].page,\r
+ pip[!(pip->video->p)].page, x-4, y-4, x-4, y-4, 28, 36);*/\r
+//     else modexCopyPageRegion(pip[1].page, pip[0].page, x-4, y-4, x-4, y-4, 28, 40);\r
+       switch(ls)\r
+       {\r
+               case 1:\r
+                       FRAME1\r
+               break;\r
+               case 2:\r
+                       FRAME2\r
+               break;\r
+               case 3:\r
+                       FRAME3\r
+               break;\r
+               case 4:\r
+                       FRAME4\r
+               break;\r
+       }\r
+//     if(2>ls && ls>=1) { FRAME1 }else\r
+//     if(3>ls && ls>=2) { FRAME2 }else\r
+//     if(4>ls && ls>=3) { FRAME3 }else\r
+//     if(5>ls && ls>=4) { FRAME4 }\r
+       //modexCopyPageRegion(pip[0].page, pip[3].page, 0, 0, x, y, 24, 32);\r
+       //printf("x=%d  y=%d    bx=%d           by=%d\n", x, y, bx, by);\r
+       pip->video->r=1;\r
+}\r
index a3402a02801377ec6ee892cb9c7452a1aa20d9bf..9602732d38d79e6c9660ff649ce494011a7e1dae 100755 (executable)
@@ -1,95 +1,95 @@
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef __SCROLL16_H_
-#define __SCROLL16_H_
-
-#include "src/lib/16_head.h"
-#include "src/lib/bakapee.h"
-#include "src/lib/modex16.h"
-#include "src/lib/16_in.h"
-#include "src/lib/bitmap.h"
-#include "src/lib/mapread.h" //map is loaded here www
-#include "src/lib/16_timer.h"
-#include "src/lib/wcpu/wcpu.h"
-
-#include <hw/cpu/cpu.h>
-#include <hw/dos/dos.h>
-#include <hw/vga/vga.h>
-#include <hw/vga/vrl.h>
-
-#define SPRITE
-//#define TILERENDER
-
-//modexDrawSpritePBufRegion
-//modexDrawBmpPBufRegion
-#define PBUFSFUN               modexDrawSpriteRegion
-#define PBUFBFUN               modexDrawBmpRegion
-#define PLAYERBMPDATA  player[pn].data
-
-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; //????
-       video_t *video; //pointer to game variables of the video
-       pan_t *pan;             //pointer the the page panning debug system
-} map_view_t;
-
-typedef struct
-{
-       map_view_t *mv;
-} map_view_db_t;
-
-//for null map!
-#define MAPW   40
-#define MAPH   30
-
-extern boolean pageflipflop, pageploop;
-extern unsigned char shinku_fps_indicator_page;
-
-//map_t allocMap(int w, int h);
-//void initMap(map_t *map);
-void walk(map_view_t *pip, player_t *player, word pn);
-void panpagemanual(map_view_t *pip,  player_t *player, word pn);
-void near mapScrollRight(map_view_t *mv, player_t *player, word id, word plid);
-void near mapScrollLeft(map_view_t *mv, player_t *player, word id, word plid);
-void near mapScrollUp(map_view_t *mv, player_t *player, word id, word plid);
-void near mapScrollDown(map_view_t *mv, player_t *player, word id, word plid);
-void near ScrollRight(map_view_t *mv, player_t *player, word id, word plid);
-void near ScrollLeft(map_view_t *mv, player_t *player, word id, word plid);
-void near ScrollUp(map_view_t *mv, player_t *player, word id, word plid);
-void near ScrollDown(map_view_t *mv, player_t *player, word id, word plid);
-sword chkmap(map_t *map, word q);
-void mapGoTo(map_view_t *mv, int tx, int ty);
-void near mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y);
-void near mapDrawRow(map_view_t *mv, int tx, int ty, word y, player_t *p, word poopoffset);
-void near mapDrawCol(map_view_t *mv, int tx, int ty, word x, player_t *p, 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 qclean();
-void shinku(global_game_variables_t *gv);
-void near animatePlayer(map_view_t *pip, player_t *player, word playnum, sword scrollswitch);
-
-#endif /*__SCROLL16_H_*/
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+\r
+#ifndef __SCROLL16_H_\r
+#define __SCROLL16_H_\r
+\r
+#include "src/lib/16_head.h"\r
+#include "src/lib/bakapee.h"\r
+#include "src/lib/modex16.h"\r
+#include "src/lib/16_in.h"\r
+#include "src/lib/bitmap.h"\r
+#include "src/lib/mapread.h" //map is loaded here www\r
+#include "src/lib/16_timer.h"\r
+#include "src/lib/wcpu/wcpu.h"\r
+\r
+#include <hw/cpu/cpu.h>\r
+#include <hw/dos/dos.h>\r
+#include <hw/vga/vga.h>\r
+#include <hw/vga/vrl.h>\r
+\r
+#define SPRITE\r
+//#define TILERENDER\r
+\r
+//modexDrawSpritePBufRegion\r
+//modexDrawBmpPBufRegion\r
+#define PBUFSFUN               modexDrawSpriteRegion\r
+#define PBUFBFUN               modexDrawBmpRegion\r
+#define PLAYERBMPDATA  player[pn].data\r
+\r
+typedef struct {\r
+       map_t *map;\r
+       page_t *page;\r
+       int tx; //appears to be the top left tile position on the viewable screen map\r
+       int ty; //appears to be the top left tile position on the viewable screen map\r
+       word dxThresh; //????\r
+       word dyThresh; //????\r
+       video_t *video; //pointer to game variables of the video\r
+       pan_t *pan;             //pointer the the page panning debug system\r
+} map_view_t;\r
+\r
+typedef struct\r
+{\r
+       map_view_t *mv;\r
+} map_view_db_t;\r
+\r
+//for null map!\r
+#define MAPW   40\r
+#define MAPH   30\r
+\r
+extern boolean pageflipflop, pageploop;\r
+extern unsigned char shinku_fps_indicator_page;\r
+\r
+//map_t allocMap(int w, int h);\r
+//void initMap(map_t *map);\r
+void walk(map_view_t *pip, player_t *player, word pn);\r
+void panpagemanual(map_view_t *pip,  player_t *player, word pn);\r
+void near mapScrollRight(map_view_t *mv, player_t *player, word id, word plid);\r
+void near mapScrollLeft(map_view_t *mv, player_t *player, word id, word plid);\r
+void near mapScrollUp(map_view_t *mv, player_t *player, word id, word plid);\r
+void near mapScrollDown(map_view_t *mv, player_t *player, word id, word plid);\r
+void near ScrollRight(map_view_t *mv, player_t *player, word id, word plid);\r
+void near ScrollLeft(map_view_t *mv, player_t *player, word id, word plid);\r
+void near ScrollUp(map_view_t *mv, player_t *player, word id, word plid);\r
+void near ScrollDown(map_view_t *mv, player_t *player, word id, word plid);\r
+sword chkmap(map_t *map, word q);\r
+void mapGoTo(map_view_t *mv, int tx, int ty);\r
+void near mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y);\r
+void near mapDrawRow(map_view_t *mv, int tx, int ty, word y, player_t *p, word poopoffset);\r
+void near mapDrawCol(map_view_t *mv, int tx, int ty, word x, player_t *p, word poopoffset);\r
+void mapDrawWRow(map_view_t *mv, int tx, int ty, word y);\r
+void mapDrawWCol(map_view_t *mv, int tx, int ty, word x);\r
+//void qclean();\r
+void shinku(global_game_variables_t *gv);\r
+void near animatePlayer(map_view_t *pip, player_t *player, word playnum, sword scrollswitch);\r
+\r
+#endif /*__SCROLL16_H_*/\r
index 1781754f0c0e00c6f1f973e2578b0b71234208ab..7464a32fae6bed8feee46c2d1f685da236d9b64b 100755 (executable)
-/* This file implements rudimentary XMS memory handling.
- * Documentation on the XMS API was found on http://www.qzx.com/pc-gpe/xms30.txt
- */
-
-#include "src\lib\xms.h"
-
-/* Set up the XMS driver, returns 0 on success and non-zero on failure */
-static int initxms(void)
-{
-       char XMSStatus = 0;
-
-       if ( XMSControl == 0 )
-       {
-               __asm {
-               ; Is an XMS driver installed?
-                       mov ax,4300h
-                       int 2Fh
-                       mov [XMSStatus], al
-               }
-
-               if ( XMSStatus == 0x80 )
-               {
-                       __asm {
-                       ; Get the address of the driver control function
-                               mov ax,4310h
-                               int 2Fh
-                               mov word ptr [XMSControl]  ,bx
-                               mov word ptr [XMSControl+2],es
-                       }
-               }
-       }
-
-       return ( XMSControl == 0 );
-}
-
-/* Allocate a slab of memory from XMS */
-void huge * xmsmalloc(long unsigned int size)
-{
-       unsigned int kB;
-       unsigned int XMSStatus = 0;
-       unsigned int XMSHandle = 0;
-       void huge * XMSPointer = NULL;
-       int n;
-
-       /* If we can not initialize XMS, the allocation fails */
-       if ( initxms() )
-               return NULL;
-
-       /* It is not possible to allocate more kilobytes than a 16-bit register can hold :-) */
-       if ( size / 1024 > UINT_MAX )
-               return NULL;
-
-       /* Get the next free entry in the handle <-> pointer mapping */
-       for ( n = 0; n < MAX_XMS_ALLOCATIONS; n++ )
-       {
-               if ( allocMapXMS[n].XMSPointer == NULL )
-                       break;
-       }
-
-       if ( n == MAX_XMS_ALLOCATIONS )
-               return NULL;
-
-       kB = size / 1024 + (size % 1024 > 0);
-
-       __asm {
-       ; Allocate [kB] kilobytes of XMS memory
-               mov ah, 09h
-               mov dx, [kB]
-               call [XMSControl]
-               mov [XMSStatus], ax
-               mov [XMSHandle], dx
-       }
-
-       /* Check if XMS allocation failed */
-       if ( XMSStatus == 0)
-               return NULL;
-
-       __asm {
-       ; Convert XMS handle to normal pointer
-               mov ah, 0Ch
-               mov dx, [XMSHandle]
-               call [XMSControl]
-               mov [XMSStatus], ax
-
-               mov word ptr [XMSPointer],  bx
-               mov word ptr [XMSPointer+2],dx
-       }
-
-       if ( XMSStatus == 0 )
-       {
-               /* Lock failed, deallocate the handle */
-               __asm {
-               ; Free XMS handle
-                       mov ah, 0Ah
-                       mov dx, [XMSHandle]
-                       call [XMSControl]
-
-               ; Return value is not really interesting 
-               ;   mov [XMSStatus], ax
-               }
-               return NULL;
-       }
-
-       /* Create an entry in the handle <-> pointer mapping */
-       allocMapXMS[n].XMSHandle = XMSHandle;
-       allocMapXMS[n].XMSPointer = XMSPointer;
-
-       return XMSPointer;
-}
-
-/* Free a pointer allocated with xmsalloc */
-void xmsfree(void huge * XMSPointer)
-{
-       int n;
-
-       if ( XMSPointer == NULL )
-               return;
-
-       if ( initxms() )
-               return;
-
-       for ( n = 0; n < MAX_XMS_ALLOCATIONS; n++ )
-       {
-               if ( allocMapXMS[n].XMSPointer == XMSPointer )
-               {
-                       int XMSHandle = allocMapXMS[n].XMSHandle;
-
-                       __asm {
-                       ; Unlock handle so we can free the memory block
-                               mov ah, 0Dh
-                               mov dx, [XMSHandle]
-                               call [XMSControl]
-
-                       ; Free XMS memory
-                               mov ah, 0Ah
-                               mov dx, [XMSHandle]
-                               call [XMSControl]
-
-                       ; Return value ignored
-                       }
-
-                       /* Clear handle <-> pointer map entry so it can be reused */
-                       allocMapXMS[n].XMSHandle = 0;
-                       allocMapXMS[n].XMSPointer = NULL;
-
-                       return;
-               }
-       }
-}
-
-/* Write a memory report for debugging purposes */
-void xmsreport(void/*FILE * stream*/)
-{
-       int XMSVersionNumber = 0;
-       unsigned int XMSLargestBlock = 0;
-       unsigned int XMSTotal = 0;
-
-       if ( initxms() )
-       {
-               puts("Could not initialize XMS Driver!");
-               return;
-       }
-
-       __asm {
-       ; Get the driver version number
-               mov ah,00h
-               call [XMSControl] ; Get XMS Version Number
-               mov [XMSVersionNumber], ax
-
-       ; Get the amount of free XMS memory
-               mov ah, 08h
-               call [XMSControl]
-               mov [XMSLargestBlock], ax
-               mov [XMSTotal], dx
-       }
-
-       //fprintf(stream, "XMS Version number: %d\n", XMSVersionNumber);
-       //fprintf(stream, "Largest available block: %d kB (%d kB total)\n", XMSLargestBlock, XMSTotal);
-       printf("XMS Version number: %d\n", XMSVersionNumber);
-       printf("Largest available block: %d kB (%d kB total)\n", XMSLargestBlock, XMSTotal);
-}
-
-/*int main()
-{
-       xmsreport(fopen("xms.log", "w"));
-       return 0;
-}*/
+/* This file implements rudimentary XMS memory handling.\r
+ * Documentation on the XMS API was found on http://www.qzx.com/pc-gpe/xms30.txt\r
+ */\r
+\r
+#include "src\lib\xms.h"\r
+\r
+/* Set up the XMS driver, returns 0 on success and non-zero on failure */\r
+static int initxms(void)\r
+{\r
+       char XMSStatus = 0;\r
+\r
+       if ( XMSControl == 0 )\r
+       {\r
+               __asm {\r
+               ; Is an XMS driver installed?\r
+                       mov ax,4300h\r
+                       int 2Fh\r
+                       mov [XMSStatus], al\r
+               }\r
+\r
+               if ( XMSStatus == 0x80 )\r
+               {\r
+                       __asm {\r
+                       ; Get the address of the driver control function\r
+                               mov ax,4310h\r
+                               int 2Fh\r
+                               mov word ptr [XMSControl]  ,bx\r
+                               mov word ptr [XMSControl+2],es\r
+                       }\r
+               }\r
+       }\r
+\r
+       return ( XMSControl == 0 );\r
+}\r
+\r
+/* Allocate a slab of memory from XMS */\r
+void huge * xmsmalloc(long unsigned int size)\r
+{\r
+       unsigned int kB;\r
+       unsigned int XMSStatus = 0;\r
+       unsigned int XMSHandle = 0;\r
+       void huge * XMSPointer = NULL;\r
+       int n;\r
+\r
+       /* If we can not initialize XMS, the allocation fails */\r
+       if ( initxms() )\r
+               return NULL;\r
+\r
+       /* It is not possible to allocate more kilobytes than a 16-bit register can hold :-) */\r
+       if ( size / 1024 > UINT_MAX )\r
+               return NULL;\r
+\r
+       /* Get the next free entry in the handle <-> pointer mapping */\r
+       for ( n = 0; n < MAX_XMS_ALLOCATIONS; n++ )\r
+       {\r
+               if ( allocMapXMS[n].XMSPointer == NULL )\r
+                       break;\r
+       }\r
+\r
+       if ( n == MAX_XMS_ALLOCATIONS )\r
+               return NULL;\r
+\r
+       kB = size / 1024 + (size % 1024 > 0);\r
+\r
+       __asm {\r
+       ; Allocate [kB] kilobytes of XMS memory\r
+               mov ah, 09h\r
+               mov dx, [kB]\r
+               call [XMSControl]\r
+               mov [XMSStatus], ax\r
+               mov [XMSHandle], dx\r
+       }\r
+\r
+       /* Check if XMS allocation failed */\r
+       if ( XMSStatus == 0)\r
+               return NULL;\r
+\r
+       __asm {\r
+       ; Convert XMS handle to normal pointer\r
+               mov ah, 0Ch\r
+               mov dx, [XMSHandle]\r
+               call [XMSControl]\r
+               mov [XMSStatus], ax\r
+\r
+               mov word ptr [XMSPointer],  bx\r
+               mov word ptr [XMSPointer+2],dx\r
+       }\r
+\r
+       if ( XMSStatus == 0 )\r
+       {\r
+               /* Lock failed, deallocate the handle */\r
+               __asm {\r
+               ; Free XMS handle\r
+                       mov ah, 0Ah\r
+                       mov dx, [XMSHandle]\r
+                       call [XMSControl]\r
+\r
+               ; Return value is not really interesting \r
+               ;   mov [XMSStatus], ax\r
+               }\r
+               return NULL;\r
+       }\r
+\r
+       /* Create an entry in the handle <-> pointer mapping */\r
+       allocMapXMS[n].XMSHandle = XMSHandle;\r
+       allocMapXMS[n].XMSPointer = XMSPointer;\r
+\r
+       return XMSPointer;\r
+}\r
+\r
+/* Free a pointer allocated with xmsalloc */\r
+void xmsfree(void huge * XMSPointer)\r
+{\r
+       int n;\r
+\r
+       if ( XMSPointer == NULL )\r
+               return;\r
+\r
+       if ( initxms() )\r
+               return;\r
+\r
+       for ( n = 0; n < MAX_XMS_ALLOCATIONS; n++ )\r
+       {\r
+               if ( allocMapXMS[n].XMSPointer == XMSPointer )\r
+               {\r
+                       int XMSHandle = allocMapXMS[n].XMSHandle;\r
+\r
+                       __asm {\r
+                       ; Unlock handle so we can free the memory block\r
+                               mov ah, 0Dh\r
+                               mov dx, [XMSHandle]\r
+                               call [XMSControl]\r
+\r
+                       ; Free XMS memory\r
+                               mov ah, 0Ah\r
+                               mov dx, [XMSHandle]\r
+                               call [XMSControl]\r
+\r
+                       ; Return value ignored\r
+                       }\r
+\r
+                       /* Clear handle <-> pointer map entry so it can be reused */\r
+                       allocMapXMS[n].XMSHandle = 0;\r
+                       allocMapXMS[n].XMSPointer = NULL;\r
+\r
+                       return;\r
+               }\r
+       }\r
+}\r
+\r
+/* Write a memory report for debugging purposes */\r
+void xmsreport(void/*FILE * stream*/)\r
+{\r
+       int XMSVersionNumber = 0;\r
+       unsigned int XMSLargestBlock = 0;\r
+       unsigned int XMSTotal = 0;\r
+\r
+       if ( initxms() )\r
+       {\r
+               puts("Could not initialize XMS Driver!");\r
+               return;\r
+       }\r
+\r
+       __asm {\r
+       ; Get the driver version number\r
+               mov ah,00h\r
+               call [XMSControl] ; Get XMS Version Number\r
+               mov [XMSVersionNumber], ax\r
+\r
+       ; Get the amount of free XMS memory\r
+               mov ah, 08h\r
+               call [XMSControl]\r
+               mov [XMSLargestBlock], ax\r
+               mov [XMSTotal], dx\r
+       }\r
+\r
+       //fprintf(stream, "XMS Version number: %d\n", XMSVersionNumber);\r
+       //fprintf(stream, "Largest available block: %d kB (%d kB total)\n", XMSLargestBlock, XMSTotal);\r
+       printf("XMS Version number: %d\n", XMSVersionNumber);\r
+       printf("Largest available block: %d kB (%d kB total)\n", XMSLargestBlock, XMSTotal);\r
+}\r
+\r
+/*int main()\r
+{\r
+       xmsreport(fopen("xms.log", "w"));\r
+       return 0;\r
+}*/\r
index b65874943985849cfb9c69de61cff85f09136792..b1bdb012ae40ed897599a2ea46390e9449cc4708 100755 (executable)
@@ -1,28 +1,28 @@
-#ifndef _XMS_H_
-#define _XMS_H_
-#include <stddef.h> /* Definition of NULL */
-#include <limits.h> /* Definition of UINT_MAX */
-#include <stdio.h>  /* fprintf and (FILE *) */
-
-/* Allow external configuration of maximum concurrent XMS allocations */
-#ifndef MAX_XMS_ALLOCATIONS
-#define MAX_XMS_ALLOCATIONS 4
-#endif
-
-/* Address of the XMS driver */
-static long XMSControl;
-
-/* Mapping of XMS handle <-> normal pointer */
-typedef struct {
-       unsigned int XMSHandle;
-       void huge * XMSPointer;
-} XMSHandleMap;
-
-static XMSHandleMap allocMapXMS[MAX_XMS_ALLOCATIONS];
-
-static int initxms(void);
-void huge * xmsmalloc(long unsigned int size);
-void xmsfree(void huge * XMSPointer);
-void xmsreport(void/*FILE * stream*/);
-
-#endif/*_XMS_H_*/
+#ifndef _XMS_H_\r
+#define _XMS_H_\r
+#include <stddef.h> /* Definition of NULL */\r
+#include <limits.h> /* Definition of UINT_MAX */\r
+#include <stdio.h>  /* fprintf and (FILE *) */\r
+\r
+/* Allow external configuration of maximum concurrent XMS allocations */\r
+#ifndef MAX_XMS_ALLOCATIONS\r
+#define MAX_XMS_ALLOCATIONS 4\r
+#endif\r
+\r
+/* Address of the XMS driver */\r
+static long XMSControl;\r
+\r
+/* Mapping of XMS handle <-> normal pointer */\r
+typedef struct {\r
+       unsigned int XMSHandle;\r
+       void huge * XMSPointer;\r
+} XMSHandleMap;\r
+\r
+static XMSHandleMap allocMapXMS[MAX_XMS_ALLOCATIONS];\r
+\r
+static int initxms(void);\r
+void huge * xmsmalloc(long unsigned int size);\r
+void xmsfree(void huge * XMSPointer);\r
+void xmsreport(void/*FILE * stream*/);\r
+\r
+#endif/*_XMS_H_*/\r
index 02750443c16a3a812f99fa4cb05851a2f8c5bbb5..12a5ee1b591d8f14bc6479caa66ae8e9bad95a37 100755 (executable)
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-/*
-       scroll16 library~
-*/
-#include "src/lib/zcroll16.h"
-
-boolean boundary_check(int x, int y, int dx, int dy, int h, int w){
-       return (dx > 0 && (x + dx) < w) || (dx < 0 && (x + dx) >= 0) || (dy > 0 && (y + dy) < h) || (dy < 0 && (y + dy) >= 0) || (dx == dy && dx == 0);
-}
-
-boolean coll_check(int x, int y, int dx, int dy, map_view_t *map_v){
-       // Assume everything crosses at most 1 tile at once
-       return dx && crossable_tile(x + dx, map_v) || dy && crossable_tile(y + dy, map_v);
-}
-
-boolean walk(entity_t *ent, map_view_t *map_v)
-{
-       int dx = 1;
-       int dy = 1;
-       switch(ent->d)
-       {
-               case STOP:
-                       return;
-               case LEFT:
-                       dx = -dx;
-               case RIGHT:
-                       dy = 0;
-                       break;
-               case UP:
-                       dy = -dy;
-               case DOWN:
-                       dx = 0;
-                       break;
-       }
-       if(coll_check(ent->x, ent->y, dx, dy,  map_v)){
-               // Allow movement
-               // Set speed
-               // Start animation
-               // Mark next tile as occupied
-               // Mark this tile as vacant
-               return true;
-       }
-       return false;
-}
-
-void player_walk(player_t *player, map_view_t *map_v){
-       if(walk(player->ent, map_v) && boundary_check(map_v->tx, map_v->ty, dx, dy, map_v->map->width - 2*map_v->page->tilesw, map_v->map->height - 2*map_v->page->tilesh)){
-               mapScroll(map_v, player);
-               // (Un)load stuff?
-       }
-}
-
-
-void near mapScroll(map_view_t *mv, player_t *player){
-       word x, y;  /* coordinate for drawing */
-       int c = 1;
-       int delta;
-       mv->delta += player->dx | player->dy;
-       delta = mv->delta;
-       mv->d = (player->dx) ? (player->dx > 0) ? RIGHT : LEFT : (player->dy) ? (player->dy > 0) ? DOWN : UP : STOP;
-       switch(mv->d){
-               case DOWN:
-                       c = -1;
-                       delta = -delta;
-               case UP:
-                       if(!(delta + mv->dxThresh)){
-                               mv->delta = 0;
-                               mv->ty += c;
-                       }
-                       break;
-               case RIGHT:
-                       c = -1;
-                       delta = -delta;
-               case LEFT:
-                       if(!(delta + mv->dyThresh)){
-                               mv->delta = 0;
-                               mv->tx += c;
-                       }
-                       break;
-               default:
-                       break;
-       }
-
-       mv->video->r=1;
-}
-
-sword chkmap(map_t *map, word q)
-{
-//     bitmap_t bp;
-       static byte x[(MAPW*MAPH)+1] =
-{ 1, 2, 3, 4, 0, 3, 3, 3, 3, 3, 3, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 11, 12, 4, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 0, 1, 1, 1, 5, 8, 1, 11, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 4, 0, 0, 0, 0, 0, 8, 8, 1, 11, 11, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 2, 3, 4, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 5, 6, 7, 8, 6, 6, 6, 6, 6, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 9, 10, 11, 12, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10 };
-/*1,   2,      3,      4,      0,      3,      3,      3,      3,      3,      3,      3,      3,      4,      1,      1,      1,      1,      1,      1,      \
-5,     6,      7,      8,      0,      1,      0,      1,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-9,     10,     11,     12,     4,      1,      0,      1,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-13,    14,     15,     16,     0,      1,      1,      1,      5,      8,      1,      11,     11,     1,      1,      1,      1,      1,      1,      1,      \
-0,     0,      4,      0,      0,      0,      0,      0,      8,      8,      1,      11,     11,     3,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      0,      0,      0,      0,      8,      8,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      0,      0,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      0,      0,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \
-1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      3,      3,      3,      1,      2,      3,      4 };*/
-       //check for failed to load map
-       if((map->width == map->height == 0) && (q>0))
-       {
-               //initiate a null map!
-               map->width=MAPW;///2;
-               map->height=MAPH;///2;
-//             map->data = malloc(((map->width*map->height)+1)*sizeof(byte));
-               map->data = &x;
-               map->tiles = malloc(sizeof(tiles_t));
-               //fix this to be far~
-//             bp = bitmapLoadPcx("data/ed.pcx");
-//             map->tiles->data = &bp;
-               map->tiles->debug_data = map->data;
-               map->tiles->tileHeight = 16;
-               map->tiles->tileWidth = 16;
-               map->tiles->rows = 1;
-               map->tiles->cols = 1;
-               map->tiles->debug_text = true;
-       }
-       else map->tiles->debug_text = false;
-       return 0;
-}
-
-//TODO: player position here
-void mapGoTo(map_view_t *mv, int tx, int ty)
-{
-       int px, py;
-       unsigned int i;
-
-       /* set up the coordinates */
-       mv->tx = tx;
-       mv->ty = ty;
-       mv->page->delta = 0;
-
-       /* set up the thresholds */
-       mv->dxThresh = mv->map->tiles[0]->tileWidth * 2;
-       mv->dyThresh = mv->map->tiles[0]->tileHeight * 2;
-
-       /* draw the tiles */
-       modexClearRegion(mv->page, 0, 0, mv->page->width, mv->page->height, 0);
-       py=0;
-       i=mv->ty * mv->map->width + mv->tx;
-/*     for(ty=mv[0].ty-1; py < mv[0].page->sh+mv->dyThresh && ty < mv[0].map->height; ty++, py+=mv[0].map->tiles->tileHeight) {
-               mapDrawWRow(&mv[0], tx-1, ty, py);
-       i+=mv->map->width - tx;
-       }
-       if(!pageploop) modexCopyPageRegion(mv[1].page, mv[0].page, 0, 0, 0, 0, mv[0].page->width, mv[0].page->height);
-//     {
-//             unsigned int k,j,o;
-//             // fill screen with a distinctive pattern 
-//             for (k=0;k < vga_state.vga_width;k++) {
-//                     o = k >> 2;
-//                     vga_write_sequencer(0x02/*map mask*//*,1 << (k&3));
-//                             for (j=0;j < (mv[0].page->height)+(mv[1].page->height)+(mv[2].page->height)+(mv[3].page->height);j++,o += vga_state.vga_stride)
-//                                     vga_state.vga_graphics_ram[o] = (k^j)&15; // VRL samples put all colors in first 15!
-//             }
-//     }
-       modexCopyPageRegion(mv[3].page, mv[0].page, 0, 0, 0, 0, 24, 32);*/
-}
-
-void near
-mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y)
-{
-       word rx;
-       word ry;
-       word textx=0;
-       word texty=0;
-       //if(i==0) i=2;
-       if(i==0)
-       {
-               //wwww
-               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, 0); //currently the over scan color!
-       }
-       else
-       {
-               rx = (((i-1) % ((t->data->width)/t->tileWidth)) * t->tileWidth);
-               ry = (((i-1) / ((t->data->height)/t->tileHeight)) * t->tileHeight);
-////0000printf("i=%d\n", i);
-               switch(t->debug_text)
-               {
-                       case 0:
-#ifndef TILERENDER
-                               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, ((t->debug_data[i])+1));
-                               //modexprint(page, x, y, 1, 15, 0, (char const *)(t->debug_data[i]));
-#else
-                               PBUFBFUN                (page, x, y, rx, ry, t->tileWidth, t->tileHeight, (t->data));
-                               /* then the sprite. note modding ram ptr means we just draw to (x&3,0) */
-                               //draw_vrl1_vgax_modex(x-rx,y-ry,vrl_header,vrl_lineoffs,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));
-                               //modexDrawBmpRegion    (page, x, y, rx, ry, t->tileWidth, t->tileHeight, (t->data));
-#endif
-                       break;
-                       case 1:
-                               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, (t->debug_data[i])+1);
-                               //modexprintbig(page, x, y, 1, 15, 0, (t->debug_data));
-                               /*for(texty=0; texty<2; texty++)
-                               {
-                                       for(textx=0; textx<2; textx++)
-                                       {*/
-//                                             modexprint(page, x+(textx*8), y+(texty*8), 1, (word)(t->debug_data), 0, (t->debug_data));
-/*                                     }
-                               }*/
-                       break;
-               }
-       }
-}
-
-unsigned char shinku_fps_indicator_page = 2;
-boolean pageflipflop = 1;
-boolean pageploop = 1;
-
-/*     sync    */
-void shinku(global_game_variables_t *gv)
-{
-       word x = (0) + gv->video.page[/*!*/(gv->video.p)].dx; // follow the screen
-       word y = (0) + gv->video.page[/*!*/(gv->video.p)].dy; // follow the screen
-       word w = 64, h = 8, col = 7, bgcol = 0, type = 1;
-       byte o,o2,i;
-       if(elapsed_timer(gv) >= (1.0 / gv->kurokku.frames_per_second))
-       {
-               sprintf(gv->pee, "%.0f fps", (double)gv->kurokku.tiku/ticktock(gv));
-               //modexClearRegion(&(gv->video.page[shinku_fps_indicator_page]), x, y, w, h, 45);
-               modexprint(&(gv->video.page[/*!*/(gv->video.p)]), x, y, type, col, bgcol, gv->pee);
-               gv->kurokku.tiku=0;
-       }else //copy dat sheet
-       gv->kurokku.tiku++;
-
-       switch(gv->kurokku.fpscap)
-       {
-               case 0:
-                       gv->kurokku.frames_per_second=1;
-               break;
-               case 1:
-                       //turn this off if XT
-                       vga_wait_for_vsync();
-                       gv->kurokku.frames_per_second=60;
-               break;
-       }
-       if(pageflipflop){
-       if(gv->video.r){
-               if(!pageploop) modexCopyPageRegion(&(gv->video.page[(gv->video.p)]), &(gv->video.page[(!gv->video.p)]), 0, 0, 0, 0, gv->video.page[gv->video.p].width, gv->video.page[!gv->video.p].height);
-               modexShowPage(&(gv->video.page[gv->video.p]));
-               if(!pageploop) gv->video.p=!gv->video.p;
-               gv->video.r=!gv->video.r;
-       }
-       }
-}
-
-void near animatePlayer(map_view_t *pip, player_t *player,  sword scrollswitch)
-{
-       sword x = player->x;
-       sword y = player->y;
-       sword bx = x+16;        //buffer's x
-       sword by = y+16;        //buffer's y
-       word dire=32; //direction
-       sword qq; //scroll offset
-       word ls = player->persist_aniframe;
-
-       switch(scrollswitch)
-       {
-               case 0:
-                       qq = 0;
-               break;
-               default:
-                       qq = ((player->q)*(player->speed));
-               break;
-       }
-       //x-=4;
-       y-=pip->map->tiles->tileHeight;
-       switch (player->d)
-       {
-               case 0:
-                       //up
-                       dire*=player->d;
-                       y-=qq;
-                       by-=4;
-               break;
-               case 3:
-                       // right
-                       dire*=(player->d-2);
-                       x+=qq;
-                       bx+=4;
-               break;
-               case 2:
-               break;
-               case 4:
-                       //down
-                       dire*=(player->d-2);
-                       y+=qq;
-                       by+=4;
-               break;
-               case 1:
-                       //left
-                       dire*=(player->d+2);
-                       x-=qq;
-                       bx-=4;
-               break;
-       }
-
-#ifdef SPRITE
-#define FRAME1 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 48, dire, 24, 32,        PLAYERBMPDATA);
-#define FRAME2 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 24, dire, 24, 32,        PLAYERBMPDATA);
-#define FRAME3 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 0, dire, 24, 32, PLAYERBMPDATA);
-#define FRAME4 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 24, dire, 24, 32,        PLAYERBMPDATA);
-#else
-#define FRAME1 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, 2+dire);
-#define FRAME2 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, 1+dire);
-#define FRAME3 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, dire);
-#define FRAME4 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, 1+dire);
-#endif
-       if(!pageflipflop)
-               modexCopyPageRegion(pip->page, pip->page, x-4, y-4, x-4, y-4, 28, 36);
-       else{
-               //copy old bg to page0
-               //modexCopyPageRegion(pip[3].page, pip[0].page, bx, by, 0, 0,   20, 36);
-               //update buffer
-               //modexCopyPageRegion(pip[0].page, pip[3].page, 0, 0,   x, y,   20, 36);
-       }
-       switch(ls)
-       {
-               case 1:
-                       FRAME1
-               break;
-               case 2:
-                       FRAME2
-               break;
-               case 3:
-                       FRAME3
-               break;
-               case 4:
-                       FRAME4
-               break;
-       }
-       pip->video->r=1;
-}
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+/*\r
+       scroll16 library~\r
+*/\r
+#include "src/lib/zcroll16.h"\r
+\r
+boolean boundary_check(int x, int y, int dx, int dy, int h, int w){\r
+       return (dx > 0 && (x + dx) < w) || (dx < 0 && (x + dx) >= 0) || (dy > 0 && (y + dy) < h) || (dy < 0 && (y + dy) >= 0) || (dx == dy && dx == 0);\r
+}\r
+\r
+boolean coll_check(int x, int y, int dx, int dy, map_view_t *map_v){\r
+       // Assume everything crosses at most 1 tile at once\r
+       return dx && crossable_tile(x + dx, map_v) || dy && crossable_tile(y + dy, map_v);\r
+}\r
+\r
+boolean walk(entity_t *ent, map_view_t *map_v)\r
+{\r
+       int dx = 1;\r
+       int dy = 1;\r
+       switch(ent->d)\r
+       {\r
+               case STOP:\r
+                       return;\r
+               case LEFT:\r
+                       dx = -dx;\r
+               case RIGHT:\r
+                       dy = 0;\r
+                       break;\r
+               case UP:\r
+                       dy = -dy;\r
+               case DOWN:\r
+                       dx = 0;\r
+                       break;\r
+       }\r
+       if(coll_check(ent->x, ent->y, dx, dy,  map_v)){\r
+               // Allow movement\r
+               // Set speed\r
+               // Start animation\r
+               // Mark next tile as occupied\r
+               // Mark this tile as vacant\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+\r
+void player_walk(player_t *player, map_view_t *map_v){\r
+       if(walk(player->ent, map_v) && boundary_check(map_v->tx, map_v->ty, dx, dy, map_v->map->width - 2*map_v->page->tilesw, map_v->map->height - 2*map_v->page->tilesh)){\r
+               mapScroll(map_v, player);\r
+               // (Un)load stuff?\r
+       }\r
+}\r
+\r
+\r
+void near mapScroll(map_view_t *mv, player_t *player){\r
+       word x, y;  /* coordinate for drawing */\r
+       int c = 1;\r
+       int delta;\r
+       mv->delta += player->dx | player->dy;\r
+       delta = mv->delta;\r
+       mv->d = (player->dx) ? (player->dx > 0) ? RIGHT : LEFT : (player->dy) ? (player->dy > 0) ? DOWN : UP : STOP;\r
+       switch(mv->d){\r
+               case DOWN:\r
+                       c = -1;\r
+                       delta = -delta;\r
+               case UP:\r
+                       if(!(delta + mv->dxThresh)){\r
+                               mv->delta = 0;\r
+                               mv->ty += c;\r
+                       }\r
+                       break;\r
+               case RIGHT:\r
+                       c = -1;\r
+                       delta = -delta;\r
+               case LEFT:\r
+                       if(!(delta + mv->dyThresh)){\r
+                               mv->delta = 0;\r
+                               mv->tx += c;\r
+                       }\r
+                       break;\r
+               default:\r
+                       break;\r
+       }\r
+\r
+       mv->video->r=1;\r
+}\r
+\r
+sword chkmap(map_t *map, word q)\r
+{\r
+//     bitmap_t bp;\r
+       static byte x[(MAPW*MAPH)+1] =\r
+{ 1, 2, 3, 4, 0, 3, 3, 3, 3, 3, 3, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 11, 12, 4, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 0, 1, 1, 1, 5, 8, 1, 11, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 4, 0, 0, 0, 0, 0, 8, 8, 1, 11, 11, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 2, 3, 4, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 5, 6, 7, 8, 6, 6, 6, 6, 6, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 9, 10, 11, 12, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10 };\r
+/*1,   2,      3,      4,      0,      3,      3,      3,      3,      3,      3,      3,      3,      4,      1,      1,      1,      1,      1,      1,      \\r
+5,     6,      7,      8,      0,      1,      0,      1,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+9,     10,     11,     12,     4,      1,      0,      1,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+13,    14,     15,     16,     0,      1,      1,      1,      5,      8,      1,      11,     11,     1,      1,      1,      1,      1,      1,      1,      \\r
+0,     0,      4,      0,      0,      0,      0,      0,      8,      8,      1,      11,     11,     3,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      0,      0,      0,      0,      8,      8,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      0,      0,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      0,      0,      0,      0,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      \\r
+1,     1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      3,      3,      3,      3,      1,      2,      3,      4 };*/\r
+       //check for failed to load map\r
+       if((map->width == map->height == 0) && (q>0))\r
+       {\r
+               //initiate a null map!\r
+               map->width=MAPW;///2;\r
+               map->height=MAPH;///2;\r
+//             map->data = malloc(((map->width*map->height)+1)*sizeof(byte));\r
+               map->data = &x;\r
+               map->tiles = malloc(sizeof(tiles_t));\r
+               //fix this to be far~\r
+//             bp = bitmapLoadPcx("data/ed.pcx");\r
+//             map->tiles->data = &bp;\r
+               map->tiles->debug_data = map->data;\r
+               map->tiles->tileHeight = 16;\r
+               map->tiles->tileWidth = 16;\r
+               map->tiles->rows = 1;\r
+               map->tiles->cols = 1;\r
+               map->tiles->debug_text = true;\r
+       }\r
+       else map->tiles->debug_text = false;\r
+       return 0;\r
+}\r
+\r
+//TODO: player position here\r
+void mapGoTo(map_view_t *mv, int tx, int ty)\r
+{\r
+       int px, py;\r
+       unsigned int i;\r
+\r
+       /* set up the coordinates */\r
+       mv->tx = tx;\r
+       mv->ty = ty;\r
+       mv->page->delta = 0;\r
+\r
+       /* set up the thresholds */\r
+       mv->dxThresh = mv->map->tiles[0]->tileWidth * 2;\r
+       mv->dyThresh = mv->map->tiles[0]->tileHeight * 2;\r
+\r
+       /* draw the tiles */\r
+       modexClearRegion(mv->page, 0, 0, mv->page->width, mv->page->height, 0);\r
+       py=0;\r
+       i=mv->ty * mv->map->width + mv->tx;\r
+/*     for(ty=mv[0].ty-1; py < mv[0].page->sh+mv->dyThresh && ty < mv[0].map->height; ty++, py+=mv[0].map->tiles->tileHeight) {\r
+               mapDrawWRow(&mv[0], tx-1, ty, py);\r
+       i+=mv->map->width - tx;\r
+       }\r
+       if(!pageploop) modexCopyPageRegion(mv[1].page, mv[0].page, 0, 0, 0, 0, mv[0].page->width, mv[0].page->height);\r
+//     {\r
+//             unsigned int k,j,o;\r
+//             // fill screen with a distinctive pattern \r
+//             for (k=0;k < vga_state.vga_width;k++) {\r
+//                     o = k >> 2;\r
+//                     vga_write_sequencer(0x02/*map mask*//*,1 << (k&3));\r
+//                             for (j=0;j < (mv[0].page->height)+(mv[1].page->height)+(mv[2].page->height)+(mv[3].page->height);j++,o += vga_state.vga_stride)\r
+//                                     vga_state.vga_graphics_ram[o] = (k^j)&15; // VRL samples put all colors in first 15!\r
+//             }\r
+//     }\r
+       modexCopyPageRegion(mv[3].page, mv[0].page, 0, 0, 0, 0, 24, 32);*/\r
+}\r
+\r
+void near\r
+mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y)\r
+{\r
+       word rx;\r
+       word ry;\r
+       word textx=0;\r
+       word texty=0;\r
+       //if(i==0) i=2;\r
+       if(i==0)\r
+       {\r
+               //wwww\r
+               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, 0); //currently the over scan color!\r
+       }\r
+       else\r
+       {\r
+               rx = (((i-1) % ((t->data->width)/t->tileWidth)) * t->tileWidth);\r
+               ry = (((i-1) / ((t->data->height)/t->tileHeight)) * t->tileHeight);\r
+////0000printf("i=%d\n", i);\r
+               switch(t->debug_text)\r
+               {\r
+                       case 0:\r
+#ifndef TILERENDER\r
+                               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, ((t->debug_data[i])+1));\r
+                               //modexprint(page, x, y, 1, 15, 0, (char const *)(t->debug_data[i]));\r
+#else\r
+                               PBUFBFUN                (page, x, y, rx, ry, t->tileWidth, t->tileHeight, (t->data));\r
+                               /* then the sprite. note modding ram ptr means we just draw to (x&3,0) */\r
+                               //draw_vrl1_vgax_modex(x-rx,y-ry,vrl_header,vrl_lineoffs,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));\r
+                               //modexDrawBmpRegion    (page, x, y, rx, ry, t->tileWidth, t->tileHeight, (t->data));\r
+#endif\r
+                       break;\r
+                       case 1:\r
+                               modexClearRegion(page, x, y, t->tileWidth, t->tileHeight, (t->debug_data[i])+1);\r
+                               //modexprintbig(page, x, y, 1, 15, 0, (t->debug_data));\r
+                               /*for(texty=0; texty<2; texty++)\r
+                               {\r
+                                       for(textx=0; textx<2; textx++)\r
+                                       {*/\r
+//                                             modexprint(page, x+(textx*8), y+(texty*8), 1, (word)(t->debug_data), 0, (t->debug_data));\r
+/*                                     }\r
+                               }*/\r
+                       break;\r
+               }\r
+       }\r
+}\r
+\r
+unsigned char shinku_fps_indicator_page = 2;\r
+boolean pageflipflop = 1;\r
+boolean pageploop = 1;\r
+\r
+/*     sync    */\r
+void shinku(global_game_variables_t *gv)\r
+{\r
+       word x = (0) + gv->video.page[/*!*/(gv->video.p)].dx; // follow the screen\r
+       word y = (0) + gv->video.page[/*!*/(gv->video.p)].dy; // follow the screen\r
+       word w = 64, h = 8, col = 7, bgcol = 0, type = 1;\r
+       byte o,o2,i;\r
+       if(elapsed_timer(gv) >= (1.0 / gv->kurokku.frames_per_second))\r
+       {\r
+               sprintf(gv->pee, "%.0f fps", (double)gv->kurokku.tiku/ticktock(gv));\r
+               //modexClearRegion(&(gv->video.page[shinku_fps_indicator_page]), x, y, w, h, 45);\r
+               modexprint(&(gv->video.page[/*!*/(gv->video.p)]), x, y, type, col, bgcol, gv->pee);\r
+               gv->kurokku.tiku=0;\r
+       }else //copy dat sheet\r
+       gv->kurokku.tiku++;\r
+\r
+       switch(gv->kurokku.fpscap)\r
+       {\r
+               case 0:\r
+                       gv->kurokku.frames_per_second=1;\r
+               break;\r
+               case 1:\r
+                       //turn this off if XT\r
+                       vga_wait_for_vsync();\r
+                       gv->kurokku.frames_per_second=60;\r
+               break;\r
+       }\r
+       if(pageflipflop){\r
+       if(gv->video.r){\r
+               if(!pageploop) modexCopyPageRegion(&(gv->video.page[(gv->video.p)]), &(gv->video.page[(!gv->video.p)]), 0, 0, 0, 0, gv->video.page[gv->video.p].width, gv->video.page[!gv->video.p].height);\r
+               modexShowPage(&(gv->video.page[gv->video.p]));\r
+               if(!pageploop) gv->video.p=!gv->video.p;\r
+               gv->video.r=!gv->video.r;\r
+       }\r
+       }\r
+}\r
+\r
+void near animatePlayer(map_view_t *pip, player_t *player,  sword scrollswitch)\r
+{\r
+       sword x = player->x;\r
+       sword y = player->y;\r
+       sword bx = x+16;        //buffer's x\r
+       sword by = y+16;        //buffer's y\r
+       word dire=32; //direction\r
+       sword qq; //scroll offset\r
+       word ls = player->persist_aniframe;\r
+\r
+       switch(scrollswitch)\r
+       {\r
+               case 0:\r
+                       qq = 0;\r
+               break;\r
+               default:\r
+                       qq = ((player->q)*(player->speed));\r
+               break;\r
+       }\r
+       //x-=4;\r
+       y-=pip->map->tiles->tileHeight;\r
+       switch (player->d)\r
+       {\r
+               case 0:\r
+                       //up\r
+                       dire*=player->d;\r
+                       y-=qq;\r
+                       by-=4;\r
+               break;\r
+               case 3:\r
+                       // right\r
+                       dire*=(player->d-2);\r
+                       x+=qq;\r
+                       bx+=4;\r
+               break;\r
+               case 2:\r
+               break;\r
+               case 4:\r
+                       //down\r
+                       dire*=(player->d-2);\r
+                       y+=qq;\r
+                       by+=4;\r
+               break;\r
+               case 1:\r
+                       //left\r
+                       dire*=(player->d+2);\r
+                       x-=qq;\r
+                       bx-=4;\r
+               break;\r
+       }\r
+\r
+#ifdef SPRITE\r
+#define FRAME1 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 48, dire, 24, 32,        PLAYERBMPDATA);\r
+#define FRAME2 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 24, dire, 24, 32,        PLAYERBMPDATA);\r
+#define FRAME3 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 0, dire, 24, 32, PLAYERBMPDATA);\r
+#define FRAME4 PBUFSFUN(pip[/*!*/(pip->video->p)].page, x, y, 24, dire, 24, 32,        PLAYERBMPDATA);\r
+#else\r
+#define FRAME1 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, 2+dire);\r
+#define FRAME2 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, 1+dire);\r
+#define FRAME3 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, dire);\r
+#define FRAME4 modexClearRegion(pip[/*!*/(pip->video->p)].page, x, y, 24, 32, 1+dire);\r
+#endif\r
+       if(!pageflipflop)\r
+               modexCopyPageRegion(pip->page, pip->page, x-4, y-4, x-4, y-4, 28, 36);\r
+       else{\r
+               //copy old bg to page0\r
+               //modexCopyPageRegion(pip[3].page, pip[0].page, bx, by, 0, 0,   20, 36);\r
+               //update buffer\r
+               //modexCopyPageRegion(pip[0].page, pip[3].page, 0, 0,   x, y,   20, 36);\r
+       }\r
+       switch(ls)\r
+       {\r
+               case 1:\r
+                       FRAME1\r
+               break;\r
+               case 2:\r
+                       FRAME2\r
+               break;\r
+               case 3:\r
+                       FRAME3\r
+               break;\r
+               case 4:\r
+                       FRAME4\r
+               break;\r
+       }\r
+       pip->video->r=1;\r
+}\r
index 3c4851c38964a5ad1994bbd15c93313c343161fa..6f66342967ca388e630e2d1528f6e1359c812541 100755 (executable)
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef __ZCROLL16_H_
-#define __ZCROLL16_H_
-
-#include "src/lib/16_head.h"
-//#include "src/lib/bakapee.h"
-#include "src/lib/modex16.h"
-//#include "src/lib/16_in.h"
-#include "src/lib/bitmap.h"
-#include "src/lib/16_map.h" //map is loaded here www
-#include "src/lib/16_timer.h"
-#include "src/lib/wcpu/wcpu.h"
-
-#include <hw/cpu/cpu.h>
-#include <hw/dos/dos.h>
-#include <hw/vga/vga.h>
-#include <hw/vga/vrl.h>
-
-#define SPRITE
-//#define TILERENDER
-
-//modexDrawSpritePBufRegion
-//modexDrawBmpPBufRegion
-#define PBUFSFUN               modexDrawSpriteRegion
-#define PBUFBFUN               modexDrawBmpRegion
-#define PLAYERBMPDATA  player->data
-
-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; //Threshold for physical tile switch
-       word dyThresh; //Threshold for physical tile switch
-       video_t *video; //pointer to game variables of the video
-       pan_t *pan;             //pointer the the page panning debug system
-} map_view_t;
-
-#define MAPW   40
-#define MAPH   30
-
-enum direction {STOP, UP, DOWN, LEFT, RIGHT};
-typedef struct {
-       word id;        /* the Identification number of the page~ For layering~ */
-       byte far* data; /* the data for the page */
-       word sw;                /* screen width */
-       word sh;                /* screen heigth */
-       word tw;                /* screen width in tiles */
-       word th;                /* screen height in tiles */
-       word width;             /* virtual width of the page */
-       word height;    /* virtual height of the page */
-       word tilesw;            /* virtual screen width in tiles */
-       word tilesh;            /* virtual screen height in tiles */
-       sword tilemidposscreenx;        /* middle tile position */
-       sword tilemidposscreeny;        /* middle tile position */
-       sword tileplayerposscreenx;     /* player position on screen */
-       sword tileplayerposscreeny;     /* player position on screen */
-       word stridew;                   /*width/4*/
-       word pagesize;                  /* page size */
-       word pi;                                /* incremention page by this much to preserve location */
-       word delta;                     // How much should we shift the page for smooth scrolling
-       direction d;                    // Direction we should shift the page
-} page_t;
-extern boolean pageflipflop, pageploop;
-extern unsigned char shinku_fps_indicator_page;
-
-/* Map is presumed to:
- * 1. Have all the required layers and tilesets within itself
- * 2. Have a 'fence' around accessible blocks to simplify boundary logic
- * 3. Have a persistent map and tile size among the layers
- * Map view is presumed to:
- * 1. Calculate, store and update a panning info, which includes, but not limited to:
- *     combined layer information, actual map representation (reflecting real state of the game),
- *     pixel shift for smooth tile scrolling.
- * 2. Provide ways to draw a visible part of map. For simplicity with smooth scrolling, 
- *     additional row/column is always drawn at the each side of the map. This implies that 'fence'
- *     should have a sprite too. Map is drawn left-to-right, top-to-bottom.
- */
-
-// Move an entity around. Should actually be in 16_entity
-boolean walk(entity_t *ent, map_view_t *map_v);
-
-// Move player around and call map scrolling if required/possible
-void walk_player(player_t *player, map_view_t *map_v);
-
-// Scroll map in one direction (assumed from player's movement)
-void near mapScroll(map_view_t *mv, player_t *player);
-sword chkmap(map_t *map, word q);
-void mapGoTo(map_view_t *mv, int tx, int ty);
-void near mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y);
-//void qclean();
-void shinku(global_game_variables_t *gv);
-void near animatePlayer(map_view_t *pip, player_t *player, sword scrollswitch);
-
-#endif /*__ZCROLL16_H_*/
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+\r
+#ifndef __ZCROLL16_H_\r
+#define __ZCROLL16_H_\r
+\r
+#include "src/lib/16_head.h"\r
+//#include "src/lib/bakapee.h"\r
+#include "src/lib/modex16.h"\r
+//#include "src/lib/16_in.h"\r
+#include "src/lib/bitmap.h"\r
+#include "src/lib/16_map.h" //map is loaded here www\r
+#include "src/lib/16_timer.h"\r
+#include "src/lib/wcpu/wcpu.h"\r
+\r
+#include <hw/cpu/cpu.h>\r
+#include <hw/dos/dos.h>\r
+#include <hw/vga/vga.h>\r
+#include <hw/vga/vrl.h>\r
+\r
+#define SPRITE\r
+//#define TILERENDER\r
+\r
+//modexDrawSpritePBufRegion\r
+//modexDrawBmpPBufRegion\r
+#define PBUFSFUN               modexDrawSpriteRegion\r
+#define PBUFBFUN               modexDrawBmpRegion\r
+#define PLAYERBMPDATA  player->data\r
+\r
+typedef struct {\r
+       map_t *map;\r
+       page_t *page;\r
+       int tx; //appears to be the top left tile position on the viewable screen map\r
+       int ty; //appears to be the top left tile position on the viewable screen map\r
+       word dxThresh; //Threshold for physical tile switch\r
+       word dyThresh; //Threshold for physical tile switch\r
+       video_t *video; //pointer to game variables of the video\r
+       pan_t *pan;             //pointer the the page panning debug system\r
+} map_view_t;\r
+\r
+#define MAPW   40\r
+#define MAPH   30\r
+\r
+enum direction {STOP, UP, DOWN, LEFT, RIGHT};\r
+typedef struct {\r
+       word id;        /* the Identification number of the page~ For layering~ */\r
+       byte far* data; /* the data for the page */\r
+       word sw;                /* screen width */\r
+       word sh;                /* screen heigth */\r
+       word tw;                /* screen width in tiles */\r
+       word th;                /* screen height in tiles */\r
+       word width;             /* virtual width of the page */\r
+       word height;    /* virtual height of the page */\r
+       word tilesw;            /* virtual screen width in tiles */\r
+       word tilesh;            /* virtual screen height in tiles */\r
+       sword tilemidposscreenx;        /* middle tile position */\r
+       sword tilemidposscreeny;        /* middle tile position */\r
+       sword tileplayerposscreenx;     /* player position on screen */\r
+       sword tileplayerposscreeny;     /* player position on screen */\r
+       word stridew;                   /*width/4*/\r
+       word pagesize;                  /* page size */\r
+       word pi;                                /* incremention page by this much to preserve location */\r
+       word delta;                     // How much should we shift the page for smooth scrolling\r
+       direction d;                    // Direction we should shift the page\r
+} page_t;\r
+extern boolean pageflipflop, pageploop;\r
+extern unsigned char shinku_fps_indicator_page;\r
+\r
+/* Map is presumed to:\r
+ * 1. Have all the required layers and tilesets within itself\r
+ * 2. Have a 'fence' around accessible blocks to simplify boundary logic\r
+ * 3. Have a persistent map and tile size among the layers\r
+ * Map view is presumed to:\r
+ * 1. Calculate, store and update a panning info, which includes, but not limited to:\r
+ *     combined layer information, actual map representation (reflecting real state of the game),\r
+ *     pixel shift for smooth tile scrolling.\r
+ * 2. Provide ways to draw a visible part of map. For simplicity with smooth scrolling, \r
+ *     additional row/column is always drawn at the each side of the map. This implies that 'fence'\r
+ *     should have a sprite too. Map is drawn left-to-right, top-to-bottom.\r
+ */\r
+\r
+// Move an entity around. Should actually be in 16_entity\r
+boolean walk(entity_t *ent, map_view_t *map_v);\r
+\r
+// Move player around and call map scrolling if required/possible\r
+void walk_player(player_t *player, map_view_t *map_v);\r
+\r
+// Scroll map in one direction (assumed from player's movement)\r
+void near mapScroll(map_view_t *mv, player_t *player);\r
+sword chkmap(map_t *map, word q);\r
+void mapGoTo(map_view_t *mv, int tx, int ty);\r
+void near mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y);\r
+//void qclean();\r
+void shinku(global_game_variables_t *gv);\r
+void near animatePlayer(map_view_t *pip, player_t *player, sword scrollswitch);\r
+\r
+#endif /*__ZCROLL16_H_*/\r
index e36a85320bd449fe97c6b881e4ff2c576e2fcd3c..04126d4eb1a860ffc6805f32db80f060f675de0d 100755 (executable)
-/* midi.c
- *
- * Adlib OPL2/OPL3 FM synthesizer chipset test program.
- * Play MIDI file using the OPLx synthesizer (well, poorly anyway)
- * (C) 2010-2012 Jonathan Campbell.
- * Hackipedia DOS library.
- *
- * This code is licensed under the LGPL.
- * <insert LGPL legal text here>
- *
- * Compiles for intended target environments:
- *   - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]
- */
-#include <stdio.h>
-#include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <malloc.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <math.h>
-#include <dos.h>
-
-#include "src/lib/doslib/vga.h"
-#include "src/lib/doslib/dos.h"
-#include "src/lib/doslib/8254.h"               /* 8254 timer */
-#include "src/lib/doslib/8259.h"
-#include "src/lib/doslib/vgagui.h"
-#include "src/lib/doslib/vgatty.h"
-#include "src/lib/doslib/adlib.h"
-
-/* one per OPL channel */
-struct midi_note {
-       unsigned char           note_number;
-       unsigned char           note_velocity;
-       unsigned char           note_track;     /* from what MIDI track */
-       unsigned char           note_channel;   /* from what MIDI channel */
-       unsigned int            busy:1;         /* if occupied */
-};
-
-struct midi_channel {
-       unsigned char           program;
-};
-
-struct midi_track {
-       /* track data, raw */
-       unsigned char*          raw;            /* raw data base */
-       unsigned char*          fence;          /* raw data end (last byte + 1) */
-       unsigned char*          read;           /* raw data read ptr */
-       /* state */
-       unsigned long           us_per_quarter_note; /* Microseconds per quarter note (def 120 BPM) */
-       unsigned long           us_tick_cnt_mtpq; /* Microseconds advanced (up to 10000 us or one unit at 100Hz) x ticks per quarter note */
-       unsigned long           wait;
-       unsigned char           last_status;    /* MIDI last status byte */
-       unsigned int            eof:1;          /* we hit the end of the track */
-};
-
-#define MIDI_MAX_CHANNELS      16
-#define MIDI_MAX_TRACKS                64
-
-struct midi_note               midi_notes[ADLIB_FM_VOICES];
-struct midi_channel            midi_ch[MIDI_MAX_CHANNELS];
-struct midi_track              midi_trk[MIDI_MAX_TRACKS];
-static unsigned int            midi_trk_count=0;
-static volatile unsigned char  midi_playing=0;
-
-/* MIDI params. Nobody ever said it was a straightforward standard!
- * NTS: These are for reading reference. Internally we convert everything to 100Hz time base. */
-static unsigned int ticks_per_quarter_note=0;  /* "Ticks per beat" */
-
-static void (interrupt *old_irq0)();
-static volatile unsigned long irq0_ticks=0;
-static volatile unsigned int irq0_cnt=0,irq0_add=0,irq0_max=0;
-
-#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))
-static inline unsigned long farptr2phys(unsigned char far *p) { /* take 16:16 pointer convert to physical memory address */
-       return ((unsigned long)FP_SEG(p) << 4UL) + ((unsigned long)FP_OFF(p));
-}
-#endif
-
-static inline unsigned char midi_trk_read(struct midi_track *t) {
-       unsigned char c;
-
-       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */
-       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence) {
-               t->eof = 1;
-               return 0xFF;
-       }
-
-       c = *(t->read);
-#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))
-       if (FP_OFF(t->read) >= 0xF) /* 16:16 far pointer aware (NTS: Programs reassigning this pointer MUST normalize the FAR pointer) */
-               t->read = MK_FP(FP_SEG(t->read)+0x1,0);
-       else
-               t->read++;
-#else
-       t->read++;
-#endif
-       return c;
-}
-
-void midi_trk_end(struct midi_track *t) {
-       t->wait = ~0UL;
-       t->read = t->fence;
-}
-
-void midi_trk_skip(struct midi_track *t,unsigned long len) {
-       unsigned long rem;
-
-       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */
-       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence)
-               return;
-
-       if (len > 0xFFF0UL) {
-               midi_trk_end(t);
-               return;
-       }
-#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))
-       {
-               unsigned long tt;
-
-               tt = farptr2phys(t->read);
-               rem = farptr2phys(t->fence) - tt;
-               if (rem > len) rem = len;
-               tt += rem;
-               t->read = MK_FP(tt>>4,tt&0xF);
-       }
-#else
-       rem = (unsigned long)(t->fence - t->read);
-       if (len > rem) len = rem;
-       t->read += len;
-#endif
-}
-
-static const uint32_t midikeys_freqs[0x80] = {
-       0x00082d01,     /* key 0 = 8.17579891564371Hz */
-       0x0008a976,     /* key 1 = 8.66195721802725Hz */
-       0x00092d51,     /* key 2 = 9.17702399741899Hz */
-       0x0009b904,     /* key 3 = 9.72271824131503Hz */
-       0x000a4d05,     /* key 4 = 10.3008611535272Hz */
-       0x000ae9d3,     /* key 5 = 10.9133822322814Hz */
-       0x000b8ff4,     /* key 6 = 11.5623257097386Hz */
-       0x000c3ff6,     /* key 7 = 12.2498573744297Hz */
-       0x000cfa70,     /* key 8 = 12.9782717993733Hz */
-       0x000dc000,     /* key 9 = 13.75Hz */
-       0x000e914f,     /* key 10 = 14.5676175474403Hz */
-       0x000f6f11,     /* key 11 = 15.4338531642539Hz */
-       0x00105a02,     /* key 12 = 16.3515978312874Hz */
-       0x001152ec,     /* key 13 = 17.3239144360545Hz */
-       0x00125aa2,     /* key 14 = 18.354047994838Hz */
-       0x00137208,     /* key 15 = 19.4454364826301Hz */
-       0x00149a0a,     /* key 16 = 20.6017223070544Hz */
-       0x0015d3a6,     /* key 17 = 21.8267644645627Hz */
-       0x00171fe9,     /* key 18 = 23.1246514194771Hz */
-       0x00187fed,     /* key 19 = 24.4997147488593Hz */
-       0x0019f4e0,     /* key 20 = 25.9565435987466Hz */
-       0x001b8000,     /* key 21 = 27.5Hz */
-       0x001d229e,     /* key 22 = 29.1352350948806Hz */
-       0x001ede22,     /* key 23 = 30.8677063285078Hz */
-       0x0020b404,     /* key 24 = 32.7031956625748Hz */
-       0x0022a5d8,     /* key 25 = 34.647828872109Hz */
-       0x0024b545,     /* key 26 = 36.7080959896759Hz */
-       0x0026e410,     /* key 27 = 38.8908729652601Hz */
-       0x00293414,     /* key 28 = 41.2034446141087Hz */
-       0x002ba74d,     /* key 29 = 43.6535289291255Hz */
-       0x002e3fd2,     /* key 30 = 46.2493028389543Hz */
-       0x0030ffda,     /* key 31 = 48.9994294977187Hz */
-       0x0033e9c0,     /* key 32 = 51.9130871974931Hz */
-       0x00370000,     /* key 33 = 55Hz */
-       0x003a453d,     /* key 34 = 58.2704701897612Hz */
-       0x003dbc44,     /* key 35 = 61.7354126570155Hz */
-       0x00416809,     /* key 36 = 65.4063913251497Hz */
-       0x00454bb0,     /* key 37 = 69.295657744218Hz */
-       0x00496a8b,     /* key 38 = 73.4161919793519Hz */
-       0x004dc820,     /* key 39 = 77.7817459305202Hz */
-       0x00526829,     /* key 40 = 82.4068892282175Hz */
-       0x00574e9b,     /* key 41 = 87.307057858251Hz */
-       0x005c7fa4,     /* key 42 = 92.4986056779086Hz */
-       0x0061ffb5,     /* key 43 = 97.9988589954373Hz */
-       0x0067d380,     /* key 44 = 103.826174394986Hz */
-       0x006e0000,     /* key 45 = 110Hz */
-       0x00748a7b,     /* key 46 = 116.540940379522Hz */
-       0x007b7888,     /* key 47 = 123.470825314031Hz */
-       0x0082d012,     /* key 48 = 130.812782650299Hz */
-       0x008a9760,     /* key 49 = 138.591315488436Hz */
-       0x0092d517,     /* key 50 = 146.832383958704Hz */
-       0x009b9041,     /* key 51 = 155.56349186104Hz */
-       0x00a4d053,     /* key 52 = 164.813778456435Hz */
-       0x00ae9d36,     /* key 53 = 174.614115716502Hz */
-       0x00b8ff49,     /* key 54 = 184.997211355817Hz */
-       0x00c3ff6a,     /* key 55 = 195.997717990875Hz */
-       0x00cfa700,     /* key 56 = 207.652348789973Hz */
-       0x00dc0000,     /* key 57 = 220Hz */
-       0x00e914f6,     /* key 58 = 233.081880759045Hz */
-       0x00f6f110,     /* key 59 = 246.941650628062Hz */
-       0x0105a025,     /* key 60 = 261.625565300599Hz */
-       0x01152ec0,     /* key 61 = 277.182630976872Hz */
-       0x0125aa2e,     /* key 62 = 293.664767917408Hz */
-       0x01372082,     /* key 63 = 311.126983722081Hz */
-       0x0149a0a7,     /* key 64 = 329.62755691287Hz */
-       0x015d3a6d,     /* key 65 = 349.228231433004Hz */
-       0x0171fe92,     /* key 66 = 369.994422711634Hz */
-       0x0187fed4,     /* key 67 = 391.995435981749Hz */
-       0x019f4e00,     /* key 68 = 415.304697579945Hz */
-       0x01b80000,     /* key 69 = 440Hz */
-       0x01d229ec,     /* key 70 = 466.16376151809Hz */
-       0x01ede220,     /* key 71 = 493.883301256124Hz */
-       0x020b404a,     /* key 72 = 523.251130601197Hz */
-       0x022a5d81,     /* key 73 = 554.365261953744Hz */
-       0x024b545c,     /* key 74 = 587.329535834815Hz */
-       0x026e4104,     /* key 75 = 622.253967444162Hz */
-       0x0293414f,     /* key 76 = 659.25511382574Hz */
-       0x02ba74da,     /* key 77 = 698.456462866008Hz */
-       0x02e3fd24,     /* key 78 = 739.988845423269Hz */
-       0x030ffda9,     /* key 79 = 783.990871963499Hz */
-       0x033e9c01,     /* key 80 = 830.60939515989Hz */
-       0x03700000,     /* key 81 = 880Hz */
-       0x03a453d8,     /* key 82 = 932.32752303618Hz */
-       0x03dbc440,     /* key 83 = 987.766602512248Hz */
-       0x04168094,     /* key 84 = 1046.50226120239Hz */
-       0x0454bb03,     /* key 85 = 1108.73052390749Hz */
-       0x0496a8b8,     /* key 86 = 1174.65907166963Hz */
-       0x04dc8208,     /* key 87 = 1244.50793488832Hz */
-       0x0526829e,     /* key 88 = 1318.51022765148Hz */
-       0x0574e9b5,     /* key 89 = 1396.91292573202Hz */
-       0x05c7fa49,     /* key 90 = 1479.97769084654Hz */
-       0x061ffb53,     /* key 91 = 1567.981743927Hz */
-       0x067d3802,     /* key 92 = 1661.21879031978Hz */
-       0x06e00000,     /* key 93 = 1760Hz */
-       0x0748a7b1,     /* key 94 = 1864.65504607236Hz */
-       0x07b78880,     /* key 95 = 1975.5332050245Hz */
-       0x082d0128,     /* key 96 = 2093.00452240479Hz */
-       0x08a97607,     /* key 97 = 2217.46104781498Hz */
-       0x092d5171,     /* key 98 = 2349.31814333926Hz */
-       0x09b90410,     /* key 99 = 2489.01586977665Hz */
-       0x0a4d053c,     /* key 100 = 2637.02045530296Hz */
-       0x0ae9d36b,     /* key 101 = 2793.82585146403Hz */
-       0x0b8ff493,     /* key 102 = 2959.95538169308Hz */
-       0x0c3ff6a7,     /* key 103 = 3135.96348785399Hz */
-       0x0cfa7005,     /* key 104 = 3322.43758063956Hz */
-       0x0dc00000,     /* key 105 = 3520Hz */
-       0x0e914f62,     /* key 106 = 3729.31009214472Hz */
-       0x0f6f1100,     /* key 107 = 3951.06641004899Hz */
-       0x105a0250,     /* key 108 = 4186.00904480958Hz */
-       0x1152ec0e,     /* key 109 = 4434.92209562995Hz */
-       0x125aa2e3,     /* key 110 = 4698.63628667852Hz */
-       0x13720820,     /* key 111 = 4978.03173955329Hz */
-       0x149a0a79,     /* key 112 = 5274.04091060592Hz */
-       0x15d3a6d6,     /* key 113 = 5587.65170292806Hz */
-       0x171fe927,     /* key 114 = 5919.91076338615Hz */
-       0x187fed4e,     /* key 115 = 6271.92697570799Hz */
-       0x19f4e00a,     /* key 116 = 6644.87516127912Hz */
-       0x1b800000,     /* key 117 = 7040Hz */
-       0x1d229ec4,     /* key 118 = 7458.62018428944Hz */
-       0x1ede2200,     /* key 119 = 7902.13282009799Hz */
-       0x20b404a1,     /* key 120 = 8372.01808961916Hz */
-       0x22a5d81c,     /* key 121 = 8869.84419125991Hz */
-       0x24b545c7,     /* key 122 = 9397.27257335704Hz */
-       0x26e41040,     /* key 123 = 9956.06347910659Hz */
-       0x293414f2,     /* key 124 = 10548.0818212118Hz */
-       0x2ba74dac,     /* key 125 = 11175.3034058561Hz */
-       0x2e3fd24f,     /* key 126 = 11839.8215267723Hz */
-       0x30ffda9c      /* key 127 = 12543.853951416Hz */
-};
-
-static uint32_t midi_note_freq(struct midi_channel *ch,unsigned char key) {
-       return midikeys_freqs[key&0x7F];
-}
-
-static struct midi_note *get_fm_note(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char do_alloc) {
-       unsigned int tch = (unsigned int)(t - midi_trk); /* pointer math */
-       unsigned int ach = (unsigned int)(ch - midi_ch); /* pointer math */
-       unsigned int i,freen=~0;
-
-       for (i=0;i < ADLIB_FM_VOICES;i++) {
-               if (midi_notes[i].busy) {
-                       if (midi_notes[i].note_channel == ach && midi_notes[i].note_track == tch && midi_notes[i].note_number == key)
-                               return &midi_notes[i];
-               }
-               else {
-                       if (freen == ~0) freen = i;
-               }
-       }
-
-       if (do_alloc && freen != ~0) return &midi_notes[freen];
-       return NULL;
-}
-
-static void drop_fm_note(struct midi_channel *ch,unsigned char key) {
-       unsigned int ach = (unsigned int)(ch - midi_ch); /* pointer math */
-       unsigned int i;
-
-       for (i=0;i < ADLIB_FM_VOICES;i++) {
-               if (midi_notes[i].busy && midi_notes[i].note_channel == ach) {
-                       midi_notes[i].busy = 0;
-                       break;
-               }
-       }
-}
-
-static inline void on_key_aftertouch(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {
-       struct midi_note *note = get_fm_note(t,ch,key,/*do_alloc*/0);
-       uint32_t freq = midi_note_freq(ch,key);
-       unsigned int ach;
-
-       if (note == NULL) return;
-
-       note->busy = 1;
-       note->note_number = key;
-       note->note_velocity = vel;
-       note->note_track = (unsigned int)(t - midi_trk);
-       note->note_channel = (unsigned int)(ch - midi_ch);
-       ach = (unsigned int)(note - midi_notes); /* which FM channel? */
-       adlib_freq_to_fm_op(&adlib_fm[ach].mod,(double)freq / 65536);
-       adlib_fm[ach].mod.attack_rate = vel >> 3; /* 0-127 to 0-15 */
-       adlib_fm[ach].mod.sustain_level = vel >> 3;
-       adlib_fm[ach].mod.key_on = 1;
-       adlib_update_groupA0(ach,&adlib_fm[ach]);
-}
-
-static inline void on_key_on(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {
-       struct midi_note *note = get_fm_note(t,ch,key,/*do_alloc*/1);
-       uint32_t freq = midi_note_freq(ch,key);
-       unsigned int ach;
-
-       /* HACK: Ignore percussion */
-       if ((ch->program >= 8 && ch->program <= 15)/*Chromatic percussion*/ ||
-               (ch->program >= 112 && ch->program <= 119)/*Percussive*/ ||
-               ch == &midi_ch[9]/*MIDI channel 10 (DAMN YOU 1-BASED COUNTING)*/)
-               return;
-
-       if (note == NULL) {
-               /* then we'll have to knock one off to make room */
-               drop_fm_note(ch,key);
-               note = get_fm_note(t,ch,key,1);
-               if (note == NULL) return;
-       }
-
-       note->busy = 1;
-       note->note_number = key;
-       note->note_velocity = vel;
-       note->note_track = (unsigned int)(t - midi_trk);
-       note->note_channel = (unsigned int)(ch - midi_ch);
-       ach = (unsigned int)(note - midi_notes); /* which FM channel? */
-       adlib_freq_to_fm_op(&adlib_fm[ach].mod,(double)freq / 65536);
-       adlib_fm[ach].mod.attack_rate = vel >> 3; /* 0-127 to 0-15 */
-       adlib_fm[ach].mod.sustain_level = vel >> 3;
-       adlib_fm[ach].mod.key_on = 1;
-       adlib_update_groupA0(ach,&adlib_fm[ach]);
-}
-
-static inline void on_key_off(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {
-       struct midi_note *note = get_fm_note(t,ch,key,/*do_alloc*/0);
-       uint32_t freq = midi_note_freq(ch,key);
-       unsigned int ach;
-
-       if (note == NULL) return;
-
-       note->busy = 0;
-       ach = (unsigned int)(note - midi_notes); /* which FM channel? */
-       adlib_freq_to_fm_op(&adlib_fm[ach].mod,(double)freq / 65536);
-       adlib_fm[ach].mod.attack_rate = vel >> 3; /* 0-127 to 0-15 */
-       adlib_fm[ach].mod.sustain_level = vel >> 3;
-       adlib_fm[ach].mod.key_on = 0;
-       adlib_update_groupA0(ach,&adlib_fm[ach]);
-}
-
-static inline void on_control_change(struct midi_track *t,struct midi_channel *ch,unsigned char num,unsigned char val) {
-}
-
-static inline void on_program_change(struct midi_track *t,struct midi_channel *ch,unsigned char inst) {
-       ch->program = inst;
-}
-
-static inline void on_channel_aftertouch(struct midi_track *t,struct midi_channel *ch,unsigned char velocity) {
-}
-
-static inline void on_pitch_bend(struct midi_track *t,struct midi_channel *ch,int bend/*-8192 to 8192*/) {
-}
-
-unsigned long midi_trk_read_delta(struct midi_track *t) {
-       unsigned long tc = 0;
-       unsigned char c = 0,b;
-
-       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */
-       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence)
-               return tc;
-
-       while (c < 4) {
-               b = midi_trk_read(t);
-               tc = (tc << 7UL) + (unsigned long)(b&0x7F);
-               if (!(b&0x80)) break;
-               c++;
-       }
-
-       return tc;
-}
-
-void midi_tick_track(unsigned int i) {
-       struct midi_track *t = midi_trk + i;
-       struct midi_channel *ch;
-       unsigned char b,c,d;
-       int cnt=0;
-
-       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */
-       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence) {
-               t->eof = 1;
-               return;
-       }
-
-       t->us_tick_cnt_mtpq += 10000UL * (unsigned long)ticks_per_quarter_note;
-       while (t->us_tick_cnt_mtpq >= t->us_per_quarter_note) {
-               t->us_tick_cnt_mtpq -= t->us_per_quarter_note;
-               cnt++;
-
-               while (t->wait == 0) {
-                       if ((unsigned long)t->read >= (unsigned long)t->fence) {
-                               t->eof = 1;
-                               break;
-                       }
-
-                       /* read pointer should be pointing at MIDI event bytes, just after the time delay */
-                       b = midi_trk_read(t);
-                       if (b&0x80) {
-                               if (b < 0xF8) {
-                                       if (b >= 0xF0)
-                                               t->last_status = 0;
-                                       else
-                                               t->last_status = b;
-                               }
-                               if (b != 0x00 && ((b&0xF8) != 0xF0))
-                                       c = midi_trk_read(t);
-                       }
-                       else {
-                               /* blegh. last status */
-                               c = b;
-                               b = t->last_status;
-                       }
-                       switch (b>>4) {
-                               case 0x8: { /* note off */
-                                       d = midi_trk_read(t);
-                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */
-                                       on_key_off(t,ch,c,d);
-                                       } break;
-                               case 0x9: { /* note on */
-                                       d = midi_trk_read(t);
-                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */
-                                       if (d != 0) on_key_on(t,ch,c,d); /* "A Note On with a velocity of 0 is actually a note off" Bleh, really? */
-                                       else on_key_off(t,ch,c,d);
-                                       } break;
-                               case 0xA: { /* polyphonic aftertouch */
-                                       d = midi_trk_read(t);
-                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */
-                                       on_key_aftertouch(t,ch,c,d);
-                                       } break;
-                               case 0xB: { /* control change */
-                                       d = midi_trk_read(t);
-                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */
-                                       on_control_change(t,ch,c,d);
-                                       } break;
-                               case 0xC: { /* program change */
-                                       on_program_change(t,ch,c); /* c=instrument d=not used */
-                                       } break;
-                               case 0xD: { /* channel aftertouch */
-                                       on_channel_aftertouch(t,ch,c); /* c=velocity d=not used */
-                                       } break;
-                               case 0xE: { /* pitch bend */
-                                       d = midi_trk_read(t);
-                                       on_pitch_bend(t,ch,((c&0x7F)|((d&0x7F)<<7))-8192); /* c=LSB d=MSB */
-                                       } break;
-                               case 0xF: { /* event */
-                                       if (b == 0xFF) {
-                                               if (c == 0x7F) { /* c=type d=len */
-                                                       unsigned long len = midi_trk_read_delta(t);
-//                                                     fprintf(stderr,"Type 0x7F len=%lu %p/%p/%p\n",len,t->raw,t->read,t->fence);
-                                                       if (len < 512UL) {
-                                                               /* unknown */
-                                                               midi_trk_skip(t,len);
-                                                       }
-                                                       else {
-                                                               midi_trk_end(t);
-                                                       }
-                                               }
-                                               else if (c < 0x7F) {
-                                                       d = midi_trk_read(t);
-
-                                                       if (c == 0x51 && d >= 3) {
-                                                               d -= 3;
-                                                               t->us_per_quarter_note = ((unsigned long)midi_trk_read(t)<<16UL)+
-                                                                       ((unsigned long)midi_trk_read(t)<<8UL)+
-                                                                       ((unsigned long)midi_trk_read(t)<<0UL);
-
-                                                               if (1/*TODO: If format 0 or format 1*/) {
-                                                                       /* Ugh. Unless format 2, the tempo applies to all tracks */
-                                                                       int j;
-
-                                                                       for (j=0;j < midi_trk_count;j++) {
-                                                                               if (j != i) midi_trk[j].us_per_quarter_note =
-                                                                                       t->us_per_quarter_note;
-                                                                       }
-                                                               }
-                                                       }
-                                                       else {
-//                                                             fprintf(stderr,"Type 0x%02x len=%lu %p/%p/%p\n",c,d,t->raw,t->read,t->fence);
-                                                       }
-
-                                                       midi_trk_skip(t,d);
-                                               }
-                                               else {
-                                                       fprintf(stderr,"t=%u Unknown MIDI f message 0x%02x 0x%02x %p/%p/%p\n",i,b,c,t->raw,t->read,t->fence);
-                                               }
-                                       }
-                                       else {
-                                               unsigned long len = midi_trk_read_delta(t);
-//                                             fprintf(stderr,"Sysex len=%lu %p/%p/%p\n",len,t->raw,t->read,t->fence);
-                                               midi_trk_skip(t,len);
-                                       }
-                                       } break;
-                               default:
-                                       if (b != 0x00) {
-                                               fprintf(stderr,"t=%u Unknown MIDI message 0x%02x at %p/%p/%p\n",i,b,t->raw,t->read,t->fence);
-                                               midi_trk_end(t);
-                                       }
-                                       break;
-                       };
-
-                       /* and then read the next event */
-                       t->wait = midi_trk_read_delta(t);
-               }
-               if (t->wait != 0) {
-                       t->wait--;
-               }
-       }
-}
-
-void adlib_shut_up();
-void midi_reset_tracks();
-void midi_reset_channels();
-
-void midi_tick() {
-       if (midi_playing) {
-               unsigned int i;
-               int eof=0;
-
-               for (i=0;i < midi_trk_count;i++) {
-                       midi_tick_track(i);
-                       eof += midi_trk[i].eof?1:0;
-               }
-
-               if (eof >= midi_trk_count) {
-                       adlib_shut_up();
-                       midi_reset_tracks();
-                       midi_reset_channels();
-               }
-       }
-}
-
-/* WARNING: subroutine call in interrupt handler. make sure you compile with -zu flag for large/compact memory models */
-void interrupt irq0() {
-//     midi_tick();
-       irq0_ticks++;
-       if ((irq0_cnt += irq0_add) >= irq0_max) {
-               irq0_cnt -= irq0_max;
-               old_irq0();
-       }
-       else {
-               p8259_OCW2(0,P8259_OCW2_NON_SPECIFIC_EOI);
-       }
-}
-
-void adlib_shut_up() {
-       int i;
-
-       memset(adlib_fm,0,sizeof(adlib_fm));
-       memset(&adlib_reg_bd,0,sizeof(adlib_reg_bd));
-       for (i=0;i < adlib_fm_voices;i++) {
-               struct adlib_fm_operator *f;
-               f = &adlib_fm[i].mod;
-               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;
-               f = &adlib_fm[i].car;
-               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;
-       }
-
-       for (i=0;i < adlib_fm_voices;i++) {
-               struct adlib_fm_operator *f;
-
-               midi_notes[i].busy = 0;
-               midi_notes[i].note_channel = 0;
-
-               f = &adlib_fm[i].mod;
-               f->mod_multiple = 1;
-               f->total_level = 63 - 16;
-               f->attack_rate = 15;
-               f->decay_rate = 4;
-               f->sustain_level = 0;
-               f->release_rate = 8;
-               f->f_number = 400;
-               f->sustain = 1;
-               f->octave = 4;
-               f->key_on = 0;
-
-               f = &adlib_fm[i].car;
-               f->mod_multiple = 1;
-               f->total_level = 63 - 16;
-               f->attack_rate = 15;
-               f->decay_rate = 4;
-               f->sustain_level = 0;
-               f->release_rate = 8;
-               f->f_number = 0;
-               f->sustain = 1;
-               f->octave = 0;
-               f->key_on = 0;
-       }
-
-       adlib_apply_all();
-}
-
-void midi_reset_track(unsigned int i) {
-       struct midi_track *t;
-
-       if (i >= MIDI_MAX_TRACKS) return;
-       t = &midi_trk[i];
-       t->eof = 0;
-       t->last_status = 0;
-       t->us_tick_cnt_mtpq = 0;
-       t->us_per_quarter_note = (60000000UL / 120UL); /* 120BPM */
-       t->read = midi_trk[i].raw;
-       t->wait = midi_trk_read_delta(t); /* and then the read pointer will point at the MIDI event when wait counts down */
-}
-
-void midi_reset_tracks() {
-       int i;
-
-       for (i=0;i < midi_trk_count;i++)
-               midi_reset_track(i);
-}
-
-void midi_reset_channels() {
-       int i;
-
-       for (i=0;i < MIDI_MAX_CHANNELS;i++) {
-               midi_ch[i].program = 0;
-       }
-}
-
-int load_midi_file(const char *path) {
-       unsigned char tmp[256];
-       unsigned int tracks=0;
-       unsigned int tracki=0;
-       int fd;
-
-       fd = open(path,O_RDONLY|O_BINARY);
-       if (fd < 0) {
-               printf("Failed to load file %s\n",path);
-               return 0;
-       }
-
-       ticks_per_quarter_note = 0;
-       while (read(fd,tmp,8) == 8) {
-               uint32_t sz;
-
-               sz =    ((uint32_t)tmp[4] << (uint32_t)24) |
-                       ((uint32_t)tmp[5] << (uint32_t)16) |
-                       ((uint32_t)tmp[6] << (uint32_t)8) |
-                       ((uint32_t)tmp[7] << (uint32_t)0);
-               if (!memcmp(tmp,"MThd",4)) {
-                       unsigned short t,tdiv;
-
-                       if (sz < 6 || sz > 255) {
-                               fprintf(stderr,"Invalid MThd size %lu\n",(unsigned long)sz);
-                               goto err;
-                       }
-                       if (read(fd,tmp,(int)sz) != (int)sz) {
-                               fprintf(stderr,"MThd read error\n");
-                               goto err;
-                       }
-
-                       /* byte 0-1 = format type (0,1 or 2) */
-                       /* byte 2-3 = number of tracks */
-                       /* byte 4-5 = time divison */
-                       t = tmp[1] | (tmp[0] << 8);
-                       if (t > 1) {
-                               fprintf(stderr,"MThd type %u not supported\n",t);
-                               goto err; /* we only take type 0 or 1, don't support 2 */
-                       }
-                       tracks = tmp[3] | (tmp[2] << 8);
-                       if (tracks > MIDI_MAX_TRACKS) {
-                               fprintf(stderr,"MThd too many (%u) tracks\n",tracks);
-                               goto err;
-                       }
-                       tdiv = tmp[5] | (tmp[4] << 8);
-                       if (tdiv & 0x8000) {
-                               fprintf(stderr,"MThd SMPTE time division not supported\n");
-                               goto err; /* we do not support the SMPTE form */
-                       }
-                       if (tdiv == 0) {
-                               fprintf(stderr,"MThd time division == 0\n");
-                               goto err;
-                       }
-                       ticks_per_quarter_note = tdiv;
-               }
-               else if (!memcmp(tmp,"MTrk",4)) {
-                       if (sz == 0UL) continue;
-#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))
-                       if (sz > (640UL << 10UL)) goto err; /* 640KB */
-#elif TARGET_MSDOS == 32
-                       if (sz > (1UL << 20UL)) goto err; /* 1MB */
-#else
-                       if (sz > (60UL << 10UL)) goto err; /* 60KB */
-#endif
-                       if (tracki >= MIDI_MAX_TRACKS) goto err;
-#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))
-                       {
-                               unsigned segv;
-
-                               /* NTS: _fmalloc() is still limited to 64KB sizes */
-                               if (_dos_allocmem((unsigned)((sz+15UL)>>4UL),&segv) != 0) goto err;
-                               midi_trk[tracki].raw = MK_FP(segv,0);
-                       }
-#else
-                       midi_trk[tracki].raw = malloc(sz);
-#endif
-                       if (midi_trk[tracki].raw == NULL) goto err;
-                       midi_trk[tracki].read = midi_trk[tracki].raw;
-#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))
-                       {
-                               unsigned char far *p = midi_trk[tracki].raw;
-                               unsigned long rem = (unsigned long)sz;
-                               unsigned long cando;
-                               unsigned read;
-
-                               while (rem != 0UL) {
-                                       read = 0;
-
-                                       cando = 0x10000UL - (unsigned long)FP_OFF(p);
-                                       if (cando > rem) cando = rem;
-                                       if (cando > 0xFFFFUL) cando = 0xFFFFUL; /* we're limited to 64KB-1 of reading */
-
-                                       if (_dos_read(fd,p,(unsigned)cando,&read) != 0) goto err;
-                                       if (read != (unsigned)cando) goto err;
-
-                                       rem -= cando;
-                                       if ((((unsigned long)FP_OFF(p))+cando) == 0x10000UL)
-                                               p = MK_FP(FP_SEG(p)+0x1000,0);
-                                       else
-                                               p += (unsigned)cando;
-                               }
-
-                               cando = farptr2phys(p);
-                               midi_trk[tracki].fence = MK_FP(cando>>4,cando&0xF);
-                       }
-#else
-                       midi_trk[tracki].fence = midi_trk[tracki].raw + (unsigned)sz;
-                       if (read(fd,midi_trk[tracki].raw,(unsigned)sz) != (int)sz) goto err;
-#endif
-                       tracki++;
-               }
-               else {
-                       fprintf(stderr,"Unknown MIDI chunk %c%c%c%c\n",tmp[0],tmp[1],tmp[2],tmp[3]);
-                       goto err;
-               }
-       }
-       if (tracki == 0 || ticks_per_quarter_note == 0) goto err;
-       midi_trk_count = tracki;
-
-       fprintf(stderr,"Ticks per quarter note: %u\n",ticks_per_quarter_note);
-
-       close(fd);
-       return 1;
-err:
-       close(fd);
-       return 0;
-}
-
-int main(int argc,char **argv) {
-       unsigned long ptick;
-       int i,c;
-
-       printf("ADLIB FM test program\n");
-       if (argc < 2) {
-               printf("You must specify a MIDI file to play\n");
-               return 1;
-       }
-
-       if (!probe_vga()) {
-               printf("Cannot init VGA\n");
-               return 1;
-       }
-       if (!init_adlib()) {
-               printf("Cannot init library\n");
-               return 1;
-       }
-       if (!probe_8254()) { /* we need the timer to keep time with the music */
-               printf("8254 timer not found\n");
-               return 1;
-       }
-
-       for (i=0;i < MIDI_MAX_TRACKS;i++) {
-               midi_trk[i].raw = NULL;
-               midi_trk[i].read = NULL;
-               midi_trk[i].fence = NULL;
-       }
-
-       if (load_midi_file(argv[1]) == 0) {
-               printf("Failed to load MIDI\n");
-               return 1;
-       }
-
-       write_8254_system_timer(T8254_REF_CLOCK_HZ / 100); /* tick faster at 100Hz please */
-       irq0_cnt = 0;
-       irq0_add = 182;
-       irq0_max = 1000; /* about 18.2Hz */
-       old_irq0 = _dos_getvect(8);/*IRQ0*/
-       _dos_setvect(8,irq0);
-
-       adlib_shut_up();
-       midi_reset_channels();
-       midi_reset_tracks();
-       _cli();
-       irq0_ticks = ptick = 0;
-       _sti();
-       midi_playing = 1;
-
-       while (1) {
-               unsigned long adv;
-
-               _cli();
-               adv = irq0_ticks - ptick;
-               if (adv >= 100UL) adv = 100UL;
-               ptick = irq0_ticks;
-               _sti();
-
-               while (adv != 0) {
-                       midi_tick();
-                       adv--;
-               }
-
-               if (kbhit()) {
-                       c = getch();
-                       if (c == 0) c = getch() << 8;
-
-                       if (c == 27) {
-                               break;
-                       }
-               }
-       }
-
-       midi_playing = 0;
-       adlib_shut_up();
-       shutdown_adlib();
-       _dos_setvect(8,old_irq0);
-       write_8254_system_timer(0); /* back to normal 18.2Hz */
-
-       for (i=0;i < MIDI_MAX_TRACKS;i++) {
-               if (midi_trk[i].raw) {
-#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))
-                       _dos_freemem(FP_SEG(midi_trk[i].raw)); /* NTS: Because we allocated with _dos_allocmem */
-#else
-                       free(midi_trk[i].raw);
-#endif
-                       midi_trk[i].raw = NULL;
-               }
-               midi_trk[i].fence = NULL;
-               midi_trk[i].read = NULL;
-       }
-
-       return 0;
-}
+/* midi.c\r
+ *\r
+ * Adlib OPL2/OPL3 FM synthesizer chipset test program.\r
+ * Play MIDI file using the OPLx synthesizer (well, poorly anyway)\r
+ * (C) 2010-2012 Jonathan Campbell.\r
+ * Hackipedia DOS library.\r
+ *\r
+ * This code is licensed under the LGPL.\r
+ * <insert LGPL legal text here>\r
+ *\r
+ * Compiles for intended target environments:\r
+ *   - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]\r
+ */\r
\r
+#include <stdio.h>\r
+#include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+#include <malloc.h>\r
+#include <ctype.h>\r
+#include <fcntl.h>\r
+#include <math.h>\r
+#include <dos.h>\r
+\r
+#include "src/lib/doslib/vga.h"\r
+#include "src/lib/doslib/dos.h"\r
+#include "src/lib/doslib/8254.h"               /* 8254 timer */\r
+#include "src/lib/doslib/8259.h"\r
+#include "src/lib/doslib/vgagui.h"\r
+#include "src/lib/doslib/vgatty.h"\r
+#include "src/lib/doslib/adlib.h"\r
+\r
+/* one per OPL channel */\r
+struct midi_note {\r
+       unsigned char           note_number;\r
+       unsigned char           note_velocity;\r
+       unsigned char           note_track;     /* from what MIDI track */\r
+       unsigned char           note_channel;   /* from what MIDI channel */\r
+       unsigned int            busy:1;         /* if occupied */\r
+};\r
+\r
+struct midi_channel {\r
+       unsigned char           program;\r
+};\r
+\r
+struct midi_track {\r
+       /* track data, raw */\r
+       unsigned char*          raw;            /* raw data base */\r
+       unsigned char*          fence;          /* raw data end (last byte + 1) */\r
+       unsigned char*          read;           /* raw data read ptr */\r
+       /* state */\r
+       unsigned long           us_per_quarter_note; /* Microseconds per quarter note (def 120 BPM) */\r
+       unsigned long           us_tick_cnt_mtpq; /* Microseconds advanced (up to 10000 us or one unit at 100Hz) x ticks per quarter note */\r
+       unsigned long           wait;\r
+       unsigned char           last_status;    /* MIDI last status byte */\r
+       unsigned int            eof:1;          /* we hit the end of the track */\r
+};\r
+\r
+#define MIDI_MAX_CHANNELS      16\r
+#define MIDI_MAX_TRACKS                64\r
+\r
+struct midi_note               midi_notes[ADLIB_FM_VOICES];\r
+struct midi_channel            midi_ch[MIDI_MAX_CHANNELS];\r
+struct midi_track              midi_trk[MIDI_MAX_TRACKS];\r
+static unsigned int            midi_trk_count=0;\r
+static volatile unsigned char  midi_playing=0;\r
+\r
+/* MIDI params. Nobody ever said it was a straightforward standard!\r
+ * NTS: These are for reading reference. Internally we convert everything to 100Hz time base. */\r
+static unsigned int ticks_per_quarter_note=0;  /* "Ticks per beat" */\r
+\r
+static void (interrupt *old_irq0)();\r
+static volatile unsigned long irq0_ticks=0;\r
+static volatile unsigned int irq0_cnt=0,irq0_add=0,irq0_max=0;\r
+\r
+#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))\r
+static inline unsigned long farptr2phys(unsigned char far *p) { /* take 16:16 pointer convert to physical memory address */\r
+       return ((unsigned long)FP_SEG(p) << 4UL) + ((unsigned long)FP_OFF(p));\r
+}\r
+#endif\r
+\r
+static inline unsigned char midi_trk_read(struct midi_track *t) {\r
+       unsigned char c;\r
+\r
+       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */\r
+       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence) {\r
+               t->eof = 1;\r
+               return 0xFF;\r
+       }\r
+\r
+       c = *(t->read);\r
+#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))\r
+       if (FP_OFF(t->read) >= 0xF) /* 16:16 far pointer aware (NTS: Programs reassigning this pointer MUST normalize the FAR pointer) */\r
+               t->read = MK_FP(FP_SEG(t->read)+0x1,0);\r
+       else\r
+               t->read++;\r
+#else\r
+       t->read++;\r
+#endif\r
+       return c;\r
+}\r
+\r
+void midi_trk_end(struct midi_track *t) {\r
+       t->wait = ~0UL;\r
+       t->read = t->fence;\r
+}\r
+\r
+void midi_trk_skip(struct midi_track *t,unsigned long len) {\r
+       unsigned long rem;\r
+\r
+       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */\r
+       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence)\r
+               return;\r
+\r
+       if (len > 0xFFF0UL) {\r
+               midi_trk_end(t);\r
+               return;\r
+       }\r
+#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))\r
+       {\r
+               unsigned long tt;\r
+\r
+               tt = farptr2phys(t->read);\r
+               rem = farptr2phys(t->fence) - tt;\r
+               if (rem > len) rem = len;\r
+               tt += rem;\r
+               t->read = MK_FP(tt>>4,tt&0xF);\r
+       }\r
+#else\r
+       rem = (unsigned long)(t->fence - t->read);\r
+       if (len > rem) len = rem;\r
+       t->read += len;\r
+#endif\r
+}\r
+\r
+static const uint32_t midikeys_freqs[0x80] = {\r
+       0x00082d01,     /* key 0 = 8.17579891564371Hz */\r
+       0x0008a976,     /* key 1 = 8.66195721802725Hz */\r
+       0x00092d51,     /* key 2 = 9.17702399741899Hz */\r
+       0x0009b904,     /* key 3 = 9.72271824131503Hz */\r
+       0x000a4d05,     /* key 4 = 10.3008611535272Hz */\r
+       0x000ae9d3,     /* key 5 = 10.9133822322814Hz */\r
+       0x000b8ff4,     /* key 6 = 11.5623257097386Hz */\r
+       0x000c3ff6,     /* key 7 = 12.2498573744297Hz */\r
+       0x000cfa70,     /* key 8 = 12.9782717993733Hz */\r
+       0x000dc000,     /* key 9 = 13.75Hz */\r
+       0x000e914f,     /* key 10 = 14.5676175474403Hz */\r
+       0x000f6f11,     /* key 11 = 15.4338531642539Hz */\r
+       0x00105a02,     /* key 12 = 16.3515978312874Hz */\r
+       0x001152ec,     /* key 13 = 17.3239144360545Hz */\r
+       0x00125aa2,     /* key 14 = 18.354047994838Hz */\r
+       0x00137208,     /* key 15 = 19.4454364826301Hz */\r
+       0x00149a0a,     /* key 16 = 20.6017223070544Hz */\r
+       0x0015d3a6,     /* key 17 = 21.8267644645627Hz */\r
+       0x00171fe9,     /* key 18 = 23.1246514194771Hz */\r
+       0x00187fed,     /* key 19 = 24.4997147488593Hz */\r
+       0x0019f4e0,     /* key 20 = 25.9565435987466Hz */\r
+       0x001b8000,     /* key 21 = 27.5Hz */\r
+       0x001d229e,     /* key 22 = 29.1352350948806Hz */\r
+       0x001ede22,     /* key 23 = 30.8677063285078Hz */\r
+       0x0020b404,     /* key 24 = 32.7031956625748Hz */\r
+       0x0022a5d8,     /* key 25 = 34.647828872109Hz */\r
+       0x0024b545,     /* key 26 = 36.7080959896759Hz */\r
+       0x0026e410,     /* key 27 = 38.8908729652601Hz */\r
+       0x00293414,     /* key 28 = 41.2034446141087Hz */\r
+       0x002ba74d,     /* key 29 = 43.6535289291255Hz */\r
+       0x002e3fd2,     /* key 30 = 46.2493028389543Hz */\r
+       0x0030ffda,     /* key 31 = 48.9994294977187Hz */\r
+       0x0033e9c0,     /* key 32 = 51.9130871974931Hz */\r
+       0x00370000,     /* key 33 = 55Hz */\r
+       0x003a453d,     /* key 34 = 58.2704701897612Hz */\r
+       0x003dbc44,     /* key 35 = 61.7354126570155Hz */\r
+       0x00416809,     /* key 36 = 65.4063913251497Hz */\r
+       0x00454bb0,     /* key 37 = 69.295657744218Hz */\r
+       0x00496a8b,     /* key 38 = 73.4161919793519Hz */\r
+       0x004dc820,     /* key 39 = 77.7817459305202Hz */\r
+       0x00526829,     /* key 40 = 82.4068892282175Hz */\r
+       0x00574e9b,     /* key 41 = 87.307057858251Hz */\r
+       0x005c7fa4,     /* key 42 = 92.4986056779086Hz */\r
+       0x0061ffb5,     /* key 43 = 97.9988589954373Hz */\r
+       0x0067d380,     /* key 44 = 103.826174394986Hz */\r
+       0x006e0000,     /* key 45 = 110Hz */\r
+       0x00748a7b,     /* key 46 = 116.540940379522Hz */\r
+       0x007b7888,     /* key 47 = 123.470825314031Hz */\r
+       0x0082d012,     /* key 48 = 130.812782650299Hz */\r
+       0x008a9760,     /* key 49 = 138.591315488436Hz */\r
+       0x0092d517,     /* key 50 = 146.832383958704Hz */\r
+       0x009b9041,     /* key 51 = 155.56349186104Hz */\r
+       0x00a4d053,     /* key 52 = 164.813778456435Hz */\r
+       0x00ae9d36,     /* key 53 = 174.614115716502Hz */\r
+       0x00b8ff49,     /* key 54 = 184.997211355817Hz */\r
+       0x00c3ff6a,     /* key 55 = 195.997717990875Hz */\r
+       0x00cfa700,     /* key 56 = 207.652348789973Hz */\r
+       0x00dc0000,     /* key 57 = 220Hz */\r
+       0x00e914f6,     /* key 58 = 233.081880759045Hz */\r
+       0x00f6f110,     /* key 59 = 246.941650628062Hz */\r
+       0x0105a025,     /* key 60 = 261.625565300599Hz */\r
+       0x01152ec0,     /* key 61 = 277.182630976872Hz */\r
+       0x0125aa2e,     /* key 62 = 293.664767917408Hz */\r
+       0x01372082,     /* key 63 = 311.126983722081Hz */\r
+       0x0149a0a7,     /* key 64 = 329.62755691287Hz */\r
+       0x015d3a6d,     /* key 65 = 349.228231433004Hz */\r
+       0x0171fe92,     /* key 66 = 369.994422711634Hz */\r
+       0x0187fed4,     /* key 67 = 391.995435981749Hz */\r
+       0x019f4e00,     /* key 68 = 415.304697579945Hz */\r
+       0x01b80000,     /* key 69 = 440Hz */\r
+       0x01d229ec,     /* key 70 = 466.16376151809Hz */\r
+       0x01ede220,     /* key 71 = 493.883301256124Hz */\r
+       0x020b404a,     /* key 72 = 523.251130601197Hz */\r
+       0x022a5d81,     /* key 73 = 554.365261953744Hz */\r
+       0x024b545c,     /* key 74 = 587.329535834815Hz */\r
+       0x026e4104,     /* key 75 = 622.253967444162Hz */\r
+       0x0293414f,     /* key 76 = 659.25511382574Hz */\r
+       0x02ba74da,     /* key 77 = 698.456462866008Hz */\r
+       0x02e3fd24,     /* key 78 = 739.988845423269Hz */\r
+       0x030ffda9,     /* key 79 = 783.990871963499Hz */\r
+       0x033e9c01,     /* key 80 = 830.60939515989Hz */\r
+       0x03700000,     /* key 81 = 880Hz */\r
+       0x03a453d8,     /* key 82 = 932.32752303618Hz */\r
+       0x03dbc440,     /* key 83 = 987.766602512248Hz */\r
+       0x04168094,     /* key 84 = 1046.50226120239Hz */\r
+       0x0454bb03,     /* key 85 = 1108.73052390749Hz */\r
+       0x0496a8b8,     /* key 86 = 1174.65907166963Hz */\r
+       0x04dc8208,     /* key 87 = 1244.50793488832Hz */\r
+       0x0526829e,     /* key 88 = 1318.51022765148Hz */\r
+       0x0574e9b5,     /* key 89 = 1396.91292573202Hz */\r
+       0x05c7fa49,     /* key 90 = 1479.97769084654Hz */\r
+       0x061ffb53,     /* key 91 = 1567.981743927Hz */\r
+       0x067d3802,     /* key 92 = 1661.21879031978Hz */\r
+       0x06e00000,     /* key 93 = 1760Hz */\r
+       0x0748a7b1,     /* key 94 = 1864.65504607236Hz */\r
+       0x07b78880,     /* key 95 = 1975.5332050245Hz */\r
+       0x082d0128,     /* key 96 = 2093.00452240479Hz */\r
+       0x08a97607,     /* key 97 = 2217.46104781498Hz */\r
+       0x092d5171,     /* key 98 = 2349.31814333926Hz */\r
+       0x09b90410,     /* key 99 = 2489.01586977665Hz */\r
+       0x0a4d053c,     /* key 100 = 2637.02045530296Hz */\r
+       0x0ae9d36b,     /* key 101 = 2793.82585146403Hz */\r
+       0x0b8ff493,     /* key 102 = 2959.95538169308Hz */\r
+       0x0c3ff6a7,     /* key 103 = 3135.96348785399Hz */\r
+       0x0cfa7005,     /* key 104 = 3322.43758063956Hz */\r
+       0x0dc00000,     /* key 105 = 3520Hz */\r
+       0x0e914f62,     /* key 106 = 3729.31009214472Hz */\r
+       0x0f6f1100,     /* key 107 = 3951.06641004899Hz */\r
+       0x105a0250,     /* key 108 = 4186.00904480958Hz */\r
+       0x1152ec0e,     /* key 109 = 4434.92209562995Hz */\r
+       0x125aa2e3,     /* key 110 = 4698.63628667852Hz */\r
+       0x13720820,     /* key 111 = 4978.03173955329Hz */\r
+       0x149a0a79,     /* key 112 = 5274.04091060592Hz */\r
+       0x15d3a6d6,     /* key 113 = 5587.65170292806Hz */\r
+       0x171fe927,     /* key 114 = 5919.91076338615Hz */\r
+       0x187fed4e,     /* key 115 = 6271.92697570799Hz */\r
+       0x19f4e00a,     /* key 116 = 6644.87516127912Hz */\r
+       0x1b800000,     /* key 117 = 7040Hz */\r
+       0x1d229ec4,     /* key 118 = 7458.62018428944Hz */\r
+       0x1ede2200,     /* key 119 = 7902.13282009799Hz */\r
+       0x20b404a1,     /* key 120 = 8372.01808961916Hz */\r
+       0x22a5d81c,     /* key 121 = 8869.84419125991Hz */\r
+       0x24b545c7,     /* key 122 = 9397.27257335704Hz */\r
+       0x26e41040,     /* key 123 = 9956.06347910659Hz */\r
+       0x293414f2,     /* key 124 = 10548.0818212118Hz */\r
+       0x2ba74dac,     /* key 125 = 11175.3034058561Hz */\r
+       0x2e3fd24f,     /* key 126 = 11839.8215267723Hz */\r
+       0x30ffda9c      /* key 127 = 12543.853951416Hz */\r
+};\r
+\r
+static uint32_t midi_note_freq(struct midi_channel *ch,unsigned char key) {\r
+       return midikeys_freqs[key&0x7F];\r
+}\r
+\r
+static struct midi_note *get_fm_note(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char do_alloc) {\r
+       unsigned int tch = (unsigned int)(t - midi_trk); /* pointer math */\r
+       unsigned int ach = (unsigned int)(ch - midi_ch); /* pointer math */\r
+       unsigned int i,freen=~0;\r
+\r
+       for (i=0;i < ADLIB_FM_VOICES;i++) {\r
+               if (midi_notes[i].busy) {\r
+                       if (midi_notes[i].note_channel == ach && midi_notes[i].note_track == tch && midi_notes[i].note_number == key)\r
+                               return &midi_notes[i];\r
+               }\r
+               else {\r
+                       if (freen == ~0) freen = i;\r
+               }\r
+       }\r
+\r
+       if (do_alloc && freen != ~0) return &midi_notes[freen];\r
+       return NULL;\r
+}\r
+\r
+static void drop_fm_note(struct midi_channel *ch,unsigned char key) {\r
+       unsigned int ach = (unsigned int)(ch - midi_ch); /* pointer math */\r
+       unsigned int i;\r
+\r
+       for (i=0;i < ADLIB_FM_VOICES;i++) {\r
+               if (midi_notes[i].busy && midi_notes[i].note_channel == ach) {\r
+                       midi_notes[i].busy = 0;\r
+                       break;\r
+               }\r
+       }\r
+}\r
+\r
+static inline void on_key_aftertouch(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {\r
+       struct midi_note *note = get_fm_note(t,ch,key,/*do_alloc*/0);\r
+       uint32_t freq = midi_note_freq(ch,key);\r
+       unsigned int ach;\r
+\r
+       if (note == NULL) return;\r
+\r
+       note->busy = 1;\r
+       note->note_number = key;\r
+       note->note_velocity = vel;\r
+       note->note_track = (unsigned int)(t - midi_trk);\r
+       note->note_channel = (unsigned int)(ch - midi_ch);\r
+       ach = (unsigned int)(note - midi_notes); /* which FM channel? */\r
+       adlib_freq_to_fm_op(&adlib_fm[ach].mod,(double)freq / 65536);\r
+       adlib_fm[ach].mod.attack_rate = vel >> 3; /* 0-127 to 0-15 */\r
+       adlib_fm[ach].mod.sustain_level = vel >> 3;\r
+       adlib_fm[ach].mod.key_on = 1;\r
+       adlib_update_groupA0(ach,&adlib_fm[ach]);\r
+}\r
+\r
+static inline void on_key_on(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {\r
+       struct midi_note *note = get_fm_note(t,ch,key,/*do_alloc*/1);\r
+       uint32_t freq = midi_note_freq(ch,key);\r
+       unsigned int ach;\r
+\r
+       /* HACK: Ignore percussion */\r
+       if ((ch->program >= 8 && ch->program <= 15)/*Chromatic percussion*/ ||\r
+               (ch->program >= 112 && ch->program <= 119)/*Percussive*/ ||\r
+               ch == &midi_ch[9]/*MIDI channel 10 (DAMN YOU 1-BASED COUNTING)*/)\r
+               return;\r
+\r
+       if (note == NULL) {\r
+               /* then we'll have to knock one off to make room */\r
+               drop_fm_note(ch,key);\r
+               note = get_fm_note(t,ch,key,1);\r
+               if (note == NULL) return;\r
+       }\r
+\r
+       note->busy = 1;\r
+       note->note_number = key;\r
+       note->note_velocity = vel;\r
+       note->note_track = (unsigned int)(t - midi_trk);\r
+       note->note_channel = (unsigned int)(ch - midi_ch);\r
+       ach = (unsigned int)(note - midi_notes); /* which FM channel? */\r
+       adlib_freq_to_fm_op(&adlib_fm[ach].mod,(double)freq / 65536);\r
+       adlib_fm[ach].mod.attack_rate = vel >> 3; /* 0-127 to 0-15 */\r
+       adlib_fm[ach].mod.sustain_level = vel >> 3;\r
+       adlib_fm[ach].mod.key_on = 1;\r
+       adlib_update_groupA0(ach,&adlib_fm[ach]);\r
+}\r
+\r
+static inline void on_key_off(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {\r
+       struct midi_note *note = get_fm_note(t,ch,key,/*do_alloc*/0);\r
+       uint32_t freq = midi_note_freq(ch,key);\r
+       unsigned int ach;\r
+\r
+       if (note == NULL) return;\r
+\r
+       note->busy = 0;\r
+       ach = (unsigned int)(note - midi_notes); /* which FM channel? */\r
+       adlib_freq_to_fm_op(&adlib_fm[ach].mod,(double)freq / 65536);\r
+       adlib_fm[ach].mod.attack_rate = vel >> 3; /* 0-127 to 0-15 */\r
+       adlib_fm[ach].mod.sustain_level = vel >> 3;\r
+       adlib_fm[ach].mod.key_on = 0;\r
+       adlib_update_groupA0(ach,&adlib_fm[ach]);\r
+}\r
+\r
+static inline void on_control_change(struct midi_track *t,struct midi_channel *ch,unsigned char num,unsigned char val) {\r
+}\r
+\r
+static inline void on_program_change(struct midi_track *t,struct midi_channel *ch,unsigned char inst) {\r
+       ch->program = inst;\r
+}\r
+\r
+static inline void on_channel_aftertouch(struct midi_track *t,struct midi_channel *ch,unsigned char velocity) {\r
+}\r
+\r
+static inline void on_pitch_bend(struct midi_track *t,struct midi_channel *ch,int bend/*-8192 to 8192*/) {\r
+}\r
+\r
+unsigned long midi_trk_read_delta(struct midi_track *t) {\r
+       unsigned long tc = 0;\r
+       unsigned char c = 0,b;\r
+\r
+       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */\r
+       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence)\r
+               return tc;\r
+\r
+       while (c < 4) {\r
+               b = midi_trk_read(t);\r
+               tc = (tc << 7UL) + (unsigned long)(b&0x7F);\r
+               if (!(b&0x80)) break;\r
+               c++;\r
+       }\r
+\r
+       return tc;\r
+}\r
+\r
+void midi_tick_track(unsigned int i) {\r
+       struct midi_track *t = midi_trk + i;\r
+       struct midi_channel *ch;\r
+       unsigned char b,c,d;\r
+       int cnt=0;\r
+\r
+       /* NTS: 16-bit large/compact builds MUST compare pointers as unsigned long to compare FAR pointers correctly! */\r
+       if (t->read == NULL || (unsigned long)t->read >= (unsigned long)t->fence) {\r
+               t->eof = 1;\r
+               return;\r
+       }\r
+\r
+       t->us_tick_cnt_mtpq += 10000UL * (unsigned long)ticks_per_quarter_note;\r
+       while (t->us_tick_cnt_mtpq >= t->us_per_quarter_note) {\r
+               t->us_tick_cnt_mtpq -= t->us_per_quarter_note;\r
+               cnt++;\r
+\r
+               while (t->wait == 0) {\r
+                       if ((unsigned long)t->read >= (unsigned long)t->fence) {\r
+                               t->eof = 1;\r
+                               break;\r
+                       }\r
+\r
+                       /* read pointer should be pointing at MIDI event bytes, just after the time delay */\r
+                       b = midi_trk_read(t);\r
+                       if (b&0x80) {\r
+                               if (b < 0xF8) {\r
+                                       if (b >= 0xF0)\r
+                                               t->last_status = 0;\r
+                                       else\r
+                                               t->last_status = b;\r
+                               }\r
+                               if (b != 0x00 && ((b&0xF8) != 0xF0))\r
+                                       c = midi_trk_read(t);\r
+                       }\r
+                       else {\r
+                               /* blegh. last status */\r
+                               c = b;\r
+                               b = t->last_status;\r
+                       }\r
+                       switch (b>>4) {\r
+                               case 0x8: { /* note off */\r
+                                       d = midi_trk_read(t);\r
+                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */\r
+                                       on_key_off(t,ch,c,d);\r
+                                       } break;\r
+                               case 0x9: { /* note on */\r
+                                       d = midi_trk_read(t);\r
+                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */\r
+                                       if (d != 0) on_key_on(t,ch,c,d); /* "A Note On with a velocity of 0 is actually a note off" Bleh, really? */\r
+                                       else on_key_off(t,ch,c,d);\r
+                                       } break;\r
+                               case 0xA: { /* polyphonic aftertouch */\r
+                                       d = midi_trk_read(t);\r
+                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */\r
+                                       on_key_aftertouch(t,ch,c,d);\r
+                                       } break;\r
+                               case 0xB: { /* control change */\r
+                                       d = midi_trk_read(t);\r
+                                       ch = midi_ch + (b&0xF); /* c=key d=velocity */\r
+                                       on_control_change(t,ch,c,d);\r
+                                       } break;\r
+                               case 0xC: { /* program change */\r
+                                       on_program_change(t,ch,c); /* c=instrument d=not used */\r
+                                       } break;\r
+                               case 0xD: { /* channel aftertouch */\r
+                                       on_channel_aftertouch(t,ch,c); /* c=velocity d=not used */\r
+                                       } break;\r
+                               case 0xE: { /* pitch bend */\r
+                                       d = midi_trk_read(t);\r
+                                       on_pitch_bend(t,ch,((c&0x7F)|((d&0x7F)<<7))-8192); /* c=LSB d=MSB */\r
+                                       } break;\r
+                               case 0xF: { /* event */\r
+                                       if (b == 0xFF) {\r
+                                               if (c == 0x7F) { /* c=type d=len */\r
+                                                       unsigned long len = midi_trk_read_delta(t);\r
+//                                                     fprintf(stderr,"Type 0x7F len=%lu %p/%p/%p\n",len,t->raw,t->read,t->fence);\r
+                                                       if (len < 512UL) {\r
+                                                               /* unknown */\r
+                                                               midi_trk_skip(t,len);\r
+                                                       }\r
+                                                       else {\r
+                                                               midi_trk_end(t);\r
+                                                       }\r
+                                               }\r
+                                               else if (c < 0x7F) {\r
+                                                       d = midi_trk_read(t);\r
+\r
+                                                       if (c == 0x51 && d >= 3) {\r
+                                                               d -= 3;\r
+                                                               t->us_per_quarter_note = ((unsigned long)midi_trk_read(t)<<16UL)+\r
+                                                                       ((unsigned long)midi_trk_read(t)<<8UL)+\r
+                                                                       ((unsigned long)midi_trk_read(t)<<0UL);\r
+\r
+                                                               if (1/*TODO: If format 0 or format 1*/) {\r
+                                                                       /* Ugh. Unless format 2, the tempo applies to all tracks */\r
+                                                                       int j;\r
+\r
+                                                                       for (j=0;j < midi_trk_count;j++) {\r
+                                                                               if (j != i) midi_trk[j].us_per_quarter_note =\r
+                                                                                       t->us_per_quarter_note;\r
+                                                                       }\r
+                                                               }\r
+                                                       }\r
+                                                       else {\r
+//                                                             fprintf(stderr,"Type 0x%02x len=%lu %p/%p/%p\n",c,d,t->raw,t->read,t->fence);\r
+                                                       }\r
+\r
+                                                       midi_trk_skip(t,d);\r
+                                               }\r
+                                               else {\r
+                                                       fprintf(stderr,"t=%u Unknown MIDI f message 0x%02x 0x%02x %p/%p/%p\n",i,b,c,t->raw,t->read,t->fence);\r
+                                               }\r
+                                       }\r
+                                       else {\r
+                                               unsigned long len = midi_trk_read_delta(t);\r
+//                                             fprintf(stderr,"Sysex len=%lu %p/%p/%p\n",len,t->raw,t->read,t->fence);\r
+                                               midi_trk_skip(t,len);\r
+                                       }\r
+                                       } break;\r
+                               default:\r
+                                       if (b != 0x00) {\r
+                                               fprintf(stderr,"t=%u Unknown MIDI message 0x%02x at %p/%p/%p\n",i,b,t->raw,t->read,t->fence);\r
+                                               midi_trk_end(t);\r
+                                       }\r
+                                       break;\r
+                       };\r
+\r
+                       /* and then read the next event */\r
+                       t->wait = midi_trk_read_delta(t);\r
+               }\r
+               if (t->wait != 0) {\r
+                       t->wait--;\r
+               }\r
+       }\r
+}\r
+\r
+void adlib_shut_up();\r
+void midi_reset_tracks();\r
+void midi_reset_channels();\r
+\r
+void midi_tick() {\r
+       if (midi_playing) {\r
+               unsigned int i;\r
+               int eof=0;\r
+\r
+               for (i=0;i < midi_trk_count;i++) {\r
+                       midi_tick_track(i);\r
+                       eof += midi_trk[i].eof?1:0;\r
+               }\r
+\r
+               if (eof >= midi_trk_count) {\r
+                       adlib_shut_up();\r
+                       midi_reset_tracks();\r
+                       midi_reset_channels();\r
+               }\r
+       }\r
+}\r
+\r
+/* WARNING: subroutine call in interrupt handler. make sure you compile with -zu flag for large/compact memory models */\r
+void interrupt irq0() {\r
+//     midi_tick();\r
+       irq0_ticks++;\r
+       if ((irq0_cnt += irq0_add) >= irq0_max) {\r
+               irq0_cnt -= irq0_max;\r
+               old_irq0();\r
+       }\r
+       else {\r
+               p8259_OCW2(0,P8259_OCW2_NON_SPECIFIC_EOI);\r
+       }\r
+}\r
+\r
+void adlib_shut_up() {\r
+       int i;\r
+\r
+       memset(adlib_fm,0,sizeof(adlib_fm));\r
+       memset(&adlib_reg_bd,0,sizeof(adlib_reg_bd));\r
+       for (i=0;i < adlib_fm_voices;i++) {\r
+               struct adlib_fm_operator *f;\r
+               f = &adlib_fm[i].mod;\r
+               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;\r
+               f = &adlib_fm[i].car;\r
+               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;\r
+       }\r
+\r
+       for (i=0;i < adlib_fm_voices;i++) {\r
+               struct adlib_fm_operator *f;\r
+\r
+               midi_notes[i].busy = 0;\r
+               midi_notes[i].note_channel = 0;\r
+\r
+               f = &adlib_fm[i].mod;\r
+               f->mod_multiple = 1;\r
+               f->total_level = 63 - 16;\r
+               f->attack_rate = 15;\r
+               f->decay_rate = 4;\r
+               f->sustain_level = 0;\r
+               f->release_rate = 8;\r
+               f->f_number = 400;\r
+               f->sustain = 1;\r
+               f->octave = 4;\r
+               f->key_on = 0;\r
+\r
+               f = &adlib_fm[i].car;\r
+               f->mod_multiple = 1;\r
+               f->total_level = 63 - 16;\r
+               f->attack_rate = 15;\r
+               f->decay_rate = 4;\r
+               f->sustain_level = 0;\r
+               f->release_rate = 8;\r
+               f->f_number = 0;\r
+               f->sustain = 1;\r
+               f->octave = 0;\r
+               f->key_on = 0;\r
+       }\r
+\r
+       adlib_apply_all();\r
+}\r
+\r
+void midi_reset_track(unsigned int i) {\r
+       struct midi_track *t;\r
+\r
+       if (i >= MIDI_MAX_TRACKS) return;\r
+       t = &midi_trk[i];\r
+       t->eof = 0;\r
+       t->last_status = 0;\r
+       t->us_tick_cnt_mtpq = 0;\r
+       t->us_per_quarter_note = (60000000UL / 120UL); /* 120BPM */\r
+       t->read = midi_trk[i].raw;\r
+       t->wait = midi_trk_read_delta(t); /* and then the read pointer will point at the MIDI event when wait counts down */\r
+}\r
+\r
+void midi_reset_tracks() {\r
+       int i;\r
+\r
+       for (i=0;i < midi_trk_count;i++)\r
+               midi_reset_track(i);\r
+}\r
+\r
+void midi_reset_channels() {\r
+       int i;\r
+\r
+       for (i=0;i < MIDI_MAX_CHANNELS;i++) {\r
+               midi_ch[i].program = 0;\r
+       }\r
+}\r
+\r
+int load_midi_file(const char *path) {\r
+       unsigned char tmp[256];\r
+       unsigned int tracks=0;\r
+       unsigned int tracki=0;\r
+       int fd;\r
+\r
+       fd = open(path,O_RDONLY|O_BINARY);\r
+       if (fd < 0) {\r
+               printf("Failed to load file %s\n",path);\r
+               return 0;\r
+       }\r
+\r
+       ticks_per_quarter_note = 0;\r
+       while (read(fd,tmp,8) == 8) {\r
+               uint32_t sz;\r
+\r
+               sz =    ((uint32_t)tmp[4] << (uint32_t)24) |\r
+                       ((uint32_t)tmp[5] << (uint32_t)16) |\r
+                       ((uint32_t)tmp[6] << (uint32_t)8) |\r
+                       ((uint32_t)tmp[7] << (uint32_t)0);\r
+               if (!memcmp(tmp,"MThd",4)) {\r
+                       unsigned short t,tdiv;\r
+\r
+                       if (sz < 6 || sz > 255) {\r
+                               fprintf(stderr,"Invalid MThd size %lu\n",(unsigned long)sz);\r
+                               goto err;\r
+                       }\r
+                       if (read(fd,tmp,(int)sz) != (int)sz) {\r
+                               fprintf(stderr,"MThd read error\n");\r
+                               goto err;\r
+                       }\r
+\r
+                       /* byte 0-1 = format type (0,1 or 2) */\r
+                       /* byte 2-3 = number of tracks */\r
+                       /* byte 4-5 = time divison */\r
+                       t = tmp[1] | (tmp[0] << 8);\r
+                       if (t > 1) {\r
+                               fprintf(stderr,"MThd type %u not supported\n",t);\r
+                               goto err; /* we only take type 0 or 1, don't support 2 */\r
+                       }\r
+                       tracks = tmp[3] | (tmp[2] << 8);\r
+                       if (tracks > MIDI_MAX_TRACKS) {\r
+                               fprintf(stderr,"MThd too many (%u) tracks\n",tracks);\r
+                               goto err;\r
+                       }\r
+                       tdiv = tmp[5] | (tmp[4] << 8);\r
+                       if (tdiv & 0x8000) {\r
+                               fprintf(stderr,"MThd SMPTE time division not supported\n");\r
+                               goto err; /* we do not support the SMPTE form */\r
+                       }\r
+                       if (tdiv == 0) {\r
+                               fprintf(stderr,"MThd time division == 0\n");\r
+                               goto err;\r
+                       }\r
+                       ticks_per_quarter_note = tdiv;\r
+               }\r
+               else if (!memcmp(tmp,"MTrk",4)) {\r
+                       if (sz == 0UL) continue;\r
+#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))\r
+                       if (sz > (640UL << 10UL)) goto err; /* 640KB */\r
+#elif TARGET_MSDOS == 32\r
+                       if (sz > (1UL << 20UL)) goto err; /* 1MB */\r
+#else\r
+                       if (sz > (60UL << 10UL)) goto err; /* 60KB */\r
+#endif\r
+                       if (tracki >= MIDI_MAX_TRACKS) goto err;\r
+#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))\r
+                       {\r
+                               unsigned segv;\r
+\r
+                               /* NTS: _fmalloc() is still limited to 64KB sizes */\r
+                               if (_dos_allocmem((unsigned)((sz+15UL)>>4UL),&segv) != 0) goto err;\r
+                               midi_trk[tracki].raw = MK_FP(segv,0);\r
+                       }\r
+#else\r
+                       midi_trk[tracki].raw = malloc(sz);\r
+#endif\r
+                       if (midi_trk[tracki].raw == NULL) goto err;\r
+                       midi_trk[tracki].read = midi_trk[tracki].raw;\r
+#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))\r
+                       {\r
+                               unsigned char far *p = midi_trk[tracki].raw;\r
+                               unsigned long rem = (unsigned long)sz;\r
+                               unsigned long cando;\r
+                               unsigned read;\r
+\r
+                               while (rem != 0UL) {\r
+                                       read = 0;\r
+\r
+                                       cando = 0x10000UL - (unsigned long)FP_OFF(p);\r
+                                       if (cando > rem) cando = rem;\r
+                                       if (cando > 0xFFFFUL) cando = 0xFFFFUL; /* we're limited to 64KB-1 of reading */\r
+\r
+                                       if (_dos_read(fd,p,(unsigned)cando,&read) != 0) goto err;\r
+                                       if (read != (unsigned)cando) goto err;\r
+\r
+                                       rem -= cando;\r
+                                       if ((((unsigned long)FP_OFF(p))+cando) == 0x10000UL)\r
+                                               p = MK_FP(FP_SEG(p)+0x1000,0);\r
+                                       else\r
+                                               p += (unsigned)cando;\r
+                               }\r
+\r
+                               cando = farptr2phys(p);\r
+                               midi_trk[tracki].fence = MK_FP(cando>>4,cando&0xF);\r
+                       }\r
+#else\r
+                       midi_trk[tracki].fence = midi_trk[tracki].raw + (unsigned)sz;\r
+                       if (read(fd,midi_trk[tracki].raw,(unsigned)sz) != (int)sz) goto err;\r
+#endif\r
+                       tracki++;\r
+               }\r
+               else {\r
+                       fprintf(stderr,"Unknown MIDI chunk %c%c%c%c\n",tmp[0],tmp[1],tmp[2],tmp[3]);\r
+                       goto err;\r
+               }\r
+       }\r
+       if (tracki == 0 || ticks_per_quarter_note == 0) goto err;\r
+       midi_trk_count = tracki;\r
+\r
+       fprintf(stderr,"Ticks per quarter note: %u\n",ticks_per_quarter_note);\r
+\r
+       close(fd);\r
+       return 1;\r
+err:\r
+       close(fd);\r
+       return 0;\r
+}\r
+\r
+int main(int argc,char **argv) {\r
+       unsigned long ptick;\r
+       int i,c;\r
+\r
+       printf("ADLIB FM test program\n");\r
+       if (argc < 2) {\r
+               printf("You must specify a MIDI file to play\n");\r
+               return 1;\r
+       }\r
+\r
+       if (!probe_vga()) {\r
+               printf("Cannot init VGA\n");\r
+               return 1;\r
+       }\r
+       if (!init_adlib()) {\r
+               printf("Cannot init library\n");\r
+               return 1;\r
+       }\r
+       if (!probe_8254()) { /* we need the timer to keep time with the music */\r
+               printf("8254 timer not found\n");\r
+               return 1;\r
+       }\r
+\r
+       for (i=0;i < MIDI_MAX_TRACKS;i++) {\r
+               midi_trk[i].raw = NULL;\r
+               midi_trk[i].read = NULL;\r
+               midi_trk[i].fence = NULL;\r
+       }\r
+\r
+       if (load_midi_file(argv[1]) == 0) {\r
+               printf("Failed to load MIDI\n");\r
+               return 1;\r
+       }\r
+\r
+       write_8254_system_timer(T8254_REF_CLOCK_HZ / 100); /* tick faster at 100Hz please */\r
+       irq0_cnt = 0;\r
+       irq0_add = 182;\r
+       irq0_max = 1000; /* about 18.2Hz */\r
+       old_irq0 = _dos_getvect(8);/*IRQ0*/\r
+       _dos_setvect(8,irq0);\r
+\r
+       adlib_shut_up();\r
+       midi_reset_channels();\r
+       midi_reset_tracks();\r
+       _cli();\r
+       irq0_ticks = ptick = 0;\r
+       _sti();\r
+       midi_playing = 1;\r
+\r
+       while (1) {\r
+               unsigned long adv;\r
+\r
+               _cli();\r
+               adv = irq0_ticks - ptick;\r
+               if (adv >= 100UL) adv = 100UL;\r
+               ptick = irq0_ticks;\r
+               _sti();\r
+\r
+               while (adv != 0) {\r
+                       midi_tick();\r
+                       adv--;\r
+               }\r
+\r
+               if (kbhit()) {\r
+                       c = getch();\r
+                       if (c == 0) c = getch() << 8;\r
+\r
+                       if (c == 27) {\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+\r
+       midi_playing = 0;\r
+       adlib_shut_up();\r
+       shutdown_adlib();\r
+       _dos_setvect(8,old_irq0);\r
+       write_8254_system_timer(0); /* back to normal 18.2Hz */\r
+\r
+       for (i=0;i < MIDI_MAX_TRACKS;i++) {\r
+               if (midi_trk[i].raw) {\r
+#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))\r
+                       _dos_freemem(FP_SEG(midi_trk[i].raw)); /* NTS: Because we allocated with _dos_allocmem */\r
+#else\r
+                       free(midi_trk[i].raw);\r
+#endif\r
+                       midi_trk[i].raw = NULL;\r
+               }\r
+               midi_trk[i].fence = NULL;\r
+               midi_trk[i].read = NULL;\r
+       }\r
+\r
+       return 0;\r
+}\r
index 73b47057b54dd2825819ef00369366164407a64b..ade69519dd91a3b03368d933c2295b63fa0481a1 100755 (executable)
-/* miditest.c
- *
- * Adlib OPL2/OPL3 FM synthesizer chipset test program.
- * Play MIDI file using the OPLx synthesizer (well, poorly anyway)
- * (C) 2010-2012 Jonathan Campbell.
- * Hackipedia DOS library.
- *
- * This code is licensed under the LGPL.
- * <insert LGPL legal text here>
- *
- * Compiles for intended target environments:
- *   - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]
- */
-
-#include "src/lib/midi.h"
-
-int main(int argc,char **argv) {
-       unsigned long ptick;
-       int i,c;
-
-       printf("ADLIB FM test program\n");
-       if (argc < 2) {
-               printf("You must specify a MIDI file to play\n");
-               return 1;
-       }
-
-       /*if (!probe_vga()) {
-               printf("Cannot init VGA\n");
-               return 1;
-       }*/
-       if (!init_adlib()) {
-               printf("Cannot init library\n");
-               return 1;
-       }
-       if (!probe_8254()) { /* we need the timer to keep time with the music */
-               printf("8254 timer not found\n");
-               return 1;
-       }
-
-       for (i=0;i < MIDI_MAX_TRACKS;i++) {
-               midi_trk[i].raw = NULL;
-               midi_trk[i].read = NULL;
-               midi_trk[i].fence = NULL;
-       }
-
-       if (load_midi_file(argv[1]) == 0) {
-               printf("Failed to load MIDI\n");
-               return 1;
-       }
-
-       write_8254_system_timer(T8254_REF_CLOCK_HZ / 100); /* tick faster at 100Hz please */
-       irq0_cnt = 0;
-       irq0_add = 182;
-       irq0_max = 1000; /* about 18.2Hz */
-       old_irq0 = _dos_getvect(8);/*IRQ0*/
-       _dos_setvect(8,irq0);
-
-       //adlib_shut_up();
-       midi_reset_channels();
-       midi_reset_tracks();
-       _cli();
-       irq0_ticks = ptick = 0;
-       _sti();
-       midi_playing = 1;
-
-       while (1) {
-               unsigned long adv;
-
-               _cli();
-               adv = irq0_ticks - ptick;
-               //adv = ptick;
-               if (adv >= 100UL) adv = 100UL;
-               ptick = irq0_ticks;
-               //ptick++;
-               _sti();
-
-               while (adv != 0) {
-                       midi_tick();
-                       adv--;
-               }
-
-               if (kbhit()) {
-                       c = getch();
-                       if (c == 0) c = getch() << 8;
-
-                       if (c == 27) {
-                               break;
-                       }
-               }
-       }
-
-       midi_playing = 0;
-       //adlib_shut_up();
-       shutdown_adlib();
-       _dos_setvect(8,old_irq0);
-       write_8254_system_timer(0); /* back to normal 18.2Hz */
-
-       for (i=0;i < MIDI_MAX_TRACKS;i++) {
-               if (midi_trk[i].raw) {
-#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))
-                       _dos_freemem(FP_SEG(midi_trk[i].raw)); /* NTS: Because we allocated with _dos_allocmem */
-#else
-                       free(midi_trk[i].raw);
-#endif
-                       midi_trk[i].raw = NULL;
-               }
-               midi_trk[i].fence = NULL;
-               midi_trk[i].read = NULL;
-       }
-
-       return 0;
-}
+/* miditest.c\r
+ *\r
+ * Adlib OPL2/OPL3 FM synthesizer chipset test program.\r
+ * Play MIDI file using the OPLx synthesizer (well, poorly anyway)\r
+ * (C) 2010-2012 Jonathan Campbell.\r
+ * Hackipedia DOS library.\r
+ *\r
+ * This code is licensed under the LGPL.\r
+ * <insert LGPL legal text here>\r
+ *\r
+ * Compiles for intended target environments:\r
+ *   - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]\r
+ */\r
+\r
+#include "src/lib/midi.h"\r
+\r
+int main(int argc,char **argv) {\r
+       unsigned long ptick;\r
+       int i,c;\r
+\r
+       printf("ADLIB FM test program\n");\r
+       if (argc < 2) {\r
+               printf("You must specify a MIDI file to play\n");\r
+               return 1;\r
+       }\r
+\r
+       /*if (!probe_vga()) {\r
+               printf("Cannot init VGA\n");\r
+               return 1;\r
+       }*/\r
+       if (!init_adlib()) {\r
+               printf("Cannot init library\n");\r
+               return 1;\r
+       }\r
+       if (!probe_8254()) { /* we need the timer to keep time with the music */\r
+               printf("8254 timer not found\n");\r
+               return 1;\r
+       }\r
+\r
+       for (i=0;i < MIDI_MAX_TRACKS;i++) {\r
+               midi_trk[i].raw = NULL;\r
+               midi_trk[i].read = NULL;\r
+               midi_trk[i].fence = NULL;\r
+       }\r
+\r
+       if (load_midi_file(argv[1]) == 0) {\r
+               printf("Failed to load MIDI\n");\r
+               return 1;\r
+       }\r
+\r
+       write_8254_system_timer(T8254_REF_CLOCK_HZ / 100); /* tick faster at 100Hz please */\r
+       irq0_cnt = 0;\r
+       irq0_add = 182;\r
+       irq0_max = 1000; /* about 18.2Hz */\r
+       old_irq0 = _dos_getvect(8);/*IRQ0*/\r
+       _dos_setvect(8,irq0);\r
+\r
+       //adlib_shut_up();\r
+       midi_reset_channels();\r
+       midi_reset_tracks();\r
+       _cli();\r
+       irq0_ticks = ptick = 0;\r
+       _sti();\r
+       midi_playing = 1;\r
+\r
+       while (1) {\r
+               unsigned long adv;\r
+\r
+               _cli();\r
+               adv = irq0_ticks - ptick;\r
+               //adv = ptick;\r
+               if (adv >= 100UL) adv = 100UL;\r
+               ptick = irq0_ticks;\r
+               //ptick++;\r
+               _sti();\r
+\r
+               while (adv != 0) {\r
+                       midi_tick();\r
+                       adv--;\r
+               }\r
+\r
+               if (kbhit()) {\r
+                       c = getch();\r
+                       if (c == 0) c = getch() << 8;\r
+\r
+                       if (c == 27) {\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+\r
+       midi_playing = 0;\r
+       //adlib_shut_up();\r
+       shutdown_adlib();\r
+       _dos_setvect(8,old_irq0);\r
+       write_8254_system_timer(0); /* back to normal 18.2Hz */\r
+\r
+       for (i=0;i < MIDI_MAX_TRACKS;i++) {\r
+               if (midi_trk[i].raw) {\r
+#if TARGET_MSDOS == 16 && (defined(__LARGE__) || defined(__COMPACT__))\r
+                       _dos_freemem(FP_SEG(midi_trk[i].raw)); /* NTS: Because we allocated with _dos_allocmem */\r
+#else\r
+                       free(midi_trk[i].raw);\r
+#endif\r
+                       midi_trk[i].raw = NULL;\r
+               }\r
+               midi_trk[i].fence = NULL;\r
+               midi_trk[i].read = NULL;\r
+       }\r
+\r
+       return 0;\r
+}\r
index 2746ca4f1cc500316ba210f54ce75dc116b13871..e638df1b06c0677b09dce6d45fe3b32e956024a8 100755 (executable)
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "src/lib/scroll16.h"
-#include "src/lib/16_timer.h"
-#include "src/lib/wcpu/wcpu.h"
-
-//#define FADE
-#define MODEX  //this is for mode x initiating
-
-//word far *clock= (word far*) 0x046C; /* 18.2hz clock */
-//bitmap_t *p;
-global_game_variables_t gvar;
-static map_t map;
-player_t player[MaxPlayers];
-map_view_t mv[4];
-//word pn=0; //i forgot ww
-float t;
-sword bakapee;
-pan_t pan;
-//debugswitches
-boolean panswitch=0;
-//extern boolean pageflipflop=1;
-       unsigned int i;
-       const char *cpus;
-       //static int persist_aniframe = 0;    /* gonna be increased to 1 before being used, so 0 is ok for default */
-
-       //map_view_db_t pgid[4];
-       word pg;
-//#ifdef FADE
-       static word paloffset=0;
-       byte *dpal;
-//#endif
-       byte *gpal;
-       byte *ptr;
-       byte *mappalptr;
-
-void main(int argc, char *argv[])
-{
-       byte *mesg=malloc(sizeof(dword));
-
-       if(argv[1]) bakapee = atoi(argv[1]);
-       else bakapee = 1;
-
-       // DOSLIB: check our environment
-       probe_dos();
-
-       // DOSLIB: what CPU are we using?
-       // NTS: I can see from the makefile Sparky4 intends this to run on 8088 by the -0 switch in CFLAGS.
-       //      So this code by itself shouldn't care too much what CPU it's running on. Except that other
-       //      parts of this project (DOSLIB itself) rely on CPU detection to know what is appropriate for
-       //      the CPU to carry out tasks. --J.C.
-       cpu_probe();
-
-       // DOSLIB: check for VGA
-       if (!probe_vga()) {
-               printf("VGA probe failed\n");
-               return;
-       }
-       // hardware must be VGA or higher!
-       if (!(vga_state.vga_flags & VGA_IS_VGA)) {
-               printf("This program requires VGA or higher graphics hardware\n");
-               return;
-       }
-
-       if (_DEBUG_INIT() == 0) {
-#ifdef DEBUGSERIAL
-               printf("WARNING: Failed to initialize DEBUG output\n");
-#endif
-       }
-       _DEBUG("Serial debug output started\n"); // NTS: All serial output must end messages with newline, or DOSBox-X will not emit text to log
-       _DEBUGF("Serial debug output printf test %u %u %u\n",1U,2U,3U);
-
-       pan.pn=1;
-
-       start_timer(&gvar);
-
-       /* create the map */
-       fprintf(stderr, "testing map load~      ");
-       loadmap("data/test.map", &map);
-       chkmap(&map, 0);
-       printf("chkmap ok       ");
-       fprintf(stderr, "yay map loaded~~\n");
-
-       /* draw the tiles */
-#ifdef MODEX
-       ptr = map.data;
-       //mappalptr = map.tiles->btdata->palette;
-
-       /* data */
-       player[0].data = malloc(48*128); //TODO use exmm
-       *player[0].data = bitmapLoadPcx("data/chikyuu.pcx"); // load sprite
-
-       /* create the planar buffer */
-////++++       (player[0].data) = *planar_buf_from_bitmap(&p);
-       /*++++printf("load pee!!        ");
-       pp = planar_buf_from_bitmap(&p);
-       printf("done!\n");*/
-
-#endif
-       /*      input!  */
-       IN_Startup();
-       IN_Default(0,&player,ctrl_Joystick);
-       //IN_Default(1,&player,ctrl_Joystick);
-
-       /* save the palette */
-#ifdef MODEX
-#ifdef FADE
-       dpal = modexNewPal();
-       modexPalSave(dpal);
-       modexFadeOff(4, dpal);
-#endif
-
-       textInit();
-       VGAmodeX(bakapee, 1, &gvar);
-//     printf("%dx%d\n", gvar.video.page[0].sw, gvar.video.page[0].sh);
-#ifdef FADE
-       modexPalBlack();        //reset the palette~
-#endif
-#endif
-//     printf("Total used @ before palette initiation:         %zu\n", oldfreemem-GetFreeSize());
-//++++ player[0].data.offset=(paloffset/3);
-//++++ modexPalUpdate1(&player[0].data, &paloffset, 0, 0);
-               modexPalUpdate1(player[0].data->palette);
-//++++0000             modexPalUpdate1(map.tiles->btdata->palette);
-       //printf("      %d\n", sizeof(ptmp->data));
-       //printf("1:    %d\n", paloffset);
-//++++ map.tiles->data->offset=(paloffset/3);
-       //XTmodexPalUpdate(map.tiles->data, &paloffset, 0, 0);
-//     printf("\n====\n");
-//     printf("0       paloffset=      %d\n", paloffset/3);
-//     printf("====\n\n");
-#ifdef MODEX
-#ifdef FADE
-       gpal = modexNewPal();
-       modexPalSave(gpal);
-       modexSavePalFile("data/g.pal", gpal);
-       modexPalBlack();        //so player will not see loadings~
-#endif
-#endif
-
-       /* setup camera and screen~ */
-       modexHiganbanaPageSetup(&gvar.video);
-       for(i=0;i<gvar.video.num_of_pages;i++)
-       {
-               mv[i].page = &gvar.video.page[i];
-               mv[i].map = &map;
-               mv[i].video = &gvar.video;
-               mv[i].pan       = &pan;
-       }
-
-       /* set up paging */
-       //TODO: LOAD map data and position the map in the middle of the screen if smaller then screen
-       mapGoTo(mv, 0, 0);
-       //_fmemcpy(mv[1].page->data, mv[0].page->data, mv[0].page->pagesize);
-
-       //TODO: put player in starting position of spot
-       //default player position on the viewable map
-       player[0].tx = mv[0].tx + mv[0].page->tilemidposscreenx;
-       player[0].ty = mv[0].ty + mv[0].page->tilemidposscreeny;
-       IN_initplayer(&player, 0);
-       //IN_initplayer(&player, 1);
-
-#ifndef        SPRITE
-       modexClearRegion(mv[0].page, player[0].x, player[0].y-TILEWH, 16, 32, 15);
-       //modexClearRegion(mv[1].page, player[0].x, player[0].y-TILEWH, 16, 32, 15);
-#else
-       //PBUFSFUN(mv[1].page, player[0].x, player[0].y-TILEWH, 16, 64, 24, 32, PLAYERBMPDATA);
-       PBUFSFUN(mv[0].page, player[0].x, player[0].y-TILEWH, 16, 64, 16, 32,   player[0].data);
-#endif
-
-       if(!pageflipflop)       modexShowPage(mv[1].page);
-       else                    modexShowPage(mv[0].page);//!(gvar.video.p)
-               shinku_fps_indicator_page = 0; // we're on page 1 now, shinku(). follow along please or it will not be visible.
-
-       /* buffer pages */
-//     modexClearRegion(mv[2].page, 0, 0, mv[2].page->width, mv[2].page->height, 47);
-//     modexClearRegion(mv[3].page, 0, 0, mv[3].page->width, mv[3].page->height, 45);
-//     {
-//             unsigned int k,j,o;
-//             /* fill screen with a distinctive pattern */
-//             for (k=0;k < vga_state.vga_width;k++) {
-//                     o = k >> 2;
-//                     vga_write_sequencer(0x02/*map mask*/,1 << (k&3));
-//                             for (j=0;j < vga_state.vga_height;j++,o += vga_state.vga_stride)
-//                                     vga_state.vga_graphics_ram[o] = (k^j)&15; // VRL samples put all colors in first 15!
-//             }
-//     }
-       modexClearRegion(mv[3].page, 0, 128, 24, 36, 15);
-
-#ifdef MODEX
-#ifdef FADE
-       modexFadeOn(4, gpal);
-#endif
-#endif
-       while(!IN_KeyDown(sc_Escape) && player[0].hp>0)
-       {
-               shinku(&gvar);
-       //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[0].tx or player[0].ty == 0 or player[0].tx == 20 or player[0].ty == 15 then stop because that is edge of map and you do not want to walk of the map
-
-       //player movement
-               IN_ReadControl(0,&player);
-       if(!panswitch){
-               walk(mv, player, 0);
-       }else{
-               panpagemanual(mv, player, 0);
-               //printf("      player[0].q: %d", player[0].q); printf("        player[0].d: %d\n", player[0].d);
-       }
-
-       //the scripting stuff....
-       //if(((player[0].triggerx == TRIGGX && player[0].triggery == TRIGGY) && IN_KeyDown(0x1C))||(player[0].tx == 5 && player[0].ty == 5))
-       if(((mv[0].map->data[(player[0].triggerx-1)+(map.width*(player[0].triggery-1))] == 0) && IN_KeyDown(0x1C))||(player[0].tx == 5 && player[0].ty == 5))
-       {
-               short i;
-               for(i=800; i>=400; i--)
-               {
-                       sound(i);
-               }
-               nosound();
-       }
-       if(player[0].q == (TILEWH/(player[0].speed))+1 && player[0].info.dir != 2 && (player[0].triggerx == 5 && player[0].triggery == 5)){ player[0].hp--; }
-       //debugging binds!
-       if(IN_KeyDown(2)){ modexShowPage(mv[0].page); pan.pn=0; }
-       if(IN_KeyDown(3)){ modexShowPage(mv[1].page); pan.pn=1; }
-       if(IN_KeyDown(4)){ modexShowPage(mv[2].page); pan.pn=2; }
-       if(IN_KeyDown(4+1)){ modexShowPage(mv[3].page); pan.pn=3; }
-       if(IN_KeyDown(25)){ modexpdump(mv[0].page); modexpdump(mv[1].page);
-                IN_UserInput(1,1);
-       }       //p
-#ifdef MODEX
-#ifdef FADE
-       if(IN_KeyDown(24)){ modexPalUpdate0(gpal); paloffset=0; modexpdump(mv[0].page); modexpdump(mv[1].page);  IN_UserInput(1,1); }
-       if(IN_KeyDown(22)){
-       paloffset=0; modexPalBlack(); modexPalUpdate(player[0].data, &paloffset, 0, 0);
-       printf("1paloffset      =       %d\n", paloffset/3);
-        modexPalUpdate(map.tiles->data, &paloffset, 0, 0);
-       printf("2paloffset      =       %d\n", paloffset/3);
-        modexpdump(mv[0].page); modexpdump(mv[1].page);
-               IN_UserInput(1,1);
-       }
-#endif
-#endif
-       //pan switch
-       if(IN_KeyDown(88)){panswitch=!panswitch; IN_UserInput(1,1);}    //f12
-       if(IN_KeyDown(87))      //f11
-       {
-               pageflipflop=!pageflipflop;
-               IN_UserInput(1,1);
-//             VGAmodeX(0, 0, &gvar);
-//             IN_Shutdown();
-//             __asm
-//             {
-//                     mov ah,31h
-//                     int 21h
-//             }
-       }
-       if(IN_KeyDown(68))      //f10
-       {
-               gvar.kurokku.fpscap=!gvar.kurokku.fpscap;
-               IN_UserInput(1,1);
-       }
-       if(IN_KeyDown(67))      //f9
-       {
-               modexClearRegion(mv[1].page, 0, 0, mv[1].page->width, mv[1].page->height, 2);
-               modexClearRegion(mv[2].page, 0, 0, mv[2].page->width, mv[2].page->height, 3);
-               modexClearRegion(mv[3].page, 0, 0, mv[3].page->width, mv[3].page->height, 4);
-               modexClearRegion(mv[3].page, 0, 0, 20, 36, 15);
-               //IN_UserInput(1,1);
-       }
-       if(IN_KeyDown(66))      //f8
-       {
-//             modexDrawSprite(mv[0].page, 16, 16, p);
-               modexDrawSprite(mv[0].page, 32+48, 16, (player[0].data));
-       }
-       //TODO fmemtest into page
-       /*if(IN_KeyDown(4+1))   //4
-       {
-               pg=1;
-               SELECT_ALL_PLANES();
-               _fmemset(((mv[pg].page->data+4)+(16*(mv[pg].page->width/4))), 15, 4);
-       }*/
-
-       //9
-       if(IN_KeyDown(10)){ modexPalOverscan(rand()%56); modexPalUpdate1(dpal); IN_UserInput(1,1); }
-       //if(IN_KeyDown(11)){ modexPalOverscan(15); }
-       if((player[0].q==1) && !(player[0].x%TILEWH==0 && player[0].y%TILEWH==0)) break;        //incase things go out of sync!
-       }
-
-       /* fade back to text mode */
-       /* but 1st lets save the game palette~ */
-#ifdef MODEX
-#ifdef FADE
-       modexPalSave(gpal);
-       modexSavePalFile("data/g.pal", gpal);
-       modexFadeOff(4, gpal);
-#endif
-       VGAmodeX(0, 1, &gvar);
-#endif
-       IN_Shutdown();
-       printf("\nProject 16 scroll.exe. This is just a test file!\n");
-       printf("version %s\n", VERSION);
-       printf("tx: %d  ", mv[0].tx);
-       printf("ty: %d\n", mv[0].ty);
-       printf("\n");
-       printf("player vars:\n");
-       printf("        x: %d", player[0].x); printf("  y: %d\n", player[0].y);
-       //if(player[0].hp==0) printf("%d wwww\n", player[0].y+8);
-       //else printf("\nplayer[0].y: %d\n", player[0].y);
-       printf("        tx: %d", player[0].tx); printf("        ty: %d\n", player[0].ty);
-       printf("        triggx: %d", player[0].triggerx); printf("      triggy: %d\n", player[0].triggery);
-       printf("        hp: %d", (player[0].hp));       printf("        q: %d", player[0].q);   printf("        player.info.dir: %d", player[0].info.dir);      printf("        player.d: %d ", player[0].d);
-               printf("        pdir=%d\n", player[0].pdir);
-       printf("        tile data value at player trigger position: %d\n\n", mv[0].map->data[(player[0].triggerx-1)+(map.width*(player[0].triggery-1))]);
-//     printf("palette offset: %d\n", paloffset/3);
-//++++ printf("Total used: %zu\n", oldfreemem-GetFreeSize());
-//++++ printf("Total free: %zu\n", GetFreeSize());
-//not used now printf("temporary player sprite 0: http://www.pixiv.net/member_illust.php?mode=medium&illust_id=45556867\n");
-//not used now printf("temporary player sprite 1: http://www.pixiv.net/member_illust.php?mode=medium&illust_id=44606385\n");
-       printf("Virtual Screen: %dx", gvar.video.page[0].width);        printf("%d      ", gvar.video.page[0].height);
-       printf("Screen: %dx", gvar.video.page[0].sw);   printf("%d\n", gvar.video.page[0].sh);
-       printf("virtual tile resolution: %dx", gvar.video.page[0].tilesw);      printf("%d      ", gvar.video.page[0].tilesh);
-       printf("tile resolution: %dx", gvar.video.page[0].tw);  printf("%d\n", gvar.video.page[0].th);
-       printf("middle tile position: %dx", gvar.video.page[0].tilemidposscreenx);      printf("%d\n", gvar.video.page[0].tilemidposscreeny);
-       modexprintmeminfo(&gvar.video);
-       //printf("mv[%u].tx: %d", pan.pn, mv[pan.pn].tx); printf("      mv[%u].ty: %d   ", pan.pn, mv[pan.pn].ty);
-       printf("gvar.video.p=%u ", gvar.video.p); printf("gvar.video.r=%u ", gvar.video.r);
-       printf("pageflipflop=%u\n", pageflipflop);
-       //0000printf("\ngvar.video.tickclk=%f\n", gvar.video.tickclk);
-       //0000printf("gvar.video.clk=%f", gvar.video.clk);
-       printf("\n");
-       //printf("map.width=%d  map.height=%d   map.data[0]=%d\n", mv[0].map->width, mv[0].map->height, mv[0].map->data[0]);
-
-       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);
-#ifdef MODEX
-#ifdef FADE
-       modexFadeOn(4, dpal);
-#endif
-#endif
-}
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+\r
+#include "src/lib/scroll16.h"\r
+#include "src/lib/16_timer.h"\r
+#include "src/lib/wcpu/wcpu.h"\r
+\r
+//#define FADE\r
+#define MODEX  //this is for mode x initiating\r
+\r
+//word far *clock= (word far*) 0x046C; /* 18.2hz clock */\r
+//bitmap_t *p;\r
+global_game_variables_t gvar;\r
+static map_t map;\r
+player_t player[MaxPlayers];\r
+map_view_t mv[4];\r
+//word pn=0; //i forgot ww\r
+float t;\r
+sword bakapee;\r
+pan_t pan;\r
+//debugswitches\r
+boolean panswitch=0;\r
+//extern boolean pageflipflop=1;\r
+       unsigned int i;\r
+       const char *cpus;\r
+       //static int persist_aniframe = 0;    /* gonna be increased to 1 before being used, so 0 is ok for default */\r
+\r
+       //map_view_db_t pgid[4];\r
+       word pg;\r
+//#ifdef FADE\r
+       static word paloffset=0;\r
+       byte *dpal;\r
+//#endif\r
+       byte *gpal;\r
+       byte *ptr;\r
+       byte *mappalptr;\r
+\r
+void main(int argc, char *argv[])\r
+{\r
+       byte *mesg=malloc(sizeof(dword));\r
+\r
+       if(argv[1]) bakapee = atoi(argv[1]);\r
+       else bakapee = 1;\r
+\r
+       // DOSLIB: check our environment\r
+       probe_dos();\r
+\r
+       // DOSLIB: what CPU are we using?\r
+       // NTS: I can see from the makefile Sparky4 intends this to run on 8088 by the -0 switch in CFLAGS.\r
+       //      So this code by itself shouldn't care too much what CPU it's running on. Except that other\r
+       //      parts of this project (DOSLIB itself) rely on CPU detection to know what is appropriate for\r
+       //      the CPU to carry out tasks. --J.C.\r
+       cpu_probe();\r
+\r
+       // DOSLIB: check for VGA\r
+       if (!probe_vga()) {\r
+               printf("VGA probe failed\n");\r
+               return;\r
+       }\r
+       // hardware must be VGA or higher!\r
+       if (!(vga_state.vga_flags & VGA_IS_VGA)) {\r
+               printf("This program requires VGA or higher graphics hardware\n");\r
+               return;\r
+       }\r
+\r
+       if (_DEBUG_INIT() == 0) {\r
+#ifdef DEBUGSERIAL\r
+               printf("WARNING: Failed to initialize DEBUG output\n");\r
+#endif\r
+       }\r
+       _DEBUG("Serial debug output started\n"); // NTS: All serial output must end messages with newline, or DOSBox-X will not emit text to log\r
+       _DEBUGF("Serial debug output printf test %u %u %u\n",1U,2U,3U);\r
+\r
+       pan.pn=1;\r
+\r
+       start_timer(&gvar);\r
+\r
+       /* create the map */\r
+       fprintf(stderr, "testing map load~      ");\r
+       loadmap("data/test.map", &map);\r
+       chkmap(&map, 0);\r
+       printf("chkmap ok       ");\r
+       fprintf(stderr, "yay map loaded~~\n");\r
+\r
+       /* draw the tiles */\r
+#ifdef MODEX\r
+       ptr = map.data;\r
+       //mappalptr = map.tiles->btdata->palette;\r
+\r
+       /* data */\r
+       player[0].data = malloc(48*128); //TODO use exmm\r
+       *player[0].data = bitmapLoadPcx("data/chikyuu.pcx"); // load sprite\r
+\r
+       /* create the planar buffer */\r
+////++++       (player[0].data) = *planar_buf_from_bitmap(&p);\r
+       /*++++printf("load pee!!        ");\r
+       pp = planar_buf_from_bitmap(&p);\r
+       printf("done!\n");*/\r
+\r
+#endif\r
+       /*      input!  */\r
+       IN_Startup();\r
+       IN_Default(0,&player,ctrl_Joystick);\r
+       //IN_Default(1,&player,ctrl_Joystick);\r
+\r
+       /* save the palette */\r
+#ifdef MODEX\r
+#ifdef FADE\r
+       dpal = modexNewPal();\r
+       modexPalSave(dpal);\r
+       modexFadeOff(4, dpal);\r
+#endif\r
+\r
+       textInit();\r
+       VGAmodeX(bakapee, 1, &gvar);\r
+//     printf("%dx%d\n", gvar.video.page[0].sw, gvar.video.page[0].sh);\r
+#ifdef FADE\r
+       modexPalBlack();        //reset the palette~\r
+#endif\r
+#endif\r
+//     printf("Total used @ before palette initiation:         %zu\n", oldfreemem-GetFreeSize());\r
+//++++ player[0].data.offset=(paloffset/3);\r
+//++++ modexPalUpdate1(&player[0].data, &paloffset, 0, 0);\r
+               modexPalUpdate1(player[0].data->palette);\r
+//++++0000             modexPalUpdate1(map.tiles->btdata->palette);\r
+       //printf("      %d\n", sizeof(ptmp->data));\r
+       //printf("1:    %d\n", paloffset);\r
+//++++ map.tiles->data->offset=(paloffset/3);\r
+       //XTmodexPalUpdate(map.tiles->data, &paloffset, 0, 0);\r
+//     printf("\n====\n");\r
+//     printf("0       paloffset=      %d\n", paloffset/3);\r
+//     printf("====\n\n");\r
+#ifdef MODEX\r
+#ifdef FADE\r
+       gpal = modexNewPal();\r
+       modexPalSave(gpal);\r
+       modexSavePalFile("data/g.pal", gpal);\r
+       modexPalBlack();        //so player will not see loadings~\r
+#endif\r
+#endif\r
+\r
+       /* setup camera and screen~ */\r
+       modexHiganbanaPageSetup(&gvar.video);\r
+       for(i=0;i<gvar.video.num_of_pages;i++)\r
+       {\r
+               mv[i].page = &gvar.video.page[i];\r
+               mv[i].map = &map;\r
+               mv[i].video = &gvar.video;\r
+               mv[i].pan       = &pan;\r
+       }\r
+\r
+       /* set up paging */\r
+       //TODO: LOAD map data and position the map in the middle of the screen if smaller then screen\r
+       mapGoTo(mv, 0, 0);\r
+       //_fmemcpy(mv[1].page->data, mv[0].page->data, mv[0].page->pagesize);\r
+\r
+       //TODO: put player in starting position of spot\r
+       //default player position on the viewable map\r
+       player[0].tx = mv[0].tx + mv[0].page->tilemidposscreenx;\r
+       player[0].ty = mv[0].ty + mv[0].page->tilemidposscreeny;\r
+       IN_initplayer(&player, 0);\r
+       //IN_initplayer(&player, 1);\r
+\r
+#ifndef        SPRITE\r
+       modexClearRegion(mv[0].page, player[0].x, player[0].y-TILEWH, 16, 32, 15);\r
+       //modexClearRegion(mv[1].page, player[0].x, player[0].y-TILEWH, 16, 32, 15);\r
+#else\r
+       //PBUFSFUN(mv[1].page, player[0].x, player[0].y-TILEWH, 16, 64, 24, 32, PLAYERBMPDATA);\r
+       PBUFSFUN(mv[0].page, player[0].x, player[0].y-TILEWH, 16, 64, 16, 32,   player[0].data);\r
+#endif\r
+\r
+       if(!pageflipflop)       modexShowPage(mv[1].page);\r
+       else                    modexShowPage(mv[0].page);//!(gvar.video.p)\r
+               shinku_fps_indicator_page = 0; // we're on page 1 now, shinku(). follow along please or it will not be visible.\r
+\r
+       /* buffer pages */\r
+//     modexClearRegion(mv[2].page, 0, 0, mv[2].page->width, mv[2].page->height, 47);\r
+//     modexClearRegion(mv[3].page, 0, 0, mv[3].page->width, mv[3].page->height, 45);\r
+//     {\r
+//             unsigned int k,j,o;\r
+//             /* fill screen with a distinctive pattern */\r
+//             for (k=0;k < vga_state.vga_width;k++) {\r
+//                     o = k >> 2;\r
+//                     vga_write_sequencer(0x02/*map mask*/,1 << (k&3));\r
+//                             for (j=0;j < vga_state.vga_height;j++,o += vga_state.vga_stride)\r
+//                                     vga_state.vga_graphics_ram[o] = (k^j)&15; // VRL samples put all colors in first 15!\r
+//             }\r
+//     }\r
+       modexClearRegion(mv[3].page, 0, 128, 24, 36, 15);\r
+\r
+#ifdef MODEX\r
+#ifdef FADE\r
+       modexFadeOn(4, gpal);\r
+#endif\r
+#endif\r
+       while(!IN_KeyDown(sc_Escape) && player[0].hp>0)\r
+       {\r
+               shinku(&gvar);\r
+       //top left corner & bottem right corner of map veiw be set as map edge trigger since maps are actually square\r
+       //to stop scrolling and have the player position data move to the edge of the screen with respect to the direction\r
+       //when player[0].tx or player[0].ty == 0 or player[0].tx == 20 or player[0].ty == 15 then stop because that is edge of map and you do not want to walk of the map\r
+\r
+       //player movement\r
+               IN_ReadControl(0,&player);\r
+       if(!panswitch){\r
+               walk(mv, player, 0);\r
+       }else{\r
+               panpagemanual(mv, player, 0);\r
+               //printf("      player[0].q: %d", player[0].q); printf("        player[0].d: %d\n", player[0].d);\r
+       }\r
+\r
+       //the scripting stuff....\r
+       //if(((player[0].triggerx == TRIGGX && player[0].triggery == TRIGGY) && IN_KeyDown(0x1C))||(player[0].tx == 5 && player[0].ty == 5))\r
+       if(((mv[0].map->data[(player[0].triggerx-1)+(map.width*(player[0].triggery-1))] == 0) && IN_KeyDown(0x1C))||(player[0].tx == 5 && player[0].ty == 5))\r
+       {\r
+               short i;\r
+               for(i=800; i>=400; i--)\r
+               {\r
+                       sound(i);\r
+               }\r
+               nosound();\r
+       }\r
+       if(player[0].q == (TILEWH/(player[0].speed))+1 && player[0].info.dir != 2 && (player[0].triggerx == 5 && player[0].triggery == 5)){ player[0].hp--; }\r
+       //debugging binds!\r
+       if(IN_KeyDown(2)){ modexShowPage(mv[0].page); pan.pn=0; }\r
+       if(IN_KeyDown(3)){ modexShowPage(mv[1].page); pan.pn=1; }\r
+       if(IN_KeyDown(4)){ modexShowPage(mv[2].page); pan.pn=2; }\r
+       if(IN_KeyDown(4+1)){ modexShowPage(mv[3].page); pan.pn=3; }\r
+       if(IN_KeyDown(25)){ modexpdump(mv[0].page); modexpdump(mv[1].page);\r
+                IN_UserInput(1,1);\r
+       }       //p\r
+#ifdef MODEX\r
+#ifdef FADE\r
+       if(IN_KeyDown(24)){ modexPalUpdate0(gpal); paloffset=0; modexpdump(mv[0].page); modexpdump(mv[1].page);  IN_UserInput(1,1); }\r
+       if(IN_KeyDown(22)){\r
+       paloffset=0; modexPalBlack(); modexPalUpdate(player[0].data, &paloffset, 0, 0);\r
+       printf("1paloffset      =       %d\n", paloffset/3);\r
+        modexPalUpdate(map.tiles->data, &paloffset, 0, 0);\r
+       printf("2paloffset      =       %d\n", paloffset/3);\r
+        modexpdump(mv[0].page); modexpdump(mv[1].page);\r
+               IN_UserInput(1,1);\r
+       }\r
+#endif\r
+#endif\r
+       //pan switch\r
+       if(IN_KeyDown(88)){panswitch=!panswitch; IN_UserInput(1,1);}    //f12\r
+       if(IN_KeyDown(87))      //f11\r
+       {\r
+               pageflipflop=!pageflipflop;\r
+               IN_UserInput(1,1);\r
+//             VGAmodeX(0, 0, &gvar);\r
+//             IN_Shutdown();\r
+//             __asm\r
+//             {\r
+//                     mov ah,31h\r
+//                     int 21h\r
+//             }\r
+       }\r
+       if(IN_KeyDown(68))      //f10\r
+       {\r
+               gvar.kurokku.fpscap=!gvar.kurokku.fpscap;\r
+               IN_UserInput(1,1);\r
+       }\r
+       if(IN_KeyDown(67))      //f9\r
+       {\r
+               modexClearRegion(mv[1].page, 0, 0, mv[1].page->width, mv[1].page->height, 2);\r
+               modexClearRegion(mv[2].page, 0, 0, mv[2].page->width, mv[2].page->height, 3);\r
+               modexClearRegion(mv[3].page, 0, 0, mv[3].page->width, mv[3].page->height, 4);\r
+               modexClearRegion(mv[3].page, 0, 0, 20, 36, 15);\r
+               //IN_UserInput(1,1);\r
+       }\r
+       if(IN_KeyDown(66))      //f8\r
+       {\r
+//             modexDrawSprite(mv[0].page, 16, 16, p);\r
+               modexDrawSprite(mv[0].page, 32+48, 16, (player[0].data));\r
+       }\r
+       //TODO fmemtest into page\r
+       /*if(IN_KeyDown(4+1))   //4\r
+       {\r
+               pg=1;\r
+               SELECT_ALL_PLANES();\r
+               _fmemset(((mv[pg].page->data+4)+(16*(mv[pg].page->width/4))), 15, 4);\r
+       }*/\r
+\r
+       //9\r
+       if(IN_KeyDown(10)){ modexPalOverscan(rand()%56); modexPalUpdate1(dpal); IN_UserInput(1,1); }\r
+       //if(IN_KeyDown(11)){ modexPalOverscan(15); }\r
+       if((player[0].q==1) && !(player[0].x%TILEWH==0 && player[0].y%TILEWH==0)) break;        //incase things go out of sync!\r
+       }\r
+\r
+       /* fade back to text mode */\r
+       /* but 1st lets save the game palette~ */\r
+#ifdef MODEX\r
+#ifdef FADE\r
+       modexPalSave(gpal);\r
+       modexSavePalFile("data/g.pal", gpal);\r
+       modexFadeOff(4, gpal);\r
+#endif\r
+       VGAmodeX(0, 1, &gvar);\r
+#endif\r
+       IN_Shutdown();\r
+       printf("\nProject 16 scroll.exe. This is just a test file!\n");\r
+       printf("version %s\n", VERSION);\r
+       printf("tx: %d  ", mv[0].tx);\r
+       printf("ty: %d\n", mv[0].ty);\r
+       printf("\n");\r
+       printf("player vars:\n");\r
+       printf("        x: %d", player[0].x); printf("  y: %d\n", player[0].y);\r
+       //if(player[0].hp==0) printf("%d wwww\n", player[0].y+8);\r
+       //else printf("\nplayer[0].y: %d\n", player[0].y);\r
+       printf("        tx: %d", player[0].tx); printf("        ty: %d\n", player[0].ty);\r
+       printf("        triggx: %d", player[0].triggerx); printf("      triggy: %d\n", player[0].triggery);\r
+       printf("        hp: %d", (player[0].hp));       printf("        q: %d", player[0].q);   printf("        player.info.dir: %d", player[0].info.dir);      printf("        player.d: %d ", player[0].d);\r
+               printf("        pdir=%d\n", player[0].pdir);\r
+       printf("        tile data value at player trigger position: %d\n\n", mv[0].map->data[(player[0].triggerx-1)+(map.width*(player[0].triggery-1))]);\r
+//     printf("palette offset: %d\n", paloffset/3);\r
+//++++ printf("Total used: %zu\n", oldfreemem-GetFreeSize());\r
+//++++ printf("Total free: %zu\n", GetFreeSize());\r
+//not used now printf("temporary player sprite 0: http://www.pixiv.net/member_illust.php?mode=medium&illust_id=45556867\n");\r
+//not used now printf("temporary player sprite 1: http://www.pixiv.net/member_illust.php?mode=medium&illust_id=44606385\n");\r
+       printf("Virtual Screen: %dx", gvar.video.page[0].width);        printf("%d      ", gvar.video.page[0].height);\r
+       printf("Screen: %dx", gvar.video.page[0].sw);   printf("%d\n", gvar.video.page[0].sh);\r
+       printf("virtual tile resolution: %dx", gvar.video.page[0].tilesw);      printf("%d      ", gvar.video.page[0].tilesh);\r
+       printf("tile resolution: %dx", gvar.video.page[0].tw);  printf("%d\n", gvar.video.page[0].th);\r
+       printf("middle tile position: %dx", gvar.video.page[0].tilemidposscreenx);      printf("%d\n", gvar.video.page[0].tilemidposscreeny);\r
+       modexprintmeminfo(&gvar.video);\r
+       //printf("mv[%u].tx: %d", pan.pn, mv[pan.pn].tx); printf("      mv[%u].ty: %d   ", pan.pn, mv[pan.pn].ty);\r
+       printf("gvar.video.p=%u ", gvar.video.p); printf("gvar.video.r=%u ", gvar.video.r);\r
+       printf("pageflipflop=%u\n", pageflipflop);\r
+       //0000printf("\ngvar.video.tickclk=%f\n", gvar.video.tickclk);\r
+       //0000printf("gvar.video.clk=%f", gvar.video.clk);\r
+       printf("\n");\r
+       //printf("map.width=%d  map.height=%d   map.data[0]=%d\n", mv[0].map->width, mv[0].map->height, mv[0].map->data[0]);\r
+\r
+       printf("\n");\r
+       switch(detectcpu())\r
+       {\r
+               case 0: cpus = "8086/8088 or 186/88"; break;\r
+               case 1: cpus = "286"; break;\r
+               case 2: cpus = "386 or newer"; break;\r
+               default: cpus = "internal error"; break;\r
+       }\r
+       printf("detected CPU type: %s\n", cpus);\r
+#ifdef MODEX\r
+#ifdef FADE\r
+       modexFadeOn(4, dpal);\r
+#endif\r
+#endif\r
+}\r
index b78f449edcc119a4a352d3316768364d7c7afb37..40a2ac41445f5f8db4840afdd1802e3dc1155c50 100755 (executable)
-/* testemm.c
- *
- * Test program: Expanded Memory Manager functions
- * (C) 2011-2012 Jonathan Campbell.
- * Hackipedia DOS library.
- *
- * This code is licensed under the LGPL.
- * <insert LGPL legal text here>
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <assert.h>
-#include <stdio.h>
-#include <conio.h>
-#include <dos.h>
-
-//#include "src/lib/doslib/cpu.h"
-#include "src/lib/doslib/dos.h"
-#include "src/lib/doslib/emm.h"
-//#include <hw/dos/doswin.h>
-
-static const char *message = "Hello world. How are you?";
-static const char *message2 = "Pingas. Sup dawg. Hello world. Dork. Hahahajajaja.";
-static char tmp[128],tmp2[128];
-extern int probe_emm0();
-
-#if 1
-# define x_memcpy(a,b,c) memcpy(a,b,c)
-#else
-/* what have we come to when friggin' memcpy() causes a GPF?!? */
-static void x_memcpy(unsigned char *dst,const unsigned char *src,size_t c) {
-       fprintf(stderr,"memcpy %p -> %p (%lu)\n",
-               dst,src,(unsigned long)c);
-
-       while (c != 0) {
-           *dst++ = *src++;
-           c--;
-       }
-}
-#endif
-
-int main() {
-       size_t message_l = strlen(message),message2_l = strlen(message2);
-
-       probe_dos();
-       printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF);
-       /*if (detect_windows()) {
-               printf("I am running under Windows.\n");
-               printf("    Mode: %s\n",windows_mode_str(windows_mode));
-               printf("    Ver:  %x.%02u\n",windows_version>>8,windows_version&0xFF);
-       }
-       else {
-               printf("Not running under Windows or OS/2\n");
-       }*/
-
-       sanity();
-       if (probe_emm()) {
-               int h1,h2,h3;
-
-               sanity();
-               printf("Expanded memory manager present. Status = 0x%02x Page frame @0x%04x v%x.%x\n",emm_status,emm_page_frame_segment,emm_version>>4,emm_version&0x0F);
-               emm_update_page_count();
-               sanity();
-               printf("  Unallocated pages:     %u (%luKB)\n",
-                       emm_unallocated_pages,
-                       (unsigned long)emm_unallocated_pages << 4UL); /* 2^14 = 16384 */
-               printf("  Total pages:           %u (%luKB)\n",
-                       emm_total_pages,
-                       (unsigned long)emm_total_pages << 4UL);
-               printf("  Physical pages:        %u (%luKB)\n",
-                       emm_phys_pages,
-                       (unsigned long)emm_phys_pages << 4UL);
-
-               while (getch() != 13);
-               sanity();
-
-               /* print out the mapping table, if available */
-               if (emm_phys_map != NULL) {
-                       struct emm_phys_page_map *me;
-                       unsigned int i;
-
-                       printf("Physical page to segment table\n");
-                       for (i=0;i < emm_phys_pages;i++) {
-                               me = emm_phys_map + i;
-                               printf("  %02x: 0x%04x",me->number,me->segment);
-                               if ((i%5) == 4) printf("\n");
-                       }
-                       printf("\n");
-                       sanity();
-               }
-
-               printf("Allocating EMM pages (1): ");
-               h1 = emm_alloc_pages(1);
-               sanity();
-               if (h1 >= 0) {
-                       printf("OK, handle=%u\n",h1);
-                       if (!emm_free_pages(h1)) printf("cannot free\n");
-               }
-               else printf("FAILED\n");
-
-               printf("Allocating EMM pages (16KB): ");
-               h1 = emm_alloc_pages(1);
-               sanity();
-               if (h1 >= 0) printf("OK, handle=%u\n",h1);
-               else printf("FAILED\n");
-
-               printf("Allocating EMM pages (1.6MB): ");
-               h2 = emm_alloc_pages(0x19999AUL >> 14UL);
-               sanity();
-               if (h2 >= 0) printf("OK, handle=%u\n",h2);
-               else printf("FAILED\n");
-
-               printf("Allocating EMM pages (12MB): ");
-               h3 = emm_alloc_pages(0xC00000UL >> 14UL);
-               sanity();
-               if (h3 >= 0) printf("OK, handle=%u\n",h3);
-               else printf("FAILED\n");
-
-               while (getch() != 13);
-
-               if (h1 >= 0 && !emm_free_pages(h1)) printf("Cannot free\n");
-               sanity();
-               if (h2 >= 0 && !emm_free_pages(h2)) printf("Cannot free\n");
-               sanity();
-               if (h3 >= 0 && !emm_free_pages(h3)) printf("Cannot free\n");
-               sanity();
-
-               printf("Allocating EMM pages (32KB): ");
-               h1 = emm_alloc_pages(2);
-               sanity();
-               if (h1 >= 0) {
-                       printf("OK, handle=%u\n",h1);
-                       if (emm_map_page(h1,/*physical*/0,/*logical*/0)) {
-                               unsigned int segm = emm_last_phys_page_segment(0);
-                               printf("Seg %04x\n",segm);
-                               sanity();
-                               if (segm > 0) {
-#if TARGET_MSDOS == 16
-                                       char far *ptr = MK_FP(segm,0);
-#else
-                                       char *ptr = (char*)(segm << 4UL);
-#endif
-
-#if TARGET_MSDOS == 16
-                                       _fmemcpy(ptr,(char far*)message,message_l+1);
-                                       _fmemcpy((char far*)tmp,ptr,message_l+1);
-#else
-                                       x_memcpy(ptr,message,message_l+1);
-                                       x_memcpy(tmp,ptr,message_l+1);
-#endif
-                                       printf("After writing message there, I read back: '%s'\n",tmp);
-
-                                       if (!emm_map_page(h1,0,1)) printf("Cannot remap\n");
-
-#if TARGET_MSDOS == 16
-                                       _fmemcpy(ptr,(char far*)message2,message2_l+1);
-                                       _fmemcpy((char far*)tmp,ptr,message2_l+1);
-#else
-                                       x_memcpy(ptr,message2,message2_l+1);
-                                       x_memcpy(tmp,ptr,message2_l+1);
-#endif
-                                       printf("After mapping to page 2 and writing there, I read back: '%s'\n",tmp);
-
-                                       if (!emm_map_page(h1,0,0)) printf("Cannot remap\n");
-
-#if TARGET_MSDOS == 16
-                                       _fmemcpy((char far*)tmp,ptr,message_l+1);
-#else
-                                       x_memcpy(tmp,ptr,message_l+1);
-#endif
-                                       printf("After mapping back to 1, I read back: '%s'\n",tmp);
-
-                                       if (emm_map_page(h1,0,2)) printf("Whoops, I was able to map logical pages beyond what I allocated\n");
-                               }
-                               else {
-                                       printf("Cannot get segment\n");
-                               }
-                               if (!emm_map_page(h1,0,0xFFFF)) printf("Cannot unmap\n");
-                       }
-                       else {
-                               printf("Cannot map\n");
-                       }
-                       if (!emm_free_pages(h1)) printf("Cannot free\n");
-               }
-               else printf("FAILED\n");
-
-               printf("Allocating EMM pages (32KB): ");
-               h1 = emm_alloc_pages(2);
-               if (h1 >= 0) {
-                       printf("OK, handle=%u\n",h1);
-                       if (    emm_map_page(h1,/*physical*/0,/*logical*/0) &&
-                               emm_map_page(h1,/*physical*/1,/*logical*/1)) {
-                               unsigned int seg1 = emm_last_phys_page_segment(0);
-                               unsigned int seg2 = emm_last_phys_page_segment(1);
-                               printf("Seg %04x,%04x\n",seg1,seg2);
-                               if (seg1 > 0 && seg2 > 0) {
-#if TARGET_MSDOS == 16
-                                       char far *ptr1 = MK_FP(seg1,0);
-                                       char far *ptr2 = MK_FP(seg2,0);
-#else
-                                       char *ptr1 = (char*)(seg1 << 4UL);
-                                       char *ptr2 = (char*)(seg2 << 4UL);
-#endif
-
-#if TARGET_MSDOS == 16
-                                       _fmemcpy(ptr1,(char far*)message,message_l+1);
-                                       _fmemcpy(ptr2,(char far*)message2,message2_l+1);
-#else
-                                       memcpy(ptr1,message,message_l+1);
-                                       memcpy(ptr2,message2,message2_l+1);
-#endif
-
-#if TARGET_MSDOS == 16
-                                       _fmemcpy((char far*)tmp,ptr1,message_l+1);
-                                       _fmemcpy((char far*)tmp2,ptr2,message2_l+1);
-#else
-                                       memcpy(tmp,ptr1,message_l+1);
-                                       memcpy(tmp2,ptr2,message2_l+1);
-#endif
-
-                                       printf("After writing message there, I read back:\n'%s'\n'%s'\n",tmp,tmp2);
-
-                                       /* now swap the pages */
-                                       if (!emm_map_page(h1,1,0)) printf("cannot map log 1 -> phys 0\n");
-                                       if (!emm_map_page(h1,0,1)) printf("cannot map log 0 -> phys 1\n");
-
-#if TARGET_MSDOS == 16
-                                       _fmemcpy((char far*)tmp,ptr1,message2_l+1);
-                                       _fmemcpy((char far*)tmp2,ptr2,message_l+1);
-#else
-                                       memcpy(tmp,ptr1,message2_l+1);
-                                       memcpy(tmp2,ptr2,message_l+1);
-#endif
-
-                                       printf("After swapping pages, I read back:\n'%s'\n'%s'\n",tmp,tmp2);
-                               }
-                               else {
-                                       printf("Cannot get segment\n");
-                               }
-                               if (!emm_map_page(h1,0,0xFFFF) || !emm_map_page(h1,1,0xFFFF)) printf("Cannot unmap\n");
-                       }
-                       else {
-                               printf("Cannot map\n");
-                       }
-                       if (!emm_free_pages(h1)) printf("Cannot free\n");
-               }
-               else printf("FAILED\n");
-
-               getch();
-
-               /* we do this test because Microsoft EMM386.EXE seems to max out at 32MB.
-                * the host could have 256MB of total memory and it would still report 32MB in EMS */
-               printf("we do this test because Microsoft EMM386.EXE seems to max out at 32MB.\n the host could have 256MB of total memory and it would still report 32MB in EMS");
-               printf("Allocating EMM pages (48MB): ");
-               h1 = emm_alloc_pages((48UL << 20UL) >> 14UL);
-               if (h1 >= 0) {
-                       printf("OK, handle=%u\n",h1);
-                       if (!emm_free_pages(h1)) printf("cannot free\n");
-               }
-               else printf("FAILED\n");
-
-               printf("Allocating EMM pages (96MB): ");
-               h1 = emm_alloc_pages((96UL << 20UL) >> 14UL);
-               if (h1 >= 0) {
-                       printf("OK, handle=%u\n",h1);
-                       if (!emm_free_pages(h1)) printf("cannot free\n");
-               }
-               else printf("FAILED\n");
-       }
-
-       return 0;
-}
-
+/* testemm.c\r
+ *\r
+ * Test program: Expanded Memory Manager functions\r
+ * (C) 2011-2012 Jonathan Campbell.\r
+ * Hackipedia DOS library.\r
+ *\r
+ * This code is licensed under the LGPL.\r
+ * <insert LGPL legal text here>\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <stdint.h>\r
+#include <assert.h>\r
+#include <stdio.h>\r
+#include <conio.h>\r
+#include <dos.h>\r
+\r
+//#include "src/lib/doslib/cpu.h"\r
+#include "src/lib/doslib/dos.h"\r
+#include "src/lib/doslib/emm.h"\r
+//#include <hw/dos/doswin.h>\r
+\r
+static const char *message = "Hello world. How are you?";\r
+static const char *message2 = "Pingas. Sup dawg. Hello world. Dork. Hahahajajaja.";\r
+static char tmp[128],tmp2[128];\r
+extern int probe_emm0();\r
+\r
+#if 1\r
+# define x_memcpy(a,b,c) memcpy(a,b,c)\r
+#else\r
+/* what have we come to when friggin' memcpy() causes a GPF?!? */\r
+static void x_memcpy(unsigned char *dst,const unsigned char *src,size_t c) {\r
+       fprintf(stderr,"memcpy %p -> %p (%lu)\n",\r
+               dst,src,(unsigned long)c);\r
+\r
+       while (c != 0) {\r
+           *dst++ = *src++;\r
+           c--;\r
+       }\r
+}\r
+#endif\r
+\r
+int main() {\r
+       size_t message_l = strlen(message),message2_l = strlen(message2);\r
+\r
+       probe_dos();\r
+       printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF);\r
+       /*if (detect_windows()) {\r
+               printf("I am running under Windows.\n");\r
+               printf("    Mode: %s\n",windows_mode_str(windows_mode));\r
+               printf("    Ver:  %x.%02u\n",windows_version>>8,windows_version&0xFF);\r
+       }\r
+       else {\r
+               printf("Not running under Windows or OS/2\n");\r
+       }*/\r
+\r
+       sanity();\r
+       if (probe_emm()) {\r
+               int h1,h2,h3;\r
+\r
+               sanity();\r
+               printf("Expanded memory manager present. Status = 0x%02x Page frame @0x%04x v%x.%x\n",emm_status,emm_page_frame_segment,emm_version>>4,emm_version&0x0F);\r
+               emm_update_page_count();\r
+               sanity();\r
+               printf("  Unallocated pages:     %u (%luKB)\n",\r
+                       emm_unallocated_pages,\r
+                       (unsigned long)emm_unallocated_pages << 4UL); /* 2^14 = 16384 */\r
+               printf("  Total pages:           %u (%luKB)\n",\r
+                       emm_total_pages,\r
+                       (unsigned long)emm_total_pages << 4UL);\r
+               printf("  Physical pages:        %u (%luKB)\n",\r
+                       emm_phys_pages,\r
+                       (unsigned long)emm_phys_pages << 4UL);\r
+\r
+               while (getch() != 13);\r
+               sanity();\r
+\r
+               /* print out the mapping table, if available */\r
+               if (emm_phys_map != NULL) {\r
+                       struct emm_phys_page_map *me;\r
+                       unsigned int i;\r
+\r
+                       printf("Physical page to segment table\n");\r
+                       for (i=0;i < emm_phys_pages;i++) {\r
+                               me = emm_phys_map + i;\r
+                               printf("  %02x: 0x%04x",me->number,me->segment);\r
+                               if ((i%5) == 4) printf("\n");\r
+                       }\r
+                       printf("\n");\r
+                       sanity();\r
+               }\r
+\r
+               printf("Allocating EMM pages (1): ");\r
+               h1 = emm_alloc_pages(1);\r
+               sanity();\r
+               if (h1 >= 0) {\r
+                       printf("OK, handle=%u\n",h1);\r
+                       if (!emm_free_pages(h1)) printf("cannot free\n");\r
+               }\r
+               else printf("FAILED\n");\r
+\r
+               printf("Allocating EMM pages (16KB): ");\r
+               h1 = emm_alloc_pages(1);\r
+               sanity();\r
+               if (h1 >= 0) printf("OK, handle=%u\n",h1);\r
+               else printf("FAILED\n");\r
+\r
+               printf("Allocating EMM pages (1.6MB): ");\r
+               h2 = emm_alloc_pages(0x19999AUL >> 14UL);\r
+               sanity();\r
+               if (h2 >= 0) printf("OK, handle=%u\n",h2);\r
+               else printf("FAILED\n");\r
+\r
+               printf("Allocating EMM pages (12MB): ");\r
+               h3 = emm_alloc_pages(0xC00000UL >> 14UL);\r
+               sanity();\r
+               if (h3 >= 0) printf("OK, handle=%u\n",h3);\r
+               else printf("FAILED\n");\r
+\r
+               while (getch() != 13);\r
+\r
+               if (h1 >= 0 && !emm_free_pages(h1)) printf("Cannot free\n");\r
+               sanity();\r
+               if (h2 >= 0 && !emm_free_pages(h2)) printf("Cannot free\n");\r
+               sanity();\r
+               if (h3 >= 0 && !emm_free_pages(h3)) printf("Cannot free\n");\r
+               sanity();\r
+\r
+               printf("Allocating EMM pages (32KB): ");\r
+               h1 = emm_alloc_pages(2);\r
+               sanity();\r
+               if (h1 >= 0) {\r
+                       printf("OK, handle=%u\n",h1);\r
+                       if (emm_map_page(h1,/*physical*/0,/*logical*/0)) {\r
+                               unsigned int segm = emm_last_phys_page_segment(0);\r
+                               printf("Seg %04x\n",segm);\r
+                               sanity();\r
+                               if (segm > 0) {\r
+#if TARGET_MSDOS == 16\r
+                                       char far *ptr = MK_FP(segm,0);\r
+#else\r
+                                       char *ptr = (char*)(segm << 4UL);\r
+#endif\r
+\r
+#if TARGET_MSDOS == 16\r
+                                       _fmemcpy(ptr,(char far*)message,message_l+1);\r
+                                       _fmemcpy((char far*)tmp,ptr,message_l+1);\r
+#else\r
+                                       x_memcpy(ptr,message,message_l+1);\r
+                                       x_memcpy(tmp,ptr,message_l+1);\r
+#endif\r
+                                       printf("After writing message there, I read back: '%s'\n",tmp);\r
+\r
+                                       if (!emm_map_page(h1,0,1)) printf("Cannot remap\n");\r
+\r
+#if TARGET_MSDOS == 16\r
+                                       _fmemcpy(ptr,(char far*)message2,message2_l+1);\r
+                                       _fmemcpy((char far*)tmp,ptr,message2_l+1);\r
+#else\r
+                                       x_memcpy(ptr,message2,message2_l+1);\r
+                                       x_memcpy(tmp,ptr,message2_l+1);\r
+#endif\r
+                                       printf("After mapping to page 2 and writing there, I read back: '%s'\n",tmp);\r
+\r
+                                       if (!emm_map_page(h1,0,0)) printf("Cannot remap\n");\r
+\r
+#if TARGET_MSDOS == 16\r
+                                       _fmemcpy((char far*)tmp,ptr,message_l+1);\r
+#else\r
+                                       x_memcpy(tmp,ptr,message_l+1);\r
+#endif\r
+                                       printf("After mapping back to 1, I read back: '%s'\n",tmp);\r
+\r
+                                       if (emm_map_page(h1,0,2)) printf("Whoops, I was able to map logical pages beyond what I allocated\n");\r
+                               }\r
+                               else {\r
+                                       printf("Cannot get segment\n");\r
+                               }\r
+                               if (!emm_map_page(h1,0,0xFFFF)) printf("Cannot unmap\n");\r
+                       }\r
+                       else {\r
+                               printf("Cannot map\n");\r
+                       }\r
+                       if (!emm_free_pages(h1)) printf("Cannot free\n");\r
+               }\r
+               else printf("FAILED\n");\r
+\r
+               printf("Allocating EMM pages (32KB): ");\r
+               h1 = emm_alloc_pages(2);\r
+               if (h1 >= 0) {\r
+                       printf("OK, handle=%u\n",h1);\r
+                       if (    emm_map_page(h1,/*physical*/0,/*logical*/0) &&\r
+                               emm_map_page(h1,/*physical*/1,/*logical*/1)) {\r
+                               unsigned int seg1 = emm_last_phys_page_segment(0);\r
+                               unsigned int seg2 = emm_last_phys_page_segment(1);\r
+                               printf("Seg %04x,%04x\n",seg1,seg2);\r
+                               if (seg1 > 0 && seg2 > 0) {\r
+#if TARGET_MSDOS == 16\r
+                                       char far *ptr1 = MK_FP(seg1,0);\r
+                                       char far *ptr2 = MK_FP(seg2,0);\r
+#else\r
+                                       char *ptr1 = (char*)(seg1 << 4UL);\r
+                                       char *ptr2 = (char*)(seg2 << 4UL);\r
+#endif\r
+\r
+#if TARGET_MSDOS == 16\r
+                                       _fmemcpy(ptr1,(char far*)message,message_l+1);\r
+                                       _fmemcpy(ptr2,(char far*)message2,message2_l+1);\r
+#else\r
+                                       memcpy(ptr1,message,message_l+1);\r
+                                       memcpy(ptr2,message2,message2_l+1);\r
+#endif\r
+\r
+#if TARGET_MSDOS == 16\r
+                                       _fmemcpy((char far*)tmp,ptr1,message_l+1);\r
+                                       _fmemcpy((char far*)tmp2,ptr2,message2_l+1);\r
+#else\r
+                                       memcpy(tmp,ptr1,message_l+1);\r
+                                       memcpy(tmp2,ptr2,message2_l+1);\r
+#endif\r
+\r
+                                       printf("After writing message there, I read back:\n'%s'\n'%s'\n",tmp,tmp2);\r
+\r
+                                       /* now swap the pages */\r
+                                       if (!emm_map_page(h1,1,0)) printf("cannot map log 1 -> phys 0\n");\r
+                                       if (!emm_map_page(h1,0,1)) printf("cannot map log 0 -> phys 1\n");\r
+\r
+#if TARGET_MSDOS == 16\r
+                                       _fmemcpy((char far*)tmp,ptr1,message2_l+1);\r
+                                       _fmemcpy((char far*)tmp2,ptr2,message_l+1);\r
+#else\r
+                                       memcpy(tmp,ptr1,message2_l+1);\r
+                                       memcpy(tmp2,ptr2,message_l+1);\r
+#endif\r
+\r
+                                       printf("After swapping pages, I read back:\n'%s'\n'%s'\n",tmp,tmp2);\r
+                               }\r
+                               else {\r
+                                       printf("Cannot get segment\n");\r
+                               }\r
+                               if (!emm_map_page(h1,0,0xFFFF) || !emm_map_page(h1,1,0xFFFF)) printf("Cannot unmap\n");\r
+                       }\r
+                       else {\r
+                               printf("Cannot map\n");\r
+                       }\r
+                       if (!emm_free_pages(h1)) printf("Cannot free\n");\r
+               }\r
+               else printf("FAILED\n");\r
+\r
+               getch();\r
+\r
+               /* we do this test because Microsoft EMM386.EXE seems to max out at 32MB.\r
+                * the host could have 256MB of total memory and it would still report 32MB in EMS */\r
+               printf("we do this test because Microsoft EMM386.EXE seems to max out at 32MB.\n the host could have 256MB of total memory and it would still report 32MB in EMS");\r
+               printf("Allocating EMM pages (48MB): ");\r
+               h1 = emm_alloc_pages((48UL << 20UL) >> 14UL);\r
+               if (h1 >= 0) {\r
+                       printf("OK, handle=%u\n",h1);\r
+                       if (!emm_free_pages(h1)) printf("cannot free\n");\r
+               }\r
+               else printf("FAILED\n");\r
+\r
+               printf("Allocating EMM pages (96MB): ");\r
+               h1 = emm_alloc_pages((96UL << 20UL) >> 14UL);\r
+               if (h1 >= 0) {\r
+                       printf("OK, handle=%u\n",h1);\r
+                       if (!emm_free_pages(h1)) printf("cannot free\n");\r
+               }\r
+               else printf("FAILED\n");\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
index 16f5654b7cb6de2c2b949a5087b8d25355ff430d..a83564e70a00831b51c28758a223a302617d788c 100755 (executable)
-/* testemm.c
- *
- * Test program: Expanded Memory Manager functions
- * (C) 2011-2012 Jonathan Campbell.
- * Hackipedia DOS library.
- *
- * This code is licensed under the LGPL.
- * <insert LGPL legal text here>
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <assert.h>
-#include <stdio.h>
-#include <conio.h>
-#include <dos.h>
-
-//#include "src/lib/doslib/cpu.h"
-#include "src/lib/doslib/dos.h"
-#include "src/lib/doslib/emm.h"
-//#include <hw/dos/doswin.h>
-
-static const char *message = "Hello world. How are you?";
-static const char *message2 = "Pingas. Sup dawg. Hello world. Dork. Hahahajajaja.";
-static char tmp[128],tmp2[128];
-extern int probe_emm0();
-
-#if 1
-# define x_memcpy(a,b,c) memcpy(a,b,c)
-#else
-/* what have we come to when friggin' memcpy() causes a GPF?!? */
-static void x_memcpy(unsigned char *dst,const unsigned char *src,size_t c) {
-       fprintf(stderr,"memcpy %p -> %p (%lu)\n",
-               dst,src,(unsigned long)c);
-
-       while (c != 0) {
-           *dst++ = *src++;
-           c--;
-       }
-}
-#endif
-
-int main() {
-       size_t message_l = strlen(message),message2_l = strlen(message2);
-
-       probe_dos();
-       printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF);
-       /*if (detect_windows()) {
-               printf("I am running under Windows.\n");
-               printf("    Mode: %s\n",windows_mode_str(windows_mode));
-               printf("    Ver:  %x.%02u\n",windows_version>>8,windows_version&0xFF);
-       }
-       else {
-               printf("Not running under Windows or OS/2\n");
-       }*/
-
-       sanity();
-       if (probe_emm()) {
-               int h1,h2,h3;
-
-               sanity();
-               printf("Expanded memory manager present. Status = 0x%02x Page frame @0x%04x v%x.%x\n",emm_status,emm_page_frame_segment,emm_version>>4,emm_version&0x0F);
-               emm_update_page_count();
-               sanity();
-               printf("  Unallocated pages:     %u (%luKB)\n",
-                       emm_unallocated_pages,
-                       (unsigned long)emm_unallocated_pages << 4UL); /* 2^14 = 16384 */
-               printf("  Total pages:           %u (%luKB)\n",
-                       emm_total_pages,
-                       (unsigned long)emm_total_pages << 4UL);
-               printf("  Physical pages:        %u (%luKB)\n",
-                       emm_phys_pages,
-                       (unsigned long)emm_phys_pages << 4UL);
-
-               while (getch() != 13);
-               sanity();
-
-               /* print out the mapping table, if available */
-               if (emm_phys_map != NULL) {
-                       struct emm_phys_page_map *me;
-                       unsigned int i;
-
-                       printf("Physical page to segment table\n");
-                       for (i=0;i < emm_phys_pages;i++) {
-                               me = emm_phys_map + i;
-                               printf("  %02x: 0x%04x",me->number,me->segment);
-                               if ((i%5) == 4) printf("\n");
-                       }
-                       printf("\n");
-                       sanity();
-               }
-
-               printf("Allocating EMM pages (1): ");
-               h1 = emm_alloc_pages(1);
-               sanity();
-               if (h1 >= 0) {
-                       printf("OK, handle=%u\n",h1);
-                       if (!emm_free_pages(h1)) printf("cannot free\n");
-               }
-               else printf("FAILED\n");
-
-               printf("Allocating EMM pages (%luKB): ", (dword)emm_unallocated_pages << 4UL);
-               h1 = emm_alloc_pages(emm_unallocated_pages);
-               sanity();
-               if (h1 >= 0) printf("OK, handle=%u\n",h1);
-               else printf("FAILED\n");
-
-//             printf("Allocating EMM pages (1.6MB): ");
-               //h2 = emm_alloc_pages(0x19999AUL >> 14UL);
-               /*h2 = emm_alloc_pages(1);
-               sanity();
-               if (h2 >= 0) printf("OK, handle=%u\n",h2);
-               else printf("FAILED\n");
-
-               //printf("Allocating EMM pages (12MB): ");
-               //h3 = emm_alloc_pages(0xC00000UL >> 14UL);
-               h3 = emm_alloc_pages(1);
-               sanity();
-               if (h3 >= 0) printf("OK, handle=%u\n",h3);
-               else printf("FAILED\n");*/
-
-               while (getch() != 13);
-
-               if (h1 >= 0 && !emm_free_pages(h1)) printf("Cannot free\n");
-               sanity();
-               /*if (h2 >= 0 && !emm_free_pages(h2)) printf("Cannot free\n");
-               sanity();
-               if (h3 >= 0 && !emm_free_pages(h3)) printf("Cannot free\n");
-               sanity();*/
-
-               printf("Allocating EMM pages (32KB): ");
-               h1 = emm_alloc_pages(2);
-               sanity();
-               if (h1 >= 0) {
-                       printf("OK, handle=%u\n",h1);
-                       if (emm_map_page(h1,/*physical*/0,/*logical*/0)) {
-                               unsigned int segm = emm_last_phys_page_segment(0);
-                               printf("Seg %04x\n",segm);
-                               sanity();
-                               if (segm > 0) {
-#if TARGET_MSDOS == 16
-                                       char far *ptr = MK_FP(segm,0);
-#else
-                                       char *ptr = (char*)(segm << 4UL);
-#endif
-
-#if TARGET_MSDOS == 16
-                                       _fmemcpy(ptr,(char far*)message,message_l+1);
-                                       _fmemcpy((char far*)tmp,ptr,message_l+1);
-#else
-                                       x_memcpy(ptr,message,message_l+1);
-                                       x_memcpy(tmp,ptr,message_l+1);
-#endif
-                                       printf("After writing message there, I read back: '%s'\n",tmp);
-
-                                       if (!emm_map_page(h1,0,1)) printf("Cannot remap\n");
-
-#if TARGET_MSDOS == 16
-                                       _fmemcpy(ptr,(char far*)message2,message2_l+1);
-                                       _fmemcpy((char far*)tmp,ptr,message2_l+1);
-#else
-                                       x_memcpy(ptr,message2,message2_l+1);
-                                       x_memcpy(tmp,ptr,message2_l+1);
-#endif
-                                       printf("After mapping to page 2 and writing there, I read back: '%s'\n",tmp);
-
-                                       if (!emm_map_page(h1,0,0)) printf("Cannot remap\n");
-
-#if TARGET_MSDOS == 16
-                                       _fmemcpy((char far*)tmp,ptr,message_l+1);
-#else
-                                       x_memcpy(tmp,ptr,message_l+1);
-#endif
-                                       printf("After mapping back to 1, I read back: '%s'\n",tmp);
-
-                                       if (emm_map_page(h1,0,2)) printf("Whoops, I was able to map logical pages beyond what I allocated\n");
-                               }
-                               else {
-                                       printf("Cannot get segment\n");
-                               }
-                               if (!emm_map_page(h1,0,0xFFFF)) printf("Cannot unmap\n");
-                       }
-                       else {
-                               printf("Cannot map\n");
-                       }
-                       if (!emm_free_pages(h1)) printf("Cannot free\n");
-               }
-               else printf("FAILED\n");
-
-               printf("Allocating EMM pages (32KB): ");
-               h1 = emm_alloc_pages(2);
-               if (h1 >= 0) {
-                       printf("OK, handle=%u\n",h1);
-                       if (    emm_map_page(h1,/*physical*/0,/*logical*/0) &&
-                               emm_map_page(h1,/*physical*/1,/*logical*/1)) {
-                               unsigned int seg1 = emm_last_phys_page_segment(0);
-                               unsigned int seg2 = emm_last_phys_page_segment(1);
-                               printf("Seg %04x,%04x\n",seg1,seg2);
-                               if (seg1 > 0 && seg2 > 0) {
-#if TARGET_MSDOS == 16
-                                       char far *ptr1 = MK_FP(seg1,0);
-                                       char far *ptr2 = MK_FP(seg2,0);
-#else
-                                       char *ptr1 = (char*)(seg1 << 4UL);
-                                       char *ptr2 = (char*)(seg2 << 4UL);
-#endif
-
-#if TARGET_MSDOS == 16
-                                       _fmemcpy(ptr1,(char far*)message,message_l+1);
-                                       _fmemcpy(ptr2,(char far*)message2,message2_l+1);
-#else
-                                       memcpy(ptr1,message,message_l+1);
-                                       memcpy(ptr2,message2,message2_l+1);
-#endif
-
-#if TARGET_MSDOS == 16
-                                       _fmemcpy((char far*)tmp,ptr1,message_l+1);
-                                       _fmemcpy((char far*)tmp2,ptr2,message2_l+1);
-#else
-                                       memcpy(tmp,ptr1,message_l+1);
-                                       memcpy(tmp2,ptr2,message2_l+1);
-#endif
-
-                                       printf("After writing message there, I read back:\n'%s'\n'%s'\n",tmp,tmp2);
-
-                                       /* now swap the pages */
-                                       if (!emm_map_page(h1,1,0)) printf("cannot map log 1 -> phys 0\n");
-                                       if (!emm_map_page(h1,0,1)) printf("cannot map log 0 -> phys 1\n");
-
-#if TARGET_MSDOS == 16
-                                       _fmemcpy((char far*)tmp,ptr1,message2_l+1);
-                                       _fmemcpy((char far*)tmp2,ptr2,message_l+1);
-#else
-                                       memcpy(tmp,ptr1,message2_l+1);
-                                       memcpy(tmp2,ptr2,message_l+1);
-#endif
-
-                                       printf("After swapping pages, I read back:\n'%s'\n'%s'\n",tmp,tmp2);
-                               }
-                               else {
-                                       printf("Cannot get segment\n");
-                               }
-                               if (!emm_map_page(h1,0,0xFFFF) || !emm_map_page(h1,1,0xFFFF)) printf("Cannot unmap\n");
-                       }
-                       else {
-                               printf("Cannot map\n");
-                       }
-                       if (!emm_free_pages(h1)) printf("Cannot free\n");
-               }
-               else printf("FAILED\n");
-
-               getch();
-
-               /* we do this test because Microsoft EMM386.EXE seems to max out at 32MB.
-                * the host could have 256MB of total memory and it would still report 32MB in EMS */
-               printf("we do this test because Microsoft EMM386.EXE seems to max out at 32MB.\n the host could have 256MB of total memory and it would still report 32MB in EMS");
-               printf("Allocating EMM pages (48MB): ");
-               h1 = emm_alloc_pages((48UL << 20UL) >> 14UL);
-               if (h1 >= 0) {
-                       printf("OK, handle=%u\n",h1);
-                       if (!emm_free_pages(h1)) printf("cannot free\n");
-               }
-               else printf("FAILED\n");
-
-               printf("Allocating EMM pages (96MB): ");
-               h1 = emm_alloc_pages((96UL << 20UL) >> 14UL);
-               if (h1 >= 0) {
-                       printf("OK, handle=%u\n",h1);
-                       if (!emm_free_pages(h1)) printf("cannot free\n");
-               }
-               else printf("FAILED\n");
-       }
-
-       return 0;
-}
+/* testemm.c\r
+ *\r
+ * Test program: Expanded Memory Manager functions\r
+ * (C) 2011-2012 Jonathan Campbell.\r
+ * Hackipedia DOS library.\r
+ *\r
+ * This code is licensed under the LGPL.\r
+ * <insert LGPL legal text here>\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <stdint.h>\r
+#include <assert.h>\r
+#include <stdio.h>\r
+#include <conio.h>\r
+#include <dos.h>\r
+\r
+//#include "src/lib/doslib/cpu.h"\r
+#include "src/lib/doslib/dos.h"\r
+#include "src/lib/doslib/emm.h"\r
+//#include <hw/dos/doswin.h>\r
+\r
+static const char *message = "Hello world. How are you?";\r
+static const char *message2 = "Pingas. Sup dawg. Hello world. Dork. Hahahajajaja.";\r
+static char tmp[128],tmp2[128];\r
+extern int probe_emm0();\r
+\r
+#if 1\r
+# define x_memcpy(a,b,c) memcpy(a,b,c)\r
+#else\r
+/* what have we come to when friggin' memcpy() causes a GPF?!? */\r
+static void x_memcpy(unsigned char *dst,const unsigned char *src,size_t c) {\r
+       fprintf(stderr,"memcpy %p -> %p (%lu)\n",\r
+               dst,src,(unsigned long)c);\r
+\r
+       while (c != 0) {\r
+           *dst++ = *src++;\r
+           c--;\r
+       }\r
+}\r
+#endif\r
+\r
+int main() {\r
+       size_t message_l = strlen(message),message2_l = strlen(message2);\r
+\r
+       probe_dos();\r
+       printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF);\r
+       /*if (detect_windows()) {\r
+               printf("I am running under Windows.\n");\r
+               printf("    Mode: %s\n",windows_mode_str(windows_mode));\r
+               printf("    Ver:  %x.%02u\n",windows_version>>8,windows_version&0xFF);\r
+       }\r
+       else {\r
+               printf("Not running under Windows or OS/2\n");\r
+       }*/\r
+\r
+       sanity();\r
+       if (probe_emm()) {\r
+               int h1,h2,h3;\r
+\r
+               sanity();\r
+               printf("Expanded memory manager present. Status = 0x%02x Page frame @0x%04x v%x.%x\n",emm_status,emm_page_frame_segment,emm_version>>4,emm_version&0x0F);\r
+               emm_update_page_count();\r
+               sanity();\r
+               printf("  Unallocated pages:     %u (%luKB)\n",\r
+                       emm_unallocated_pages,\r
+                       (unsigned long)emm_unallocated_pages << 4UL); /* 2^14 = 16384 */\r
+               printf("  Total pages:           %u (%luKB)\n",\r
+                       emm_total_pages,\r
+                       (unsigned long)emm_total_pages << 4UL);\r
+               printf("  Physical pages:        %u (%luKB)\n",\r
+                       emm_phys_pages,\r
+                       (unsigned long)emm_phys_pages << 4UL);\r
+\r
+               while (getch() != 13);\r
+               sanity();\r
+\r
+               /* print out the mapping table, if available */\r
+               if (emm_phys_map != NULL) {\r
+                       struct emm_phys_page_map *me;\r
+                       unsigned int i;\r
+\r
+                       printf("Physical page to segment table\n");\r
+                       for (i=0;i < emm_phys_pages;i++) {\r
+                               me = emm_phys_map + i;\r
+                               printf("  %02x: 0x%04x",me->number,me->segment);\r
+                               if ((i%5) == 4) printf("\n");\r
+                       }\r
+                       printf("\n");\r
+                       sanity();\r
+               }\r
+\r
+               printf("Allocating EMM pages (1): ");\r
+               h1 = emm_alloc_pages(1);\r
+               sanity();\r
+               if (h1 >= 0) {\r
+                       printf("OK, handle=%u\n",h1);\r
+                       if (!emm_free_pages(h1)) printf("cannot free\n");\r
+               }\r
+               else printf("FAILED\n");\r
+\r
+               printf("Allocating EMM pages (%luKB): ", (dword)emm_unallocated_pages << 4UL);\r
+               h1 = emm_alloc_pages(emm_unallocated_pages);\r
+               sanity();\r
+               if (h1 >= 0) printf("OK, handle=%u\n",h1);\r
+               else printf("FAILED\n");\r
+\r
+//             printf("Allocating EMM pages (1.6MB): ");\r
+               //h2 = emm_alloc_pages(0x19999AUL >> 14UL);\r
+               /*h2 = emm_alloc_pages(1);\r
+               sanity();\r
+               if (h2 >= 0) printf("OK, handle=%u\n",h2);\r
+               else printf("FAILED\n");\r
+\r
+               //printf("Allocating EMM pages (12MB): ");\r
+               //h3 = emm_alloc_pages(0xC00000UL >> 14UL);\r
+               h3 = emm_alloc_pages(1);\r
+               sanity();\r
+               if (h3 >= 0) printf("OK, handle=%u\n",h3);\r
+               else printf("FAILED\n");*/\r
+\r
+               while (getch() != 13);\r
+\r
+               if (h1 >= 0 && !emm_free_pages(h1)) printf("Cannot free\n");\r
+               sanity();\r
+               /*if (h2 >= 0 && !emm_free_pages(h2)) printf("Cannot free\n");\r
+               sanity();\r
+               if (h3 >= 0 && !emm_free_pages(h3)) printf("Cannot free\n");\r
+               sanity();*/\r
+\r
+               printf("Allocating EMM pages (32KB): ");\r
+               h1 = emm_alloc_pages(2);\r
+               sanity();\r
+               if (h1 >= 0) {\r
+                       printf("OK, handle=%u\n",h1);\r
+                       if (emm_map_page(h1,/*physical*/0,/*logical*/0)) {\r
+                               unsigned int segm = emm_last_phys_page_segment(0);\r
+                               printf("Seg %04x\n",segm);\r
+                               sanity();\r
+                               if (segm > 0) {\r
+#if TARGET_MSDOS == 16\r
+                                       char far *ptr = MK_FP(segm,0);\r
+#else\r
+                                       char *ptr = (char*)(segm << 4UL);\r
+#endif\r
+\r
+#if TARGET_MSDOS == 16\r
+                                       _fmemcpy(ptr,(char far*)message,message_l+1);\r
+                                       _fmemcpy((char far*)tmp,ptr,message_l+1);\r
+#else\r
+                                       x_memcpy(ptr,message,message_l+1);\r
+                                       x_memcpy(tmp,ptr,message_l+1);\r
+#endif\r
+                                       printf("After writing message there, I read back: '%s'\n",tmp);\r
+\r
+                                       if (!emm_map_page(h1,0,1)) printf("Cannot remap\n");\r
+\r
+#if TARGET_MSDOS == 16\r
+                                       _fmemcpy(ptr,(char far*)message2,message2_l+1);\r
+                                       _fmemcpy((char far*)tmp,ptr,message2_l+1);\r
+#else\r
+                                       x_memcpy(ptr,message2,message2_l+1);\r
+                                       x_memcpy(tmp,ptr,message2_l+1);\r
+#endif\r
+                                       printf("After mapping to page 2 and writing there, I read back: '%s'\n",tmp);\r
+\r
+                                       if (!emm_map_page(h1,0,0)) printf("Cannot remap\n");\r
+\r
+#if TARGET_MSDOS == 16\r
+                                       _fmemcpy((char far*)tmp,ptr,message_l+1);\r
+#else\r
+                                       x_memcpy(tmp,ptr,message_l+1);\r
+#endif\r
+                                       printf("After mapping back to 1, I read back: '%s'\n",tmp);\r
+\r
+                                       if (emm_map_page(h1,0,2)) printf("Whoops, I was able to map logical pages beyond what I allocated\n");\r
+                               }\r
+                               else {\r
+                                       printf("Cannot get segment\n");\r
+                               }\r
+                               if (!emm_map_page(h1,0,0xFFFF)) printf("Cannot unmap\n");\r
+                       }\r
+                       else {\r
+                               printf("Cannot map\n");\r
+                       }\r
+                       if (!emm_free_pages(h1)) printf("Cannot free\n");\r
+               }\r
+               else printf("FAILED\n");\r
+\r
+               printf("Allocating EMM pages (32KB): ");\r
+               h1 = emm_alloc_pages(2);\r
+               if (h1 >= 0) {\r
+                       printf("OK, handle=%u\n",h1);\r
+                       if (    emm_map_page(h1,/*physical*/0,/*logical*/0) &&\r
+                               emm_map_page(h1,/*physical*/1,/*logical*/1)) {\r
+                               unsigned int seg1 = emm_last_phys_page_segment(0);\r
+                               unsigned int seg2 = emm_last_phys_page_segment(1);\r
+                               printf("Seg %04x,%04x\n",seg1,seg2);\r
+                               if (seg1 > 0 && seg2 > 0) {\r
+#if TARGET_MSDOS == 16\r
+                                       char far *ptr1 = MK_FP(seg1,0);\r
+                                       char far *ptr2 = MK_FP(seg2,0);\r
+#else\r
+                                       char *ptr1 = (char*)(seg1 << 4UL);\r
+                                       char *ptr2 = (char*)(seg2 << 4UL);\r
+#endif\r
+\r
+#if TARGET_MSDOS == 16\r
+                                       _fmemcpy(ptr1,(char far*)message,message_l+1);\r
+                                       _fmemcpy(ptr2,(char far*)message2,message2_l+1);\r
+#else\r
+                                       memcpy(ptr1,message,message_l+1);\r
+                                       memcpy(ptr2,message2,message2_l+1);\r
+#endif\r
+\r
+#if TARGET_MSDOS == 16\r
+                                       _fmemcpy((char far*)tmp,ptr1,message_l+1);\r
+                                       _fmemcpy((char far*)tmp2,ptr2,message2_l+1);\r
+#else\r
+                                       memcpy(tmp,ptr1,message_l+1);\r
+                                       memcpy(tmp2,ptr2,message2_l+1);\r
+#endif\r
+\r
+                                       printf("After writing message there, I read back:\n'%s'\n'%s'\n",tmp,tmp2);\r
+\r
+                                       /* now swap the pages */\r
+                                       if (!emm_map_page(h1,1,0)) printf("cannot map log 1 -> phys 0\n");\r
+                                       if (!emm_map_page(h1,0,1)) printf("cannot map log 0 -> phys 1\n");\r
+\r
+#if TARGET_MSDOS == 16\r
+                                       _fmemcpy((char far*)tmp,ptr1,message2_l+1);\r
+                                       _fmemcpy((char far*)tmp2,ptr2,message_l+1);\r
+#else\r
+                                       memcpy(tmp,ptr1,message2_l+1);\r
+                                       memcpy(tmp2,ptr2,message_l+1);\r
+#endif\r
+\r
+                                       printf("After swapping pages, I read back:\n'%s'\n'%s'\n",tmp,tmp2);\r
+                               }\r
+                               else {\r
+                                       printf("Cannot get segment\n");\r
+                               }\r
+                               if (!emm_map_page(h1,0,0xFFFF) || !emm_map_page(h1,1,0xFFFF)) printf("Cannot unmap\n");\r
+                       }\r
+                       else {\r
+                               printf("Cannot map\n");\r
+                       }\r
+                       if (!emm_free_pages(h1)) printf("Cannot free\n");\r
+               }\r
+               else printf("FAILED\n");\r
+\r
+               getch();\r
+\r
+               /* we do this test because Microsoft EMM386.EXE seems to max out at 32MB.\r
+                * the host could have 256MB of total memory and it would still report 32MB in EMS */\r
+               printf("we do this test because Microsoft EMM386.EXE seems to max out at 32MB.\n the host could have 256MB of total memory and it would still report 32MB in EMS");\r
+               printf("Allocating EMM pages (48MB): ");\r
+               h1 = emm_alloc_pages((48UL << 20UL) >> 14UL);\r
+               if (h1 >= 0) {\r
+                       printf("OK, handle=%u\n",h1);\r
+                       if (!emm_free_pages(h1)) printf("cannot free\n");\r
+               }\r
+               else printf("FAILED\n");\r
+\r
+               printf("Allocating EMM pages (96MB): ");\r
+               h1 = emm_alloc_pages((96UL << 20UL) >> 14UL);\r
+               if (h1 >= 0) {\r
+                       printf("OK, handle=%u\n",h1);\r
+                       if (!emm_free_pages(h1)) printf("cannot free\n");\r
+               }\r
+               else printf("FAILED\n");\r
+       }\r
+\r
+       return 0;\r
+}\r
index 4c5f653443c850642b1126eeab71f374cec9a0bb..43dae78ed1651de061d6c3b181bf58462abf76a0 100755 (executable)
-/* test.c
- *
- * Adlib OPL2/OPL3 FM synthesizer chipset test program.
- * (C) 2010-2012 Jonathan Campbell.
- * Hackipedia DOS library.
- *
- * This code is licensed under the LGPL.
- * <insert LGPL legal text here>
- *
- * Compiles for intended target environments:
- *   - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]
- *
- * This test program uses a "text user interface" to allow you to play
- * with the OPL2/OPL3 chipset and it's parameters. Some "instruments"
- * are preset for you if you want to make noise faster.
- */
-#include <stdio.h>
-#include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <malloc.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <dos.h>
-
-#include <hw/vga/vga.h>
-#include <hw/dos/dos.h>
-#include <hw/8254/8254.h>              /* 8254 timer */
-#include <hw/vga/vgagui.h>
-#include <hw/vga/vgatty.h>
-#include <hw/adlib/adlib.h>
-
-static unsigned int musical_scale[18] = {
-       0x1B0,                  /* E */
-       0x1CA,                  /* F */
-       0x1E5,                  /* f# */
-       0x202,                  /* G */
-       0x220,                  /* G# */
-       0x241,                  /* A */
-       0x263,                  /* A# */
-       0x287,                  /* B */
-       0x2AE,                  /* C */
-
-       0x2B0,                  /* E */
-       0x2CA,                  /* F */
-       0x2E5,                  /* f# */
-       0x302,                  /* G */
-       0x320,                  /* G# */
-       0x341,                  /* A */
-       0x363,                  /* A# */
-       0x387,                  /* B */
-       0x3AE,                  /* C */
-};
-
-int main(int argc,char **argv) {
-       int i,loop,redraw,c,cc,selector=0,redrawln=0,hselect=0,selectsub=0;
-       VGA_ALPHA_PTR vga;
-       char tmp[128];
-
-       printf("ADLIB FM test program\n");
-
-       if (!probe_vga()) {
-               printf("Cannot init VGA\n");
-               return 1;
-       }
-       if (!init_adlib()) {
-               printf("Cannot init library\n");
-               return 1;
-       }
-
-       int10_setmode(3);
-
-       /* for VGA: free up space if needed by going to 80x50 */
-       if (adlib_fm_voices > 9)
-               vga_bios_set_80x50_text();
-
-       memset(adlib_fm,0,sizeof(adlib_fm));
-       memset(&adlib_reg_bd,0,sizeof(adlib_reg_bd));
-       for (i=0;i < adlib_fm_voices;i++) {
-               struct adlib_fm_operator *f;
-               f = &adlib_fm[i].mod;
-               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;
-               f = &adlib_fm[i].car;
-               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;
-       }
-
-       for (i=0;i < adlib_fm_voices;i++) {
-               struct adlib_fm_operator *f;
-
-               f = &adlib_fm[i].mod;
-               f->mod_multiple = 1;
-               f->total_level = 63 - 16;
-               f->attack_rate = 15;
-               f->decay_rate = 0;
-               f->sustain_level = 7;
-               f->release_rate = 7;
-               f->f_number = musical_scale[i%18];
-               f->octave = 4;
-               f->key_on = 0;
-
-               f = &adlib_fm[i].car;
-               f->mod_multiple = 1;
-               f->total_level = 63 - 16;
-               f->attack_rate = 15;
-               f->decay_rate = 0;
-               f->sustain_level = 7;
-               f->release_rate = 7;
-               f->f_number = 0;
-               f->octave = 0;
-               f->key_on = 0;
-       }
-
-       adlib_apply_all();
-
-       vga_write_color(0x07);
-       vga_clear();
-
-       loop=1;
-       redraw=1;
-       while (loop) {
-               if (redraw || redrawln) {
-                       if (redraw) {
-                               for (vga=vga_alpha_ram,cc=0;cc < (80*vga_height);cc++) *vga++ = 0x1E00 | 177;
-                               vga_moveto(0,0);
-                               vga_write_color(0x1F);
-                               sprintf(tmp,"Adlib FM, %u-voice %s. Use Z & X to adj  F10=PRESET F1=QUIET ",adlib_fm_voices,
-                                       (adlib_flags & ADLIB_FM_OPL3) ? "OPL3" :
-                                       (adlib_flags & ADLIB_FM_DUAL_OPL2) ? "Dual OPL2" : "OPL2");
-                               vga_write(tmp);
-                               if (adlib_flags & ADLIB_FM_OPL3) vga_write("F2=OPL3 off ");
-                       }
-
-                       if (redrawln || redraw) {
-                               struct adlib_reg_bd *bd = &adlib_reg_bd;
-                               static const char *hsel_str[18] = {
-                                       "Amplitude modulatation",
-                                       "Vibrato",
-                                       "Sustain",
-                                       "Key scaling rate",
-                                       "Modulator frequency multiple",
-                                       "Level key scaling",
-                                       "Total level",
-                                       "Attack rate",
-                                       "Decay rate",
-                                       "Sustain level",
-                                       "Release rate",
-                                       "KEY ON",
-                                       "Octave",
-                                       "F-Number",
-                                       "Feedback",
-                                       "Connection (operator 1 -> operator 2)",
-                                       "Waveform",
-                                       "Channel mapping (OPL3)"
-                               };
-
-                               vga_write_color(0x1A);
-
-                               vga_moveto(0,2);
-                               sprintf(tmp,"AM=%u VB=%u RYTHM=%u BAS=%u SNA=%u TOM=%u CYM=%u HI=%u\n",
-                                       bd->am_depth,
-                                       bd->vibrato_depth,
-                                       bd->rythm_enable,
-                                       bd->bass_drum_on,
-                                       bd->snare_drum_on,
-                                       bd->tom_tom_on,
-                                       bd->cymbal_on,
-                                       bd->hi_hat_on);
-                               vga_write(tmp);
-
-                               vga_moveto(0,3);
-                               vga_write("                                                       ");
-                               vga_moveto(0,3);
-                               vga_write(hsel_str[hselect]);
-
-                               vga_moveto(0,4);
-                               vga_write_color(hselect ==  0 ? 0x70 : 0x1E);           vga_write("AM ");
-                               vga_write_color(hselect ==  1 ? 0x70 : 0x1E);           vga_write("VB ");
-                               vga_write_color(hselect ==  2 ? 0x70 : 0x1E);           vga_write("SUST ");
-                               vga_write_color(hselect ==  3 ? 0x70 : 0x1E);           vga_write("KSR ");
-                               vga_write_color(hselect ==  4 ? 0x70 : 0x1E);           vga_write("MMUL ");
-                               vga_write_color(hselect ==  5 ? 0x70 : 0x1E);           vga_write("LKS ");
-                               vga_write_color(hselect ==  6 ? 0x70 : 0x1E);           vga_write("TL ");
-                               vga_write_color(hselect ==  7 ? 0x70 : 0x1E);           vga_write("AR ");
-                               vga_write_color(hselect ==  8 ? 0x70 : 0x1E);           vga_write("DR ");
-                               vga_write_color(hselect ==  9 ? 0x70 : 0x1E);           vga_write("SL ");
-                               vga_write_color(hselect == 10 ? 0x70 : 0x1E);           vga_write("RR ");
-                               vga_write_color(hselect == 11 ? 0x70 : 0x1E);           vga_write("KEY ");
-                               vga_write_color(hselect == 12 ? 0x70 : 0x1E);           vga_write("OCT ");
-                               vga_write_color(hselect == 13 ? 0x70 : 0x1E);           vga_write("FNUM ");
-                               vga_write_color(hselect == 14 ? 0x70 : 0x1E);           vga_write("FEED ");
-                               vga_write_color(hselect == 15 ? 0x70 : 0x1E);           vga_write("CON ");
-                               vga_write_color(hselect == 16 ? 0x70 : 0x1E);           vga_write("WV ");
-                               vga_write_color(hselect == 17 ? 0x70 : 0x1E);           vga_write("ABCD ");
-
-                               for (i=0;i < adlib_fm_voices;i++) {
-                                       struct adlib_fm_operator *f;
-                                       double freq;
-                                       
-                                       f = &adlib_fm[i].mod;
-                                       vga_moveto(0,5+i*2);
-                                       freq = adlib_fm_op_to_freq(f);
-                                       vga_write_color(i == selector && selectsub == 0 ? 0x70 : 0x1E);
-                                       cc = sprintf(tmp,"%u  %u  %u    %u   %-2u   %u   %-2u %-2u %-2u %-2u %-2u %u   %u   %-4u %u    %u   %u  %c%c%c%c %u %.1fHz ",
-                                               f->am,                  f->vibrato,             f->sustain,             f->key_scaling_rate,
-                                               f->mod_multiple,        f->level_key_scale,     f->total_level,         f->attack_rate,
-                                               f->decay_rate,          f->sustain_level,       f->release_rate,        f->key_on,
-                                               f->octave,              f->f_number,            f->feedback,            f->connection,
-                                               f->waveform,            f->ch_a?'*':'-',        f->ch_b?'*':'-',        f->ch_c?'*':'-',
-                                               f->ch_d?'*':'-',        i+1,                    freq);
-                                       vga_write(tmp);
-
-                                       f = &adlib_fm[i].car;
-                                       vga_moveto(0,5+i*2+1);
-                                       vga_write_color(i == selector && selectsub == 1 ? 0x70 : 0x1E);
-                                       cc = sprintf(tmp,"%u  %u  %u    %u   %-2u   %u   %-2u %-2u %-2u %-2u %-2u                       %u       CAR   ",
-                                               f->am,                  f->vibrato,             f->sustain,             f->key_scaling_rate,
-                                               f->mod_multiple,        f->level_key_scale,     f->total_level,         f->attack_rate,
-                                               f->decay_rate,          f->sustain_level,       f->release_rate,        f->waveform);
-                                       vga_write(tmp);
-                               }
-                       }
-
-                       redrawln = 0;
-                       redraw = 0;
-               }
-
-               if (kbhit()) {
-                       c = getch();
-                       if (c == 0) c = getch() << 8;
-
-                       if (c == 27) {
-                               loop = 0;
-                       }
-                       else if (c == 0x3B00) { /* F1 */
-                               for (i=0;i < adlib_fm_voices;i++) {
-                                       adlib_fm[i].mod.key_on = 0;
-                                       adlib_fm[i].car.key_on = 0;
-                                       adlib_update_groupA0(i,&adlib_fm[i]);
-                               }
-                               redrawln = 1;
-                       }
-                       else if (c == 0x3C00) { /* F2 */
-                               if (adlib_flags & ADLIB_FM_OPL3) {
-                                       shutdown_adlib_opl3();
-                                       int10_setmode(3);
-                                       redraw = 1;
-                               }
-                       }
-                       else if (c == 0x4400) { /* F10 */
-                               unsigned short op = adlib_voice_to_op[selector];
-
-                               vga_write_color(0x07);
-                               vga_clear();
-                               vga_moveto(0,0);
-
-                               vga_write("Choose an instrument to load into the channel:\n");
-                               vga_write(" 1. Violin     2. Piano     3. Harpsichord     4. Horn      5. Deep bass drum\n");
-                               vga_write(" 6. Small drum \n");
-                               vga_write_sync();
-
-                               c = getch();
-
-                               if (c == '1')
-                                       adlib_fm[selector] =
-                                               (adlib_flags & ADLIB_FM_OPL3 ?
-                                                adlib_fm_preset_violin_opl3 : adlib_fm_preset_violin_opl2);
-                               else if (c == '2')
-                                       adlib_fm[selector] = adlib_fm_preset_piano;
-                               else if (c == '3')
-                                       adlib_fm[selector] = adlib_fm_preset_harpsichord;
-                               else if (c == '4')
-                                       adlib_fm[selector] = adlib_fm_preset_horn;
-                               else if (c == '5')
-                                       adlib_fm[selector] = adlib_fm_preset_deep_bass_drum;
-                               else if (c == '6')
-                                       adlib_fm[selector] = adlib_fm_preset_small_drum;
-
-                               adlib_update_groupA0(selector,&adlib_fm[selector]);
-                               adlib_update_groupC0(selector,&adlib_fm[selector]);
-                               adlib_update_operator(op,&adlib_fm[selector].mod);
-                               adlib_update_operator(op+3,&adlib_fm[selector].car);
-
-                               redraw = 1;
-                       }
-                       else if (c == ' ') {
-                               adlib_fm[selector].mod.key_on ^= 1;
-                               adlib_update_groupA0(selector,&adlib_fm[selector]);
-                               redrawln=1;
-                       }
-                       else if (c == 'a') {
-                               if (hselect == 17) {
-                                       struct adlib_fm_operator *f = &adlib_fm[selector].mod; f->ch_a ^= 1;
-                                       adlib_update_groupC0(selector,&adlib_fm[selector]);
-                               }
-                               else {
-                                       adlib_reg_bd.am_depth ^= 1;
-                                       adlib_update_bd(&adlib_reg_bd);
-                               }
-                               redrawln = 1;
-                       }
-                       else if (c == 'v') {
-                               adlib_reg_bd.vibrato_depth ^= 1;
-                               adlib_update_bd(&adlib_reg_bd);
-                               redrawln = 1;
-                       }
-                       else if (c == 'r') {
-                               adlib_reg_bd.rythm_enable ^= 1;
-                               adlib_update_bd(&adlib_reg_bd);
-                               redrawln = 1;
-                       }
-                       else if (c == 'b') {
-                               if (hselect == 17) {
-                                       struct adlib_fm_operator *f = &adlib_fm[selector].mod; f->ch_b ^= 1;
-                                       adlib_update_groupC0(selector,&adlib_fm[selector]);
-                               }
-                               else {
-                                       adlib_reg_bd.bass_drum_on ^= 1;
-                                       adlib_update_bd(&adlib_reg_bd);
-                               }
-                               redrawln = 1;
-                       }
-                       else if (c == 's') {
-                               adlib_reg_bd.snare_drum_on ^= 1;
-                               adlib_update_bd(&adlib_reg_bd);
-                               redrawln = 1;
-                       }
-                       else if (c == 't') {
-                               adlib_reg_bd.tom_tom_on ^= 1;
-                               adlib_update_bd(&adlib_reg_bd);
-                               redrawln = 1;
-                       }
-                       else if (c == 'c') {
-                               if (hselect == 17) {
-                                       struct adlib_fm_operator *f = &adlib_fm[selector].mod; f->ch_c ^= 1;
-                                       adlib_update_groupC0(selector,&adlib_fm[selector]);
-                               }
-                               else {
-                                       adlib_reg_bd.cymbal_on ^= 1;
-                                       adlib_update_bd(&adlib_reg_bd);
-                               }
-                               redrawln = 1;
-                       }
-                       else if (c == 'd') {
-                               if (hselect == 17) {
-                                       struct adlib_fm_operator *f = &adlib_fm[selector].mod; f->ch_d ^= 1;
-                                       adlib_update_groupC0(selector,&adlib_fm[selector]);
-                               }
-                               else {
-                               }
-                               redrawln = 1;
-                       }
-                       else if (c == 'h') {
-                               adlib_reg_bd.hi_hat_on ^= 1;
-                               adlib_update_bd(&adlib_reg_bd);
-                               redrawln = 1;
-                       }
-                       else if (c == 'z' || c == 'Z' || c == 'x' || c == 'X') {
-                               struct adlib_fm_operator *f;
-                               int dec = tolower(c) == 'z';
-                               unsigned short operator;
-
-                               switch (hselect) {
-                                       case 11:selectsub = 0;
-                                               break;
-                               }
-
-                               if (selectsub) f = &adlib_fm[selector].car;
-                               else           f = &adlib_fm[selector].mod;
-                               operator = adlib_voice_to_op[selector] + (selectsub*3);
-
-                               switch (hselect) {
-                                       case 0:         f->am ^= 1;                     adlib_update_group20(operator,f); break;
-                                       case 11:        f->key_on ^= 1;                 adlib_update_groupA0(selector,&adlib_fm[selector]); break;
-                                       case 1:         f->vibrato ^= 1;                adlib_update_group20(operator,f); break;
-                                       case 2:         f->sustain ^= 1;                adlib_update_group20(operator,f); break;
-                                       case 15:        f->connection ^= 1;             adlib_update_group20(operator,f); break;
-                                       case 3:         f->key_scaling_rate ^= 1;       adlib_update_group20(operator,f); break;
-
-                                       case 4:         if (dec) f->mod_multiple--; else f->mod_multiple++;
-                                                       adlib_update_group20(operator,f); break;
-                                       case 5:         if (dec) f->level_key_scale--; else f->level_key_scale++;
-                                                       adlib_update_group40(operator,f); break;
-                                       case 6:         if (dec) f->total_level--; else f->total_level++;
-                                                       adlib_update_group40(operator,f); break;
-                                       case 7:         if (dec) f->attack_rate--; else f->attack_rate++;
-                                                       adlib_update_group60(operator,f); break;
-                                       case 8:         if (dec) f->decay_rate--; else f->decay_rate++;
-                                                       adlib_update_group60(operator,f); break;
-                                       case 9:         if (dec) f->sustain_level--; else f->sustain_level++;
-                                                       adlib_update_group80(operator,f); break;
-                                       case 10:        if (dec) f->release_rate--; else f->release_rate++;
-                                                       adlib_update_group80(operator,f); break;
-                                       case 12:        if (dec) f->octave--; else f->octave++;
-                                                       adlib_update_groupA0(selector,&adlib_fm[selector]); break;
-                                       case 13:        if (dec) f->f_number--; else f->f_number++;
-                                                       adlib_update_groupA0(selector,&adlib_fm[selector]); break;
-                                       case 14:        if (dec) f->feedback--; else f->feedback++;
-                                                       adlib_update_groupC0(selector,&adlib_fm[selector]); break;
-                                       case 16:        if (dec) f->waveform--; else f->waveform++;
-                                                       adlib_update_groupE0(operator,f); break;
-                               };
-
-                               redrawln=1;
-                       }
-                       else if (c == 0x4800) {
-                               if (selectsub && !(hselect >= 11 && hselect <= 15)) {
-                                       selectsub = 0;
-                                       redrawln = 1;
-                               }
-                               else if (selector > 0) {
-                                       selectsub = !(hselect >= 11 && hselect <= 15);
-                                       selector--;
-                                       redrawln = 1;
-                               }
-                       }
-                       else if (c == 0x4B00) {
-                               if (hselect > 0) {
-                                       hselect--;
-                                       redrawln=1;
-                               }
-                       }
-                       else if (c == 0x4D00) {
-                               if (hselect < 17) {
-                                       hselect++;
-                                       redrawln=1;
-                               }
-                       }
-                       else if (c == 0x5000) {
-                               if (selectsub == 0 && !(hselect >= 11 && hselect <= 15)) {
-                                       selectsub = 1;
-                                       redrawln = 1;
-                               }
-                               else if ((selector+1) < adlib_fm_voices) {
-                                       selectsub = 0;
-                                       selector++;
-                                       redrawln=1;
-                               }
-                       }
-
-               }
-       }
-
-       shutdown_adlib();
-       int10_setmode(3);
-
-       return 0;
-}
-
+/* test.c\r
+ *\r
+ * Adlib OPL2/OPL3 FM synthesizer chipset test program.\r
+ * (C) 2010-2012 Jonathan Campbell.\r
+ * Hackipedia DOS library.\r
+ *\r
+ * This code is licensed under the LGPL.\r
+ * <insert LGPL legal text here>\r
+ *\r
+ * Compiles for intended target environments:\r
+ *   - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]\r
+ *\r
+ * This test program uses a "text user interface" to allow you to play\r
+ * with the OPL2/OPL3 chipset and it's parameters. Some "instruments"\r
+ * are preset for you if you want to make noise faster.\r
+ */\r
\r
+#include <stdio.h>\r
+#include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+#include <malloc.h>\r
+#include <ctype.h>\r
+#include <fcntl.h>\r
+#include <dos.h>\r
+\r
+#include <hw/vga/vga.h>\r
+#include <hw/dos/dos.h>\r
+#include <hw/8254/8254.h>              /* 8254 timer */\r
+#include <hw/vga/vgagui.h>\r
+#include <hw/vga/vgatty.h>\r
+#include <hw/adlib/adlib.h>\r
+\r
+static unsigned int musical_scale[18] = {\r
+       0x1B0,                  /* E */\r
+       0x1CA,                  /* F */\r
+       0x1E5,                  /* f# */\r
+       0x202,                  /* G */\r
+       0x220,                  /* G# */\r
+       0x241,                  /* A */\r
+       0x263,                  /* A# */\r
+       0x287,                  /* B */\r
+       0x2AE,                  /* C */\r
+\r
+       0x2B0,                  /* E */\r
+       0x2CA,                  /* F */\r
+       0x2E5,                  /* f# */\r
+       0x302,                  /* G */\r
+       0x320,                  /* G# */\r
+       0x341,                  /* A */\r
+       0x363,                  /* A# */\r
+       0x387,                  /* B */\r
+       0x3AE,                  /* C */\r
+};\r
+\r
+int main(int argc,char **argv) {\r
+       int i,loop,redraw,c,cc,selector=0,redrawln=0,hselect=0,selectsub=0;\r
+       VGA_ALPHA_PTR vga;\r
+       char tmp[128];\r
+\r
+       printf("ADLIB FM test program\n");\r
+\r
+       if (!probe_vga()) {\r
+               printf("Cannot init VGA\n");\r
+               return 1;\r
+       }\r
+       if (!init_adlib()) {\r
+               printf("Cannot init library\n");\r
+               return 1;\r
+       }\r
+\r
+       int10_setmode(3);\r
+\r
+       /* for VGA: free up space if needed by going to 80x50 */\r
+       if (adlib_fm_voices > 9)\r
+               vga_bios_set_80x50_text();\r
+\r
+       memset(adlib_fm,0,sizeof(adlib_fm));\r
+       memset(&adlib_reg_bd,0,sizeof(adlib_reg_bd));\r
+       for (i=0;i < adlib_fm_voices;i++) {\r
+               struct adlib_fm_operator *f;\r
+               f = &adlib_fm[i].mod;\r
+               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;\r
+               f = &adlib_fm[i].car;\r
+               f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;\r
+       }\r
+\r
+       for (i=0;i < adlib_fm_voices;i++) {\r
+               struct adlib_fm_operator *f;\r
+\r
+               f = &adlib_fm[i].mod;\r
+               f->mod_multiple = 1;\r
+               f->total_level = 63 - 16;\r
+               f->attack_rate = 15;\r
+               f->decay_rate = 0;\r
+               f->sustain_level = 7;\r
+               f->release_rate = 7;\r
+               f->f_number = musical_scale[i%18];\r
+               f->octave = 4;\r
+               f->key_on = 0;\r
+\r
+               f = &adlib_fm[i].car;\r
+               f->mod_multiple = 1;\r
+               f->total_level = 63 - 16;\r
+               f->attack_rate = 15;\r
+               f->decay_rate = 0;\r
+               f->sustain_level = 7;\r
+               f->release_rate = 7;\r
+               f->f_number = 0;\r
+               f->octave = 0;\r
+               f->key_on = 0;\r
+       }\r
+\r
+       adlib_apply_all();\r
+\r
+       vga_write_color(0x07);\r
+       vga_clear();\r
+\r
+       loop=1;\r
+       redraw=1;\r
+       while (loop) {\r
+               if (redraw || redrawln) {\r
+                       if (redraw) {\r
+                               for (vga=vga_alpha_ram,cc=0;cc < (80*vga_height);cc++) *vga++ = 0x1E00 | 177;\r
+                               vga_moveto(0,0);\r
+                               vga_write_color(0x1F);\r
+                               sprintf(tmp,"Adlib FM, %u-voice %s. Use Z & X to adj  F10=PRESET F1=QUIET ",adlib_fm_voices,\r
+                                       (adlib_flags & ADLIB_FM_OPL3) ? "OPL3" :\r
+                                       (adlib_flags & ADLIB_FM_DUAL_OPL2) ? "Dual OPL2" : "OPL2");\r
+                               vga_write(tmp);\r
+                               if (adlib_flags & ADLIB_FM_OPL3) vga_write("F2=OPL3 off ");\r
+                       }\r
+\r
+                       if (redrawln || redraw) {\r
+                               struct adlib_reg_bd *bd = &adlib_reg_bd;\r
+                               static const char *hsel_str[18] = {\r
+                                       "Amplitude modulatation",\r
+                                       "Vibrato",\r
+                                       "Sustain",\r
+                                       "Key scaling rate",\r
+                                       "Modulator frequency multiple",\r
+                                       "Level key scaling",\r
+                                       "Total level",\r
+                                       "Attack rate",\r
+                                       "Decay rate",\r
+                                       "Sustain level",\r
+                                       "Release rate",\r
+                                       "KEY ON",\r
+                                       "Octave",\r
+                                       "F-Number",\r
+                                       "Feedback",\r
+                                       "Connection (operator 1 -> operator 2)",\r
+                                       "Waveform",\r
+                                       "Channel mapping (OPL3)"\r
+                               };\r
+\r
+                               vga_write_color(0x1A);\r
+\r
+                               vga_moveto(0,2);\r
+                               sprintf(tmp,"AM=%u VB=%u RYTHM=%u BAS=%u SNA=%u TOM=%u CYM=%u HI=%u\n",\r
+                                       bd->am_depth,\r
+                                       bd->vibrato_depth,\r
+                                       bd->rythm_enable,\r
+                                       bd->bass_drum_on,\r
+                                       bd->snare_drum_on,\r
+                                       bd->tom_tom_on,\r
+                                       bd->cymbal_on,\r
+                                       bd->hi_hat_on);\r
+                               vga_write(tmp);\r
+\r
+                               vga_moveto(0,3);\r
+                               vga_write("                                                       ");\r
+                               vga_moveto(0,3);\r
+                               vga_write(hsel_str[hselect]);\r
+\r
+                               vga_moveto(0,4);\r
+                               vga_write_color(hselect ==  0 ? 0x70 : 0x1E);           vga_write("AM ");\r
+                               vga_write_color(hselect ==  1 ? 0x70 : 0x1E);           vga_write("VB ");\r
+                               vga_write_color(hselect ==  2 ? 0x70 : 0x1E);           vga_write("SUST ");\r
+                               vga_write_color(hselect ==  3 ? 0x70 : 0x1E);           vga_write("KSR ");\r
+                               vga_write_color(hselect ==  4 ? 0x70 : 0x1E);           vga_write("MMUL ");\r
+                               vga_write_color(hselect ==  5 ? 0x70 : 0x1E);           vga_write("LKS ");\r
+                               vga_write_color(hselect ==  6 ? 0x70 : 0x1E);           vga_write("TL ");\r
+                               vga_write_color(hselect ==  7 ? 0x70 : 0x1E);           vga_write("AR ");\r
+                               vga_write_color(hselect ==  8 ? 0x70 : 0x1E);           vga_write("DR ");\r
+                               vga_write_color(hselect ==  9 ? 0x70 : 0x1E);           vga_write("SL ");\r
+                               vga_write_color(hselect == 10 ? 0x70 : 0x1E);           vga_write("RR ");\r
+                               vga_write_color(hselect == 11 ? 0x70 : 0x1E);           vga_write("KEY ");\r
+                               vga_write_color(hselect == 12 ? 0x70 : 0x1E);           vga_write("OCT ");\r
+                               vga_write_color(hselect == 13 ? 0x70 : 0x1E);           vga_write("FNUM ");\r
+                               vga_write_color(hselect == 14 ? 0x70 : 0x1E);           vga_write("FEED ");\r
+                               vga_write_color(hselect == 15 ? 0x70 : 0x1E);           vga_write("CON ");\r
+                               vga_write_color(hselect == 16 ? 0x70 : 0x1E);           vga_write("WV ");\r
+                               vga_write_color(hselect == 17 ? 0x70 : 0x1E);           vga_write("ABCD ");\r
+\r
+                               for (i=0;i < adlib_fm_voices;i++) {\r
+                                       struct adlib_fm_operator *f;\r
+                                       double freq;\r
+                                       \r
+                                       f = &adlib_fm[i].mod;\r
+                                       vga_moveto(0,5+i*2);\r
+                                       freq = adlib_fm_op_to_freq(f);\r
+                                       vga_write_color(i == selector && selectsub == 0 ? 0x70 : 0x1E);\r
+                                       cc = sprintf(tmp,"%u  %u  %u    %u   %-2u   %u   %-2u %-2u %-2u %-2u %-2u %u   %u   %-4u %u    %u   %u  %c%c%c%c %u %.1fHz ",\r
+                                               f->am,                  f->vibrato,             f->sustain,             f->key_scaling_rate,\r
+                                               f->mod_multiple,        f->level_key_scale,     f->total_level,         f->attack_rate,\r
+                                               f->decay_rate,          f->sustain_level,       f->release_rate,        f->key_on,\r
+                                               f->octave,              f->f_number,            f->feedback,            f->connection,\r
+                                               f->waveform,            f->ch_a?'*':'-',        f->ch_b?'*':'-',        f->ch_c?'*':'-',\r
+                                               f->ch_d?'*':'-',        i+1,                    freq);\r
+                                       vga_write(tmp);\r
+\r
+                                       f = &adlib_fm[i].car;\r
+                                       vga_moveto(0,5+i*2+1);\r
+                                       vga_write_color(i == selector && selectsub == 1 ? 0x70 : 0x1E);\r
+                                       cc = sprintf(tmp,"%u  %u  %u    %u   %-2u   %u   %-2u %-2u %-2u %-2u %-2u                       %u       CAR   ",\r
+                                               f->am,                  f->vibrato,             f->sustain,             f->key_scaling_rate,\r
+                                               f->mod_multiple,        f->level_key_scale,     f->total_level,         f->attack_rate,\r
+                                               f->decay_rate,          f->sustain_level,       f->release_rate,        f->waveform);\r
+                                       vga_write(tmp);\r
+                               }\r
+                       }\r
+\r
+                       redrawln = 0;\r
+                       redraw = 0;\r
+               }\r
+\r
+               if (kbhit()) {\r
+                       c = getch();\r
+                       if (c == 0) c = getch() << 8;\r
+\r
+                       if (c == 27) {\r
+                               loop = 0;\r
+                       }\r
+                       else if (c == 0x3B00) { /* F1 */\r
+                               for (i=0;i < adlib_fm_voices;i++) {\r
+                                       adlib_fm[i].mod.key_on = 0;\r
+                                       adlib_fm[i].car.key_on = 0;\r
+                                       adlib_update_groupA0(i,&adlib_fm[i]);\r
+                               }\r
+                               redrawln = 1;\r
+                       }\r
+                       else if (c == 0x3C00) { /* F2 */\r
+                               if (adlib_flags & ADLIB_FM_OPL3) {\r
+                                       shutdown_adlib_opl3();\r
+                                       int10_setmode(3);\r
+                                       redraw = 1;\r
+                               }\r
+                       }\r
+                       else if (c == 0x4400) { /* F10 */\r
+                               unsigned short op = adlib_voice_to_op[selector];\r
+\r
+                               vga_write_color(0x07);\r
+                               vga_clear();\r
+                               vga_moveto(0,0);\r
+\r
+                               vga_write("Choose an instrument to load into the channel:\n");\r
+                               vga_write(" 1. Violin     2. Piano     3. Harpsichord     4. Horn      5. Deep bass drum\n");\r
+                               vga_write(" 6. Small drum \n");\r
+                               vga_write_sync();\r
+\r
+                               c = getch();\r
+\r
+                               if (c == '1')\r
+                                       adlib_fm[selector] =\r
+                                               (adlib_flags & ADLIB_FM_OPL3 ?\r
+                                                adlib_fm_preset_violin_opl3 : adlib_fm_preset_violin_opl2);\r
+                               else if (c == '2')\r
+                                       adlib_fm[selector] = adlib_fm_preset_piano;\r
+                               else if (c == '3')\r
+                                       adlib_fm[selector] = adlib_fm_preset_harpsichord;\r
+                               else if (c == '4')\r
+                                       adlib_fm[selector] = adlib_fm_preset_horn;\r
+                               else if (c == '5')\r
+                                       adlib_fm[selector] = adlib_fm_preset_deep_bass_drum;\r
+                               else if (c == '6')\r
+                                       adlib_fm[selector] = adlib_fm_preset_small_drum;\r
+\r
+                               adlib_update_groupA0(selector,&adlib_fm[selector]);\r
+                               adlib_update_groupC0(selector,&adlib_fm[selector]);\r
+                               adlib_update_operator(op,&adlib_fm[selector].mod);\r
+                               adlib_update_operator(op+3,&adlib_fm[selector].car);\r
+\r
+                               redraw = 1;\r
+                       }\r
+                       else if (c == ' ') {\r
+                               adlib_fm[selector].mod.key_on ^= 1;\r
+                               adlib_update_groupA0(selector,&adlib_fm[selector]);\r
+                               redrawln=1;\r
+                       }\r
+                       else if (c == 'a') {\r
+                               if (hselect == 17) {\r
+                                       struct adlib_fm_operator *f = &adlib_fm[selector].mod; f->ch_a ^= 1;\r
+                                       adlib_update_groupC0(selector,&adlib_fm[selector]);\r
+                               }\r
+                               else {\r
+                                       adlib_reg_bd.am_depth ^= 1;\r
+                                       adlib_update_bd(&adlib_reg_bd);\r
+                               }\r
+                               redrawln = 1;\r
+                       }\r
+                       else if (c == 'v') {\r
+                               adlib_reg_bd.vibrato_depth ^= 1;\r
+                               adlib_update_bd(&adlib_reg_bd);\r
+                               redrawln = 1;\r
+                       }\r
+                       else if (c == 'r') {\r
+                               adlib_reg_bd.rythm_enable ^= 1;\r
+                               adlib_update_bd(&adlib_reg_bd);\r
+                               redrawln = 1;\r
+                       }\r
+                       else if (c == 'b') {\r
+                               if (hselect == 17) {\r
+                                       struct adlib_fm_operator *f = &adlib_fm[selector].mod; f->ch_b ^= 1;\r
+                                       adlib_update_groupC0(selector,&adlib_fm[selector]);\r
+                               }\r
+                               else {\r
+                                       adlib_reg_bd.bass_drum_on ^= 1;\r
+                                       adlib_update_bd(&adlib_reg_bd);\r
+                               }\r
+                               redrawln = 1;\r
+                       }\r
+                       else if (c == 's') {\r
+                               adlib_reg_bd.snare_drum_on ^= 1;\r
+                               adlib_update_bd(&adlib_reg_bd);\r
+                               redrawln = 1;\r
+                       }\r
+                       else if (c == 't') {\r
+                               adlib_reg_bd.tom_tom_on ^= 1;\r
+                               adlib_update_bd(&adlib_reg_bd);\r
+                               redrawln = 1;\r
+                       }\r
+                       else if (c == 'c') {\r
+                               if (hselect == 17) {\r
+                                       struct adlib_fm_operator *f = &adlib_fm[selector].mod; f->ch_c ^= 1;\r
+                                       adlib_update_groupC0(selector,&adlib_fm[selector]);\r
+                               }\r
+                               else {\r
+                                       adlib_reg_bd.cymbal_on ^= 1;\r
+                                       adlib_update_bd(&adlib_reg_bd);\r
+                               }\r
+                               redrawln = 1;\r
+                       }\r
+                       else if (c == 'd') {\r
+                               if (hselect == 17) {\r
+                                       struct adlib_fm_operator *f = &adlib_fm[selector].mod; f->ch_d ^= 1;\r
+                                       adlib_update_groupC0(selector,&adlib_fm[selector]);\r
+                               }\r
+                               else {\r
+                               }\r
+                               redrawln = 1;\r
+                       }\r
+                       else if (c == 'h') {\r
+                               adlib_reg_bd.hi_hat_on ^= 1;\r
+                               adlib_update_bd(&adlib_reg_bd);\r
+                               redrawln = 1;\r
+                       }\r
+                       else if (c == 'z' || c == 'Z' || c == 'x' || c == 'X') {\r
+                               struct adlib_fm_operator *f;\r
+                               int dec = tolower(c) == 'z';\r
+                               unsigned short operator;\r
+\r
+                               switch (hselect) {\r
+                                       case 11:selectsub = 0;\r
+                                               break;\r
+                               }\r
+\r
+                               if (selectsub) f = &adlib_fm[selector].car;\r
+                               else           f = &adlib_fm[selector].mod;\r
+                               operator = adlib_voice_to_op[selector] + (selectsub*3);\r
+\r
+                               switch (hselect) {\r
+                                       case 0:         f->am ^= 1;                     adlib_update_group20(operator,f); break;\r
+                                       case 11:        f->key_on ^= 1;                 adlib_update_groupA0(selector,&adlib_fm[selector]); break;\r
+                                       case 1:         f->vibrato ^= 1;                adlib_update_group20(operator,f); break;\r
+                                       case 2:         f->sustain ^= 1;                adlib_update_group20(operator,f); break;\r
+                                       case 15:        f->connection ^= 1;             adlib_update_group20(operator,f); break;\r
+                                       case 3:         f->key_scaling_rate ^= 1;       adlib_update_group20(operator,f); break;\r
+\r
+                                       case 4:         if (dec) f->mod_multiple--; else f->mod_multiple++;\r
+                                                       adlib_update_group20(operator,f); break;\r
+                                       case 5:         if (dec) f->level_key_scale--; else f->level_key_scale++;\r
+                                                       adlib_update_group40(operator,f); break;\r
+                                       case 6:         if (dec) f->total_level--; else f->total_level++;\r
+                                                       adlib_update_group40(operator,f); break;\r
+                                       case 7:         if (dec) f->attack_rate--; else f->attack_rate++;\r
+                                                       adlib_update_group60(operator,f); break;\r
+                                       case 8:         if (dec) f->decay_rate--; else f->decay_rate++;\r
+                                                       adlib_update_group60(operator,f); break;\r
+                                       case 9:         if (dec) f->sustain_level--; else f->sustain_level++;\r
+                                                       adlib_update_group80(operator,f); break;\r
+                                       case 10:        if (dec) f->release_rate--; else f->release_rate++;\r
+                                                       adlib_update_group80(operator,f); break;\r
+                                       case 12:        if (dec) f->octave--; else f->octave++;\r
+                                                       adlib_update_groupA0(selector,&adlib_fm[selector]); break;\r
+                                       case 13:        if (dec) f->f_number--; else f->f_number++;\r
+                                                       adlib_update_groupA0(selector,&adlib_fm[selector]); break;\r
+                                       case 14:        if (dec) f->feedback--; else f->feedback++;\r
+                                                       adlib_update_groupC0(selector,&adlib_fm[selector]); break;\r
+                                       case 16:        if (dec) f->waveform--; else f->waveform++;\r
+                                                       adlib_update_groupE0(operator,f); break;\r
+                               };\r
+\r
+                               redrawln=1;\r
+                       }\r
+                       else if (c == 0x4800) {\r
+                               if (selectsub && !(hselect >= 11 && hselect <= 15)) {\r
+                                       selectsub = 0;\r
+                                       redrawln = 1;\r
+                               }\r
+                               else if (selector > 0) {\r
+                                       selectsub = !(hselect >= 11 && hselect <= 15);\r
+                                       selector--;\r
+                                       redrawln = 1;\r
+                               }\r
+                       }\r
+                       else if (c == 0x4B00) {\r
+                               if (hselect > 0) {\r
+                                       hselect--;\r
+                                       redrawln=1;\r
+                               }\r
+                       }\r
+                       else if (c == 0x4D00) {\r
+                               if (hselect < 17) {\r
+                                       hselect++;\r
+                                       redrawln=1;\r
+                               }\r
+                       }\r
+                       else if (c == 0x5000) {\r
+                               if (selectsub == 0 && !(hselect >= 11 && hselect <= 15)) {\r
+                                       selectsub = 1;\r
+                                       redrawln = 1;\r
+                               }\r
+                               else if ((selector+1) < adlib_fm_voices) {\r
+                                       selectsub = 0;\r
+                                       selector++;\r
+                                       redrawln=1;\r
+                               }\r
+                       }\r
+\r
+               }\r
+       }\r
+\r
+       shutdown_adlib();\r
+       int10_setmode(3);\r
+\r
+       return 0;\r
+}\r
+\r
index 83f3712eef3d0bfea0dd774f8bef9b0eac2b67f5..ab7e2db64924be9a4ca49e3aa1edcedfedf1267e 100755 (executable)
-#include <hw/cpu/cpu.h>
-#include <hw/dos/dos.h>
-#include <hw/vga/vga.h>
-#include <hw/vga/vrl.h>
-
-#include "src/tesuto.h"
-
-static unsigned char palette[768];
-
-int main(int argc,char **argv) {
-       struct vrl1_vgax_header *vrl_header;
-       vrl1_vgax_offset_t *vrl_lineoffs;
-       unsigned char *buffer;
-       unsigned int bufsz;
-       int fd;
-
-       if (argc < 3) {
-               fprintf(stderr,"drawvrl <VRL file> <palette file>\n");
-               return 1;
-       }
-
-       fd = open(argv[1],O_RDONLY|O_BINARY);
-       if (fd < 0) {
-               fprintf(stderr,"Unable to open '%s'\n",argv[1]);
-               return 1;
-       }
-       {
-               unsigned long sz = lseek(fd,0,SEEK_END);
-               if (sz < sizeof(*vrl_header)) return 1;
-               if (sz >= 65535UL) return 1;
-
-               bufsz = (unsigned int)sz;
-               buffer = malloc(bufsz);
-               if (buffer == NULL) return 1;
-
-               lseek(fd,0,SEEK_SET);
-               if ((unsigned int)read(fd,buffer,bufsz) < bufsz) return 1;
-
-               vrl_header = (struct vrl1_vgax_header*)buffer;
-               if (memcmp(vrl_header->vrl_sig,"VRL1",4) || memcmp(vrl_header->fmt_sig,"VGAX",4)) return 1;
-               if (vrl_header->width == 0 || vrl_header->height == 0) return 1;
-       }
-       close(fd);
-
-       probe_dos();
-       if (!probe_vga()) {
-               printf("VGA probe failed\n");
-               return 1;
-       }
-       int10_setmode(19);
-       update_state_from_vga();
-       vga_enable_256color_modex(); // VGA mode X
-       vga_state.vga_width = 320; // VGA lib currently does not update this
-       vga_state.vga_height = 240; // VGA lib currently does not update this
-
-#if 1 // 320x240 test mode: this is how Project 16 is using our code, enable for test case
-       {
-               struct vga_mode_params cm;
-
-               vga_read_crtc_mode(&cm);
-
-               // 320x240 mode 60Hz
-               cm.vertical_total = 525;
-               cm.vertical_start_retrace = 0x1EA;
-               cm.vertical_end_retrace = 0x1EC;
-               cm.vertical_display_end = 480;
-               cm.vertical_blank_start = 489;
-               cm.vertical_blank_end = 517;
-
-               vga_write_crtc_mode(&cm,0);
-       }
-       vga_state.vga_height = 240; // VGA lib currently does not update this
-#endif
-
-       /* load color palette */
-       fd = open(argv[2],O_RDONLY|O_BINARY);
-       if (fd >= 0) {
-               unsigned int i;
-
-               read(fd,palette,768);
-               close(fd);
-
-               vga_palette_lseek(0);
-               for (i=0;i < 256;i++) vga_palette_write(palette[(i*3)+0]>>2,palette[(i*3)+1]>>2,palette[(i*3)+2]>>2);
-       }
-
-       /* preprocess the sprite to generate line offsets */
-       vrl_lineoffs = vrl1_vgax_genlineoffsets(vrl_header,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));
-       if (vrl_lineoffs == NULL) return 1;
-
-       {
-               unsigned int i,j,o;
-
-               /* fill screen with a distinctive pattern */
-               for (i=0;i < vga_state.vga_width;i++) {
-                       o = i >> 2;
-                       vga_write_sequencer(0x02/*map mask*/,1 << (i&3));
-                       for (j=0;j < vga_state.vga_height;j++,o += vga_state.vga_stride)
-                               vga_state.vga_graphics_ram[o] = (i^j)&15; // VRL samples put all colors in first 15!
-               }
-       }
-       //while (getch() != 13);
-
-       /* make distinctive pattern offscreen, render sprite, copy onscreen */
-       {
-               const unsigned int offscreen_ofs = (vga_state.vga_stride * vga_state.vga_height);
-               unsigned int i,j,o,o2,x,y,rx,ry,w,h;
-               unsigned int overdraw = 1;      // how many pixels to "overdraw" so that moving sprites with edge pixels don't leave streaks.
-                                               // if the sprite's edge pixels are clear anyway, you can set this to 0.
-               VGA_RAM_PTR omemptr;
-               int xdir=1,ydir=1;
-
-               /* starting coords. note: this technique is limited to x coordinates of multiple of 4 */
-               x = 0;
-               y = 0;
-
-               /* do it */
-               omemptr = vga_state.vga_graphics_ram; // save original mem ptr
-               while (1) {
-                       /* stop animating if the user hits ENTER */
-                       if (kbhit()) {
-                               if (getch() == 13) break;
-                       }
-
-                       /* render box bounds. y does not need modification, but x and width must be multiple of 4 */
-                       if (x >= overdraw) rx = (x - overdraw) & (~3);
-                       else rx = 0;
-                       if (y >= overdraw) ry = (y - overdraw);
-                       else ry = 0;
-                       h = vrl_header->height + overdraw + y - ry;
-                       w = (x + vrl_header->width + (overdraw*2) + 3/*round up*/ - rx) & (~3);
-                       if ((rx+w) > vga_state.vga_width) w = vga_state.vga_width-rx;
-                       if ((ry+h) > vga_state.vga_height) h = vga_state.vga_height-ry;
-
-                       /* replace VGA stride with our own and mem ptr. then sprite rendering at this stage is just (0,0) */
-                       vga_state.vga_draw_stride_limit = (vga_state.vga_width + 3/*round up*/ - x) >> 2;
-                       vga_state.vga_draw_stride = w >> 2;
-                       vga_state.vga_graphics_ram = omemptr + offscreen_ofs;
-
-                       /* first draw pattern corresponding to that part of the screen. this COULD be optimized, obviously, but it's designed for study.
-                        * also note we don't have to use the same stride as the display! */
-                       for (i=rx;i < (rx+w);i++) {
-                               o = (i-rx) >> 2;
-                               vga_write_sequencer(0x02/*map mask*/,1 << (i&3));
-                               for (j=ry;j < (ry+h);j++,o += vga_state.vga_draw_stride)
-                                       vga_state.vga_graphics_ram[o] = (i^j)&15; // VRL samples put all colors in first 15!
-                       }
-
-                       /* then the sprite. note modding ram ptr means we just draw to (x&3,0) */
-                       draw_vrl1_vgax_modex(x-rx,y-ry,vrl_header,vrl_lineoffs,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));
-
-                       /* restore ptr */
-                       vga_state.vga_graphics_ram = omemptr;
-
-                       /* block copy to visible RAM from offscreen */
-                       vga_setup_wm1_block_copy();
-                       o = offscreen_ofs; // source offscreen
-                       o2 = (ry * vga_state.vga_stride) + (rx >> 2); // dest visible (original stride)
-                       for (i=0;i < h;i++,o += vga_state.vga_draw_stride,o2 += vga_state.vga_stride) vga_wm1_mem_block_copy(o2,o,w >> 2);
-                       /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */
-                       vga_restore_rm0wm0();
-
-                       /* restore stride */
-                       vga_state.vga_draw_stride_limit = vga_state.vga_draw_stride = vga_state.vga_stride;
-
-                       /* step */
-                       x += xdir;
-                       y += ydir;
-                       if (x >= (vga_state.vga_width - 1) || x == 0)
-                               xdir = -xdir;
-                       if (y >= (vga_state.vga_height - 1) || y == 0)
-                               ydir = -ydir;
-               }
-       }
-
-       /* make distinctive pattern offscreen, render sprite, copy onscreen.
-        * this time, we render the distinctive pattern to another offscreen location and just copy.
-        * note this version is much faster too! */
-       {
-               const unsigned int offscreen_ofs = (vga_state.vga_stride * vga_state.vga_height);
-               const unsigned int pattern_ofs = 0x10000UL - (vga_state.vga_stride * vga_state.vga_height);
-               unsigned int i,j,o,o2,x,y,rx,ry,w,h;
-               unsigned int overdraw = 1;      // how many pixels to "overdraw" so that moving sprites with edge pixels don't leave streaks.
-                                               // if the sprite's edge pixels are clear anyway, you can set this to 0.
-               VGA_RAM_PTR omemptr;
-               int xdir=1,ydir=1;
-
-               /* fill pattern offset with a distinctive pattern */
-               for (i=0;i < vga_state.vga_width;i++) {
-                       o = (i >> 2) + pattern_ofs;
-                       vga_write_sequencer(0x02/*map mask*/,1 << (i&3));
-                       for (j=0;j < vga_state.vga_height;j++,o += vga_state.vga_stride)
-                               vga_state.vga_graphics_ram[o] = (i^j)&15; // VRL samples put all colors in first 15!
-               }
-
-               /* starting coords. note: this technique is limited to x coordinates of multiple of 4 */
-               x = 0;
-               y = 0;
-
-               /* do it */
-               omemptr = vga_state.vga_graphics_ram; // save original mem ptr
-               while (1) {
-                       /* stop animating if the user hits ENTER */
-                       if (kbhit()) {
-                               if (getch() == 13) break;
-                       }
-
-                       /* render box bounds. y does not need modification, but x and width must be multiple of 4 */
-                       if (x >= overdraw) rx = (x - overdraw) & (~3);
-                       else rx = 0;
-                       if (y >= overdraw) ry = (y - overdraw);
-                       else ry = 0;
-                       h = vrl_header->height + overdraw + y - ry;
-                       w = (x + vrl_header->width + (overdraw*2) + 3/*round up*/ - rx) & (~3);
-                       if ((rx+w) > vga_state.vga_width) w = vga_state.vga_width-rx;
-                       if ((ry+h) > vga_state.vga_height) h = vga_state.vga_height-ry;
-
-                       /* block copy pattern to where we will draw the sprite */
-                       vga_setup_wm1_block_copy();
-                       o2 = offscreen_ofs;
-                       o = pattern_ofs + (ry * vga_state.vga_stride) + (rx >> 2); // source offscreen
-                       for (i=0;i < h;i++,o += vga_state.vga_stride,o2 += (w >> 2)) vga_wm1_mem_block_copy(o2,o,w >> 2);
-                       /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */
-                       vga_restore_rm0wm0();
-
-                       /* replace VGA stride with our own and mem ptr. then sprite rendering at this stage is just (0,0) */
-                       vga_state.vga_draw_stride_limit = (vga_state.vga_width + 3/*round up*/ - x) >> 2;
-                       vga_state.vga_draw_stride = w >> 2;
-                       vga_state.vga_graphics_ram = omemptr + offscreen_ofs;
-
-                       /* then the sprite. note modding ram ptr means we just draw to (x&3,0) */
-                       draw_vrl1_vgax_modex(x-rx,y-ry,vrl_header,vrl_lineoffs,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));
-
-                       /* restore ptr */
-                       vga_state.vga_graphics_ram = omemptr;
-
-                       /* block copy to visible RAM from offscreen */
-                       vga_setup_wm1_block_copy();
-                       o = offscreen_ofs; // source offscreen
-                       o2 = (ry * vga_state.vga_stride) + (rx >> 2); // dest visible (original stride)
-                       for (i=0;i < h;i++,o += vga_state.vga_draw_stride,o2 += vga_state.vga_stride) vga_wm1_mem_block_copy(o2,o,w >> 2);
-                       /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */
-                       vga_restore_rm0wm0();
-
-                       /* restore stride */
-                       vga_state.vga_draw_stride_limit = vga_state.vga_draw_stride = vga_state.vga_stride;
-
-                       /* step */
-                       x += xdir;
-                       y += ydir;
-                       if (x >= (vga_state.vga_width - 1) || x == 0)
-                               xdir = -xdir;
-                       if (y >= (vga_state.vga_height - 1) || y == 0)
-                               ydir = -ydir;
-               }
-       }
-
-       /* another handy "demo" effect using VGA write mode 1.
-        * we can take what's on screen and vertically squash it like an old analog TV set turning off. */
-       {
-               unsigned int blank_line_ofs = (vga_state.vga_stride * vga_state.vga_height * 2);
-               unsigned int copy_ofs = (vga_state.vga_stride * vga_state.vga_height);
-               unsigned int display_ofs = 0x0000;
-               unsigned int i,y,soh,doh,dstart;
-               unsigned int dh_blankfill = 8;
-               unsigned int dh_step = 8;
-               uint32_t sh,dh,yf,ystep;
-
-               /* copy active display (0) to offscreen buffer (0x4000) */
-               vga_state.vga_draw_stride_limit = vga_state.vga_draw_stride = vga_state.vga_stride;
-               vga_setup_wm1_block_copy();
-               vga_wm1_mem_block_copy(copy_ofs,display_ofs,vga_state.vga_stride * vga_state.vga_height);
-               vga_restore_rm0wm0();
-
-               /* need a blank line as well */
-               for (i=0;i < vga_state.vga_stride;i++) vga_state.vga_graphics_ram[i+blank_line_ofs] = 0;
-
-               sh = dh = vga_state.vga_height;
-               while (dh >= dh_step) {
-                       /* stop animating if the user hits ENTER */
-                       if (kbhit()) {
-                               if (getch() == 13) break;
-                       }
-
-                       /* wait for vsync end */
-                       vga_wait_for_vsync_end();
-
-                       /* what scalefactor to use for stretching? */
-                       ystep = (0x10000UL * sh) / dh;
-                       dstart = (vga_state.vga_height - dh) / 2; // center the squash effect on screen, otherwise it would squash to top of screen
-                       doh = display_ofs;
-                       soh = copy_ofs;
-                       yf = 0;
-                       y = 0;
-
-                       /* for performance, keep VGA in write mode 1 the entire render */
-                       vga_setup_wm1_block_copy();
-
-                       /* blank lines */
-                       if (dstart >= dh_blankfill) y = dstart - dh_blankfill;
-                       else y = 0;
-                       doh = vga_state.vga_stride * y;
-
-                       while (y < dstart) {
-                               vga_wm1_mem_block_copy(doh,blank_line_ofs,vga_state.vga_stride);
-                               doh += vga_state.vga_stride;
-                               y++;
-                       }
-
-                       /* draw */
-                       while (y < (dh+dstart)) {
-                               soh = copy_ofs + ((yf >> 16UL) * vga_state.vga_stride);
-                               vga_wm1_mem_block_copy(doh,soh,vga_state.vga_stride);
-                               doh += vga_state.vga_stride;
-                               yf += ystep;
-                               y++;
-                       }
-
-                       /* blank lines */
-                       while (y < vga_state.vga_height && y < (dh+dstart+dh_blankfill)) {
-                               vga_wm1_mem_block_copy(doh,blank_line_ofs,vga_state.vga_stride);
-                               doh += vga_state.vga_stride;
-                               y++;
-                       }
-
-                       /* done */
-                       vga_restore_rm0wm0();
-
-                       /* wait for vsync */
-                       vga_wait_for_vsync();
-
-                       /* make it shrink */
-                       dh -= dh_step;
-                       if (dh < 40) dh_step = 1;
-               }
-       }
-
-       int10_setmode(3);
-       free(vrl_lineoffs);
-       buffer = NULL;
-       free(buffer);
-       bufsz = 0;
-       return 0;
-}
+#include <hw/cpu/cpu.h>\r
+#include <hw/dos/dos.h>\r
+#include <hw/vga/vga.h>\r
+#include <hw/vga/vrl.h>\r
+\r
+#include "src/tesuto.h"\r
+\r
+static unsigned char palette[768];\r
+\r
+int main(int argc,char **argv) {\r
+       struct vrl1_vgax_header *vrl_header;\r
+       vrl1_vgax_offset_t *vrl_lineoffs;\r
+       unsigned char *buffer;\r
+       unsigned int bufsz;\r
+       int fd;\r
+\r
+       if (argc < 3) {\r
+               fprintf(stderr,"drawvrl <VRL file> <palette file>\n");\r
+               return 1;\r
+       }\r
+\r
+       fd = open(argv[1],O_RDONLY|O_BINARY);\r
+       if (fd < 0) {\r
+               fprintf(stderr,"Unable to open '%s'\n",argv[1]);\r
+               return 1;\r
+       }\r
+       {\r
+               unsigned long sz = lseek(fd,0,SEEK_END);\r
+               if (sz < sizeof(*vrl_header)) return 1;\r
+               if (sz >= 65535UL) return 1;\r
+\r
+               bufsz = (unsigned int)sz;\r
+               buffer = malloc(bufsz);\r
+               if (buffer == NULL) return 1;\r
+\r
+               lseek(fd,0,SEEK_SET);\r
+               if ((unsigned int)read(fd,buffer,bufsz) < bufsz) return 1;\r
+\r
+               vrl_header = (struct vrl1_vgax_header*)buffer;\r
+               if (memcmp(vrl_header->vrl_sig,"VRL1",4) || memcmp(vrl_header->fmt_sig,"VGAX",4)) return 1;\r
+               if (vrl_header->width == 0 || vrl_header->height == 0) return 1;\r
+       }\r
+       close(fd);\r
+\r
+       probe_dos();\r
+       if (!probe_vga()) {\r
+               printf("VGA probe failed\n");\r
+               return 1;\r
+       }\r
+       int10_setmode(19);\r
+       update_state_from_vga();\r
+       vga_enable_256color_modex(); // VGA mode X\r
+       vga_state.vga_width = 320; // VGA lib currently does not update this\r
+       vga_state.vga_height = 240; // VGA lib currently does not update this\r
+\r
+#if 1 // 320x240 test mode: this is how Project 16 is using our code, enable for test case\r
+       {\r
+               struct vga_mode_params cm;\r
+\r
+               vga_read_crtc_mode(&cm);\r
+\r
+               // 320x240 mode 60Hz\r
+               cm.vertical_total = 525;\r
+               cm.vertical_start_retrace = 0x1EA;\r
+               cm.vertical_end_retrace = 0x1EC;\r
+               cm.vertical_display_end = 480;\r
+               cm.vertical_blank_start = 489;\r
+               cm.vertical_blank_end = 517;\r
+\r
+               vga_write_crtc_mode(&cm,0);\r
+       }\r
+       vga_state.vga_height = 240; // VGA lib currently does not update this\r
+#endif\r
+\r
+       /* load color palette */\r
+       fd = open(argv[2],O_RDONLY|O_BINARY);\r
+       if (fd >= 0) {\r
+               unsigned int i;\r
+\r
+               read(fd,palette,768);\r
+               close(fd);\r
+\r
+               vga_palette_lseek(0);\r
+               for (i=0;i < 256;i++) vga_palette_write(palette[(i*3)+0]>>2,palette[(i*3)+1]>>2,palette[(i*3)+2]>>2);\r
+       }\r
+\r
+       /* preprocess the sprite to generate line offsets */\r
+       vrl_lineoffs = vrl1_vgax_genlineoffsets(vrl_header,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));\r
+       if (vrl_lineoffs == NULL) return 1;\r
+\r
+       {\r
+               unsigned int i,j,o;\r
+\r
+               /* fill screen with a distinctive pattern */\r
+               for (i=0;i < vga_state.vga_width;i++) {\r
+                       o = i >> 2;\r
+                       vga_write_sequencer(0x02/*map mask*/,1 << (i&3));\r
+                       for (j=0;j < vga_state.vga_height;j++,o += vga_state.vga_stride)\r
+                               vga_state.vga_graphics_ram[o] = (i^j)&15; // VRL samples put all colors in first 15!\r
+               }\r
+       }\r
+       //while (getch() != 13);\r
+\r
+       /* make distinctive pattern offscreen, render sprite, copy onscreen */\r
+       {\r
+               const unsigned int offscreen_ofs = (vga_state.vga_stride * vga_state.vga_height);\r
+               unsigned int i,j,o,o2,x,y,rx,ry,w,h;\r
+               unsigned int overdraw = 1;      // how many pixels to "overdraw" so that moving sprites with edge pixels don't leave streaks.\r
+                                               // if the sprite's edge pixels are clear anyway, you can set this to 0.\r
+               VGA_RAM_PTR omemptr;\r
+               int xdir=1,ydir=1;\r
+\r
+               /* starting coords. note: this technique is limited to x coordinates of multiple of 4 */\r
+               x = 0;\r
+               y = 0;\r
+\r
+               /* do it */\r
+               omemptr = vga_state.vga_graphics_ram; // save original mem ptr\r
+               while (1) {\r
+                       /* stop animating if the user hits ENTER */\r
+                       if (kbhit()) {\r
+                               if (getch() == 13) break;\r
+                       }\r
+\r
+                       /* render box bounds. y does not need modification, but x and width must be multiple of 4 */\r
+                       if (x >= overdraw) rx = (x - overdraw) & (~3);\r
+                       else rx = 0;\r
+                       if (y >= overdraw) ry = (y - overdraw);\r
+                       else ry = 0;\r
+                       h = vrl_header->height + overdraw + y - ry;\r
+                       w = (x + vrl_header->width + (overdraw*2) + 3/*round up*/ - rx) & (~3);\r
+                       if ((rx+w) > vga_state.vga_width) w = vga_state.vga_width-rx;\r
+                       if ((ry+h) > vga_state.vga_height) h = vga_state.vga_height-ry;\r
+\r
+                       /* replace VGA stride with our own and mem ptr. then sprite rendering at this stage is just (0,0) */\r
+                       vga_state.vga_draw_stride_limit = (vga_state.vga_width + 3/*round up*/ - x) >> 2;\r
+                       vga_state.vga_draw_stride = w >> 2;\r
+                       vga_state.vga_graphics_ram = omemptr + offscreen_ofs;\r
+\r
+                       /* first draw pattern corresponding to that part of the screen. this COULD be optimized, obviously, but it's designed for study.\r
+                        * also note we don't have to use the same stride as the display! */\r
+                       for (i=rx;i < (rx+w);i++) {\r
+                               o = (i-rx) >> 2;\r
+                               vga_write_sequencer(0x02/*map mask*/,1 << (i&3));\r
+                               for (j=ry;j < (ry+h);j++,o += vga_state.vga_draw_stride)\r
+                                       vga_state.vga_graphics_ram[o] = (i^j)&15; // VRL samples put all colors in first 15!\r
+                       }\r
+\r
+                       /* then the sprite. note modding ram ptr means we just draw to (x&3,0) */\r
+                       draw_vrl1_vgax_modex(x-rx,y-ry,vrl_header,vrl_lineoffs,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));\r
+\r
+                       /* restore ptr */\r
+                       vga_state.vga_graphics_ram = omemptr;\r
+\r
+                       /* block copy to visible RAM from offscreen */\r
+                       vga_setup_wm1_block_copy();\r
+                       o = offscreen_ofs; // source offscreen\r
+                       o2 = (ry * vga_state.vga_stride) + (rx >> 2); // dest visible (original stride)\r
+                       for (i=0;i < h;i++,o += vga_state.vga_draw_stride,o2 += vga_state.vga_stride) vga_wm1_mem_block_copy(o2,o,w >> 2);\r
+                       /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */\r
+                       vga_restore_rm0wm0();\r
+\r
+                       /* restore stride */\r
+                       vga_state.vga_draw_stride_limit = vga_state.vga_draw_stride = vga_state.vga_stride;\r
+\r
+                       /* step */\r
+                       x += xdir;\r
+                       y += ydir;\r
+                       if (x >= (vga_state.vga_width - 1) || x == 0)\r
+                               xdir = -xdir;\r
+                       if (y >= (vga_state.vga_height - 1) || y == 0)\r
+                               ydir = -ydir;\r
+               }\r
+       }\r
+\r
+       /* make distinctive pattern offscreen, render sprite, copy onscreen.\r
+        * this time, we render the distinctive pattern to another offscreen location and just copy.\r
+        * note this version is much faster too! */\r
+       {\r
+               const unsigned int offscreen_ofs = (vga_state.vga_stride * vga_state.vga_height);\r
+               const unsigned int pattern_ofs = 0x10000UL - (vga_state.vga_stride * vga_state.vga_height);\r
+               unsigned int i,j,o,o2,x,y,rx,ry,w,h;\r
+               unsigned int overdraw = 1;      // how many pixels to "overdraw" so that moving sprites with edge pixels don't leave streaks.\r
+                                               // if the sprite's edge pixels are clear anyway, you can set this to 0.\r
+               VGA_RAM_PTR omemptr;\r
+               int xdir=1,ydir=1;\r
+\r
+               /* fill pattern offset with a distinctive pattern */\r
+               for (i=0;i < vga_state.vga_width;i++) {\r
+                       o = (i >> 2) + pattern_ofs;\r
+                       vga_write_sequencer(0x02/*map mask*/,1 << (i&3));\r
+                       for (j=0;j < vga_state.vga_height;j++,o += vga_state.vga_stride)\r
+                               vga_state.vga_graphics_ram[o] = (i^j)&15; // VRL samples put all colors in first 15!\r
+               }\r
+\r
+               /* starting coords. note: this technique is limited to x coordinates of multiple of 4 */\r
+               x = 0;\r
+               y = 0;\r
+\r
+               /* do it */\r
+               omemptr = vga_state.vga_graphics_ram; // save original mem ptr\r
+               while (1) {\r
+                       /* stop animating if the user hits ENTER */\r
+                       if (kbhit()) {\r
+                               if (getch() == 13) break;\r
+                       }\r
+\r
+                       /* render box bounds. y does not need modification, but x and width must be multiple of 4 */\r
+                       if (x >= overdraw) rx = (x - overdraw) & (~3);\r
+                       else rx = 0;\r
+                       if (y >= overdraw) ry = (y - overdraw);\r
+                       else ry = 0;\r
+                       h = vrl_header->height + overdraw + y - ry;\r
+                       w = (x + vrl_header->width + (overdraw*2) + 3/*round up*/ - rx) & (~3);\r
+                       if ((rx+w) > vga_state.vga_width) w = vga_state.vga_width-rx;\r
+                       if ((ry+h) > vga_state.vga_height) h = vga_state.vga_height-ry;\r
+\r
+                       /* block copy pattern to where we will draw the sprite */\r
+                       vga_setup_wm1_block_copy();\r
+                       o2 = offscreen_ofs;\r
+                       o = pattern_ofs + (ry * vga_state.vga_stride) + (rx >> 2); // source offscreen\r
+                       for (i=0;i < h;i++,o += vga_state.vga_stride,o2 += (w >> 2)) vga_wm1_mem_block_copy(o2,o,w >> 2);\r
+                       /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */\r
+                       vga_restore_rm0wm0();\r
+\r
+                       /* replace VGA stride with our own and mem ptr. then sprite rendering at this stage is just (0,0) */\r
+                       vga_state.vga_draw_stride_limit = (vga_state.vga_width + 3/*round up*/ - x) >> 2;\r
+                       vga_state.vga_draw_stride = w >> 2;\r
+                       vga_state.vga_graphics_ram = omemptr + offscreen_ofs;\r
+\r
+                       /* then the sprite. note modding ram ptr means we just draw to (x&3,0) */\r
+                       draw_vrl1_vgax_modex(x-rx,y-ry,vrl_header,vrl_lineoffs,buffer+sizeof(*vrl_header),bufsz-sizeof(*vrl_header));\r
+\r
+                       /* restore ptr */\r
+                       vga_state.vga_graphics_ram = omemptr;\r
+\r
+                       /* block copy to visible RAM from offscreen */\r
+                       vga_setup_wm1_block_copy();\r
+                       o = offscreen_ofs; // source offscreen\r
+                       o2 = (ry * vga_state.vga_stride) + (rx >> 2); // dest visible (original stride)\r
+                       for (i=0;i < h;i++,o += vga_state.vga_draw_stride,o2 += vga_state.vga_stride) vga_wm1_mem_block_copy(o2,o,w >> 2);\r
+                       /* must restore Write Mode 0/Read Mode 0 for this code to continue drawing normally */\r
+                       vga_restore_rm0wm0();\r
+\r
+                       /* restore stride */\r
+                       vga_state.vga_draw_stride_limit = vga_state.vga_draw_stride = vga_state.vga_stride;\r
+\r
+                       /* step */\r
+                       x += xdir;\r
+                       y += ydir;\r
+                       if (x >= (vga_state.vga_width - 1) || x == 0)\r
+                               xdir = -xdir;\r
+                       if (y >= (vga_state.vga_height - 1) || y == 0)\r
+                               ydir = -ydir;\r
+               }\r
+       }\r
+\r
+       /* another handy "demo" effect using VGA write mode 1.\r
+        * we can take what's on screen and vertically squash it like an old analog TV set turning off. */\r
+       {\r
+               unsigned int blank_line_ofs = (vga_state.vga_stride * vga_state.vga_height * 2);\r
+               unsigned int copy_ofs = (vga_state.vga_stride * vga_state.vga_height);\r
+               unsigned int display_ofs = 0x0000;\r
+               unsigned int i,y,soh,doh,dstart;\r
+               unsigned int dh_blankfill = 8;\r
+               unsigned int dh_step = 8;\r
+               uint32_t sh,dh,yf,ystep;\r
+\r
+               /* copy active display (0) to offscreen buffer (0x4000) */\r
+               vga_state.vga_draw_stride_limit = vga_state.vga_draw_stride = vga_state.vga_stride;\r
+               vga_setup_wm1_block_copy();\r
+               vga_wm1_mem_block_copy(copy_ofs,display_ofs,vga_state.vga_stride * vga_state.vga_height);\r
+               vga_restore_rm0wm0();\r
+\r
+               /* need a blank line as well */\r
+               for (i=0;i < vga_state.vga_stride;i++) vga_state.vga_graphics_ram[i+blank_line_ofs] = 0;\r
+\r
+               sh = dh = vga_state.vga_height;\r
+               while (dh >= dh_step) {\r
+                       /* stop animating if the user hits ENTER */\r
+                       if (kbhit()) {\r
+                               if (getch() == 13) break;\r
+                       }\r
+\r
+                       /* wait for vsync end */\r
+                       vga_wait_for_vsync_end();\r
+\r
+                       /* what scalefactor to use for stretching? */\r
+                       ystep = (0x10000UL * sh) / dh;\r
+                       dstart = (vga_state.vga_height - dh) / 2; // center the squash effect on screen, otherwise it would squash to top of screen\r
+                       doh = display_ofs;\r
+                       soh = copy_ofs;\r
+                       yf = 0;\r
+                       y = 0;\r
+\r
+                       /* for performance, keep VGA in write mode 1 the entire render */\r
+                       vga_setup_wm1_block_copy();\r
+\r
+                       /* blank lines */\r
+                       if (dstart >= dh_blankfill) y = dstart - dh_blankfill;\r
+                       else y = 0;\r
+                       doh = vga_state.vga_stride * y;\r
+\r
+                       while (y < dstart) {\r
+                               vga_wm1_mem_block_copy(doh,blank_line_ofs,vga_state.vga_stride);\r
+                               doh += vga_state.vga_stride;\r
+                               y++;\r
+                       }\r
+\r
+                       /* draw */\r
+                       while (y < (dh+dstart)) {\r
+                               soh = copy_ofs + ((yf >> 16UL) * vga_state.vga_stride);\r
+                               vga_wm1_mem_block_copy(doh,soh,vga_state.vga_stride);\r
+                               doh += vga_state.vga_stride;\r
+                               yf += ystep;\r
+                               y++;\r
+                       }\r
+\r
+                       /* blank lines */\r
+                       while (y < vga_state.vga_height && y < (dh+dstart+dh_blankfill)) {\r
+                               vga_wm1_mem_block_copy(doh,blank_line_ofs,vga_state.vga_stride);\r
+                               doh += vga_state.vga_stride;\r
+                               y++;\r
+                       }\r
+\r
+                       /* done */\r
+                       vga_restore_rm0wm0();\r
+\r
+                       /* wait for vsync */\r
+                       vga_wait_for_vsync();\r
+\r
+                       /* make it shrink */\r
+                       dh -= dh_step;\r
+                       if (dh < 40) dh_step = 1;\r
+               }\r
+       }\r
+\r
+       int10_setmode(3);\r
+       free(vrl_lineoffs);\r
+       buffer = NULL;\r
+       free(buffer);\r
+       bufsz = 0;\r
+       return 0;\r
+}\r
index dbe0bfc7e98182b72049236427bda12d48d2f39c..d1f8bbbe3ee54e1ec2fead4424e8a66ee3f89bf3 100755 (executable)
@@ -1,20 +1,20 @@
-#ifndef __TESUTO_H__
-#define __TESUTO_H__
-
-#include "src/lib/16_head.h"
-#include "src/lib/modex16.h"
-#include "src/lib/16_in.h"
-#include <hw/cpu/cpu.h>
-#include <hw/dos/dos.h>
-#include <hw/vga/vga.h>
-#include <hw/vga/vrl.h>
-
-typedef unsigned char far *VGA_RAM_PTR;
-//VGA_RAM_PTR vga_graphics_ram = (VGA_RAM_PTR)MK_FP(0xA000,0x0000);
-//unsigned char vga_stride = 80; // 80 x 4 = 320 for 320-pixel wide modes
-
-/*static inline void vga_write_sequencer(unsigned char i,unsigned char c) {
-    outp(0x3C4,i);
-    outp(0x3C5,c);
-}*/
-#endif
+#ifndef __TESUTO_H__\r
+#define __TESUTO_H__\r
+\r
+#include "src/lib/16_head.h"\r
+#include "src/lib/modex16.h"\r
+#include "src/lib/16_in.h"\r
+#include <hw/cpu/cpu.h>\r
+#include <hw/dos/dos.h>\r
+#include <hw/vga/vga.h>\r
+#include <hw/vga/vrl.h>\r
+\r
+typedef unsigned char far *VGA_RAM_PTR;\r
+//VGA_RAM_PTR vga_graphics_ram = (VGA_RAM_PTR)MK_FP(0xA000,0x0000);\r
+//unsigned char vga_stride = 80; // 80 x 4 = 320 for 320-pixel wide modes\r
+\r
+/*static inline void vga_write_sequencer(unsigned char i,unsigned char c) {\r
+    outp(0x3C4,i);\r
+    outp(0x3C5,c);\r
+}*/\r
+#endif\r
index 7476b7ea67db79d88b81547dfb4d5eb23461b369..245a5335831a4a928ecbaeb7a2bdf7330f491e2c 100755 (executable)
-/* tsthimem.c
- *
- * Test program: HIMEM.SYS functions
- * (C) 2010-2012 Jonathan Campbell.
- * Hackipedia DOS library.
- *
- * This code is licensed under the LGPL.
- * <insert LGPL legal text here>
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <conio.h>
-#include <dos.h>
-
-//#include "src/lib/doslib/cpu.h"
-#include "src/lib/doslib/dos.h"
-//#include doswin.h>
-#include "src/lib/doslib/himemsys.h"
-
-int main() {
-       probe_dos();
-       printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF);
-       /*if (detect_windows()) {
-               printf("I am running under Windows.\n");
-               printf("    Mode: %s\n",windows_mode_str(windows_mode));
-               printf("    Ver:  %x.%02u\n",windows_version>>8,windows_version&0xFF);
-       }
-       else {
-               printf("Not running under Windows or OS/2\n");
-       }*/
-
-       if (probe_himem_sys()) {
-               int h1,h2,h3;
-
-               printf("HIMEM.SYS detected. Entry point %04x:%04x. v%x.%02x\n",
-                               (unsigned int)((himem_sys_entry >> 16) & 0xFFFFUL),
-                               (unsigned int)(himem_sys_entry & 0xFFFFUL),
-                               (unsigned int)(himem_sys_version >> 8),
-                               (unsigned int)(himem_sys_version & 0xFF));
-
-               if (himem_sys_flags & HIMEM_F_HMA)
-                       printf("  - HMA is present\n");
-               if (himem_sys_flags & HIMEM_F_4GB)
-                       printf("  - Extensions are present to address up to 4GB of memory\n");
-
-               printf("A20 status: %u\n",himem_sys_query_a20());
-               printf("Global A20 line:         "); fflush(stdout);
-               printf("en=%d ",himem_sys_global_a20(1)); fflush(stdout);
-               printf("query=%d ",himem_sys_query_a20(1)); fflush(stdout);
-               printf("dis=%d ",himem_sys_global_a20(0)); fflush(stdout);
-               printf("query=%d ",himem_sys_query_a20(1)); fflush(stdout);
-               printf("\n");
-
-               printf("Local A20 line:          "); fflush(stdout);
-               printf("en=%d ",himem_sys_local_a20(1)); fflush(stdout);
-               printf("query=%d ",himem_sys_query_a20(1)); fflush(stdout);
-               printf("dis=%d ",himem_sys_local_a20(0)); fflush(stdout);
-               printf("query=%d ",himem_sys_query_a20(1)); fflush(stdout);
-               printf("\n");
-
-               himem_sys_update_free_memory_status();
-               printf("Free memory: %luKB (largest block %luKB)\n",
-                       (unsigned long)himem_sys_total_free,
-                       (unsigned long)himem_sys_largest_free);
-
-               printf("Attempting to alloc 4KB: ");
-               h1 = himem_sys_alloc(4); /* NTS: This is in KB, not bytes */
-               if (h1 != -1) printf("ok, handle %u\n",h1);
-               else printf("failed\n");
-
-               printf("Attempting to alloc 64KB: ");
-               h2 = himem_sys_alloc(46); /* NTS: This is in KB, not bytes */
-               if (h2 != -1) printf("ok, handle %u\n",h2);
-               else printf("failed\n");
-
-               printf("Attempting to alloc 1MB: ");
-               h3 = himem_sys_alloc(1024); /* NTS: This is in KB, not bytes */
-               if (h3 != -1) printf("ok, handle %u\n",h3);
-               else printf("failed\n");
-
-               if (h1 != -1) {
-                       if (!himem_sys_free(h1)) printf(" - Free failed\n");
-               }
-               if (h2 != -1) {
-                       if (!himem_sys_free(h2)) printf(" - Free failed\n");
-               }
-               if (h3 != -1) {
-                       if (!himem_sys_free(h3)) printf(" - Free failed\n");
-               }
-
-               printf("Attempting to alloc 1MB (for writing to): ");
-               h3 = himem_sys_alloc(1024); /* NTS: This is in KB, not bytes */
-               if (h3 != -1) {
-                       uint32_t ofs;
-                       unsigned int i;
-                       struct himem_block_info binf;
-#if TARGET_MSDOS == 32
-                       char *msg;
-                       unsigned char *tmp;
-                       uint16_t tmpsel=0,msgsel=0;
-                       const char *msgref = "Testing 123 hello";
-#else
-                       unsigned char tmp[16];
-                       const char *msg = "Testing 123 hello";
-#endif
-
-#if TARGET_MSDOS == 32
-                       tmp = dpmi_alloc_dos(16,&tmpsel);
-                       if (tmp == NULL) abort();
-                       msg = dpmi_alloc_dos(strlen(msgref)+16,&msgsel);
-                       if (msg == NULL) abort();
-                       memcpy(msg,msgref,strlen(msgref)+1);
-#endif
-
-                       printf("ok, handle %u\n",h3);
-
-                       if (himem_sys_get_handle_info(h3,&binf)) {
-                               printf("Handle info:\n");
-                               printf("     Lock count=%u  Free handles=%u  Size=%luKB\n",
-                                       (unsigned int)binf.lock_count,
-                                       (unsigned int)binf.free_handles,
-                                       (unsigned long)binf.block_length_kb);
-                       }
-                       else {
-                               printf("Cannot get handle info\n");
-                       }
-
-#if TARGET_MSDOS == 32
-                       if (!himem_sys_move(h3,0,0/*conventional memory*/,(unsigned long)(msg),16))
-#else
-                       if (!himem_sys_move(h3,0,0/*conventional memory*/,((unsigned long)FP_SEG(msg) << 4UL) + (unsigned long)FP_OFF(msg),sizeof(tmp)))
-#endif
-                               printf("Copy didn't work\n");
-
-                       for (i=0;i < 16;i += 2) {
-                               tmp[i+0] = 0x55;
-                               tmp[i+1] = 0xAA;
-                       }
-
-#if TARGET_MSDOS == 32
-                       if (!himem_sys_move(0/*conventional memory*/,(unsigned long)(tmp),h3,0,16))
-#else
-                       if (!himem_sys_move(0/*conventional memory*/,((unsigned long)FP_SEG(tmp) << 4UL) + (unsigned long)FP_OFF(tmp),h3,0,sizeof(tmp)))
-#endif
-                               printf("Copy didn't work\n");
-
-                       for (i=0;i < 16;i++) printf("%02x ",tmp[i]);
-                       printf("\n");
-
-                       ofs = himem_sys_lock(h3);
-                       if (ofs != 0UL) {
-                               printf(" - Locked: Physical memory address 0x%08lX\n",(unsigned long)ofs);
-                               if (!himem_sys_unlock(h3)) printf(" - Cannot unlock\n");
-                       }
-                       else {
-                               printf(" - Cannot lock\n");
-                       }
-
-                       printf("now resizing to 2MB\n");
-                       if (himem_sys_realloc(h3,2048)) {
-#if TARGET_MSDOS == 32
-                               if (!himem_sys_move(0/*conventional memory*/,(unsigned long)(tmp),h3,0,16))
-#else
-                               if (!himem_sys_move(0/*conventional memory*/,((unsigned long)FP_SEG(tmp) << 4UL) + (unsigned long)FP_OFF(tmp),h3,0,sizeof(tmp)))
-#endif
-                                       printf("Copy didn't work\n");
-
-                               for (i=0;i < 16;i++) printf("%02x ",tmp[i]);
-                               printf("\n");
-
-                               ofs = himem_sys_lock(h3);
-                               if (ofs != 0UL) {
-                                       printf(" - Locked: Physical memory address 0x%08lX\n",(unsigned long)ofs);
-                                       if (!himem_sys_unlock(h3)) printf(" - Cannot unlock\n");
-                               }
-                               else {
-                                       printf(" - Cannot lock\n");
-                               }
-                       }
-                       else {
-                               printf(" - Cannot realloc\n");
-                       }
-
-                       if (!himem_sys_free(h3)) printf(" - Free failed\n");
-
-#if TARGET_MSDOS == 32
-                       dpmi_free_dos(tmpsel); tmp=NULL;
-                       dpmi_free_dos(msgsel); msg=NULL;
-#endif
-               }
-               else printf("failed\n");
-
-               printf("Attempting to alloc 129MB (for writing to): ");
-               h3 = himem_sys_alloc(129UL * 1024UL); /* NTS: This is in KB, not bytes */
-               if (h3 != -1) {
-                       uint32_t ofs;
-                       unsigned int i;
-                       unsigned char tmp[16];
-                       struct himem_block_info binf;
-                       const char *msg = "Testing 123 hello";
-
-                       printf("ok, handle %u\n",h3);
-
-                       if (himem_sys_get_handle_info(h3,&binf)) {
-                               printf("Handle info:\n");
-                               printf("     Lock count=%u  Free handles=%u  Size=%luKB\n",
-                                       (unsigned int)binf.lock_count,
-                                       (unsigned int)binf.free_handles,
-                                       (unsigned long)binf.block_length_kb);
-                       }
-                       else {
-                               printf("Cannot get handle info\n");
-                       }
-
-#if TARGET_MSDOS == 32
-                       if (!himem_sys_move(h3,0,0/*conventional memory*/,(unsigned long)(msg),16))
-#else
-                       if (!himem_sys_move(h3,0,0/*conventional memory*/,((unsigned long)FP_SEG(msg) << 4UL) + (unsigned long)FP_OFF(msg),sizeof(tmp)))
-#endif
-                               printf("Copy didn't work\n");
-
-                       for (i=0;i < 16;i += 2) {
-                               tmp[i+0] = 0x55;
-                               tmp[i+1] = 0xAA;
-                       }
-
-#if TARGET_MSDOS == 32
-                       if (!himem_sys_move(0/*conventional memory*/,(unsigned long)(tmp),h3,0,16))
-#else
-                       if (!himem_sys_move(0/*conventional memory*/,((unsigned long)FP_SEG(tmp) << 4UL) + (unsigned long)FP_OFF(tmp),h3,0,sizeof(tmp)))
-#endif
-                               printf("Copy didn't work\n");
-
-                       for (i=0;i < 16;i++) printf("%02x ",tmp[i]);
-                       printf("\n");
-
-                       ofs = himem_sys_lock(h3);
-                       if (ofs != 0UL) {
-                               printf(" - Locked: Physical memory address 0x%08lX\n",(unsigned long)ofs);
-                               if (!himem_sys_unlock(h3)) printf(" - Cannot unlock\n");
-                       }
-                       else {
-                               printf(" - Cannot lock\n");
-                       }
-
-                       printf("now resizing to 144MB\n");
-                       if (himem_sys_realloc(h3,144UL*1024UL)) {
-                               if (himem_sys_get_handle_info(h3,&binf)) {
-                                       printf("Handle info:\n");
-                                       printf("     Lock count=%u  Free handles=%u  Size=%luKB\n",
-                                               (unsigned int)binf.lock_count,
-                                               (unsigned int)binf.free_handles,
-                                               (unsigned long)binf.block_length_kb);
-                               }
-                               else {
-                                       printf("Cannot get handle info\n");
-                               }
-
-#if TARGET_MSDOS == 32
-                               if (!himem_sys_move(0/*conventional memory*/,(unsigned long)(tmp),h3,0,16))
-#else
-                               if (!himem_sys_move(0/*conventional memory*/,((unsigned long)FP_SEG(tmp) << 4UL) + (unsigned long)FP_OFF(tmp),h3,0,sizeof(tmp)))
-#endif
-                                       printf("Copy didn't work\n");
-
-                               for (i=0;i < 16;i++) printf("%02x ",tmp[i]);
-                               printf("\n");
-
-                               ofs = himem_sys_lock(h3);
-                               if (ofs != 0UL) {
-                                       printf(" - Locked: Physical memory address 0x%08lX\n",(unsigned long)ofs);
-                                       if (!himem_sys_unlock(h3)) printf(" - Cannot unlock\n");
-                               }
-                               else {
-                                       printf(" - Cannot lock\n");
-                               }
-                       }
-                       else {
-                               printf(" - Cannot realloc\n");
-                       }
-
-                       if (!himem_sys_free(h3)) printf(" - Free failed\n");
-               }
-               else printf("failed\n");
-       }
-       else {
-               printf("HIMEM.SYS not found\n");
-       }
-
-       return 0;
-}
-
+/* tsthimem.c\r
+ *\r
+ * Test program: HIMEM.SYS functions\r
+ * (C) 2010-2012 Jonathan Campbell.\r
+ * Hackipedia DOS library.\r
+ *\r
+ * This code is licensed under the LGPL.\r
+ * <insert LGPL legal text here>\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <stdint.h>\r
+#include <stdio.h>\r
+#include <conio.h>\r
+#include <dos.h>\r
+\r
+//#include "src/lib/doslib/cpu.h"\r
+#include "src/lib/doslib/dos.h"\r
+//#include doswin.h>\r
+#include "src/lib/doslib/himemsys.h"\r
+\r
+int main() {\r
+       probe_dos();\r
+       printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF);\r
+       /*if (detect_windows()) {\r
+               printf("I am running under Windows.\n");\r
+               printf("    Mode: %s\n",windows_mode_str(windows_mode));\r
+               printf("    Ver:  %x.%02u\n",windows_version>>8,windows_version&0xFF);\r
+       }\r
+       else {\r
+               printf("Not running under Windows or OS/2\n");\r
+       }*/\r
+\r
+       if (probe_himem_sys()) {\r
+               int h1,h2,h3;\r
+\r
+               printf("HIMEM.SYS detected. Entry point %04x:%04x. v%x.%02x\n",\r
+                               (unsigned int)((himem_sys_entry >> 16) & 0xFFFFUL),\r
+                               (unsigned int)(himem_sys_entry & 0xFFFFUL),\r
+                               (unsigned int)(himem_sys_version >> 8),\r
+                               (unsigned int)(himem_sys_version & 0xFF));\r
+\r
+               if (himem_sys_flags & HIMEM_F_HMA)\r
+                       printf("  - HMA is present\n");\r
+               if (himem_sys_flags & HIMEM_F_4GB)\r
+                       printf("  - Extensions are present to address up to 4GB of memory\n");\r
+\r
+               printf("A20 status: %u\n",himem_sys_query_a20());\r
+               printf("Global A20 line:         "); fflush(stdout);\r
+               printf("en=%d ",himem_sys_global_a20(1)); fflush(stdout);\r
+               printf("query=%d ",himem_sys_query_a20(1)); fflush(stdout);\r
+               printf("dis=%d ",himem_sys_global_a20(0)); fflush(stdout);\r
+               printf("query=%d ",himem_sys_query_a20(1)); fflush(stdout);\r
+               printf("\n");\r
+\r
+               printf("Local A20 line:          "); fflush(stdout);\r
+               printf("en=%d ",himem_sys_local_a20(1)); fflush(stdout);\r
+               printf("query=%d ",himem_sys_query_a20(1)); fflush(stdout);\r
+               printf("dis=%d ",himem_sys_local_a20(0)); fflush(stdout);\r
+               printf("query=%d ",himem_sys_query_a20(1)); fflush(stdout);\r
+               printf("\n");\r
+\r
+               himem_sys_update_free_memory_status();\r
+               printf("Free memory: %luKB (largest block %luKB)\n",\r
+                       (unsigned long)himem_sys_total_free,\r
+                       (unsigned long)himem_sys_largest_free);\r
+\r
+               printf("Attempting to alloc 4KB: ");\r
+               h1 = himem_sys_alloc(4); /* NTS: This is in KB, not bytes */\r
+               if (h1 != -1) printf("ok, handle %u\n",h1);\r
+               else printf("failed\n");\r
+\r
+               printf("Attempting to alloc 64KB: ");\r
+               h2 = himem_sys_alloc(46); /* NTS: This is in KB, not bytes */\r
+               if (h2 != -1) printf("ok, handle %u\n",h2);\r
+               else printf("failed\n");\r
+\r
+               printf("Attempting to alloc 1MB: ");\r
+               h3 = himem_sys_alloc(1024); /* NTS: This is in KB, not bytes */\r
+               if (h3 != -1) printf("ok, handle %u\n",h3);\r
+               else printf("failed\n");\r
+\r
+               if (h1 != -1) {\r
+                       if (!himem_sys_free(h1)) printf(" - Free failed\n");\r
+               }\r
+               if (h2 != -1) {\r
+                       if (!himem_sys_free(h2)) printf(" - Free failed\n");\r
+               }\r
+               if (h3 != -1) {\r
+                       if (!himem_sys_free(h3)) printf(" - Free failed\n");\r
+               }\r
+\r
+               printf("Attempting to alloc 1MB (for writing to): ");\r
+               h3 = himem_sys_alloc(1024); /* NTS: This is in KB, not bytes */\r
+               if (h3 != -1) {\r
+                       uint32_t ofs;\r
+                       unsigned int i;\r
+                       struct himem_block_info binf;\r
+#if TARGET_MSDOS == 32\r
+                       char *msg;\r
+                       unsigned char *tmp;\r
+                       uint16_t tmpsel=0,msgsel=0;\r
+                       const char *msgref = "Testing 123 hello";\r
+#else\r
+                       unsigned char tmp[16];\r
+                       const char *msg = "Testing 123 hello";\r
+#endif\r
+\r
+#if TARGET_MSDOS == 32\r
+                       tmp = dpmi_alloc_dos(16,&tmpsel);\r
+                       if (tmp == NULL) abort();\r
+                       msg = dpmi_alloc_dos(strlen(msgref)+16,&msgsel);\r
+                       if (msg == NULL) abort();\r
+                       memcpy(msg,msgref,strlen(msgref)+1);\r
+#endif\r
+\r
+                       printf("ok, handle %u\n",h3);\r
+\r
+                       if (himem_sys_get_handle_info(h3,&binf)) {\r
+                               printf("Handle info:\n");\r
+                               printf("     Lock count=%u  Free handles=%u  Size=%luKB\n",\r
+                                       (unsigned int)binf.lock_count,\r
+                                       (unsigned int)binf.free_handles,\r
+                                       (unsigned long)binf.block_length_kb);\r
+                       }\r
+                       else {\r
+                               printf("Cannot get handle info\n");\r
+                       }\r
+\r
+#if TARGET_MSDOS == 32\r
+                       if (!himem_sys_move(h3,0,0/*conventional memory*/,(unsigned long)(msg),16))\r
+#else\r
+                       if (!himem_sys_move(h3,0,0/*conventional memory*/,((unsigned long)FP_SEG(msg) << 4UL) + (unsigned long)FP_OFF(msg),sizeof(tmp)))\r
+#endif\r
+                               printf("Copy didn't work\n");\r
+\r
+                       for (i=0;i < 16;i += 2) {\r
+                               tmp[i+0] = 0x55;\r
+                               tmp[i+1] = 0xAA;\r
+                       }\r
+\r
+#if TARGET_MSDOS == 32\r
+                       if (!himem_sys_move(0/*conventional memory*/,(unsigned long)(tmp),h3,0,16))\r
+#else\r
+                       if (!himem_sys_move(0/*conventional memory*/,((unsigned long)FP_SEG(tmp) << 4UL) + (unsigned long)FP_OFF(tmp),h3,0,sizeof(tmp)))\r
+#endif\r
+                               printf("Copy didn't work\n");\r
+\r
+                       for (i=0;i < 16;i++) printf("%02x ",tmp[i]);\r
+                       printf("\n");\r
+\r
+                       ofs = himem_sys_lock(h3);\r
+                       if (ofs != 0UL) {\r
+                               printf(" - Locked: Physical memory address 0x%08lX\n",(unsigned long)ofs);\r
+                               if (!himem_sys_unlock(h3)) printf(" - Cannot unlock\n");\r
+                       }\r
+                       else {\r
+                               printf(" - Cannot lock\n");\r
+                       }\r
+\r
+                       printf("now resizing to 2MB\n");\r
+                       if (himem_sys_realloc(h3,2048)) {\r
+#if TARGET_MSDOS == 32\r
+                               if (!himem_sys_move(0/*conventional memory*/,(unsigned long)(tmp),h3,0,16))\r
+#else\r
+                               if (!himem_sys_move(0/*conventional memory*/,((unsigned long)FP_SEG(tmp) << 4UL) + (unsigned long)FP_OFF(tmp),h3,0,sizeof(tmp)))\r
+#endif\r
+                                       printf("Copy didn't work\n");\r
+\r
+                               for (i=0;i < 16;i++) printf("%02x ",tmp[i]);\r
+                               printf("\n");\r
+\r
+                               ofs = himem_sys_lock(h3);\r
+                               if (ofs != 0UL) {\r
+                                       printf(" - Locked: Physical memory address 0x%08lX\n",(unsigned long)ofs);\r
+                                       if (!himem_sys_unlock(h3)) printf(" - Cannot unlock\n");\r
+                               }\r
+                               else {\r
+                                       printf(" - Cannot lock\n");\r
+                               }\r
+                       }\r
+                       else {\r
+                               printf(" - Cannot realloc\n");\r
+                       }\r
+\r
+                       if (!himem_sys_free(h3)) printf(" - Free failed\n");\r
+\r
+#if TARGET_MSDOS == 32\r
+                       dpmi_free_dos(tmpsel); tmp=NULL;\r
+                       dpmi_free_dos(msgsel); msg=NULL;\r
+#endif\r
+               }\r
+               else printf("failed\n");\r
+\r
+               printf("Attempting to alloc 129MB (for writing to): ");\r
+               h3 = himem_sys_alloc(129UL * 1024UL); /* NTS: This is in KB, not bytes */\r
+               if (h3 != -1) {\r
+                       uint32_t ofs;\r
+                       unsigned int i;\r
+                       unsigned char tmp[16];\r
+                       struct himem_block_info binf;\r
+                       const char *msg = "Testing 123 hello";\r
+\r
+                       printf("ok, handle %u\n",h3);\r
+\r
+                       if (himem_sys_get_handle_info(h3,&binf)) {\r
+                               printf("Handle info:\n");\r
+                               printf("     Lock count=%u  Free handles=%u  Size=%luKB\n",\r
+                                       (unsigned int)binf.lock_count,\r
+                                       (unsigned int)binf.free_handles,\r
+                                       (unsigned long)binf.block_length_kb);\r
+                       }\r
+                       else {\r
+                               printf("Cannot get handle info\n");\r
+                       }\r
+\r
+#if TARGET_MSDOS == 32\r
+                       if (!himem_sys_move(h3,0,0/*conventional memory*/,(unsigned long)(msg),16))\r
+#else\r
+                       if (!himem_sys_move(h3,0,0/*conventional memory*/,((unsigned long)FP_SEG(msg) << 4UL) + (unsigned long)FP_OFF(msg),sizeof(tmp)))\r
+#endif\r
+                               printf("Copy didn't work\n");\r
+\r
+                       for (i=0;i < 16;i += 2) {\r
+                               tmp[i+0] = 0x55;\r
+                               tmp[i+1] = 0xAA;\r
+                       }\r
+\r
+#if TARGET_MSDOS == 32\r
+                       if (!himem_sys_move(0/*conventional memory*/,(unsigned long)(tmp),h3,0,16))\r
+#else\r
+                       if (!himem_sys_move(0/*conventional memory*/,((unsigned long)FP_SEG(tmp) << 4UL) + (unsigned long)FP_OFF(tmp),h3,0,sizeof(tmp)))\r
+#endif\r
+                               printf("Copy didn't work\n");\r
+\r
+                       for (i=0;i < 16;i++) printf("%02x ",tmp[i]);\r
+                       printf("\n");\r
+\r
+                       ofs = himem_sys_lock(h3);\r
+                       if (ofs != 0UL) {\r
+                               printf(" - Locked: Physical memory address 0x%08lX\n",(unsigned long)ofs);\r
+                               if (!himem_sys_unlock(h3)) printf(" - Cannot unlock\n");\r
+                       }\r
+                       else {\r
+                               printf(" - Cannot lock\n");\r
+                       }\r
+\r
+                       printf("now resizing to 144MB\n");\r
+                       if (himem_sys_realloc(h3,144UL*1024UL)) {\r
+                               if (himem_sys_get_handle_info(h3,&binf)) {\r
+                                       printf("Handle info:\n");\r
+                                       printf("     Lock count=%u  Free handles=%u  Size=%luKB\n",\r
+                                               (unsigned int)binf.lock_count,\r
+                                               (unsigned int)binf.free_handles,\r
+                                               (unsigned long)binf.block_length_kb);\r
+                               }\r
+                               else {\r
+                                       printf("Cannot get handle info\n");\r
+                               }\r
+\r
+#if TARGET_MSDOS == 32\r
+                               if (!himem_sys_move(0/*conventional memory*/,(unsigned long)(tmp),h3,0,16))\r
+#else\r
+                               if (!himem_sys_move(0/*conventional memory*/,((unsigned long)FP_SEG(tmp) << 4UL) + (unsigned long)FP_OFF(tmp),h3,0,sizeof(tmp)))\r
+#endif\r
+                                       printf("Copy didn't work\n");\r
+\r
+                               for (i=0;i < 16;i++) printf("%02x ",tmp[i]);\r
+                               printf("\n");\r
+\r
+                               ofs = himem_sys_lock(h3);\r
+                               if (ofs != 0UL) {\r
+                                       printf(" - Locked: Physical memory address 0x%08lX\n",(unsigned long)ofs);\r
+                                       if (!himem_sys_unlock(h3)) printf(" - Cannot unlock\n");\r
+                               }\r
+                               else {\r
+                                       printf(" - Cannot lock\n");\r
+                               }\r
+                       }\r
+                       else {\r
+                               printf(" - Cannot realloc\n");\r
+                       }\r
+\r
+                       if (!himem_sys_free(h3)) printf(" - Free failed\n");\r
+               }\r
+               else printf("failed\n");\r
+       }\r
+       else {\r
+               printf("HIMEM.SYS not found\n");\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
index 8ed436206a06a204883da280ee7c26435092ac08..05db59e14de7dfc9f976a1f617b2509e8e0f36e8 100755 (executable)
-/* Project 16 Source Code~
- * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
- *
- * This file is part of Project 16.
- *
- * Project 16 is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Project 16 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
- * write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "src/lib/modex16.h"
-#include "src/lib/16_sprit.h"
-#include "src/lib/16_ca.h"
-#include "src/lib/16_mm.h"
-
-void main() {
-       global_game_variables_t gvar;
-       __segment sega;
-       memptr bigbuffer;
-       int i;
-       word start;
-       int plane;
-       float t1, t2;
-       boolean baka;
-       byte *pal;
-       int size, size1;
-       struct sprite spri;
-       vrl1_vgax_offset_t * off, *off1;
-       struct vrs_container vrs;
-       vrl1_vgax_offset_t **vrl_line_offsets;
-       uint32_t huge *vrl_headers_offsets;
-       uint16_t huge *vrl_id_iter;
-       uint32_t vrl_size;
-       int num_of_vrl;
-       struct vrl1_vgax_header huge *curr_vrl;
-       struct vrl_container *vrl;
-       word w=0;
-
-       // DOSLIB: check our environment
-       probe_dos();
-
-       // DOSLIB: what CPU are we using?
-       // NTS: I can see from the makefile Sparky4 intends this to run on 8088 by the -0 switch in CFLAGS.
-       //      So this code by itself shouldn't care too much what CPU it's running on. Except that other
-       //      parts of this project (DOSLIB itself) rely on CPU detection to know what is appropriate for
-       //      the CPU to carry out tasks. --J.C.
-       cpu_probe();
-
-       // DOSLIB: check for VGA
-       if (!probe_vga()) {
-               printf("VGA probe failed\n");
-               return;
-       }
-       // hardware must be VGA or higher!
-       if (!(vga_state.vga_flags & VGA_IS_VGA)) {
-               printf("This program requires VGA or higher graphics hardware\n");
-               return;
-       }
-
-       //gvar.video.page[0]=modexDefaultPage(&gvar.video.page[0]);
-
-       gvar.mm.mmstarted=0;
-       MM_Startup(&gvar);
-       CA_Startup(&gvar);
-       // What should be done by read_vrs:
-       //sega = (mm.bufferseg);
-       if(CA_LoadFile("data/spri/chikyuu.vrs", &bigbuffer, &gvar)) baka=1; else baka=0;
-
-       // Insert sanity cheks later
-       vrs.buffer = bigbuffer;
-       vrs.data_size = size - sizeof(struct vrl1_vgax_header);
-       num_of_vrl = 0;
-       vrl_id_iter = (uint16_t huge *)(vrs.buffer + vrs.vrs_hdr->offset_table[VRS_HEADER_OFFSET_SPRITE_ID_LIST]);
-       while(vrl_id_iter[num_of_vrl]){
-               num_of_vrl++;
-       }
-
-       // Allocate memory for vrl line offsets table
-       vrl_line_offsets = malloc(sizeof(vrl1_vgax_offset_t *)*num_of_vrl);
-
-       vrl_headers_offsets = (uint32_t huge *)(vrs.buffer + vrs.vrs_hdr->offset_table[VRS_HEADER_OFFSET_VRS_LIST]);
-       // Calculate line offsets for each vrl
-       for(i = 0; i < num_of_vrl; i++){
-               curr_vrl = (struct vrl1_vgax_header huge *)(vrs.buffer + vrl_headers_offsets[i]);
-
-               // Calc. vrl size as (next_offset - curr_offset)
-               if (i != num_of_vrl - 1){
-                       vrl_size = vrl_headers_offsets[i+1] - vrl_headers_offsets[i] - sizeof(struct vrl1_vgax_header);
-               }
-               // If it's the last vrl, size is (next_vrs_struct_offset - curr_offset)
-               else{
-                       vrl_size = vrs.vrs_hdr->offset_table[VRS_HEADER_OFFSET_SPRITE_ID_LIST] - vrl_headers_offsets[i] - sizeof(struct vrl1_vgax_header);
-               }
-               vrl_line_offsets[i] = vrl1_vgax_genlineoffsets(curr_vrl, (byte *)curr_vrl + sizeof(struct vrl1_vgax_header), vrl_size);
-       }
-       vrs.vrl_line_offsets = vrl_line_offsets;
-
-
-       //read_vrs(&gvar, "data/spri/chikyuu.vrs", &vrs);
-       spri.spritesheet = &vrs;
-       spri.sprite_vrl_cont = malloc(sizeof(struct vrl_container));
-       i = set_anim_by_id(&spri, 11);
-       if (i == -1)
-       {
-               return;
-       }
-       spri.x = 5;
-       spri.y = 100;
-
-//     Uncomment to see broken sprites
-/*     sega = mm.bufferseg;
-       if(CA_LoadFile("data/spri/CHUBACW1.vrl", &bigbuffer, &mm, &mmi)) baka=1; else baka=0;*/
-
-       /* clear and draw one sprite and one bitmap */
-       VGAmodeX(1, 1, &gvar);
-       modexHiganbanaPageSetup(&gvar.video);
-
-       /* non sprite comparison */
-       start = *clockw;
-       modexCopyPageRegion(&gvar.video.page[0], &gvar.video.page[0], 0, 0, 0, 0, 320, 240);
-       t1 = (*clockw-start) /18.2;
-
-       start = *clockw;
-
-       t2 = (*clockw-start)/18.2;
-
-       for (i = 0; i < 5; i++){
-       spri.delay = 1; animate_spri(&spri); spri.x += 20; sleep(1); }
-
-       while(!kbhit())
-       {
-               switch(w)
-               {
-                       case 1024:
-                               modexPalUpdate0(pal);
-                               w=0;
-                       default:
-                               w++;
-                       break;
-               }
-       }
-       VGAmodeX(0, 1, &gvar);
-       MM_ShowMemory(&gvar);
-       MM_DumpData(&gvar);
-       free(spri.sprite_vrl_cont);
-       MM_FreePtr(&bigbuffer, &gvar);
-       //MM_FreePtr(&((void __based(sega)*)spri.spritesheet->buffer), &mm);
-       CA_Shutdown(&gvar);
-       MM_Shutdown(&gvar);
-       //printf("CPU to VGA: %f\n", t1);
-       //printf("VGA to VGA: %f\n", t2);
-       heapdump(&gvar);
-       printf("Project 16 vrstest.exe. This is just a test file!\n");
-       printf("version %s\n", VERSION);
-       printf("t1: %f\n", t1);
-       printf("t2: %f\n", t2);
-       printf("gvar.video.page[0].width: %u\n", gvar.video.page[0].width);
-       printf("gvar.video.page[0].height: %u\n", gvar.video.page[0].height);
-       printf("Num %d", num_of_vrl);
-       if(baka) printf("\nyay!\n");
-       else printf("\npoo!\n");
-}
+/* Project 16 Source Code~\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ *\r
+ * This file is part of Project 16.\r
+ *\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ */\r
+\r
+#include "src/lib/modex16.h"\r
+#include "src/lib/16_sprit.h"\r
+#include "src/lib/16_ca.h"\r
+#include "src/lib/16_mm.h"\r
+\r
+void main() {\r
+       global_game_variables_t gvar;\r
+       __segment sega;\r
+       memptr bigbuffer;\r
+       int i;\r
+       word start;\r
+       int plane;\r
+       float t1, t2;\r
+       boolean baka;\r
+       byte *pal;\r
+       int size, size1;\r
+       struct sprite spri;\r
+       vrl1_vgax_offset_t * off, *off1;\r
+       struct vrs_container vrs;\r
+       vrl1_vgax_offset_t **vrl_line_offsets;\r
+       uint32_t huge *vrl_headers_offsets;\r
+       uint16_t huge *vrl_id_iter;\r
+       uint32_t vrl_size;\r
+       int num_of_vrl;\r
+       struct vrl1_vgax_header huge *curr_vrl;\r
+       struct vrl_container *vrl;\r
+       word w=0;\r
+\r
+       // DOSLIB: check our environment\r
+       probe_dos();\r
+\r
+       // DOSLIB: what CPU are we using?\r
+       // NTS: I can see from the makefile Sparky4 intends this to run on 8088 by the -0 switch in CFLAGS.\r
+       //      So this code by itself shouldn't care too much what CPU it's running on. Except that other\r
+       //      parts of this project (DOSLIB itself) rely on CPU detection to know what is appropriate for\r
+       //      the CPU to carry out tasks. --J.C.\r
+       cpu_probe();\r
+\r
+       // DOSLIB: check for VGA\r
+       if (!probe_vga()) {\r
+               printf("VGA probe failed\n");\r
+               return;\r
+       }\r
+       // hardware must be VGA or higher!\r
+       if (!(vga_state.vga_flags & VGA_IS_VGA)) {\r
+               printf("This program requires VGA or higher graphics hardware\n");\r
+               return;\r
+       }\r
+\r
+       //gvar.video.page[0]=modexDefaultPage(&gvar.video.page[0]);\r
+\r
+       gvar.mm.mmstarted=0;\r
+       MM_Startup(&gvar);\r
+       CA_Startup(&gvar);\r
+       // What should be done by read_vrs:\r
+       //sega = (mm.bufferseg);\r
+       if(CA_LoadFile("data/spri/chikyuu.vrs", &bigbuffer, &gvar)) baka=1; else baka=0;\r
+\r
+       // Insert sanity cheks later\r
+       vrs.buffer = bigbuffer;\r
+       vrs.data_size = size - sizeof(struct vrl1_vgax_header);\r
+       num_of_vrl = 0;\r
+       vrl_id_iter = (uint16_t huge *)(vrs.buffer + vrs.vrs_hdr->offset_table[VRS_HEADER_OFFSET_SPRITE_ID_LIST]);\r
+       while(vrl_id_iter[num_of_vrl]){\r
+               num_of_vrl++;\r
+       }\r
+\r
+       // Allocate memory for vrl line offsets table\r
+       vrl_line_offsets = malloc(sizeof(vrl1_vgax_offset_t *)*num_of_vrl);\r
+\r
+       vrl_headers_offsets = (uint32_t huge *)(vrs.buffer + vrs.vrs_hdr->offset_table[VRS_HEADER_OFFSET_VRS_LIST]);\r
+       // Calculate line offsets for each vrl\r
+       for(i = 0; i < num_of_vrl; i++){\r
+               curr_vrl = (struct vrl1_vgax_header huge *)(vrs.buffer + vrl_headers_offsets[i]);\r
+\r
+               // Calc. vrl size as (next_offset - curr_offset)\r
+               if (i != num_of_vrl - 1){\r
+                       vrl_size = vrl_headers_offsets[i+1] - vrl_headers_offsets[i] - sizeof(struct vrl1_vgax_header);\r
+               }\r
+               // If it's the last vrl, size is (next_vrs_struct_offset - curr_offset)\r
+               else{\r
+                       vrl_size = vrs.vrs_hdr->offset_table[VRS_HEADER_OFFSET_SPRITE_ID_LIST] - vrl_headers_offsets[i] - sizeof(struct vrl1_vgax_header);\r
+               }\r
+               vrl_line_offsets[i] = vrl1_vgax_genlineoffsets(curr_vrl, (byte *)curr_vrl + sizeof(struct vrl1_vgax_header), vrl_size);\r
+       }\r
+       vrs.vrl_line_offsets = vrl_line_offsets;\r
+\r
+\r
+       //read_vrs(&gvar, "data/spri/chikyuu.vrs", &vrs);\r
+       spri.spritesheet = &vrs;\r
+       spri.sprite_vrl_cont = malloc(sizeof(struct vrl_container));\r
+       i = set_anim_by_id(&spri, 11);\r
+       if (i == -1)\r
+       {\r
+               return;\r
+       }\r
+       spri.x = 5;\r
+       spri.y = 100;\r
+\r
+//     Uncomment to see broken sprites\r
+/*     sega = mm.bufferseg;\r
+       if(CA_LoadFile("data/spri/CHUBACW1.vrl", &bigbuffer, &mm, &mmi)) baka=1; else baka=0;*/\r
+\r
+       /* clear and draw one sprite and one bitmap */\r
+       VGAmodeX(1, 1, &gvar);\r
+       modexHiganbanaPageSetup(&gvar.video);\r
+\r
+       /* non sprite comparison */\r
+       start = *clockw;\r
+       modexCopyPageRegion(&gvar.video.page[0], &gvar.video.page[0], 0, 0, 0, 0, 320, 240);\r
+       t1 = (*clockw-start) /18.2;\r
+\r
+       start = *clockw;\r
+\r
+       t2 = (*clockw-start)/18.2;\r
+\r
+       for (i = 0; i < 5; i++){\r
+       spri.delay = 1; animate_spri(&spri); spri.x += 20; sleep(1); }\r
+\r
+       while(!kbhit())\r
+       {\r
+               switch(w)\r
+               {\r
+                       case 1024:\r
+                               modexPalUpdate0(pal);\r
+                               w=0;\r
+                       default:\r
+                               w++;\r
+                       break;\r
+               }\r
+       }\r
+       VGAmodeX(0, 1, &gvar);\r
+       MM_ShowMemory(&gvar);\r
+       MM_DumpData(&gvar);\r
+       free(spri.sprite_vrl_cont);\r
+       MM_FreePtr(&bigbuffer, &gvar);\r
+       //MM_FreePtr(&((void __based(sega)*)spri.spritesheet->buffer), &mm);\r
+       CA_Shutdown(&gvar);\r
+       MM_Shutdown(&gvar);\r
+       //printf("CPU to VGA: %f\n", t1);\r
+       //printf("VGA to VGA: %f\n", t2);\r
+       heapdump(&gvar);\r
+       printf("Project 16 vrstest.exe. This is just a test file!\n");\r
+       printf("version %s\n", VERSION);\r
+       printf("t1: %f\n", t1);\r
+       printf("t2: %f\n", t2);\r
+       printf("gvar.video.page[0].width: %u\n", gvar.video.page[0].width);\r
+       printf("gvar.video.page[0].height: %u\n", gvar.video.page[0].height);\r
+       printf("Num %d", num_of_vrl);\r
+       if(baka) printf("\nyay!\n");\r
+       else printf("\npoo!\n");\r
+}\r