From: Jonathan Campbell Date: Fri, 21 Oct 2016 19:10:17 +0000 (-0700) Subject: Merge remote-tracking branch 'upstream/master' X-Git-Url: http://4ch.mooo.com/gitweb/?a=commitdiff_plain;h=fb97121f7d0be4408d8e2ed98a2f7b10b852a915;hp=631d2bde47de81ead5300f7aca378447387f254c;p=16.git Merge remote-tracking branch 'upstream/master' --- diff --git a/16/16_mm.c b/16/16_mm.c new file mode 100755 index 00000000..9f10fd39 --- /dev/null +++ b/16/16_mm.c @@ -0,0 +1,1802 @@ +/* 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 + +============================================================================= +*/ + +/* +====================== += += 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;immi.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;imm.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; + //huge void huge *start; + void far *start; + word segstart,seglength,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;imm.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)); + printf("Borland C unique function\n"); + printf(" coreleft() %lu\n", coreleft()); +#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; + gvar->mmi.mainmem = gvar->mmi.nearheap + gvar->mmi.farheap; + //printf("start=%Fp segstart=%x seglen=%lu len=%lu\n", start, segstart, seglength, length); + +#ifdef __DEBUG_PM__ +goto xmsskip; //INFO: 16_PM dose this job better +#endif + +// +// detect EMS and allocate up to 64K at page frame +// + gvar->mmi.EMSmem = 0; +//goto emsskip; //0000 + 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 + 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 +#ifndef __DEBUG_PM__ + if(MML_CheckForEMS()){ MML_ShutdownEMS(gvar); }//printf(" EMS freed\n"); } + if(MML_CheckForXMS(gvar)){ MML_ShutdownXMS(gvar); }//printf(" XMS freed\n"); } //INFO: 16_PM dose this job better +#endif +} + +//========================================================================== + +/* +==================== += += 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) + { +#ifdef __DEBUG_PM__ + printf("\nstart->useptr gvar->mm.mmhead->useptr\n"); + printf(" %Fp %Fp\n", start->useptr, gvar->mm.mmhead->useptr); + printf("& %Fp %Fp\n", &(start->useptr), &(gvar->mm.mmhead->useptr)); + printf("baseptr gvar->mm.mmrover->useptr\n"); + printf(" %Fp %Fp\n", baseptr, gvar->mm.mmrover->useptr); + printf("& %Fp %Fp\n", &(baseptr), &(gvar->mm.mmrover->useptr)); + printf("* %Fp %Fp\n", *(baseptr), *(gvar->mm.mmrover->useptr)); + printf("start gvar->mm.mmrover gvar->mm.mmrover->next\n"); + printf(" %Fp %Fp %Fp\n", start, gvar->mm.mmrover, gvar->mm.mmrover->next); + printf("& %Fp %Fp %Fp\n", &start, &gvar->mm.mmrover, gvar->mm.mmrover->next); + getch(); + MM_ShowMemory(gvar); + MM_DumpData(gvar); + MM_Report_(gvar); + getch(); +#endif + Quit("MM_SetPurge: Block not found!"); + 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 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 +*/ diff --git a/DEBUG.16B b/DEBUG.16B index 546573cb..c7bd7809 100755 --- a/DEBUG.16B +++ b/DEBUG.16B @@ -1,12 +1,210 @@ -Seg:0 Size:2982 Owner:0x6574 -++++++++++++++++++++++++++++++++++++++0 -Seg:ba6 Size:256 Owner:0xcf7a +Seg:0 Size:5151 Owner:0x0 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++0 +Seg:141f Size:256 Owner:0xed5 ++++ -Seg:ca6 Size:273 Owner:0xfde -++++000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -Seg:9fde Size:28706 Owner:0x0 +Seg:151f Size:256 Owner:0xcd6 +++++ +Seg:161f Size:256 Owner:0xcd8 +++++ +Seg:171f Size:256 Owner:0xcda ++++++ +Seg:181f Size:256 Owner:0xcdc +++++ +Seg:191f Size:256 Owner:0xcde +++++ +Seg:1a1f Size:256 Owner:0xce0 +++++ +Seg:1b1f Size:256 Owner:0xce2 +++++ +Seg:1c1f Size:256 Owner:0xce4 ++++++ +Seg:1d1f Size:256 Owner:0xce6 +++++ +Seg:1e1f Size:256 Owner:0xce8 +++++ +Seg:1f1f Size:256 Owner:0xcea +++++ +Seg:201f Size:256 Owner:0xcec +++++ +Seg:211f Size:256 Owner:0xcee ++++++ +Seg:221f Size:256 Owner:0xcf0 +++++ +Seg:231f Size:256 Owner:0xcf2 +++++ +Seg:241f Size:256 Owner:0xcf4 +++++ +Seg:251f Size:256 Owner:0xcf6 +++++ +Seg:261f Size:256 Owner:0xcf8 ++++++ +Seg:271f Size:256 Owner:0xcfa +++++ +Seg:281f Size:256 Owner:0xcfc +++++ +Seg:291f Size:256 Owner:0xcfe +++++ +Seg:2a1f Size:256 Owner:0xd00 +++++ +Seg:2b1f Size:256 Owner:0xd02 ++++++ +Seg:2c1f Size:256 Owner:0xd04 +++++ +Seg:2d1f Size:256 Owner:0xd06 +++++ +Seg:2e1f Size:256 Owner:0xd08 +++++ +Seg:2f1f Size:256 Owner:0xd0a +++++ +Seg:301f Size:256 Owner:0xd0c ++++++ +Seg:311f Size:256 Owner:0xd0e +++++ +Seg:321f Size:256 Owner:0xd10 +++++ +Seg:331f Size:256 Owner:0xd12 +++++ +Seg:341f Size:256 Owner:0xd14 +++++ +Seg:351f Size:256 Owner:0xd16 ++++++ +Seg:361f Size:256 Owner:0xd18 +++++ +Seg:371f Size:256 Owner:0xd1a +++++ +Seg:381f Size:256 Owner:0xd1c +++++ +Seg:391f Size:256 Owner:0xd1e +++++ +Seg:3a1f Size:256 Owner:0xd20 ++++++ +Seg:3b1f Size:256 Owner:0xd22 +++++ +Seg:3c1f Size:256 Owner:0xd24 +++++ +Seg:3d1f Size:256 Owner:0xd26 +++++ +Seg:3e1f Size:256 Owner:0xd28 +++++ +Seg:3f1f Size:256 Owner:0xd2a ++++++ +Seg:401f Size:256 Owner:0xd2c +++++ +Seg:411f Size:256 Owner:0xd2e +++++ +Seg:421f Size:256 Owner:0xd30 +++++ +Seg:431f Size:256 Owner:0xd32 +++++ +Seg:441f Size:256 Owner:0xd34 ++++++ +Seg:451f Size:256 Owner:0xd36 +++++ +Seg:461f Size:256 Owner:0xd38 +++++ +Seg:471f Size:256 Owner:0xd3a +++++ +Seg:481f Size:256 Owner:0xd3c +++++ +Seg:491f Size:256 Owner:0xd3e ++++++ +Seg:4a1f Size:256 Owner:0xd40 +++++ +Seg:4b1f Size:256 Owner:0xd42 +++++ +Seg:4c1f Size:256 Owner:0xd44 +++++ +Seg:4d1f Size:256 Owner:0xd46 +++++ +Seg:4e1f Size:256 Owner:0xd48 ++++++ +Seg:4f1f Size:256 Owner:0xd4a +++++ +Seg:501f Size:256 Owner:0xd4c +++++ +Seg:511f Size:256 Owner:0xd4e +++++ +Seg:521f Size:256 Owner:0xd50 +++++ +Seg:531f Size:256 Owner:0xd52 ++++++ +Seg:541f Size:256 Owner:0xd54 +++++ +Seg:551f Size:256 Owner:0xd56 +++++ +Seg:561f Size:256 Owner:0xd58 +++++ +Seg:571f Size:256 Owner:0xd5a +++++ +Seg:581f Size:256 Owner:0xd5c ++++++ +Seg:591f Size:256 Owner:0xd5e +++++ +Seg:5a1f Size:256 Owner:0xd60 +++++ +Seg:5b1f Size:256 Owner:0xd62 +++++ +Seg:5c1f Size:256 Owner:0xd64 +++++ +Seg:5d1f Size:256 Owner:0xd66 ++++++ +Seg:5e1f Size:256 Owner:0xd68 +++++ +Seg:5f1f Size:256 Owner:0xd6a +++++ +Seg:601f Size:256 Owner:0xd6c +++++ +Seg:611f Size:256 Owner:0xd6e +++++ +Seg:621f Size:256 Owner:0xd70 ++++++ +Seg:631f Size:256 Owner:0xd72 +++++ +Seg:641f Size:256 Owner:0xd74 +++++ +Seg:651f Size:256 Owner:0xd76 +++++ +Seg:661f Size:256 Owner:0xd78 +++++ +Seg:671f Size:256 Owner:0xd7a ++++++ +Seg:681f Size:256 Owner:0xd7c +++++ +Seg:691f Size:256 Owner:0xd7e +++++ +Seg:6a1f Size:256 Owner:0xd80 +++++ +Seg:6b1f Size:256 Owner:0xd82 +++++ +Seg:6c1f Size:256 Owner:0xd84 ++++++ +Seg:6d1f Size:256 Owner:0xd86 +++++ +Seg:6e1f Size:256 Owner:0xd88 +++++ +Seg:6f1f Size:256 Owner:0xd8a +++++ +Seg:701f Size:256 Owner:0xd8c +++++ +Seg:711f Size:256 Owner:0xd8e ++++++ +Seg:721f Size:256 Owner:0xd90 +++++ +Seg:731f Size:256 Owner:0xd92 +++++ +Seg:741f Size:256 Owner:0xd94 +++++ +Seg:751f Size:256 Owner:0xd96 +++++ +Seg:761f Size:256 Owner:0xd98 ++++++ +Seg:771f Size:256 Owner:0xd9a +++++ +Seg:781f Size:256 Owner:0xd9c +++++ +Seg:791f Size:273 Owner:0xfde +++++ +Seg:9fde Size:32802 Owner:0x0  -Seg:9ffe Size:16386 Owner:0x0 -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Seg:e000 Size:8191 Owner:0x0 -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \ No newline at end of file +Seg:9ffe Size:24577 Owner:0x0 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \ No newline at end of file diff --git a/DEBUG.16W b/DEBUG.16W index 8f3ffe4d..86023db0 100755 --- a/DEBUG.16W +++ b/DEBUG.16W @@ -1,12 +1,210 @@ -Seg:0 Size:7812 Owner:0x6568 -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++0 -Seg:1e84 Size:256 Owner:0x5274 -++++ -Seg:1f84 Size:273 Owner:0x92cc +Seg:0 Size:11821 Owner:0x0 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++000 +Seg:2eb4 Size:37 Owner:0x0 ++ +Seg:2ed9 Size:256 Owner:0x1784 +++++ -Seg:2513 Size:44 Owner:0x0 -++0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -Seg:b53f Size:10945 Owner:0x0 -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Seg:e000 Size:8191 Owner:0x0 -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \ No newline at end of file +Seg:2fd9 Size:256 Owner:0x1572 +++++ +Seg:30d9 Size:256 Owner:0x1574 +++++ +Seg:31d9 Size:256 Owner:0x1576 +++++ +Seg:32d9 Size:256 Owner:0x1578 +++++ +Seg:33d9 Size:256 Owner:0x157a ++++++ +Seg:34d9 Size:256 Owner:0x157c +++++ +Seg:35d9 Size:256 Owner:0x157e +++++ +Seg:36d9 Size:256 Owner:0x1580 +++++ +Seg:37d9 Size:256 Owner:0x1582 +++++ +Seg:38d9 Size:256 Owner:0x1584 ++++++ +Seg:39d9 Size:256 Owner:0x1586 +++++ +Seg:3ad9 Size:256 Owner:0x1588 +++++ +Seg:3bd9 Size:256 Owner:0x158a +++++ +Seg:3cd9 Size:256 Owner:0x158c +++++ +Seg:3dd9 Size:256 Owner:0x158e ++++++ +Seg:3ed9 Size:256 Owner:0x1590 +++++ +Seg:3fd9 Size:256 Owner:0x1592 +++++ +Seg:40d9 Size:256 Owner:0x1594 +++++ +Seg:41d9 Size:256 Owner:0x1596 +++++ +Seg:42d9 Size:256 Owner:0x1598 ++++++ +Seg:43d9 Size:256 Owner:0x159a +++++ +Seg:44d9 Size:256 Owner:0x159c +++++ +Seg:45d9 Size:256 Owner:0x159e +++++ +Seg:46d9 Size:256 Owner:0x15a0 +++++ +Seg:47d9 Size:256 Owner:0x15a2 ++++++ +Seg:48d9 Size:256 Owner:0x15a4 +++++ +Seg:49d9 Size:256 Owner:0x15a6 +++++ +Seg:4ad9 Size:256 Owner:0x15a8 +++++ +Seg:4bd9 Size:256 Owner:0x15aa +++++ +Seg:4cd9 Size:256 Owner:0x15ac ++++++ +Seg:4dd9 Size:256 Owner:0x15ae +++++ +Seg:4ed9 Size:256 Owner:0x15b0 +++++ +Seg:4fd9 Size:256 Owner:0x15b2 +++++ +Seg:50d9 Size:256 Owner:0x15b4 +++++ +Seg:51d9 Size:256 Owner:0x15b6 ++++++ +Seg:52d9 Size:256 Owner:0x15b8 +++++ +Seg:53d9 Size:256 Owner:0x15ba +++++ +Seg:54d9 Size:256 Owner:0x15bc +++++ +Seg:55d9 Size:256 Owner:0x15be +++++ +Seg:56d9 Size:256 Owner:0x15c0 ++++++ +Seg:57d9 Size:256 Owner:0x15c2 +++++ +Seg:58d9 Size:256 Owner:0x15c4 +++++ +Seg:59d9 Size:256 Owner:0x15c6 +++++ +Seg:5ad9 Size:256 Owner:0x15c8 +++++ +Seg:5bd9 Size:256 Owner:0x15ca ++++++ +Seg:5cd9 Size:256 Owner:0x15cc +++++ +Seg:5dd9 Size:256 Owner:0x15ce +++++ +Seg:5ed9 Size:256 Owner:0x15d0 +++++ +Seg:5fd9 Size:256 Owner:0x15d2 +++++ +Seg:60d9 Size:256 Owner:0x15d4 ++++++ +Seg:61d9 Size:256 Owner:0x15d6 +++++ +Seg:62d9 Size:256 Owner:0x15d8 +++++ +Seg:63d9 Size:256 Owner:0x15da +++++ +Seg:64d9 Size:256 Owner:0x15dc +++++ +Seg:65d9 Size:256 Owner:0x15de ++++++ +Seg:66d9 Size:256 Owner:0x15e0 +++++ +Seg:67d9 Size:256 Owner:0x15e2 +++++ +Seg:68d9 Size:256 Owner:0x15e4 +++++ +Seg:69d9 Size:256 Owner:0x15e6 +++++ +Seg:6ad9 Size:256 Owner:0x15e8 ++++++ +Seg:6bd9 Size:256 Owner:0x15ea +++++ +Seg:6cd9 Size:256 Owner:0x15ec +++++ +Seg:6dd9 Size:256 Owner:0x15ee +++++ +Seg:6ed9 Size:256 Owner:0x15f0 +++++ +Seg:6fd9 Size:256 Owner:0x15f2 ++++++ +Seg:70d9 Size:256 Owner:0x15f4 +++++ +Seg:71d9 Size:256 Owner:0x15f6 +++++ +Seg:72d9 Size:256 Owner:0x15f8 +++++ +Seg:73d9 Size:256 Owner:0x15fa +++++ +Seg:74d9 Size:256 Owner:0x15fc ++++++ +Seg:75d9 Size:256 Owner:0x15fe +++++ +Seg:76d9 Size:256 Owner:0x1600 +++++ +Seg:77d9 Size:256 Owner:0x1602 +++++ +Seg:78d9 Size:256 Owner:0x1604 +++++ +Seg:79d9 Size:256 Owner:0x1606 ++++++ +Seg:7ad9 Size:256 Owner:0x1608 +++++ +Seg:7bd9 Size:256 Owner:0x160a +++++ +Seg:7cd9 Size:256 Owner:0x160c +++++ +Seg:7dd9 Size:256 Owner:0x160e +++++ +Seg:7ed9 Size:256 Owner:0x1610 ++++++ +Seg:7fd9 Size:256 Owner:0x1612 +++++ +Seg:80d9 Size:256 Owner:0x1614 +++++ +Seg:81d9 Size:256 Owner:0x1616 +++++ +Seg:82d9 Size:256 Owner:0x1618 +++++ +Seg:83d9 Size:256 Owner:0x161a ++++++ +Seg:84d9 Size:256 Owner:0x161c +++++ +Seg:85d9 Size:256 Owner:0x161e +++++ +Seg:86d9 Size:256 Owner:0x1620 +++++ +Seg:87d9 Size:256 Owner:0x1622 +++++ +Seg:88d9 Size:256 Owner:0x1624 ++++++ +Seg:89d9 Size:256 Owner:0x1626 +++++ +Seg:8ad9 Size:256 Owner:0x1628 +++++ +Seg:8bd9 Size:256 Owner:0x162a +++++ +Seg:8cd9 Size:256 Owner:0x162c +++++ +Seg:8dd9 Size:256 Owner:0x162e ++++++ +Seg:8ed9 Size:256 Owner:0x1630 +++++ +Seg:8fd9 Size:256 Owner:0x1632 +++++ +Seg:90d9 Size:256 Owner:0x1634 +++++ +Seg:91d9 Size:256 Owner:0x1636 +++++ +Seg:92d9 Size:256 Owner:0x1638 ++++++ +Seg:93d9 Size:401 Owner:0xf25a +++++++ +Seg:bed9 Size:16678 Owner:0x0 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \ No newline at end of file diff --git a/DEBUG_.16W b/DEBUG_.16W deleted file mode 100755 index e5d8c2f6..00000000 --- a/DEBUG_.16W +++ /dev/null @@ -1,17 +0,0 @@ -Seg:0 Size:7705 Owner:0x0 -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++_ -0 -Seg:1e19 Size:256 Owner:0x527c -++++_ - -Seg:1f19 Size:273 Owner:0x92d4 -++++_ - -Seg:24a8 Size:40 Owner:0x0 -+_ -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -Seg:b4d0 Size:11056 Owner:0x0 -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++_ - -Seg:e000 Size:8191 Owner:0x0 -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++_ \ No newline at end of file diff --git a/HEAP.16W b/HEAP.16W index d873f507..0526b320 100755 --- a/HEAP.16W +++ b/HEAP.16W @@ -1,47 +1,71 @@ == default == - USED block at 25350016 of size 66 - USED block at 25350058 of size 66 - FREE block at 2535009a of size 18 - USED block at 253500ac of size 136 - USED block at 25350134 of size 20 - FREE block at 25350148 of size 7860 + FREE block at 2ed70016 of size 18 + USED block at 2ed70028 of size 50 + USED block at 2ed7005a of size 50 + USED block at 2ed7008c of size 50 + USED block at 2ed700be of size 50 + USED block at 2ed700f0 of size 50 + USED block at 2ed70122 of size 50 + USED block at 2ed70154 of size 50 + USED block at 2ed70186 of size 50 + USED block at 2ed701b8 of size 50 + USED block at 2ed701ea of size 50 + USED block at 2ed7021c of size 50 + USED block at 2ed7024e of size 50 + USED block at 2ed70280 of size 50 + FREE block at 2ed702b2 of size 14 + USED block at 2ed702c0 of size 20 + USED block at 2ed702d4 of size 136 + FREE block at 2ed7035c of size 7328 OK - end of heap == near == - USED block at 15349306 of size 12 - USED block at 15349312 of size 332 - USED block at 1534945e of size 52 - USED block at 15349492 of size 20 - USED block at 153494a6 of size 20 - USED block at 153494ba of size 20 - USED block at 153494ce of size 20 - USED block at 153494e2 of size 20 - USED block at 153494f6 of size 27398 + USED block at 1ed6f2a6 of size 12 + USED block at 1ed6f2b2 of size 528 + USED block at 1ed6f4c2 of size 72 + USED block at 1ed6f50a of size 20 + USED block at 1ed6f51e of size 20 + USED block at 1ed6f532 of size 20 + USED block at 1ed6f546 of size 20 + USED block at 1ed6f55a of size 20 + USED block at 1ed6f56e of size 2702 OK - end of heap == far == - USED block at 25350016 of size 66 - USED block at 25350058 of size 66 - USED block at 2535009a of size 18 - USED block at 253500ac of size 136 - USED block at 25350134 of size 20 - USED block at 25350148 of size 7860 + USED block at 2ed70016 of size 18 + USED block at 2ed70028 of size 50 + USED block at 2ed7005a of size 50 + USED block at 2ed7008c of size 50 + USED block at 2ed700be of size 50 + USED block at 2ed700f0 of size 50 + USED block at 2ed70122 of size 50 + USED block at 2ed70154 of size 50 + USED block at 2ed70186 of size 50 + USED block at 2ed701b8 of size 50 + USED block at 2ed701ea of size 50 + USED block at 2ed7021c of size 50 + USED block at 2ed7024e of size 50 + USED block at 2ed70280 of size 50 + USED block at 2ed702b2 of size 14 + USED block at 2ed702c0 of size 20 + USED block at 2ed702d4 of size 136 + USED block at 2ed7035c of size 7328 OK - end of heap Memory Type Total Used Free ---------------- -------- -------- -------- -Default 8166 288 7878 -Near 27894 496 27398 -Far 8166 288 7878 +Default 8166 806 7360 +Near 3414 712 2702 +Far 8166 806 7360 ---------------- -------- -------- -------- -coreleft = 27396 -farcoreleft = 2352 -GetFreeSize = 40512 -GetNearFreeSize = 27398 -GetFarFreeSize = 40512 -memavl = 27396 -stackavail = 11792 +coreleft = 2700 +farcoreleft = 1694 +GetFreeSize = 64548 +GetNearFreeSize = 2702 +GetFarFreeSize = 64548 +memavl = 2700 +stackavail = 31519 diff --git a/MMDUMP.16B b/MMDUMP.16B index 2e06a768..3d22065d 100755 Binary files a/MMDUMP.16B and b/MMDUMP.16B differ diff --git a/MMDUMP.16W b/MMDUMP.16W index 0270a6db..89ef9446 100755 Binary files a/MMDUMP.16W and b/MMDUMP.16W differ diff --git a/PROFILE.16W b/PROFILE.16W new file mode 100755 index 00000000..e69de29b diff --git a/bcexmm.dsk b/bcexmm.dsk index 9d1c2ae5..e1d0305c 100755 Binary files a/bcexmm.dsk and b/bcexmm.dsk differ diff --git a/bcexmm.exe b/bcexmm.exe index d4ca4af8..c11e9410 100755 Binary files a/bcexmm.exe and b/bcexmm.exe differ diff --git a/bcexmm.prj b/bcexmm.prj index 6a7ef631..bf1d7a44 100755 Binary files a/bcexmm.prj and b/bcexmm.prj differ diff --git a/data/g.pal b/data/g.pal index 0ecbac33..f162c4ca 100755 Binary files a/data/g.pal and b/data/g.pal differ diff --git a/fmemtest.exe b/fmemtest.exe new file mode 100755 index 00000000..ee3480f3 Binary files /dev/null and b/fmemtest.exe differ diff --git a/fontgfx.exe b/fontgfx.exe new file mode 100755 index 00000000..d8891c5e Binary files /dev/null and b/fontgfx.exe differ diff --git a/fonttest.exe b/fonttest.exe new file mode 100755 index 00000000..22505eb0 Binary files /dev/null and b/fonttest.exe differ diff --git a/inputest.exe b/inputest.exe new file mode 100755 index 00000000..0bc39164 Binary files /dev/null and b/inputest.exe differ diff --git a/makefile b/makefile index 22929918..2d44a1b8 100755 --- a/makefile +++ b/makefile @@ -91,7 +91,7 @@ UPXQ=-qqq S_FLAGS=-sg -st -of+ -zu -zdf -zff -zgf -k32768#54096#60000 Z_FLAGS=-zk0 -zc -zp8 -zm O_FLAGS=-obmilr -oe=24 -out -oh -ei -onac -ol+ -ok##x -T_FLAGS=-bt=dos -mh -0 -fpi87 -fo=.$(OBJ) -d1 +T_FLAGS=-bt=dos -mh -0 -fpi87 -fo=.$(OBJ) -d1###### -e=65536 CPPFLAGS=-DTARGET_MSDOS=16 -DMSDOS=1 !ifeq DEBUGSERIAL 1 @@ -106,8 +106,8 @@ LIBFLAGS=$(WLIBQ) -b -n # objects # VGMSNDOBJ = vgmSnd.$(OBJ) 16_snd.$(OBJ) -16LIBOBJS = 16_in.$(OBJ) 16_mm.$(OBJ) wcpu.$(OBJ) 16_head.$(OBJ) 16_ca.$(OBJ) 16_dbg.$(OBJ) kitten.$(OBJ) 16_hc.$(OBJ) 16_timer.$(OBJ) -GFXLIBOBJS = modex16.$(OBJ) bitmap.$(OBJ) 16text.$(OBJ) bakapee.$(OBJ) scroll16.$(OBJ) 16render.$(OBJ) 16_vrs.$(OBJ) 16_sprit.$(OBJ) #scroll16.$(OBJ) +GFXLIBOBJS = modex16.$(OBJ) bitmap.$(OBJ) 16text.$(OBJ) bakapee.$(OBJ) scroll16.$(OBJ) 16render.$(OBJ) 16_vrs.$(OBJ) 16_sprit.$(OBJ) +16LIBOBJS = 16_mm.$(OBJ) 16_pm.$(OBJ) 16_ca.$(OBJ) 16_tail.$(OBJ) 16_in.$(OBJ) 16_head.$(OBJ) 16_dbg.$(OBJ) kitten.$(OBJ) 16_hc.$(OBJ) wcpu.$(OBJ) 16_timer.$(OBJ) #16planar.$(OBJ) planar.$(OBJ) DOSLIBOBJ = adlib.$(OBJ) 8254.$(OBJ) 8259.$(OBJ) dos.$(OBJ) cpu.$(OBJ) !ifeq DEBUGSERIAL 1 @@ -154,27 +154,30 @@ DOSLIBLIBS += $(DOSLIB_8250)/dos86h/8250.lib # List of executables to build # TESTEXEC = & - test.exe & - test0.exe & - pcxtest.exe & - pcxtest2.exe & - palettec.exe & + tesuto.exe & + 0.exe & + scroll.exe & + zcroll.exe & + exmmtest.exe & + vrstest.exe +TESTEXEC2 = & + vgmtest.exe & + inputest.exe & maptest.exe & fmemtest.exe & fonttest.exe & fontgfx.exe & - scroll.exe & - vgmtest.exe & - inputest.exe & + test.exe & + test0.exe & + pcxtest.exe & + pcxtest2.exe +UTILEXEC = & palettel.exe & - exmmtest.exe & - vrstest.exe & - vgacamm.exe + palettec.exe EXEC = & 16.exe & bakapi.exe & - tesuto.exe & - 0.exe & + $(UTILEXEC) & $(TESTEXEC) all: $(EXEC) joytest.exe @@ -190,6 +193,8 @@ bakapi.exe: bakapi.$(OBJ) gfx.lib $(DOSLIBLIBS) # scroll.exe: scroll.$(OBJ) mapread.$(OBJ) jsmn.$(OBJ) $(16LIB) gfx.lib $(DOSLIBLIBS) scroll.$(OBJ): $(SRC)/scroll.c +zcroll.exe: zcroll.$(OBJ) mapread.$(OBJ) jsmn.$(OBJ) $(16LIB) gfx.lib $(DOSLIBLIBS) +zcroll.$(OBJ): $(SRC)/zcroll.c tesuto.exe: tesuto.$(OBJ) 16_head.$(OBJ) gfx.lib $(DOSLIBLIBS) tesuto.$(OBJ): $(SRC)/tesuto.c 0.exe: 0.$(OBJ) $(16LIB) gfx.lib $(DOSLIBLIBS) @@ -204,7 +209,7 @@ inputest.exe: inputest.$(OBJ) $(16LIB) $(DOSLIBLIBS) #sountest.exe: sountest.$(OBJ) $(16LIB) pcxtest.exe: pcxtest.$(OBJ) gfx.lib $(DOSLIBLIBS) vrstest.exe: vrstest.$(OBJ) $(16LIB) gfx.lib $(DOSLIBLIBS) -vgacamm.exe: vgacamm.$(OBJ) $(16LIB) gfx.lib $(DOSLIBLIBS) +#vgacamm.exe: vgacamm.$(OBJ) $(16LIB) gfx.lib $(DOSLIBLIBS) palettec.exe: palettec.$(OBJ) gfx.lib $(DOSLIBLIBS) palettel.exe: palettel.$(OBJ) gfx.lib $(DOSLIBLIBS) pcxtest2.exe: pcxtest2.$(OBJ) gfx.lib $(DOSLIBLIBS) @@ -224,7 +229,7 @@ test.$(OBJ): $(SRC)/test.c $(SRCLIB)/modex16.h test0.$(OBJ): $(SRC)/test0.c pcxtest.$(OBJ): $(SRC)/pcxtest.c $(SRCLIB)/modex16.h vrstest.$(OBJ): $(SRC)/vrstest.c $(SRCLIB)/modex16.h -vgacamm.$(OBJ): $(SRC)/vgacamm.c $(SRCLIB)/modex16.h +#vgacamm.$(OBJ): $(SRC)/vgacamm.c $(SRCLIB)/modex16.h #planrpcx.$(OBJ): $(SRC)/planrpcx.c $(SRCLIB)/modex16.h pcxtest2.$(OBJ): $(SRC)/pcxtest2.c $(SRCLIB)/modex16.h palettec.$(OBJ): $(SRC)/palettec.c @@ -288,10 +293,12 @@ mapread.$(OBJ): $(SRCLIB)/mapread.c $(SRCLIB)/mapread.h 16_timer.$(OBJ): $(SRCLIB)/16_timer.c $(SRCLIB)/16_timer.h 16_in.$(OBJ): $(SRCLIB)/16_in.c $(SRCLIB)/16_in.h 16_mm.$(OBJ): $(SRCLIB)/16_mm.c $(SRCLIB)/16_mm.h +16_pm.$(OBJ): $(SRCLIB)/16_pm.c $(SRCLIB)/16_pm.h 16_ca.$(OBJ): $(SRCLIB)/16_ca.c $(SRCLIB)/16_ca.h 16_dbg.$(OBJ): $(SRCLIB)/16_dbg.c $(SRCLIB)/16_dbg.h midi.$(OBJ): $(SRCLIB)/midi.c $(SRCLIB)/midi.h 16_head.$(OBJ): $(SRCLIB)/16_head.c $(SRCLIB)/16_head.h +16_tail.$(OBJ): $(SRCLIB)/16_tail.c $(SRCLIB)/16_tail.h 16_hc.$(OBJ): $(SRCLIB)/16_hc.c $(SRCLIB)/16_hc.h 16_snd.$(OBJ): $(SRCLIB)/16_snd.c $(SRCLIB)/16_snd.h jsmn.$(OBJ): $(JSMNLIB)/jsmn.c $(JSMNLIB)/jsmn.h diff --git a/maptest.exe b/maptest.exe new file mode 100755 index 00000000..e8e04a63 Binary files /dev/null and b/maptest.exe differ diff --git a/modex.lib b/modex.lib deleted file mode 100755 index 560a1c68..00000000 Binary files a/modex.lib and /dev/null differ diff --git a/pcxtest.exe b/pcxtest.exe new file mode 100755 index 00000000..9f5b8217 Binary files /dev/null and b/pcxtest.exe differ diff --git a/pcxtest2.exe b/pcxtest2.exe new file mode 100755 index 00000000..ef3287a2 Binary files /dev/null and b/pcxtest2.exe differ diff --git a/pm.use b/pm.use new file mode 100755 index 00000000..fbd7a2c7 --- /dev/null +++ b/pm.use @@ -0,0 +1,277 @@ +16/wf3d8086/contigsc.c: shape = PM_GetSpritePage (shapenum); +16/wf3d8086/contigsc.c: shape = PM_GetSpritePage (shapenum); +16/wf3d8086/id_pm.c:// PM_SetMainMemPurge() - Sets the purge level for all allocated main memory +16/wf3d8086/id_pm.c:// blocks. This shouldn't be called directly - the PM_LockMainMem() and +16/wf3d8086/id_pm.c:// PM_UnlockMainMem() macros should be used instead. +16/wf3d8086/id_pm.c:PM_SetMainMemPurge(int level) +16/wf3d8086/id_pm.c:// PM_CheckMainMem() - If something besides the Page Mgr makes requests of +16/wf3d8086/id_pm.c:// This routine now calls PM_LockMainMem() to make sure that any allocation +16/wf3d8086/id_pm.c:// of the other blocks. Because PM_LockMainMem() is called, +16/wf3d8086/id_pm.c:// PM_UnlockMainMem() needs to be called before any other part of the +16/wf3d8086/id_pm.c:PM_CheckMainMem(void) +16/wf3d8086/id_pm.c: PM_LockMainMem(); +16/wf3d8086/id_pm.c:// necessary to make requests of the Memory Mgr, PM_UnlockMainMem() +16/wf3d8086/id_pm.c: Quit("PM_SetupMainMem: Not enough main memory"); +16/wf3d8086/id_pm.c:// PM_GetPageAddress() - Returns the address of a given page +16/wf3d8086/id_pm.c:PM_GetPageAddress(int pagenum) +16/wf3d8086/id_pm.c: PML_CopyToXMS(PM_GetPageAddress(pagenum),page->xmsPage,page->length); +16/wf3d8086/id_pm.c: addr = PM_GetPageAddress(orig); +16/wf3d8086/id_pm.c:// PM_GetPage() - Returns the address of the page, loading it if necessary +16/wf3d8086/id_pm.c:PM_GetPage(int pagenum) +16/wf3d8086/id_pm.c: Quit("PM_GetPage: Invalid page request"); +16/wf3d8086/id_pm.c: if (!(result = PM_GetPageAddress(pagenum))) +16/wf3d8086/id_pm.c: result = PM_GetPageAddress(pagenum); +16/wf3d8086/id_pm.c:// PM_SetPageLock() - Sets the lock type on a given page +16/wf3d8086/id_pm.c:PM_SetPageLock(int pagenum,PMLockType lock) +16/wf3d8086/id_pm.c: Quit("PM_SetPageLock: Locking/unlocking non-sound page"); +16/wf3d8086/id_pm.c:// PM_Preload() - Loads as many pages as possible into all types of memory. +16/wf3d8086/id_pm.c:PM_Preload(boolean (*update)(word current,word total)) +16/wf3d8086/id_pm.c: Quit ("PM_Preload: Pages>=ChunksInFile"); +16/wf3d8086/id_pm.c: PM_GetPage(page); +16/wf3d8086/id_pm.c: addr = PM_GetPage(oogypage); +16/wf3d8086/id_pm.c: Quit("PM_Preload: XMS buffer failed"); +16/wf3d8086/id_pm.c: Quit ("PM_Preload: Pages>=ChunksInFile"); +16/wf3d8086/id_pm.c: Quit("PM_Preload: Exceeded XMS pages"); +16/wf3d8086/id_pm.c: Quit("PM_Preload: Page too long"); +16/wf3d8086/id_pm.c:// PM_NextFrame() - Increments the frame counter and adjusts the thrash +16/wf3d8086/id_pm.c:PM_NextFrame(void) +16/wf3d8086/id_pm.c: sprintf(buf,"PM_NextFrame: Page %d is locked",i); +16/wf3d8086/id_pm.c:// PM_Reset() - Sets up caching structures +16/wf3d8086/id_pm.c:PM_Reset(void) +16/wf3d8086/id_pm.c:// PM_Startup() - Start up the Page Mgr +16/wf3d8086/id_pm.c:PM_Startup(void) +16/wf3d8086/id_pm.c: Quit("PM_Startup: No main or EMS"); +16/wf3d8086/id_pm.c: PM_Reset(); +16/wf3d8086/id_pm.c:// PM_Shutdown() - Shut down the Page Mgr +16/wf3d8086/id_pm.c:PM_Shutdown(void) +16/wf3d8086/id_pm.h:#define PM_GetSoundPage(v) PM_GetPage(PMSoundStart + (v)) +16/wf3d8086/id_pm.h:#define PM_GetSpritePage(v) PM_GetPage(PMSpriteStart + (v)) +16/wf3d8086/id_pm.h:#define PM_LockMainMem() PM_SetMainMemPurge(0) +16/wf3d8086/id_pm.h:#define PM_UnlockMainMem() PM_SetMainMemPurge(3) +16/wf3d8086/id_pm.h:extern void PM_Startup(void), +16/wf3d8086/id_pm.h: PM_Shutdown(void), +16/wf3d8086/id_pm.h: PM_Reset(void), +16/wf3d8086/id_pm.h: PM_Preload(boolean (*update)(word current,word total)), +16/wf3d8086/id_pm.h: PM_NextFrame(void), +16/wf3d8086/id_pm.h: PM_SetPageLock(int pagenum,PMLockType lock), +16/wf3d8086/id_pm.h: PM_SetMainPurge(int level), +16/wf3d8086/id_pm.h: PM_CheckMainMem(void); +16/wf3d8086/id_pm.h:extern memptr PM_GetPageAddress(int pagenum), +16/wf3d8086/id_pm.h: PM_GetPage(int pagenum); // Use this one to cache page +16/wf3d8086/id_pm.h:void PM_SetMainMemPurge(int level); +16/wf3d8086/id_sd.c: addr = PM_GetSoundPage(page); +16/wf3d8086/id_sd.c: PM_SetPageLock(PMSoundStart + page,pml_Locked); +16/wf3d8086/id_sd.c: PM_SetPageLock(i + PMSoundStart,pml_Unlocked); +16/wf3d8086/id_sd.c: PM_UnlockMainMem(); +16/wf3d8086/id_sd.c: PM_CheckMainMem(); +16/wf3d8086/id_sd.c: p = (word far *)MK_FP(PM_GetPage(ChunksInFile - 1),0); +16/wf3d8086/id_sd.c: PM_UnlockMainMem(); +Binary file 16/wf3d8086/obj/wolf3d.exe matches +16/wf3d8086/obj/wolf3d.map: 1A268H 1B44AH 011E3H ID_PM_TEXT CODE +16/wf3d8086/obj/wolf3d.map: 1A26:0008 11E3 C=CODE S=ID_PM_TEXT G=(none) M=ID_PM.C ACBP=28 +16/wf3d8086/obj/wolf3d.map: 1A26:02F3 _PM_CheckMainMem +16/wf3d8086/obj/wolf3d.map: 1A26:0CDE _PM_GetPage +16/wf3d8086/obj/wolf3d.map: 1A26:080D _PM_GetPageAddress +16/wf3d8086/obj/wolf3d.map: 1A26:1036 _PM_NextFrame +16/wf3d8086/obj/wolf3d.map: 1A26:0DD0 _PM_Preload +16/wf3d8086/obj/wolf3d.map: 1A26:10B0 idle _PM_Reset +16/wf3d8086/obj/wolf3d.map: 1A26:02CA _PM_SetMainMemPurge +16/wf3d8086/obj/wolf3d.map: 1A26:0DA0 _PM_SetPageLock +16/wf3d8086/obj/wolf3d.map: 1A26:11CF _PM_Shutdown +16/wf3d8086/obj/wolf3d.map: 1A26:111E _PM_Startup +16/wf3d8086/obj/wolf3d.map: 1A26:02CA _PM_SetMainMemPurge +16/wf3d8086/obj/wolf3d.map: 1A26:02F3 _PM_CheckMainMem +16/wf3d8086/obj/wolf3d.map: 1A26:080D _PM_GetPageAddress +16/wf3d8086/obj/wolf3d.map: 1A26:0CDE _PM_GetPage +16/wf3d8086/obj/wolf3d.map: 1A26:0DA0 _PM_SetPageLock +16/wf3d8086/obj/wolf3d.map: 1A26:0DD0 _PM_Preload +16/wf3d8086/obj/wolf3d.map: 1A26:1036 _PM_NextFrame +16/wf3d8086/obj/wolf3d.map: 1A26:10B0 idle _PM_Reset +16/wf3d8086/obj/wolf3d.map: 1A26:111E _PM_Startup +16/wf3d8086/obj/wolf3d.map: 1A26:11CF _PM_Shutdown +16/wf3d8086/oldscale.c: shape = PM_GetSpritePage (shapenum); +16/wf3d8086/oldscale.c: shape = PM_GetSpritePage (shapenum); +16/wf3d8086/wl_act2.c: PM_UnlockMainMem (); +16/wf3d8086/wl_act2.c: PM_CheckMainMem (); +16/wf3d8086/wl_debug.c: addr = PM_GetPageAddress(i); +16/wf3d8086/wl_debug.c: PM_GetPage(j); +16/wf3d8086/wl_debug.c: PM_GetPage(i); +16/wf3d8086/wl_draw.c: *( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic); +16/wf3d8086/wl_draw.c: *( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic); +16/wf3d8086/wl_draw.c: *( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(doorpage); +16/wf3d8086/wl_draw.c: *( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(doorpage+1); +16/wf3d8086/wl_draw.c: *( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic); +16/wf3d8086/wl_draw.c: *( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic); +16/wf3d8086/wl_draw.c: PM_NextFrame(); +16/wf3d8086/wl_game.c: PM_UnlockMainMem(); +16/wf3d8086/wl_game.c: PM_CheckMainMem (); +16/wf3d8086/wl_game.c: PM_CheckMainMem (); +16/wf3d8086/wl_game.c: PM_CheckMainMem (); +16/wf3d8086/wl_game.c: PM_CheckMainMem (); +16/wf3d8086/wl_inter.c: PM_Preload (PreloadUpdate); +16/wf3d8086/wl_main.c: PM_Shutdown (); +16/wf3d8086/wl_main.c: PM_Startup (); +16/wf3d8086/wl_main.c: PM_UnlockMainMem (); +16/wf3d8086/wl_menu.c: PM_CheckMainMem (); +16/wf3d8086/wl_menu.c: PM_CheckMainMem (); +16/wf3d8086/wl_play.c: PM_CheckMainMem (); +16/wf3d8086/wl_play.c: PM_CheckMainMem (); +16/wf3d8086/wl_play.c: PM_CheckMainMem (); +16/wf3d8086/wl_play.c: PM_CheckMainMem (); +16/wf3d8086/wl_play.c: PM_CheckMainMem (); +16/wf3d8086/wl_scale.c: shape = PM_GetSpritePage (shapenum); +16/wf3d8086/wl_scale.c: shape = PM_GetSpritePage (shapenum); +16/wf3d8086/wolf3d.map: 19127H 1A286H 01160H ID_PM_TEXT CODE +16/wf3d8086/wolf3d.map: 1912:0007 1160 C=CODE S=ID_PM_TEXT G=(none) M=ID_PM.C ACBP=28 +16/wf3d8086/wolf3d.map: 1912:02DF _PM_CheckMainMem +16/wf3d8086/wolf3d.map: 1912:0C71 _PM_GetPage +16/wf3d8086/wolf3d.map: 1912:07BF _PM_GetPageAddress +16/wf3d8086/wolf3d.map: 1912:0FBA _PM_NextFrame +16/wf3d8086/wolf3d.map: 1912:0D60 _PM_Preload +16/wf3d8086/wolf3d.map: 1912:1034 idle _PM_Reset +16/wf3d8086/wolf3d.map: 1912:02B8 _PM_SetMainMemPurge +16/wf3d8086/wolf3d.map: 1912:0D31 _PM_SetPageLock +16/wf3d8086/wolf3d.map: 1912:114B _PM_Shutdown +16/wf3d8086/wolf3d.map: 1912:10A0 _PM_Startup +16/wf3d8086/wolf3d.map: 1912:02B8 _PM_SetMainMemPurge +16/wf3d8086/wolf3d.map: 1912:02DF _PM_CheckMainMem +16/wf3d8086/wolf3d.map: 1912:07BF _PM_GetPageAddress +16/wf3d8086/wolf3d.map: 1912:0C71 _PM_GetPage +16/wf3d8086/wolf3d.map: 1912:0D31 _PM_SetPageLock +16/wf3d8086/wolf3d.map: 1912:0D60 _PM_Preload +16/wf3d8086/wolf3d.map: 1912:0FBA _PM_NextFrame +16/wf3d8086/wolf3d.map: 1912:1034 idle _PM_Reset +16/wf3d8086/wolf3d.map: 1912:10A0 _PM_Startup +16/wf3d8086/wolf3d.map: 1912:114B _PM_Shutdown +16/wf3d8086/wolfhack.c: src = PM_GetPage(0); +16/wf3d8086/wolfhack.c: src = PM_GetPage(1); +16/wolf3d/WOLFSRC/CONTIGSC.C: shape = PM_GetSpritePage (shapenum); +16/wolf3d/WOLFSRC/CONTIGSC.C: shape = PM_GetSpritePage (shapenum); +16/wolf3d/WOLFSRC/ID_PM.C:// PM_SetMainMemPurge() - Sets the purge level for all allocated main memory +16/wolf3d/WOLFSRC/ID_PM.C:// blocks. This shouldn't be called directly - the PM_LockMainMem() and +16/wolf3d/WOLFSRC/ID_PM.C:// PM_UnlockMainMem() macros should be used instead. +16/wolf3d/WOLFSRC/ID_PM.C:PM_SetMainMemPurge(int level) +16/wolf3d/WOLFSRC/ID_PM.C:// PM_CheckMainMem() - If something besides the Page Mgr makes requests of +16/wolf3d/WOLFSRC/ID_PM.C:// This routine now calls PM_LockMainMem() to make sure that any allocation +16/wolf3d/WOLFSRC/ID_PM.C:// of the other blocks. Because PM_LockMainMem() is called, +16/wolf3d/WOLFSRC/ID_PM.C:// PM_UnlockMainMem() needs to be called before any other part of the +16/wolf3d/WOLFSRC/ID_PM.C:PM_CheckMainMem(void) +16/wolf3d/WOLFSRC/ID_PM.C: PM_LockMainMem(); +16/wolf3d/WOLFSRC/ID_PM.C:// necessary to make requests of the Memory Mgr, PM_UnlockMainMem() +16/wolf3d/WOLFSRC/ID_PM.C: Quit("PM_SetupMainMem: Not enough main memory"); +16/wolf3d/WOLFSRC/ID_PM.C:// PM_GetPageAddress() - Returns the address of a given page +16/wolf3d/WOLFSRC/ID_PM.C:PM_GetPageAddress(int pagenum) +16/wolf3d/WOLFSRC/ID_PM.C: PML_CopyToXMS(PM_GetPageAddress(pagenum),page->xmsPage,page->length); +16/wolf3d/WOLFSRC/ID_PM.C: addr = PM_GetPageAddress(orig); +16/wolf3d/WOLFSRC/ID_PM.C:// PM_GetPage() - Returns the address of the page, loading it if necessary +16/wolf3d/WOLFSRC/ID_PM.C:PM_GetPage(int pagenum) +16/wolf3d/WOLFSRC/ID_PM.C: Quit("PM_GetPage: Invalid page request"); +16/wolf3d/WOLFSRC/ID_PM.C: if (!(result = PM_GetPageAddress(pagenum))) +16/wolf3d/WOLFSRC/ID_PM.C: result = PM_GetPageAddress(pagenum); +16/wolf3d/WOLFSRC/ID_PM.C:// PM_SetPageLock() - Sets the lock type on a given page +16/wolf3d/WOLFSRC/ID_PM.C:PM_SetPageLock(int pagenum,PMLockType lock) +16/wolf3d/WOLFSRC/ID_PM.C: Quit("PM_SetPageLock: Locking/unlocking non-sound page"); +16/wolf3d/WOLFSRC/ID_PM.C:// PM_Preload() - Loads as many pages as possible into all types of memory. +16/wolf3d/WOLFSRC/ID_PM.C:PM_Preload(boolean (*update)(word current,word total)) +16/wolf3d/WOLFSRC/ID_PM.C: Quit ("PM_Preload: Pages>=ChunksInFile"); +16/wolf3d/WOLFSRC/ID_PM.C: PM_GetPage(page); +16/wolf3d/WOLFSRC/ID_PM.C: addr = PM_GetPage(oogypage); +16/wolf3d/WOLFSRC/ID_PM.C: Quit("PM_Preload: XMS buffer failed"); +16/wolf3d/WOLFSRC/ID_PM.C: Quit ("PM_Preload: Pages>=ChunksInFile"); +16/wolf3d/WOLFSRC/ID_PM.C: Quit("PM_Preload: Exceeded XMS pages"); +16/wolf3d/WOLFSRC/ID_PM.C: Quit("PM_Preload: Page too long"); +16/wolf3d/WOLFSRC/ID_PM.C:// PM_NextFrame() - Increments the frame counter and adjusts the thrash +16/wolf3d/WOLFSRC/ID_PM.C:PM_NextFrame(void) +16/wolf3d/WOLFSRC/ID_PM.C: sprintf(buf,"PM_NextFrame: Page %d is locked",i); +16/wolf3d/WOLFSRC/ID_PM.C:// PM_Reset() - Sets up caching structures +16/wolf3d/WOLFSRC/ID_PM.C:PM_Reset(void) +16/wolf3d/WOLFSRC/ID_PM.C:// PM_Startup() - Start up the Page Mgr +16/wolf3d/WOLFSRC/ID_PM.C:PM_Startup(void) +16/wolf3d/WOLFSRC/ID_PM.C: Quit("PM_Startup: No main or EMS"); +16/wolf3d/WOLFSRC/ID_PM.C: PM_Reset(); +16/wolf3d/WOLFSRC/ID_PM.C:// PM_Shutdown() - Shut down the Page Mgr +16/wolf3d/WOLFSRC/ID_PM.C:PM_Shutdown(void) +16/wolf3d/WOLFSRC/ID_PM.H:#define PM_GetSoundPage(v) PM_GetPage(PMSoundStart + (v)) +16/wolf3d/WOLFSRC/ID_PM.H:#define PM_GetSpritePage(v) PM_GetPage(PMSpriteStart + (v)) +16/wolf3d/WOLFSRC/ID_PM.H:#define PM_LockMainMem() PM_SetMainMemPurge(0) +16/wolf3d/WOLFSRC/ID_PM.H:#define PM_UnlockMainMem() PM_SetMainMemPurge(3) +16/wolf3d/WOLFSRC/ID_PM.H:extern void PM_Startup(void), +16/wolf3d/WOLFSRC/ID_PM.H: PM_Shutdown(void), +16/wolf3d/WOLFSRC/ID_PM.H: PM_Reset(void), +16/wolf3d/WOLFSRC/ID_PM.H: PM_Preload(boolean (*update)(word current,word total)), +16/wolf3d/WOLFSRC/ID_PM.H: PM_NextFrame(void), +16/wolf3d/WOLFSRC/ID_PM.H: PM_SetPageLock(int pagenum,PMLockType lock), +16/wolf3d/WOLFSRC/ID_PM.H: PM_SetMainPurge(int level), +16/wolf3d/WOLFSRC/ID_PM.H: PM_CheckMainMem(void); +16/wolf3d/WOLFSRC/ID_PM.H:extern memptr PM_GetPageAddress(int pagenum), +16/wolf3d/WOLFSRC/ID_PM.H: PM_GetPage(int pagenum); // Use this one to cache page +16/wolf3d/WOLFSRC/ID_PM.H:void PM_SetMainMemPurge(int level); +16/wolf3d/WOLFSRC/ID_SD.C: addr = PM_GetSoundPage(page); +16/wolf3d/WOLFSRC/ID_SD.C: PM_SetPageLock(PMSoundStart + page,pml_Locked); +16/wolf3d/WOLFSRC/ID_SD.C: PM_SetPageLock(i + PMSoundStart,pml_Unlocked); +16/wolf3d/WOLFSRC/ID_SD.C: PM_UnlockMainMem(); +16/wolf3d/WOLFSRC/ID_SD.C: PM_CheckMainMem(); +16/wolf3d/WOLFSRC/ID_SD.C: p = (word far *)MK_FP(PM_GetPage(ChunksInFile - 1),0); +16/wolf3d/WOLFSRC/ID_SD.C: PM_UnlockMainMem(); +16/wolf3d/WOLFSRC/OLDSCALE.C: shape = PM_GetSpritePage (shapenum); +16/wolf3d/WOLFSRC/OLDSCALE.C: shape = PM_GetSpritePage (shapenum); +16/wolf3d/WOLFSRC/WL_ACT2.C: PM_UnlockMainMem (); +16/wolf3d/WOLFSRC/WL_ACT2.C: PM_CheckMainMem (); +16/wolf3d/WOLFSRC/WL_DEBUG.C: addr = PM_GetPageAddress(i); +16/wolf3d/WOLFSRC/WL_DEBUG.C: PM_GetPage(j); +16/wolf3d/WOLFSRC/WL_DEBUG.C: PM_GetPage(i); +16/wolf3d/WOLFSRC/WL_DRAW.C: *( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic); +16/wolf3d/WOLFSRC/WL_DRAW.C: *( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic); +16/wolf3d/WOLFSRC/WL_DRAW.C: *( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(doorpage); +16/wolf3d/WOLFSRC/WL_DRAW.C: *( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(doorpage+1); +16/wolf3d/WOLFSRC/WL_DRAW.C: *( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic); +16/wolf3d/WOLFSRC/WL_DRAW.C: *( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic); +16/wolf3d/WOLFSRC/WL_DRAW.C: PM_NextFrame(); +16/wolf3d/WOLFSRC/WL_GAME.C: PM_UnlockMainMem(); +16/wolf3d/WOLFSRC/WL_GAME.C: PM_CheckMainMem (); +16/wolf3d/WOLFSRC/WL_GAME.C: PM_CheckMainMem (); +16/wolf3d/WOLFSRC/WL_GAME.C: PM_CheckMainMem (); +16/wolf3d/WOLFSRC/WL_GAME.C: PM_CheckMainMem (); +16/wolf3d/WOLFSRC/WL_INTER.C: PM_Preload (PreloadUpdate); +16/wolf3d/WOLFSRC/WL_MAIN.C: PM_Shutdown (); +16/wolf3d/WOLFSRC/WL_MAIN.C: PM_Startup (); +16/wolf3d/WOLFSRC/WL_MAIN.C: PM_UnlockMainMem (); +16/wolf3d/WOLFSRC/WL_MENU.C: PM_CheckMainMem (); +16/wolf3d/WOLFSRC/WL_MENU.C: PM_CheckMainMem (); +16/wolf3d/WOLFSRC/WL_PLAY.C: PM_CheckMainMem (); +16/wolf3d/WOLFSRC/WL_PLAY.C: PM_CheckMainMem (); +16/wolf3d/WOLFSRC/WL_PLAY.C: PM_CheckMainMem (); +16/wolf3d/WOLFSRC/WL_PLAY.C: PM_CheckMainMem (); +16/wolf3d/WOLFSRC/WL_PLAY.C: PM_CheckMainMem (); +16/wolf3d/WOLFSRC/WL_SCALE.C: shape = PM_GetSpritePage (shapenum); +16/wolf3d/WOLFSRC/WL_SCALE.C: shape = PM_GetSpritePage (shapenum); +Binary file 16/wolf3d/WOLFSRC/WOLF3D.EXE matches +16/wolf3d/WOLFSRC/WOLF3D.MAP: 19127H 1A286H 01160H ID_PM_TEXT CODE +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:0007 1160 C=CODE S=ID_PM_TEXT G=(none) M=ID_PM.C ACBP=28 +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:02DF _PM_CheckMainMem +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:0C71 _PM_GetPage +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:07BF _PM_GetPageAddress +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:0FBA _PM_NextFrame +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:0D60 _PM_Preload +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:1034 idle _PM_Reset +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:02B8 _PM_SetMainMemPurge +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:0D31 _PM_SetPageLock +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:114B _PM_Shutdown +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:10A0 _PM_Startup +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:02B8 _PM_SetMainMemPurge +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:02DF _PM_CheckMainMem +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:07BF _PM_GetPageAddress +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:0C71 _PM_GetPage +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:0D31 _PM_SetPageLock +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:0D60 _PM_Preload +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:0FBA _PM_NextFrame +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:1034 idle _PM_Reset +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:10A0 _PM_Startup +16/wolf3d/WOLFSRC/WOLF3D.MAP: 1912:114B _PM_Shutdown +16/wolf3d/WOLFSRC/WOLFHACK.C: src = PM_GetPage(0); +16/wolf3d/WOLFSRC/WOLFHACK.C: src = PM_GetPage(1); + +16/wf3d8086/id_pm.c: longword last = MAXLONG; +16/wf3d8086/id_pm.c: for (i = 0,page = PMPages,lru = -1,last = MAXLONG;i < ChunksInFile;i++,page++) +16/wf3d8086/id_pm.c: for (i = 0,page = PMPages,lru = -1,last = MAXLONG;i < ChunksInFile;i++,page++) +16/wf3d8086/id_pm.c: if (++PMFrameCount >= MAXLONG - 4) diff --git a/src/0.c b/src/0.c index ae51d058..09e8953d 100755 --- a/src/0.c +++ b/src/0.c @@ -1,294 +1,294 @@ -#include -#include -#include -#include - -#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 \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 +#include +#include +#include + +#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 \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; +} diff --git a/src/16.ses b/src/16.ses index 60043f41..faba5120 100755 --- a/src/16.ses +++ b/src/16.ses @@ -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 + +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 diff --git a/src/_scroll.c b/src/_scroll.c index 5a16247d..0db48708 100755 --- a/src/_scroll.c +++ b/src/_scroll.c @@ -1,394 +1,394 @@ -/* 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 , 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;idata, 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~ + * 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 , 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;idata, 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 +} diff --git a/src/bakapi.c b/src/bakapi.c index a74e7711..00fc689f 100755 --- a/src/bakapi.c +++ b/src/bakapi.c @@ -1,314 +1,314 @@ -/* 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 , 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i†ƒÖ…j feel free to use it ^^\nLicence: GPL v3\n"); - printf("compiled on 2016/04/04\n"); -} -//pee! +/* 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 , 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? +// INFO: This is a testing section 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i†ƒÖ…j feel free to use it ^^\nLicence: GPL v3\n"); + printf("compiled on 2016/04/04\n"); +} +//pee! diff --git a/src/bakapi.h b/src/bakapi.h index 1270fab7..7c1fb1ab 100755 --- a/src/bakapi.h +++ b/src/bakapi.h @@ -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 , 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~ + * 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 , 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_*/ diff --git a/src/emmtest.c b/src/emmtest.c index eefab9ea..e8bfe1f5 100755 --- a/src/emmtest.c +++ b/src/emmtest.c @@ -8,8 +8,8 @@ minor mods by Alex Russell to simplify - Must use memory model with FAR code - + Must use memory model with FAR code + Open Watcom patch by sparky4~ */ @@ -17,11 +17,11 @@ #include #include #include -#include +#include + +#include "src/lib/exmm/memory.h" +#include "src/lib/types.h" -#include "src/lib/exmm/memory.h" -#include "src/lib/types.h" - #define PEMMDATAPAGENUM 4 void TransformData(char *pEmmData, unsigned int len) @@ -37,30 +37,30 @@ void TransformData(char *pEmmData, unsigned int len) int main(int argc, char *argv[]) { - byte *pEmmData; - int hEData; - unsigned long advi; - unsigned long i=0; - char huge *p =(char huge *)(GetEMMSeg0()*0x10000); + byte *pEmmData; + int hEData; + unsigned long advi; + unsigned long i=0; + char huge *p =(char huge *)(GetEMMSeg0()*0x10000); if(OpenEMM() != SUCCESS) { // make sure we got EMM printf("EMM unavailable.\n"); exit(1); } - else + else { - 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()); + printf("EMS pages available are %lu\n", EMMCoreLeft()); + //printf("EMM Hardware Information %lu\n", EMInfo()); } - - 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 + + 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 if(pEmmData == NULL/* || pEmmData0 == NULL*/) { printf("Not enough EMM or out of handles.\n"); @@ -68,73 +68,73 @@ int main(int argc, char *argv[]) } else printf("EMM allocate OK\n"); - - printf("EMS pages available are %lu\n", EMMCoreLeft()); - - - + + printf("EMS pages available are %lu\n", EMMCoreLeft()); + + + printf("Map 1st 4 pages\n"); MapEMM(hEData, 0, PEMMDATAPAGENUM); // load 1st 4 pages into page frame: 0-3 - //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); +//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)); /*printf("Map next 2 pages\n"); MapEMM(hEData, 4, 2); // map last 2 pages: 4-5 - memset(pEmmData, 0x04, 32768u); -// memset(pEmmData, atoi(argv[0]), 32768u); - printf("*pEmmData=%c\n", *pEmmData); - printf(" pEmmData=%p\n", pEmmData);*/ + memset(pEmmData, 0x04, 32768u); +// memset(pEmmData, atoi(argv[0]), 32768u); + printf("*pEmmData=%c\n", *pEmmData); + printf(" pEmmData=%p\n", pEmmData);*/ /*MapEMM(hEData, 0, 4); // do some stuff with the first 64K of file data. printf("Transform data\n"); - TransformData(pEmmData, 64000UL); + TransformData(pEmmData, 64000UL); printf("*pEmmData=%lu\n", *pEmmData); MapEMM(hEData, 4, 2); // only unmaps 1st two pages of prior 64k mapping // do stuff with remaining 32K of data - 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); + printf("*pEmmData=%lu\n", *pEmmData);*/ + if(atoi(argv[2])) { - UnmapEMM(hEData, 0, PEMMDATAPAGENUM); // should unmap before freeing + 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])) + { + UnmapEMM(hEData, 0, PEMMDATAPAGENUM); // should unmap before freeing //printf("after EMS *pEmmData=%c\n", *pEmmData); printf("Close emm\n"); EMMFree(hEData); // finished with the file data - 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(); + } + 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; } diff --git a/src/emsdump.c b/src/emsdump.c index b07f7c66..45069863 100755 --- a/src/emsdump.c +++ b/src/emsdump.c @@ -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 , or - * write to the Free Software Foundation, Inc., 51 Franklin Street, - * Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include -#include -//#include - -#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~ + * 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 , or + * write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include +//#include + +#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; +} diff --git a/src/emstest.c b/src/emstest.c index f9c6500d..8c570b2e 100755 --- a/src/emstest.c +++ b/src/emstest.c @@ -1,7 +1,7 @@ -#include -#include -#include -#include "src\lib\ems.c" +#include +#include +#include +#include "src\lib\ems.c" /* Test function for the EMM routines */ @@ -55,4 +55,4 @@ } emmclose(emmhandle); - } + } diff --git a/src/exmmtest.c b/src/exmmtest.c index 02fafeb6..f68d148e 100755 --- a/src/exmmtest.c +++ b/src/exmmtest.c @@ -23,6 +23,8 @@ exmm test */ #include "src/lib/16_head.h" +#include "src/lib/16_tail.h" +#include "src/lib/16_pm.h" #include "src/lib/16_ca.h" #include "src/lib/16_mm.h" #include "src/lib/16_hc.h" @@ -60,12 +62,13 @@ void segatesuto() // getch(); } #endif +//static global_game_variables_t gvar; void main(int argc, char *argv[]) { byte w=1; - global_game_variables_t gvar; + static global_game_variables_t gvar; #ifdef __WATCOMC__ __segment sega; #endif @@ -84,6 +87,7 @@ main(int argc, char *argv[]) //file name // gvar.mm.mmstarted=0; + dbg_debugpm=1; //debug pm //PRINTBB if(argv[1]){ bakapee1 = argv[1]; @@ -93,13 +97,21 @@ main(int argc, char *argv[]) bakapee1 = "data/koishi~.pcx"; bakapee2 = "data/test.map"; } -// printf("main()=%Fp start MM\n", *argv[0]); - MM_Startup(&gvar.mm, &gvar.mmi); - //PM_Startup(); - //PM_UnlockMainMem(); + //printf("main()=%Fp start MM\n", *argv[0]); + MM_Startup(&gvar); + //printf("ok\n"); +//#ifdef __WATCOMC__ + if(dbg_debugpm>0) + { + PM_Startup(&gvar); + //printf("pmstarted ok\n"); + //PM_CheckMainMem(&gvar); + PM_UnlockMainMem(&gvar); + } +//#endif CA_Startup(&gvar); // printf(" done!\n"); - PRINTBB; + //0000PRINTBB; // printf("press any key to continue!\n"); // getch(); #ifdef FILEREAD @@ -129,11 +141,8 @@ for(w=0;w<2;w++) //printf("dark purple = purgable\n"); //printf("medium blue = non purgable\n"); //printf("red = locked\n"); - printf("press any key to continue!\n"); - getch(); - MM_ShowMemory(&gvar, &gvar.mm); - MM_DumpData(&gvar.mm); - MM_Report(&gvar); +// printf("press any key to continue!\n"); +// DebugMemory_(&gvar, 1); if(baka) printf("\nyay!\n"); else printf("\npoo!\n"); printf("press any key to continue!\n"); @@ -141,10 +150,18 @@ for(w=0;w<2;w++) #ifdef FILEREAD } #endif - MM_FreePtr(&bigbuffer, &gvar.mm); - //PM_Shutdown(); + DebugMemory_(&gvar, 1); + MM_DumpData(&gvar); + MM_Report_(&gvar); + //printf("bakapee1=%s\n", bakapee1); + //printf("bakapee2=%s\n", bakapee2); + MM_FreePtr(&bigbuffer, &gvar); +//#ifdef __WATCOMC__ + if(dbg_debugpm>0) + PM_Shutdown(&gvar); +//#endif CA_Shutdown(&gvar); - MM_Shutdown(&gvar.mm); + MM_Shutdown(&gvar); free(bakapee1); free(bakapee2); printf("========================================\n"); printf("near= %Fp ", gvar.mm.nearheap); @@ -160,12 +177,12 @@ for(w=0;w<2;w++) printf("&bigb=%Fp ", &bigbuffer); //printf("&bigb=%04x", &bigbuffer); printf("\n"); -#endif printf("========================================\n"); +#endif #ifdef __WATCOMC__ //this is far printf("Total free: %lu\n", (dword)(GetFreeSize())); - printf("Total near free: %lu\n", (dword)(GetNearFreeSize())); - printf("Total far free: %lu\n", (dword)(GetFarFreeSize())); + printf("Total near free: %lub\n", (dword)(GetNearFreeSize())); + printf("Total far free: %lub\n", (dword)(GetFarFreeSize())); heapdump(&gvar); segatesuto(); #endif diff --git a/src/inputest.c b/src/inputest.c index 62e2d817..be6ac4a2 100755 --- a/src/inputest.c +++ b/src/inputest.c @@ -30,8 +30,8 @@ main(int argc, char *argv[]) global_game_variables_t gvar; player_t player[MaxPlayers]; //extern struct inconfig inpu; - testkeyin=0; - testcontrolnoisy=1; + dbg_testkeyin=0; + dbg_testcontrolnoisy=1; IN_Startup(); IN_Default(0,&player,ctrl_Joystick1); IN_SetControlType(0,&player,ctrl_Joystick1); @@ -105,6 +105,6 @@ main(int argc, char *argv[]) //printf("%u\n", in.Keyboard[sc_Escape]); printf("inputest.exe "); printf("version %s\n", VERSION); - printf("testkeyin=%u\n", testkeyin); - printf("testcontrolnoisy=%u\n", testcontrolnoisy); + printf("testkeyin=%u\n", dbg_testkeyin); + printf("testcontrolnoisy=%u\n", dbg_testcontrolnoisy); } diff --git a/src/lib/16_ca.c b/src/lib/16_ca.c index 27e2d7ee..74fb0f67 100755 --- a/src/lib/16_ca.c +++ b/src/lib/16_ca.c @@ -226,7 +226,7 @@ boolean CA_FarRead(int handle, byte huge *dest, dword length, global_game_variab boolean flag; //dword fat=0; //word segm=0; - if(gvar->mm.EMSVer<0x40) + if(gvar->pm.emm.EMSVer<0x40) if(length>0xfffflu) { printf("File is a fat bakapee\n"); @@ -298,7 +298,7 @@ boolean CA_FarWrite(int handle, byte huge *source, dword length, global_game_var boolean flag; //dword fat=0; //word segm=0; - if(gvar->mm.EMSVer<0x40) + if(gvar->pm.emm.EMSVer<0x40) if(length>0xfffflu) { printf("File is a fat bakapee\n"); @@ -438,7 +438,7 @@ boolean CA_LoadFile(char *filename, memptr *ptr, global_game_variables_t *gvar) return false; size = filelength(handle); - MM_GetPtr(ptr,size, &(gvar->mm), &(gvar->mmi)); //TODO: gvar parameters + MM_GetPtr(ptr,size, gvar); if(!CA_FarRead(handle,*ptr,size, gvar)) { close(handle); @@ -902,7 +902,7 @@ void CA_RLEWexpand (unsigned huge *source, unsigned huge *dest,long length, // // NOTE: A repeat count that produces 0xfff0 bytes can blow this! // - __asm{ + __asm { mov bx,rlewtag mov si,sourceoff mov di,destoff diff --git a/src/lib/16_dbg.c b/src/lib/16_dbg.c index 2215c420..7766a1d4 100755 --- a/src/lib/16_dbg.c +++ b/src/lib/16_dbg.c @@ -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 -# include -# include - -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 - + +#include "src/16.h" + +// TODO: Could we also provide a build mode to emit debug to the "Bochs E9 hack?" +#ifdef DEBUGSERIAL +# include +# include +# include + +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 + diff --git a/src/lib/16_dbg.h b/src/lib/16_dbg.h index 9aaf9644..58c5a05a 100755 --- a/src/lib/16_dbg.h +++ b/src/lib/16_dbg.h @@ -1,25 +1,25 @@ - -#ifndef _SRC_LIB_16_DBG -#define _SRC_LIB_16_DBG - -# ifdef DEBUGSERIAL -# include - -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 - + +#ifndef _SRC_LIB_16_DBG +#define _SRC_LIB_16_DBG + +# ifdef DEBUGSERIAL +# include + +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 + diff --git a/src/lib/16_hc.c b/src/lib/16_hc.c index 8743a38d..13dd3f0e 100755 --- a/src/lib/16_hc.c +++ b/src/lib/16_hc.c @@ -1,537 +1,537 @@ -/* 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 , 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~ + * 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 , 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); +} diff --git a/src/lib/16_hc.h b/src/lib/16_hc.h index 4d0375e2..870d50c7 100755 --- a/src/lib/16_hc.h +++ b/src/lib/16_hc.h @@ -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 , 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~ + * 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 , 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__ */ diff --git a/src/lib/16_head.c b/src/lib/16_head.c index 027693d5..e56baa94 100755 --- a/src/lib/16_head.c +++ b/src/lib/16_head.c @@ -22,22 +22,6 @@ #include "src/lib/16_head.h" -/* Function: Wait ********************************************************** -* -* Parameters: wait - time in microseconds -* -* Description: pauses for a specified number of microseconds. -* -*/ -void wait(clock_t wait){ - clock_t goal; - - if(!wait) return; - - goal = wait + clock(); - while((goal > clock()) && !kbhit()) ; -} /* End of wait */ - long int filesize(FILE *fp) { @@ -94,6 +78,8 @@ US_CheckParm(char *parm,char **strings) } return(-1); } +#ifdef __BORLANDC__ +//=========================================================================== /* ========================== @@ -103,61 +89,61 @@ US_CheckParm(char *parm,char **strings) ========================== */ -/*void Quit(char *error, ...) +void Quit (char *error) { - short exit_code=0; - unsigned finscreen; - - va_list ap; + unsigned finscreen; + memptr screen; + union REGS in, out; - va_start(ap,error); - -#ifndef CATALOG - if (!error) + //ClearMemory (); + if (!*error) { - CA_SetAllPurge (); - CA_CacheGrChunk (PIRACY); - finscreen = (unsigned)grsegs[PIRACY]; + //WriteConfig (); + } + else + { + //CA_CacheGrChunk (ERRORSCREEN); + //screen = grsegs[ERRORSCREEN]; } -#endif //ShutdownId (); + //IN_Shutdown(); + //modexLeave(); + in.h.ah = 0x00; + in.h.al = 0x3; + int86(0x10, &in, &out); if (error && *error) { - vprintf(error,ap); - exit_code = 1; + //movedata ((unsigned)screen,7,0xb800,0,7*160); + //gotoxy (10,4); + printf("\n"); + puts(error); + printf("\n"); + //gotoxy (1,8); + exit(1); } -#ifndef CATALOG else - if (!NoWait) + if (!error || !(*error)) { - movedata (finscreen,0,0xb800,0,4000); - bioskey (0); + //clrscr(); + //#ifndef JAPAN + movedata ((unsigned)screen,7,0xb800,0,4000); + //gotoxy(1,24); + //#endif +//asm mov bh,0 +//asm mov dh,23 // row +//asm mov dl,0 // collumn +//asm mov ah,2 +//asm int 0x10 } -#endif - va_end(ap); + exit(0); +} -#ifndef CATALOG - if (!error) - { - _argc = 2; - _argv[1] = "LAST.SHL"; - _argv[2] = "ENDSCN.SCN"; - _argv[3] = NULL; - if (execv("LOADSCN.EXE", _argv) == -1) - { - clrscr(); - puts("Couldn't find executable LOADSCN.EXE.\n"); - exit(1); - } - } +//=========================================================================== #endif - exit(exit_code); -}*/ - byte dirchar(byte in) { byte out; diff --git a/src/lib/16_head.h b/src/lib/16_head.h index 74822da2..6b189d87 100755 --- a/src/lib/16_head.h +++ b/src/lib/16_head.h @@ -28,8 +28,8 @@ #error i8088 only #endif -#ifndef _LIBHEAD_H_ -#define _LIBHEAD_H_ +#ifndef __16_HEAD_H__ +#define __16_HEAD_H__ #include #include #include @@ -42,12 +42,20 @@ #include #include #include +#include +#include +#include #ifdef __WATCOMC__ #include #include #include #include //16_vrs.h #endif +#ifdef __BORLANDC__ +#include +#include +#define TILEWH 16 +#endif #include "src/lib/nyan/kitten.h" #include "src/lib/types.h" #include "src/lib/typdefst.h" @@ -151,6 +159,8 @@ static word far* clockw= (word far*) 0x046C; /* 18.2hz clock */ extern int profilehandle,debughandle; //make it into game global #define __DEBUG__ +//#define __DEBUG_PM__ +//#define __DEBUG_MM__ #define nil ((void *)0) #ifdef __BORLANDC__ @@ -159,7 +169,25 @@ extern int profilehandle,debughandle; //make it into game global #endif #ifdef __WATCOMC__ #define _FCORELEFT 0x90000UL+16UL +static union REGS CPURegs; + +#define _AX CPURegs.x.ax +#define _BX CPURegs.x.bx +#define _CX CPURegs.x.cx +#define _DX CPURegs.x.dx + +#define _SI CPURegs.x.si +#define _AH CPURegs.h.ah +#define _AL CPURegs.h.al +#define _BH CPURegs.h.bh +#define _BL CPURegs.h.bl +#define _CH CPURegs.h.ch +#define _CL CPURegs.h.cl +#define _DH CPURegs.h.dh +#define _DL CPURegs.h.dl + +#define geninterrupt(n) int86(n,&CPURegs,&CPURegs); #define peekb(segm,ofs) (*(byte far*)MK_FP((segm),(ofs))) #define peekw(segm,ofs) (*(word far*)MK_FP((segm),(ofs))) #define pokeb(segm,ofs,value) (peekb((segm),(ofs)) = (byte)(value)) @@ -171,11 +199,12 @@ typedef union REGPACK regs_t; #define INPUT_STATUS_1 0x03da /* local function */ -void wait(clock_t wait); - long int filesize(FILE *fp); void printmeminfoline(byte *strc, const byte *pee, size_t h_total, size_t h_used, size_t h_free); int US_CheckParm(char *parm,char **strings); +#ifdef __BORLANDC__ +void Quit (char *error); +#endif byte dirchar(byte in); -#endif/*_LIBHEAD_H_*/ +#endif/*__16_HEAD_H__*/ diff --git a/src/lib/16_in.c b/src/lib/16_in.c index 6df6d06a..85709c5e 100755 --- a/src/lib/16_in.c +++ b/src/lib/16_in.c @@ -38,7 +38,9 @@ #include "src/lib/16_in.h" -boolean testkeyin=0,testcontrolnoisy=0; +#ifdef __DEBUG_InputMgr__ +boolean dbg_testkeyin=0,dbg_testcontrolnoisy=0; +#endif /* ============================================================================= @@ -164,6 +166,7 @@ static Direction DirTable[] = // Quick lookup for total direction #endif // Internal routines + /////////////////////////////////////////////////////////////////////////// // // INL_KeyService() - Handles a keyboard interrupt (key up/down) @@ -234,18 +237,22 @@ static boolean special; if (INL_KeyHook && !special) INL_KeyHook(); -//#ifdef TESTKEYIN - if(testkeyin > 0) printf("%c %u [0x%x %u] %u\n", c, c, k, k, inpu.Keyboard[k]); -//endif +#ifdef __DEBUG_InputMgr__ + if(dbg_testkeyin > 0) printf("%c %u [0x%x %u] %u\n", c, c, k, k, inpu.Keyboard[k]); +#endif outp(0x20,0x20); } void Mouse(int x) { - union REGS CPURegs; - x = CPURegs.x.ax; - int86(MouseInt,&CPURegs,&CPURegs); + //union REGS CPURegs; + //x = CPURegs.x.ax; + __asm { + mov ax,x + int MouseInt + } + //int86(MouseInt,&CPURegs,&CPURegs); } /////////////////////////////////////////////////////////////////////////// @@ -299,8 +306,7 @@ IN_GetJoyAbs(word joy,word *xp,word *yp) yb = 1 << ys; // Read the absolute joystick values - __asm - { + __asm { pushf // Save some registers push si push di @@ -320,8 +326,13 @@ IN_GetJoyAbs(word joy,word *xp,word *yp) push bp // Don't mess up stack frame mov bp,MaxJoyValue - +#ifdef __BORLANDC__ + } +#endif loo: +#ifdef __BORLANDC__ + __asm { +#endif in al,dx // Get bits indicating whether all are finished dec bp // Check bounding register @@ -338,8 +349,13 @@ loo: add cl,bl jnz loo // If both bits were 0, drop out - +#ifdef __BORLANDC__ + } +#endif done: +#ifdef __BORLANDC__ + __asm { +#endif pop bp mov cl,[xs] // Get the number of bits to shift @@ -637,9 +653,9 @@ IN_Startup() checkjoys = true; checkmouse = true; - for (i = 1;i < __argc;i++) + for (i = 1;i < _argc;i++) { - switch (US_CheckParm(__argv[i],ParmStringsIN)) + switch (US_CheckParm(_argv[i],ParmStringsIN)) { case 0: checkjoys = false; @@ -881,7 +897,9 @@ register KeyboardDef *def; default: break; } - //if(testcontrolnoisy > 0){ printf("dir=%c ", dirchar(dir)); printf("pdir=%c ", dirchar(player[pn].pdir)); } +#ifdef __DEBUG_InputMgr__ + //if(dbg_testcontrolnoisy > 0){ printf("dir=%c ", dirchar(dir)); printf("pdir=%c ", dirchar(player[pn].pdir)); } +#endif } } //input from player @@ -962,7 +980,8 @@ register KeyboardDef *def; } } #endif -if(testcontrolnoisy > 0) +#ifdef __DEBUG_InputMgr__ +if(dbg_testcontrolnoisy > 0) if(player[pn].info.dir!=2/*(inpu.Keyboard[def->up] || inpu.Keyboard[def->down] || inpu.Keyboard[def->left] || inpu.Keyboard[def->right])*/ || player[pn].q>1) { //printf("b1=%u b2=%u b3=%u b4=%u ", player[pn].info.button0, player[pn].info.button1, player[pn].info.button2, player[pn].info.button3); @@ -973,6 +992,7 @@ if(player[pn].info.dir!=2/*(inpu.Keyboard[def->up] || inpu.Keyboard[def->down] | //else if(!realdelta) printf("%c%d %c%d %c%d %c%d", dirchar(0), inpu.Keyboard[def->up], dirchar(4), inpu.Keyboard[def->down], dirchar(1), inpu.Keyboard[def->left], dirchar(3), inpu.Keyboard[def->right]); printf("\n"); } +#endif } /////////////////////////////////////////////////////////////////////////// @@ -1155,6 +1175,9 @@ IN_Ack() { word i; + if (!inst.IN_Started) + return; + IN_ClearKey(inpu.LastScan); inpu.LastScan = sc_None; @@ -1236,9 +1259,9 @@ void IN_ClearKey(byte code) boolean IN_qb(byte kee) { -//#ifdef TESTKEYIN -// if(testkeyin > 0) printf("%u\n", inpu.Keyboard[kee]); -//#endif +#ifdef __DEBUG_InputMgr__ +// if(dbg_testkeyin > 0) printf("%u\n", inpu.Keyboard[kee]); +#endif if(inpu.Keyboard[kee]==true) return 1; else return 0; } diff --git a/src/lib/16_in.h b/src/lib/16_in.h index 16b9b0ae..29ecc130 100755 --- a/src/lib/16_in.h +++ b/src/lib/16_in.h @@ -36,16 +36,10 @@ #include "src/lib/bitmap.h" //old format #endif #ifdef __DEBUG__ -//#define __DEBUG_InputMgr__ +#define __DEBUG_InputMgr__ +extern boolean dbg_testkeyin,dbg_testcontrolnoisy; #endif -#ifdef __DEBUG_InputMgr__ -//#define TESTKEYIN -//#define TESTCONTROLNOISY -#endif - -extern boolean testkeyin,testcontrolnoisy; - //if else for gfxtesting and direction //player[pn].d == 2 || //player[pn].d != 2 || @@ -231,7 +225,10 @@ typedef struct //0000 planar_buf_t huge *data; //supposively the sprite sheet data // planar_buf_t data; //supposively the sprite sheet data ////0000---- - struct sprite *spri; //supposively the sprite sheet data +#ifdef __WATCOMC__ + struct sprite *spri; //supposively the sprite sheet data + memptr gr; +#endif bitmap_t *data; //supposively the sprite sheet data//old format sword hp; //hitpoints of the player int persist_aniframe; /* gonna be increased to 1 before being used, so 0 is ok for default */ diff --git a/src/lib/16_map.c b/src/lib/16_map.c index 8e2d65b2..d697142d 100755 --- a/src/lib/16_map.c +++ b/src/lib/16_map.c @@ -1,156 +1,156 @@ -/* 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 , 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(idata = 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~ + * 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 , 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(idata = 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; +} diff --git a/src/lib/16_mm.c b/src/lib/16_mm.c index add7707e..42a87440 100755 --- a/src/lib/16_mm.c +++ b/src/lib/16_mm.c @@ -140,7 +140,7 @@ boolean MML_CheckForEMS(void) return(emmcfems); } - +#ifndef __16_PM__ /* ====================== = @@ -149,7 +149,7 @@ boolean MML_CheckForEMS(void) ======================= */ -byte MML_SetupEMS(mminfo_t *mm) +byte MML_SetupEMS(global_game_variables_t *gvar) { byte str[160]; byte err; @@ -157,8 +157,8 @@ byte MML_SetupEMS(mminfo_t *mm) unsigned int EMSVer = 0; //byte EMS_status; - unsigned totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle; - totalEMSpages = freeEMSpages = EMSpageframe = EMSpagesmapped = 0; + unsigned totalEMSpages,freeEMSpages,EMSPageFrame,EMSpagesmapped,EMSHandle; + totalEMSpages = freeEMSpages = EMSPageFrame = EMSpagesmapped = 0; __asm { mov ah,EMS_STATUS @@ -179,7 +179,7 @@ byte MML_SetupEMS(mminfo_t *mm) int EMS_INT // find the page frame address or ah,ah jnz error - mov [EMSpageframe],bx + mov [EMSPageFrame],bx mov ah,EMS_GETPAGES int EMS_INT // find out how much EMS is there @@ -218,7 +218,7 @@ byte MML_SetupEMS(mminfo_t *mm) int EMS_INT or ah,ah jnz error - mov [EMShandle],dx + mov [EMSHandle],dx jmp End #ifdef __BORLANDC__ } @@ -245,12 +245,12 @@ End: printf("%s\n",str); return err; } - mm->totalEMSpages=totalEMSpages; - mm->freeEMSpages=freeEMSpages; - mm->EMSpageframe=EMSpageframe; - mm->EMSpagesmapped=EMSpagesmapped; - mm->EMShandle=EMShandle; - mm->EMSVer=EMSVer; + gvar->mm.totalEMSpages=totalEMSpages; + gvar->mm.freeEMSpages=freeEMSpages; + gvar->mm.EMSPageFrame=EMSPageFrame; + gvar->mm.EMSpagesmapped=EMSpagesmapped; + gvar->mm.EMSHandle=EMSHandle; + gvar->mm.EMSVer=EMSVer; return 0; } @@ -263,16 +263,16 @@ End: ======================= */ -void MML_ShutdownEMS(mminfo_t *mm) +void MML_ShutdownEMS(global_game_variables_t *gvar) { boolean errorflag=false; - unsigned EMShandle=mm->EMShandle; + unsigned EMSHandle=gvar->mm.EMSHandle; - if(!EMShandle) + if(!EMSHandle) return; __asm { mov ah,EMS_FREEPAGES - mov dx,[EMShandle] + mov dx,[EMSHandle] int EMS_INT or ah,ah jz ok @@ -284,7 +284,8 @@ void MML_ShutdownEMS(mminfo_t *mm) #ifdef __WATCOMC__ } #endif - if(errorflag==true) printf("MML_ShutdownEMS: Error freeing EMS!\n"); //++++ add something + if(errorflag==true) + Quit("MML_ShutdownEMS: Error freeing EMS!\n"); //++++ add something } /* @@ -299,14 +300,14 @@ void MML_ShutdownEMS(mminfo_t *mm) ==================== */ -byte MM_MapEMS(mminfo_t *mm, mminfotype *mmi) +byte MM_MapEMS(global_game_variables_t *gvar) { byte str[160]; - unsigned EMShandle; + unsigned EMSHandle; byte err; boolean errorflag=false; int i; - EMShandle=mm->EMShandle; + EMSHandle=gvar->mm.EMSHandle; for (i=0;i<4/*MAPPAGES*/;i++) { @@ -314,7 +315,7 @@ byte MM_MapEMS(mminfo_t *mm, mminfotype *mmi) mov ah,EMS_MAPPAGE mov bx,[i] // logical page mov al,bl // physical page - mov dx,[EMShandle] // handle + mov dx,[EMSHandle] // handle int EMS_INT or ah,ah jnz error @@ -343,12 +344,11 @@ byte MM_MapEMS(mminfo_t *mm, mminfotype *mmi) return err; } } - mmi->EMSmem = (i)*0x4000lu; - //printf(" mmi->EMSmem=%lu\n", mmi->EMSmem); + gvar->mmi.EMSmem = (i)*0x4000lu; return 0; } -byte MM_MapXEMS(mminfo_t *mm, mminfotype *mmi) +byte MM_MapXEMS(global_game_variables_t *gvar) { //SUB EMS.MapXPages (PhysicalStart, LogicalStart, NumPages, Handle) @@ -374,12 +374,12 @@ byte MM_MapXEMS(mminfo_t *mm, mminfotype *mmi) //END SUB byte str[160]; byte err; - word EMShandle; + word EMSHandle; boolean errorflag=false; int i; - EMShandle=mm->EMShandle; + EMSHandle=gvar->mm.EMSHandle; - if(mm->EMSVer<0x40) + if(gvar->mm.EMSVer<0x40) return 5; for (i=0;iEMSmem = (i)*0x4000lu; + gvar->mmi.EMSmem = (i)*0x4000lu; return 0; } - +#endif //========================================================================== /* @@ -437,10 +437,10 @@ byte MM_MapXEMS(mminfo_t *mm, mminfotype *mmi) ======================= */ -boolean MML_CheckForXMS(mminfo_t *mm) +boolean MML_CheckForXMS(void) { + //numUMBs = 0; boolean errorflag=false; - mm->numUMBs = 0; __asm { mov ax,0x4300 @@ -459,7 +459,7 @@ boolean MML_CheckForXMS(mminfo_t *mm) else return true; } - +#ifndef __16_PM__ /* ====================== = @@ -470,7 +470,7 @@ boolean MML_CheckForXMS(mminfo_t *mm) ======================= */ -void MML_SetupXMS(mminfo_t *mm, mminfotype *mmi) +void MML_SetupXMS(global_game_variables_t *gvar) { word base,size; @@ -514,11 +514,11 @@ getmemory: } #endif // printf("base=%u ", base); printf("size=%u\n", size); - MML_UseSpace(base,size, mm); - mmi->XMSmem += size*16; - mm->UMBbase[mm->numUMBs] = base; - mm->numUMBs++; - if(mm->numUMBs < MAXUMBS) + 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; } @@ -531,14 +531,14 @@ getmemory: ====================== */ -void MML_ShutdownXMS(mminfo_t *mm) +void MML_ShutdownXMS(global_game_variables_t *gvar) { int i; unsigned base; - for (i=0;inumUMBs;i++) + for (i=0;imm.numUMBs;i++) { - base = mm->UMBbase[i]; + base = gvar->mm.UMBbase[i]; __asm { mov ah,XMS_FREEUMB mov dx,[base] @@ -546,7 +546,7 @@ void MML_ShutdownXMS(mminfo_t *mm) } } } - +#endif //========================================================================== /* @@ -561,7 +561,7 @@ void MML_ShutdownXMS(mminfo_t *mm) ====================== */ -/*void MML_UseSpace(word segstart, dword seglength, mminfo_t *mm) +/*void MML_UseSpace(word segstart, dword seglength, global_game_variables_t *gvar) { //huge mmblocktype huge *scan,huge *last; word segm=1; @@ -569,8 +569,8 @@ void MML_ShutdownXMS(mminfo_t *mm) dword segmlen; dword extra; - scan = last = mm->mmhead; - mm->mmrover = mm->mmhead; // reset rover to start of memory + 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 @@ -595,7 +595,7 @@ void MML_ShutdownXMS(mminfo_t *mm) { scan->blob=segm; - //MML_UseSpace(segstart, seglength, mm); + //MML_UseSpace(segstart, seglength, gvar); printf("MML_UseSpace: Segment spans two blocks!\n"); //} @@ -621,25 +621,25 @@ void MML_ShutdownXMS(mminfo_t *mm) if(extra > 0) { GETNEWBLOCK; - mm->mmnew->useptr = NULL; + gvar->mm.mmnew->useptr = NULL; - mm->mmnew->next = scan->next; - scan->next = mm->mmnew; - mm->mmnew->start = segstart+seglength; - mm->mmnew->length = extra; - mm->mmnew->attributes = LOCKBIT; + 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, mminfo_t *mm) +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 = mm->mmhead; - mm->mmrover = mm->mmhead; // reset rover to start of memory + 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 @@ -691,13 +691,13 @@ void MML_UseSpace(word segstart, dword seglength, mminfo_t *mm) if (extra > 0) { GETNEWBLOCK; - mm->mmnew->useptr = NULL; + gvar->mm.mmnew->useptr = NULL; - mm->mmnew->next = scan->next; - scan->next = mm->mmnew; - mm->mmnew->start = segstart+seglength; - mm->mmnew->length = extra; - mm->mmnew->attributes = LOCKBIT; + 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; } } @@ -714,18 +714,18 @@ void MML_UseSpace(word segstart, dword seglength, mminfo_t *mm) ==================== */ -void MML_ClearBlock(mminfo_t *mm) +void MML_ClearBlock(global_game_variables_t *gvar) { //huge mmblocktype huge *scan,huge *last; mmblocktype far *scan,far *last; - scan = mm->mmhead->next; + scan = gvar->mm.mmhead->next; while(scan) { if(!(scan->attributes&LOCKBIT) && (scan->attributes&PURGEBITS)) { - MM_FreePtr(scan->useptr, mm); + MM_FreePtr(scan->useptr, gvar); return; } scan = scan->next; @@ -748,7 +748,7 @@ void MML_ClearBlock(mminfo_t *mm) =================== */ -void MM_Startup(mminfo_t *mm, mminfotype *mmi) +void MM_Startup(global_game_variables_t *gvar) { int i; //dword length,seglength; @@ -758,34 +758,34 @@ void MM_Startup(mminfo_t *mm, mminfotype *mmi) word segstart;//,endfree; //memptr *peeonself; -// if(mm->mmstarted) -// MM_Shutdown(mm); + if(gvar->mm.mmstarted) + MM_Shutdown(gvar); - mm->mmstarted = true; - mm->bombonerror = true; + gvar->mm.mmstarted = true; + gvar->mm.bombonerror = true; // // set up the linked list (everything in the free list; // - mm->mmhead = NULL; - mm->mmfree = &(mm->mmblocks[0]); + gvar->mm.mmhead = NULL; + gvar->mm.mmfree = &(gvar->mm.mmblocks[0]); for(i=0;immblocks[i].next = &(mm->mmblocks[i+1]); + gvar->mm.mmblocks[i].next = &(gvar->mm.mmblocks[i+1]); } - mm->mmblocks[i].next = NULL; + gvar->mm.mmblocks[i].next = NULL; // // locked block of all memory until we punch out free space // GETNEWBLOCK; - mm->mmhead = mm->mmnew; // this will allways be the first node - mm->mmnew->start = 0; - mm->mmnew->length = 0xffff; - mm->mmnew->attributes = LOCKBIT; - mm->mmnew->next = NULL; - //mm->mmnew->useptr = peeonself; - mm->mmrover = mm->mmhead; + 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); @@ -795,20 +795,20 @@ void MM_Startup(mminfo_t *mm, mminfotype *mmi) #ifdef __WATCOMC__ _nheapgrow(); length=(dword)_memavl();//(dword)GetFreeSize(); - //huge start = (void huge *)(mm->nearheap = _nmalloc(length)); - start = (void far *)(mm->nearheap = _nmalloc(length)); + //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 *)(mm->nearheap = malloc(length)); - start = (void far *)(mm->nearheap = malloc(length)); + //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, mm); - mmi->nearheap = length; + MML_UseSpace(segstart,seglength, gvar); + gvar->mmi.nearheap = length; //printf("start=%Fp segstart=%x seglen=%lu len=%lu\n", start, segstart, seglength, length); // @@ -817,96 +817,73 @@ void MM_Startup(mminfo_t *mm, mminfotype *mmi) //printf("_FARCORELEFT %lu\n", _FCORELEFT); #ifdef __WATCOMC__ _fheapgrow(); + length=_FCORELEFT;//_fcoreleft();//(dword)GetFarFreeSize();//0xffffUL*4UL; #endif #ifdef __BORLANDC__ printf("farcoreleft() %lu\n", farcoreleft()); printf("(farcoreleft()+32)-_FCORELEFT %d\n", (sword)((farcoreleft()+32)-_FCORELEFT)); + length=farcoreleft();//_fcoreleft();//(dword)GetFarFreeSize();//0xffffUL*4UL; #endif - length=_FCORELEFT;//_fcoreleft();//(dword)GetFarFreeSize();//0xffffUL*4UL; - start = mm->farheap = _fmalloc(length); - //start = mm->farheap = halloc(length, 1); + 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, mm); - mmi->farheap = length; + MML_UseSpace(segstart,seglength, gvar); + gvar->mmi.farheap = length; //printf("start=%Fp segstart=%x seglen=%lu len=%lu\n", start, segstart, seglength, length); - mmi->mainmem = mmi->nearheap + mmi->farheap; + gvar->mmi.mainmem = gvar->mmi.nearheap + gvar->mmi.farheap; +#ifndef __16_PM__ + if(!dbg_debugpm) { // // detect EMS and allocate up to 64K at page frame // - mmi->EMSmem = 0; + gvar->mmi.EMSmem = 0; //goto emsskip; //0000 - for(i = 1;i < -#ifdef __WATCOMC__ - __argc -#endif -#ifdef __BORLANDC__ - _argc -#endif - ;i++) + for(i = 1;i < _argc;i++) { - if(US_CheckParm( -#ifdef __WATCOMC__ - __argv[i] -#endif -#ifdef __BORLANDC__ - _argv[i] -#endif - ,ParmStringsexmm) == 0) + if(US_CheckParm(_argv[i],ParmStringsexmm) == 0) goto emsskip; // param NOEMS } if(MML_CheckForEMS()) { - MML_SetupEMS(mm); // allocate space - //TODO: EMS4! AND EMS 3.2 MASSIVE DATA HANDLMENT! - MML_UseSpace(mm->EMSpageframe,(MAPPAGES)*0x4000lu, mm); - //if(mm->EMSVer<0x40) - MM_MapEMS(mm, mmi); // map in used pages + MML_SetupEMS(gvar); // allocate space + //16_PM: EMS4! AND EMS 3.2 MASSIVE DATA HANDLMENT! + MML_UseSpace(gvar->mm.EMSPageFrame,(MAPPAGES)*0x4000lu, gvar); + //if(gvar->pm.emm.EMSVer<0x40) + MM_MapEMS(gvar); // map in used pages //else - //MM_MapXEMS(mm, mmi); // map in used pages + //MM_MapXEMS(gvar); // map in used pages } // // detect XMS and get upper memory blocks // emsskip: - mmi->XMSmem = 0; + gvar->mmi.XMSmem = 0; goto xmsskip;//0000 - for(i = 1;i < -#ifdef __WATCOMC__ - __argc -#endif -#ifdef __BORLANDC__ - _argc -#endif - ;i++) + for(i = 1;i < _argc;i++) { - if(US_CheckParm( -#ifdef __WATCOMC__ - __argv[i] -#endif -#ifdef __BORLANDC__ - _argv[i] -#endif - ,ParmStringsexmm) == 0) + if(US_CheckParm( _argv[i],ParmStringsexmm) == 0) goto xmsskip; // param NOXMS } - if(MML_CheckForXMS(mm)) + if(MML_CheckForXMS()) { - MML_SetupXMS(mm, mmi); // allocate as many UMBs as possible + MML_SetupXMS(gvar); // allocate as many UMBs as possible } + } +xmsskip: +#endif // // allocate the misc buffer // -xmsskip: - mm->mmrover = mm->mmhead; // start looking for space after low block + gvar->mm.mmrover = gvar->mm.mmhead; // start looking for space after low block - MM_GetPtr(&(mm->bufferseg),BUFFERSIZE, mm, mmi); + MM_GetPtr(&(gvar->mm.bufferseg),BUFFERSIZE, gvar); } //========================================================================== @@ -921,20 +898,28 @@ xmsskip: ==================== */ -void MM_Shutdown(mminfo_t *mm) +void MM_Shutdown(global_game_variables_t *gvar) { - if(!(mm->mmstarted)) + if(!(gvar->mm.mmstarted)) return; - _ffree(mm->farheap);// printf(" far freed\n"); + _ffree(gvar->mm.farheap);// printf(" far freed\n"); #ifdef __WATCOMC__ - _nfree(mm->nearheap);// printf(" near freed\n"); + _nfree(gvar->mm.nearheap);// printf(" near freed\n"); #endif #ifdef __BORLANDC__ - free(mm->nearheap);// printf(" near freed\n"); + free(gvar->mm.nearheap);// printf(" near freed\n"); +#endif +#ifndef __16_PM__ +#ifdef __DEBUG__ + if(!dbg_debugpm) { +#endif + if(MML_CheckForEMS()){ MML_ShutdownEMS(gvar); }//printf(" EMS freed\n"); } + if(MML_CheckForXMS()){ MML_ShutdownXMS(gvar); }//printf(" XMS freed\n"); } +#ifdef __DEBUG__ + } +#endif #endif - if(MML_CheckForEMS()){ MML_ShutdownEMS(mm); }//printf(" EMS freed\n"); } - if(MML_CheckForXMS(mm)){ MML_ShutdownXMS(mm); }//printf(" XMS freed\n"); } } //========================================================================== @@ -949,7 +934,7 @@ void MM_Shutdown(mminfo_t *mm) ==================== */ -void MM_GetPtr (memptr *baseptr, dword size, mminfo_t *mm, mminfotype *mmi) +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; @@ -959,16 +944,18 @@ void MM_GetPtr (memptr *baseptr, dword size, mminfo_t *mm, mminfotype *mmi) needed = (size+15)/16; // convert size from bytes to paragraphs GETNEWBLOCK; // fill in start and next after a spot is found - mm->mmnew->length = needed; - mm->mmnew->useptr = baseptr; - //if(mm->mmnew->useptr==NULL){ -#ifdef __DEBUG__ - printf("baseptr=%04x ", baseptr); printf("useptr=%04x\n", mm->mmnew->useptr); - printf("*baseptr=%04x ", *baseptr); printf("*useptr=%04x\n", *(mm->mmnew->useptr)); - printf("*baseptr=%Fp ", *baseptr); printf("*useptr=%Fp\n", *(mm->mmnew->useptr)); + gvar->mm.mmnew->length = needed; + gvar->mm.mmnew->useptr = baseptr; + //if(gvar->mm.mmnew->useptr==NULL){ +#ifdef __DEBUG_MM__ + printf("MM_GetPtr\n"); + //%04x + printf(" baseptr=%Fp ", baseptr); printf("useptr=%Fp\n", gvar->mm.mmnew->useptr); + printf(" *baseptr=%Fp ", *baseptr); printf("*useptr=%Fp\n", *(gvar->mm.mmnew->useptr)); + printf(" &baseptr=%Fp ", &baseptr); printf("&useptr=%Fp\n", &(gvar->mm.mmnew->useptr)); #endif //exit(-5); } - mm->mmnew->attributes = BASEATTRIBUTES; + gvar->mm.mmnew->attributes = BASEATTRIBUTES; //tryagain: for (search = 0; search<3; search++) @@ -977,25 +964,25 @@ void MM_GetPtr (memptr *baseptr, dword size, mminfo_t *mm, mminfotype *mmi) // 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 && mm->mmrover == mm->mmhead) + if (search == 1 && gvar->mm.mmrover == gvar->mm.mmhead) search++; switch (search) { case 0: - lastscan = mm->mmrover; - scan = mm->mmrover->next; + lastscan = gvar->mm.mmrover; + scan = gvar->mm.mmrover->next; endscan = NULL; break; case 1: - lastscan = mm->mmhead; - scan = mm->mmhead->next; - endscan = mm->mmrover; + lastscan = gvar->mm.mmhead; + scan = gvar->mm.mmhead->next; + endscan = gvar->mm.mmrover; break; case 2: - MM_SortMem (mm); - lastscan = mm->mmhead; - scan = mm->mmhead->next; + MM_SortMem (gvar); + lastscan = gvar->mm.mmhead; + scan = gvar->mm.mmhead->next; endscan = NULL; break; } @@ -1012,16 +999,16 @@ void MM_GetPtr (memptr *baseptr, dword size, mminfo_t *mm, mminfotype *mmi) // and allocate the new block // purge = lastscan->next; - lastscan->next = mm->mmnew; - mm->mmnew->start = *(unsigned *)baseptr = startseg; - mm->mmnew->next = scan; + 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 } - mm->mmrover = mm->mmnew; + gvar->mm.mmrover = gvar->mm.mmnew; return; // good allocation! } @@ -1040,18 +1027,18 @@ void MM_GetPtr (memptr *baseptr, dword size, mminfo_t *mm, mminfotype *mmi) } } - if (mm->bombonerror) + if (gvar->mm.bombonerror) { #ifdef __WATCOMC__ //heapdump(); #endif - printf(OUT_OF_MEM_MSG,(size-mmi->nearheap)); + printf(OUT_OF_MEM_MSG,(size-gvar->mmi.nearheap)); printf("for stability reasons the program will shut down! wwww\n"); - MM_Shutdown(mm); + MM_Shutdown(gvar); exit(-1); } else - mm->mmerror = true; + gvar->mm.mmerror = true; } //========================================================================== @@ -1066,16 +1053,16 @@ void MM_GetPtr (memptr *baseptr, dword size, mminfo_t *mm, mminfotype *mmi) ==================== */ -void MM_FreePtr(memptr *baseptr, mminfo_t *mm) +void MM_FreePtr(memptr *baseptr, global_game_variables_t *gvar) { //huge mmblocktype huge *scan,huge *last; mmblocktype far *scan,far *last; - last = mm->mmhead; + last = gvar->mm.mmhead; scan = last->next; - if(baseptr == mm->mmrover->useptr) // removed the last allocated block - mm->mmrover = mm->mmhead; + if(baseptr == gvar->mm.mmrover->useptr) // removed the last allocated block + gvar->mm.mmrover = gvar->mm.mmhead; while(scan->useptr != baseptr && scan) { @@ -1105,32 +1092,33 @@ void MM_FreePtr(memptr *baseptr, mminfo_t *mm) ===================== */ -void MM_SetPurge(memptr *baseptr, int purge, mminfo_t *mm) + +void MM_SetPurge(memptr *baseptr, int purge, global_game_variables_t *gvar) { //huge mmblocktype huge *start; mmblocktype far *start; - start = mm->mmrover; + start = gvar->mm.mmrover; do { - if(mm->mmrover->useptr == baseptr) + if(gvar->mm.mmrover->useptr == baseptr) break; - mm->mmrover = mm->mmrover->next; + gvar->mm.mmrover = gvar->mm.mmrover->next; - if(!mm->mmrover) - mm->mmrover = mm->mmhead; - else if(mm->mmrover == start) + if(!gvar->mm.mmrover) + gvar->mm.mmrover = gvar->mm.mmhead; + else if(gvar->mm.mmrover == start) { - printf("MM_SetPurge: Block not found!"); - return; + Quit("MM_SetPurge: Block not found!"); + //return; } } while(1); - mm->mmrover->attributes &= ~PURGEBITS; - mm->mmrover->attributes |= purge; + gvar->mm.mmrover->attributes &= ~PURGEBITS; + gvar->mm.mmrover->attributes |= purge; } //========================================================================== @@ -1145,32 +1133,32 @@ void MM_SetPurge(memptr *baseptr, int purge, mminfo_t *mm) ===================== */ -void MM_SetLock(memptr *baseptr, boolean locked, mminfo_t *mm) +void MM_SetLock(memptr *baseptr, boolean locked, global_game_variables_t *gvar) { //huge mmblocktype huge *start; mmblocktype far *start; - start = mm->mmrover; + start = gvar->mm.mmrover; do { - if(mm->mmrover->useptr == baseptr) + if(gvar->mm.mmrover->useptr == baseptr) break; - mm->mmrover = mm->mmrover->next; + gvar->mm.mmrover = gvar->mm.mmrover->next; - if(!mm->mmrover) - mm->mmrover = mm->mmhead; - else if(mm->mmrover == start) + if(!gvar->mm.mmrover) + gvar->mm.mmrover = gvar->mm.mmhead; + else if(gvar->mm.mmrover == start) { - printf("MM_SetLock: Block not found!"); - return; + Quit("MM_SetLock: Block not found!"); + //return; } } while(1); - mm->mmrover->attributes &= ~LOCKBIT; - mm->mmrover->attributes |= locked*LOCKBIT; + gvar->mm.mmrover->attributes &= ~LOCKBIT; + gvar->mm.mmrover->attributes |= locked*LOCKBIT; } //========================================================================== @@ -1185,7 +1173,7 @@ void MM_SetLock(memptr *baseptr, boolean locked, mminfo_t *mm) ===================== */ -void MM_SortMem(mminfo_t *mm) +void MM_SortMem(global_game_variables_t *gvar) { //huge mmblocktype huge *scan,huge *last,huge *next; mmblocktype far *scan,far *last,far *next; @@ -1218,7 +1206,7 @@ void MM_SortMem(mminfo_t *mm) if(beforesort) beforesort(); - scan = mm->mmhead; + scan = gvar->mm.mmhead; last = NULL; // shut up compiler warning @@ -1240,7 +1228,7 @@ void MM_SortMem(mminfo_t *mm) // next = scan->next; FREEBLOCK(scan); - //MM_FreeBlock(scan, mm); + //MM_FreeBlock(scan, gvar); last->next = next; scan = next; continue; @@ -1275,7 +1263,7 @@ void MM_SortMem(mminfo_t *mm) scan = scan->next; // go to next block } - mm->mmrover = mm->mmhead; + gvar->mm.mmrover = gvar->mm.mmhead; if(aftersort) aftersort(); @@ -1296,7 +1284,7 @@ void MM_SortMem(mminfo_t *mm) ===================== */ -void MM_ShowMemory(global_game_variables_t *gvar,/*page_t *page, */mminfo_t *mm) +void MM_ShowMemory(global_game_variables_t *gvar) { //huge mmblocktype huge *scan; mmblocktype far *scan; @@ -1312,7 +1300,7 @@ void MM_ShowMemory(global_game_variables_t *gvar,/*page_t *page, */mminfo_t *mm) //++++mh temp = bufferofs; //++++mh bufferofs = 0; //**** VW_SetScreen (0,0); - scan = mm->mmhead; + scan = gvar->mm.mmhead; end = -1; CA_OpenDebug (gvar); @@ -1429,14 +1417,14 @@ void MM_ShowMemory(global_game_variables_t *gvar,/*page_t *page, */mminfo_t *mm) /*strcpy(scratch1, AARESET); strcat(scratch1, "========================================\n"); strcat(scratch1, "near= "); - ultoa (*(mm->nearheap),str,10); + ultoa (*(gvar->mm.nearheap),str,10); strcat (scratch1,str); strcat(scratch1, " far= "); - ultoa (*(mm->farheap),str,10); + ultoa (*(gvar->mm.farheap),str,10); strcat (scratch1,str); strcat(scratch1, "\n"); - //strcat(scratch1, "&near= %Fp ", &(mm->nearheap)); - //strcat(scratch1, "&far= %Fp", &(mm->farheap)); + //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));*/ @@ -1459,7 +1447,7 @@ void MM_ShowMemory(global_game_variables_t *gvar,/*page_t *page, */mminfo_t *mm) ===================== */ -void MM_DumpData(mminfo_t *mm) +void MM_DumpData(global_game_variables_t *gvar) { //huge mmblocktype huge *scan,huge *best; mmblocktype far *scan,far *best; @@ -1468,7 +1456,7 @@ void MM_DumpData(mminfo_t *mm) byte lock,purge; FILE *dumpfile; - free(mm->nearheap); + free(gvar->mm.nearheap); #ifdef __BORLANDC__ dumpfile = fopen ("mmdump.16b","w"); #endif @@ -1486,7 +1474,7 @@ void MM_DumpData(mminfo_t *mm) oldlowest = lowest; lowest = 0xffff; - scan = mm->mmhead; + scan = gvar->mm.mmhead; while (scan) { owner = (unsigned)scan->useptr; @@ -1533,14 +1521,14 @@ void MM_DumpData(mminfo_t *mm) ====================== */ -dword MM_UnusedMemory(mminfo_t *mm) +dword MM_UnusedMemory(global_game_variables_t *gvar) { dword free; //huge mmblocktype huge *scan; mmblocktype far *scan; free = 0; - scan = mm->mmhead; + scan = gvar->mm.mmhead; while(scan->next) { @@ -1565,14 +1553,14 @@ dword MM_UnusedMemory(mminfo_t *mm) ====================== */ -dword MM_TotalFree(mminfo_t *mm) +dword MM_TotalFree(global_game_variables_t *gvar) { dword free; //huge mmblocktype huge *scan; mmblocktype far *scan; free = 0; - scan = mm->mmhead; + scan = gvar->mm.mmhead; while(scan->next) { @@ -1596,28 +1584,32 @@ dword MM_TotalFree(mminfo_t *mm) ===================== */ -void MM_Report(global_game_variables_t *gvar) +void MM_Report_(global_game_variables_t *gvar) { printf("========================================\n"); - printf(" MM_Report\n"); + printf(" MM_Report_\n"); printf("========================================\n"); if(MML_CheckForEMS()) { - printf(" LIMEMS\n"); - printf(" EMM v%x.%x available\n", gvar->mm.EMSVer>>4,gvar->mm.EMSVer&0x0F); - printf(" totalEMSpages: %u ", gvar->mm.totalEMSpages); printf("freeEMSpages: %u\n", gvar->mm.freeEMSpages); - printf(" EMSpageframe: %x\n", gvar->mm.EMSpageframe); + printf(" %cLIMEMS %u\n", 0xC9, gvar->pm.emm.EMSPresent); + printf(" %c%cEMM v%x.%x available\n", 0xC7, 0xC4, gvar->pm.emm.EMSVer>>4,gvar->pm.emm.EMSVer&0x0F); + printf(" %c%ctotalEMSpages: %u ", 0xC7, 0xC4, gvar->pm.emm.totalEMSpages); printf("freeEMSpages: %u\n", gvar->pm.emm.freeEMSpages); + printf(" %c%cEMSPageFrame: %04x\n", 0xC7, 0xC4, gvar->pm.emm.EMSPageFrame); + printf(" %c%cEMSmem: %lu\n", 0xD3, 0xC4, gvar->mmi.EMSmem); } - if(MML_CheckForXMS(&(gvar->mm))) + if(MML_CheckForXMS()) { - printf(" XMS\n"); - printf(" XMSaddr: %X\n", *XMSaddr); + printf(" %cXMS %u\n", 0xC9, gvar->pm.xmm.XMSPresent); + printf(" %c%cXMS v%x.%x available\n", 0xC7, 0xC4, XMSVer>>8,XMSVer&0x0F); + printf(" %c%cXMSDriver: %Fp\n", 0xC7, 0xC4, XMSDriver); + printf(" %c%cXMSHandle: %04x\n", 0xC7, 0xC4, gvar->pm.xmm.XMSHandle); + printf(" %c%cXMSmem: %lu\n", 0xD3, 0xC4, gvar->mmi.XMSmem); } - 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->mm))) printf("XMSmem: %lu", gvar->mmi.XMSmem); printf("\n"); + printf(" %cConv. %u\n", 0xC9, gvar->pm.mm.MainPresent); DebugMemory_(gvar, 0); //printf("mainmem: %lu\n", gvar->mmi.mainmem); - printf("Total convmem: %lu ", gvar->mmi.mainmem); printf("TotalFree: %lu ", MM_TotalFree(&(gvar->mm))); printf("TotalUsed: %lu\n", gvar->mmi.mainmem+gvar->mmi.EMSmem+gvar->mmi.XMSmem+gvar->mmi.XMSmem); - printf(" UnusedMemory: %lu\n", MM_UnusedMemory(&(gvar->mm))); + //printf("Total convmem: %lu ", gvar->mmi.mainmem); printf("TotalFree: %lu ", MM_TotalFree(gvar)+gvar->mmi.EMSmem+gvar->mmi.XMSmem+gvar->mmi.XMSmem); printf("TotalUsed: %lu\n", gvar->mmi.mainmem); + //printf(" UnusedMemory: %lu\n", MM_UnusedMemory(gvar)); + printf("nearheap: %lu ", gvar->mmi.nearheap); printf("farheap: %lu\n", gvar->mmi.farheap); } //========================================================================== @@ -1761,32 +1753,41 @@ void MM_EMSerr(byte *stri, byte err) ===================== */ -void MM_BombOnError(boolean bomb, mminfo_t *mm) +void MM_BombOnError(boolean bomb, global_game_variables_t *gvar) { - mm->bombonerror = bomb; + gvar->mm.bombonerror = bomb; } -/*void MM_GetNewBlock(mminfo_t *mm) +/*void MM_GetNewBlock(global_game_variables_t *gvar) { - if(!mm->mmfree) - MML_ClearBlock(mm); - mm->mmnew=mm->mmfree; - mm->mmfree=mm->mmfree->next; - if(!(mm->mmnew=mm->mmfree)) + 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; } - mm->mmfree=mm->mmfree->next; + gvar->mm.mmfree=gvar->mm.mmfree->next; } -void MM_FreeBlock(mmblocktype *x, mminfo_t *mm) +void MM_FreeBlock(mmblocktype *x, global_game_variables_t *gvar) { x->useptr=NULL; - x->next=mm->mmfree; - mm->mmfree=x; + x->next=gvar->mm.mmfree; + gvar->mm.mmfree=x; }*/ +void xms_call(byte v, global_game_variables_t *gvar) +{ + dword XMSDriver = gvar->pm.xmm.XMSDriver; + __asm { + mov ah,[v] + call [DWORD PTR XMSDriver] + } +} + /*void MM_seguin(void) { __asm { diff --git a/src/lib/16_mm.h b/src/lib/16_mm.h index 3b1eac3d..b68eea9c 100755 --- a/src/lib/16_mm.h +++ b/src/lib/16_mm.h @@ -1,207 +1,217 @@ -/* 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 -#include -#include "src/lib/16_head.h" -#include "src/lib/16_hc.h" -//#include "src/lib/modex16.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(!mm->mmfree)MML_ClearBlock(mm);mm->mmnew=mm->mmfree;mm->mmfree=mm->mmfree->next;} - -#define FREEBLOCK(x) {*x->useptr=NULL;x->next=mm->mmfree;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_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_QUERYREE 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//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(mminfo_t *mm, mminfotype *mmi); -byte MM_MapXEMS(mminfo_t *mm, mminfotype *mmi); -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, mminfo_t *mm); -void MML_ClearBlock(mminfo_t *mm); - -void MM_Startup(mminfo_t *mm, mminfotype *mmi); -void MM_Shutdown(mminfo_t *mm); - -void MM_GetPtr(memptr *baseptr,dword size, mminfo_t *mm, mminfotype *mmi); -void MM_FreePtr(memptr *baseptr, mminfo_t *mm); -void MM_SetPurge(memptr *baseptr, int purge, mminfo_t *mm); -void MM_SetLock(memptr *baseptr, boolean locked, mminfo_t *mm); -void MM_SortMem(mminfo_t *mm); -void MM_ShowMemory(global_game_variables_t *gvar,/*page_t *page, */mminfo_t *mm); -void MM_DumpData(mminfo_t *mm); -dword MM_UnusedMemory(mminfo_t *mm); -dword MM_TotalFree(mminfo_t *mm); -void MM_Report(global_game_variables_t *gvar); -static void MM_EMSerr(byte *stri, byte err); -void MM_BombOnError(boolean bomb, mminfo_t *mm); -//void MM_GetNewBlock(mminfo_t *mm); -//void MM_FreeBlock(mmblocktype *x, mminfo_t *mm); - -//========================================================================== - -#endif +/* 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 +#include +#include "src/lib/16_head.h" +#include "src/lib/16_hc.h" +#include "src/lib/16_tail.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" +extern boolean dbg_debugpm; +#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 EMM_INT 0x21 + +#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 XMS_CALL(v) _AH = (v);\ + __asm call [DWORD PTR XMSDriver] +/*__asm { mov ah,[v]\*///} + +#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 +extern dword XMSDriver; +extern word XMSVer; + +//========================================================================== + +/* +============================================================================= + + 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(void); +//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); +void xms_call(byte v, global_game_variables_t *gvar); + +//========================================================================== + +#endif diff --git a/src/lib/16_pm.c b/src/lib/16_pm.c index bc9ba74c..c9019b78 100755 --- a/src/lib/16_pm.c +++ b/src/lib/16_pm.c @@ -1,3 +1,25 @@ +/* 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 , or + * write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + // // ID_PM.C // Id Engine's Page Manager v1.0 @@ -7,41 +29,46 @@ #include "src/lib/16_pm.h" #pragma hdrstop +#ifdef __DEBUG__ +boolean dbg_debugpm=0; +#endif + // Main Mem specific variables - boolean MainPresent; - memptr MainMemPages[PMMaxMainMem]; - PMBlockAttr MainMemUsed[PMMaxMainMem]; - int MainPagesAvail; + //boolean MainPresent; +/* memptr MainMemPages[PMMaxMainMem]; + PMBlockAttr gvar->pm.mm.MainMemUsed[PMMaxMainMem]; + int gvar->pm.mm.MainPagesAvail;*/ // EMS specific variables - boolean EMSPresent; - word EMSAvail,EMSPagesAvail,EMSHandle, - EMSPageFrame,EMSPhysicalPage; - EMSListStruct EMSList[EMSFrameCount]; + //boolean EMSPresent; +/* word gvar->pm.emm.EMSAvail,gvar->pm.emm.EMSPagesAvail,gvar->pm.emm.EMSHandle, + gvar->pm.emm.EMSPageFrame,gvar->pm.emm.EMSPhysicalPage; + gvar->pm.emm.EMSListStruct gvar->pm.emm.EMSList[EMSFrameCount];*/ // XMS specific variables - boolean XMSPresent; - word XMSAvail,XMSPagesAvail,XMSHandle; - longword XMSDriver; - int XMSProtectPage = -1; + //boolean XMSPresent; + //word gvar->pm.xmm.XMSAvail,gvar->pm.xmm.XMSPagesAvail,gvar->pm.xmm.XMSHandle; + dword XMSDriver; //hard to put in gvar + word XMSVer; //hard to put in gvar +/* int gvar->pm.xmm.XMSProtectPage = -1; // File specific variables - char PageFileName[13] = {"VSWAP."}; + char gvar->pm.fi.PageFileName[13] = {"VSWAP."}; int PageFile = -1; - word ChunksInFile; - word PMSpriteStart,PMSoundStart; + word gvar->pm.fi.ChunksInFile; + word PMSpriteStart,PMSoundStart;*/ // General usage variables - boolean PMStarted, - PMPanicMode, - PMThrashing; - word XMSPagesUsed, - EMSPagesUsed, +/* boolean PMStarted, + gvar->pm.PMPanicMode, + gvar->pm.PMThrashing; + word gvar->pm.XMSPagesUsed, + gvar->pm.EMSPagesUsed, MainPagesUsed, - PMNumBlocks; + gvar->pm.PMNumBlocks; long PMFrameCount; - PageListStruct far *PMPages, - _seg *PMSegPages; + PageListStruct far *gvar->pm.PMPages, + _seg *gvar->pm.PMSegPages;*/ static char *ParmStrings[] = {"nomain","noems","noxms",nil}; @@ -54,21 +81,50 @@ static char *ParmStrings[] = {"nomain","noems","noxms",nil}; // // PML_MapEMS() - Maps a logical page to a physical page // -void -PML_MapEMS(word logical,word physical) -{ - union REGS CPURegs; - CPURegs.h.al = physical; - CPURegs.x.bx = logical; - CPURegs.x.dx = EMSHandle; - CPURegs.h.ah = EMS_MAPPAGE; - __asm - { - int EMS_INT - } +byte +PML_MapEMS(word logical, byte physical, global_game_variables_t *gvar) +{ + byte err, str[160]; + unsigned EMShandle; + int i; - if(CPURegs.h.ah) - printf("PML_MapEMS: Page mapping failed\n"); + boolean errorflag=false; + EMShandle=gvar->pm.emm.EMSHandle; + + __asm { + mov ah,EMS_MAPPAGE + mov al,physical + mov bx,logical + mov dx,EMShandle + int EMS_INT + or ah,ah + jnz errorme + jmp Endme +#ifdef __BORLANDC__ + } +#endif + errorme: +#ifdef __BORLANDC__ + __asm { +#endif + mov err,ah + mov errorflag,1 +#ifdef __BORLANDC__ + } +#endif + Endme: +#ifdef __WATCOMC__ + } +#endif + if(errorflag==true) + { + strcpy(str,"MM_MapEMS: EMS error "); + MM_EMSerr(str, err); + printf("%s\n",str); + Quit("PML_MapEMS: Page mapping failed\n"); + return err; + } + return 0; } // @@ -80,108 +136,207 @@ PML_MapEMS(word logical,word physical) // to the maximum we need) // - char EMMDriverName[9] = "EMMXXXX0"; - boolean -PML_StartupEMS(void) +PML_StartupEMS(global_game_variables_t *gvar) { int i; - long size; - - EMSPresent = false; // Assume that we'll fail - EMSAvail = 0; - - _DX = (word)EMMDriverName; - _AX = 0x3d00; - geninterrupt(0x21); // try to open EMMXXXX0 device -asm jnc gothandle - goto error; - -gothandle: - _BX = _AX; - _AX = 0x4400; - geninterrupt(0x21); // get device info -asm jnc gotinfo; - goto error; - -gotinfo: -asm and dx,0x80 - if (!_DX) - goto error; - - _AX = 0x4407; - geninterrupt(0x21); // get status -asm jc error - if (!_AL) - goto error; - - _AH = 0x3e; - geninterrupt(0x21); // close handle - - _AH = EMS_STATUS; - geninterrupt(EMS_INT); - if (_AH) - goto error; // make sure EMS hardware is present - - _AH = EMS_VERSION; - geninterrupt(EMS_INT); - if (_AH || (_AL < 0x32)) // only work on EMS 3.2 or greater (silly, but...) - goto error; - - _AH = EMS_GETFRAME; - geninterrupt(EMS_INT); - if (_AH) - goto error; // find the page frame address - EMSPageFrame = _BX; - - _AH = EMS_GETPAGES; - geninterrupt(EMS_INT); - if (_AH) - goto error; - if (_BX < 2) - goto error; // Require at least 2 pages (32k) - EMSAvail = _BX; - - // Don't hog all available EMS - size = EMSAvail * (long)EMSPageSize; - if (size - (EMSPageSize * 2) > (ChunksInFile * (long)PMPageSize)) + //long size; + byte err, str[64]; + + boolean errorflag=false; + static char emmname[] = "EMMXXXX0"; //fix by andrius4669 + unsigned int EMSVer = 0; + unsigned totalEMSpages,freeEMSpages,EMSPageFrame,EMSHandle,EMSAvail; + totalEMSpages = freeEMSpages = EMSPageFrame = 0; + gvar->pm.emm.EMSPresent = false; // Assume that we'll fail + gvar->pm.emm.EMSAvail = 0; + gvar->mmi.EMSmem = 0; + + __asm { + mov dx,OFFSET emmname //fix by andrius4669 + mov ax,0x3d00 + int EMM_INT // try to open EMMXXXX0 device + jc error1 + + mov bx,ax + mov ax,0x4400 + + int EMM_INT // get device info + jc error1 + + and dx,0x80 + jz error1 + + mov ax,0x4407 + + int EMM_INT // get status + jc error1 + or al,al + jz error1 + + mov ah,0x3e + int EMM_INT // close handle + jc error1 + + mov ah,EMS_STATUS + int EMS_INT + jc error1 // make sure EMS hardware is present + + mov ah,EMS_VERSION + int EMS_INT // only work on EMS 3.2 or greater (silly, but...) + or ah,ah + jnz error1 + mov [EMSVer],ax // set EMSVer + cmp al,0x32 // only work on ems 3.2 or greater + jb error1 + + mov ah,EMS_GETFRAME + int EMS_INT // find the page frame address + or ah,ah + jnz error1 + mov [EMSPageFrame],bx + + mov ah,EMS_GETPAGES + int EMS_INT // find out how much EMS is there + or ah,ah + jnz error1 + or bx,bx + jz noEMS // no EMS at all to allocate + cmp bx,2 + jl noEMS // Require at least 2 pages (32k) + mov [totalEMSpages],dx + mov [freeEMSpages],bx + mov [EMSAvail],bx + jmp End1 +#ifdef __BORLANDC__ + } +#endif + error1: +#ifdef __BORLANDC__ + __asm { +#endif + mov err,ah + mov errorflag,1 + jmp End1 +#ifdef __BORLANDC__ + } +#endif +noEMS: +End1: +#ifdef __WATCOMC__ + } +#endif +/* + if(errorflag==false) { - size = (ChunksInFile * (long)PMPageSize) + EMSPageSize; - EMSAvail = size / EMSPageSize; + // Don't hog all available EMS + size = gvar->pm.emm.EMSAvail * (long)EMSPageSize; + if (size - (EMSPageSize * 2) > (gvar->pm.fi.ChunksInFile * (long)PMPageSize)) + { + size = (gvar->pm.fi.ChunksInFile * (long)PMPageSize) + EMSPageSize; + gvar->pm.emm.EMSAvail = size / EMSPageSize; + } } +*/ + __asm { + mov ah,EMS_ALLOCPAGES + mov bx,[EMSAvail]; + int EMS_INT + or ah,ah + jnz error2 + mov [EMSHandle],dx + jmp End2 +#ifdef __BORLANDC__ + } +#endif + error2: +#ifdef __BORLANDC__ + __asm { +#endif + mov err,ah + mov errorflag,1 + jmp End2 +#ifdef __BORLANDC__ + } +#endif +End2: +#ifdef __WATCOMC__ + } +#endif - _AH = EMS_ALLOCPAGES; - _BX = EMSAvail; - geninterrupt(EMS_INT); - if (_AH) - goto error; - EMSHandle = _DX; - - mminfo.EMSmem += EMSAvail * (long)EMSPageSize; + if(errorflag==false) + { + gvar->mmi.EMSmem = EMSAvail * (dword)EMSPageSize; // Initialize EMS mapping cache for (i = 0;i < EMSFrameCount;i++) - EMSList[i].baseEMSPage = -1; + gvar->pm.emm.EMSList[i].baseEMSPage = -1; - EMSPresent = true; // We have EMS + } + else + { + strcpy(str,"PML_StartupEMS: EMS error "); + MM_EMSerr(str, err); + printf("%s\n",str); + return(gvar->pm.emm.EMSPresent); + } -error: - return(EMSPresent); + gvar->pm.emm.EMSPresent = true; // We have EMS + gvar->pm.emm.EMSPageFrame = EMSPageFrame; + gvar->pm.emm.EMSAvail = EMSAvail; + gvar->pm.emm.EMSVer = EMSVer; + gvar->pm.emm.EMSHandle = EMSHandle; + gvar->pm.emm.freeEMSpages = freeEMSpages; + gvar->pm.emm.totalEMSpages = totalEMSpages; + + return(gvar->pm.emm.EMSPresent); } // // PML_ShutdownEMS() - If EMS was used, deallocate it // void -PML_ShutdownEMS(void) +PML_ShutdownEMS(global_game_variables_t *gvar) { - if (EMSPresent) + word EMSHandle; + byte err,str[64]; + + boolean errorflag=false; + EMSHandle=gvar->pm.emm.EMSHandle; + + if (gvar->pm.emm.EMSPresent) { - asm mov ah,EMS_FREEPAGES - asm mov dx,[EMSHandle] - asm int EMS_INT - if (_AH) - printf("PML_ShutdownEMS: Error freeing EMS\n"); + __asm { + mov ah,EMS_FREEPAGES + mov dx,[EMSHandle] + int EMS_INT + jc errores + jmp Endes +#ifdef __BORLANDC__ + } +#endif + errores: +#ifdef __BORLANDC__ + __asm { +#endif + mov err,ah + mov errorflag,1 + jmp Endes +#ifdef __BORLANDC__ + } +#endif + Endes: +#ifdef __WATCOMC__ + } +#endif + if(errorflag==true) + { + strcpy(str,"PML_ShutdownEMS: Error freeing EMS "); + MM_EMSerr(str, err); + printf("%s\n",str); + Quit("PML_ShutdownEMS: Error freeing EMS\n"); + //return; + } } } @@ -198,46 +353,146 @@ PML_ShutdownEMS(void) // Allocates any remaining XMS (rounded down to the nearest page size) // boolean -PML_StartupXMS(void) +PML_StartupXMS(global_game_variables_t *gvar) { - XMSPresent = false; // Assume failure - XMSAvail = 0; - -asm mov ax,0x4300 -asm int XMS_INT // Check for presence of XMS driver - if (_AL != 0x80) - goto error; - - -asm mov ax,0x4310 -asm int XMS_INT // Get address of XMS driver -asm mov [WORD PTR XMSDriver],bx -asm mov [WORD PTR XMSDriver+2],es // function pointer to XMS driver - +//TODO: translate the _REG into working assembly +//#define STARTUPXMSASM + byte err; + word XMSAvail, XMSHandle;//, XMSVer; + boolean errorflag=false; + word e=0; + gvar->pm.xmm.XMSPresent = false; // Assume failure + XMSAvail = gvar->mmi.XMSmem = 0; + + __asm { + mov ax,0x4300 + int XMS_INT // Check for presence of XMS driver + cmp al,0x80 + jne error1 + mov e,1 + + mov ax,0x4310 + int XMS_INT // Get address of XMS driver + mov [WORD PTR XMSDriver],bx + mov [WORD PTR XMSDriver+2],es // function pointer to XMS driver + + mov ah,XMS_VERSION + call [DWORD PTR XMSDriver] //; Get XMS Version Number + mov [XMSVer],ax + mov e,2 + +#ifdef STARTUPXMSASM + mov ah,XMS_QUERYFREE // Find out how much XMS is available + call [DWORD PTR XMSDriver] + mov XMSAvail,ax + or ax,ax // AJR: bugfix 10/8/92 + jz error1 + mov e,3 +#endif + jmp End1 +#ifdef __BORLANDC__ + } +#endif + error1: +#ifdef __BORLANDC__ + __asm { +#endif + mov err,bl + mov errorflag,1 + jmp End1 +#ifdef __BORLANDC__ + } +#endif +End1: +#ifdef __WATCOMC__ + } +#endif + if(errorflag==true) goto error; +#ifndef STARTUPXMSASM XMS_CALL(XMS_QUERYFREE); // Find out how much XMS is available XMSAvail = _AX; if (!_AX) // AJR: bugfix 10/8/92 + { + errorflag = true; + err = _BL; goto error; + } + e++; +#endif +#ifdef __DEBUG_PM__ + printf("XMSVer=%02X ", XMSVer); + printf("XMSAvail=%u\n", XMSAvail); + getch(); +#endif XMSAvail &= ~(PMPageSizeKB - 1); // Round off to nearest page size if (XMSAvail < (PMPageSizeKB * 2)) // Need at least 2 pages + { + errorflag=true; goto error; - + } +#ifdef STARTUPXMSASM + __asm { + mov dx,XMSAvail + mov ah,XMS_ALLOC // And do the allocation + call [DWORD PTR XMSDriver] + mov XMSHandle,dx + or ax,ax // AJR: bugfix 10/8/92 + jz error2 + mov e,4 + jmp End2 +#ifdef __BORLANDC__ + } +#endif + error2: +#ifdef __BORLANDC__ + __asm { +#endif + mov err,bl + mov errorflag,1 + jmp End2 +#ifdef __BORLANDC__ + } +#endif +End2: +#ifdef __WATCOMC__ + } +#endif +#else _DX = XMSAvail; XMS_CALL(XMS_ALLOC); // And do the allocation XMSHandle = _DX; - if (!_AX) // AJR: bugfix 10/8/92 { - XMSAvail = 0; + errorflag=true; + err = _BL; goto error; } - - mminfo.XMSmem += XMSAvail * 1024; - - XMSPresent = true; + e++; +#endif error: - return(XMSPresent); + if(errorflag==false) + { + gvar->mmi.XMSmem = (dword)(XMSAvail) * 1024; + gvar->pm.xmm.XMSAvail = XMSAvail; + gvar->pm.xmm.XMSHandle = XMSHandle; + //gvar->pm.xmm.XMSVer = XMSVer; + gvar->pm.xmm.XMSPresent = true; +#ifdef __DEBUG_PM__ + printf(" XMSmem=%lu XMSAvail=%u\n", gvar->mmi.XMSmem, XMSAvail); +#endif + } + else + { +#ifdef __DEBUG_PM__ + //printf("XMSHandle\n"); + //printf(" 1=%u 2=%u 3=%u 4=%u\n", XMSHandle1, XMSHandle2, XMSHandle3, XMSHandle4); + //printf(" 2=%u ", XMSHandle); + //printf(" %u", gvar->pm.xmm.XMSHandle); + printf(" err=%02X e=%u\n", err, e); +#endif + } + return(gvar->pm.xmm.XMSPresent); } // @@ -245,49 +500,59 @@ error: // Will round an odd-length request up to the next even value // void -PML_XMSCopy(boolean toxms,byte far *addr,word xmspage,word length) +PML_XMSCopy(boolean toxms,byte far *addr,word xmspage,word length, global_game_variables_t *gvar) { dword xoffset; struct { - longword length; + dword length; word source_handle; - longword source_offset; + dword source_offset; word target_handle; - longword target_offset; + dword target_offset; } copy; if (!addr) - printf("PML_XMSCopy: zero address\n"); + { + Quit("PML_XMSCopy: zero address\n"); + //return; + } - xoffset = (longword)xmspage * PMPageSize; + xoffset = (dword)xmspage * PMPageSize; copy.length = (length + 1) & ~1; - copy.source_handle = toxms? 0 : XMSHandle; + copy.source_handle = toxms? 0 : gvar->pm.xmm.XMSHandle; copy.source_offset = toxms? (long)addr : xoffset; - copy.target_handle = toxms? XMSHandle : 0; + copy.target_handle = toxms? gvar->pm.xmm.XMSHandle : 0; copy.target_offset = toxms? xoffset : (long)addr; -asm push si + __asm { + push si + } _SI = (word)© XMS_CALL(XMS_MOVE); -asm pop si + __asm { + pop si + } if (!_AX) + { Quit("PML_XMSCopy: Error on copy"); + //return; + } } #if 1 -#define PML_CopyToXMS(s,t,l) PML_XMSCopy(true,(s),(t),(l)) -#define PML_CopyFromXMS(t,s,l) PML_XMSCopy(false,(t),(s),(l)) +#define PML_CopyToXMS(s,t,l,gvar) PML_XMSCopy(true,(s),(t),(l),(gvar)) +#define PML_CopyFromXMS(t,s,l,gvar) PML_XMSCopy(false,(t),(s),(l),(gvar)) #else // // PML_CopyToXMS() - Copies the specified number of bytes from the real mode // segment address to the specified XMS page // void -PML_CopyToXMS(byte far *source,int targetpage,word length) +PML_CopyToXMS(byte far *source,int targetpage,word length,global_game_variables_t *gvar) { - PML_XMSCopy(true,source,targetpage,length); + PML_XMSCopy(true,source,targetpage,length, global_game_variables_t *gvar); } // @@ -295,9 +560,9 @@ PML_CopyToXMS(byte far *source,int targetpage,word length) // page to the specified real mode address // void -PML_CopyFromXMS(byte far *target,int sourcepage,word length) +PML_CopyFromXMS(byte far *target,int sourcepage,word length, global_game_variables_t *gvar) { - PML_XMSCopy(false,target,sourcepage,length); + PML_XMSCopy(false,target,sourcepage,length, global_game_variables_t *gvar); } #endif @@ -305,14 +570,42 @@ PML_CopyFromXMS(byte far *target,int sourcepage,word length) // PML_ShutdownXMS() // void -PML_ShutdownXMS(void) +PML_ShutdownXMS(global_game_variables_t *gvar) { - if (XMSPresent) + boolean errorflag=false; + word XMSHandle = gvar->pm.xmm.XMSHandle; + if (gvar->pm.xmm.XMSPresent) { - _DX = XMSHandle; - XMS_CALL(XMS_FREE); - if (_BL) + __asm { + mov dx,[XMSHandle] + //XMS_CALL(XMS_FREE); + mov ah,XMS_FREE + call [DWORD PTR XMSDriver] + or bl,bl + jz errorxs + jmp Endxs +#ifdef __BORLANDC__ + } +#endif + errorxs: +#ifdef __BORLANDC__ + __asm { +#endif + //mov err,ah + mov errorflag,1 + jmp Endxs +#ifdef __BORLANDC__ + } +#endif + Endxs: +#ifdef __WATCOMC__ + } +#endif + if(errorflag==true) + { Quit("PML_ShutdownXMS: Error freeing XMS"); + //return; + } } } @@ -328,13 +621,25 @@ PML_ShutdownXMS(void) // PM_UnlockMainMem() macros should be used instead. // void -PM_SetMainMemPurge(int level) +PM_SetMainMemPurge(int level, global_game_variables_t *gvar) { int i; + if(gvar->pm.mm.MainPresent) for (i = 0;i < PMMaxMainMem;i++) - if (MainMemPages[i]) - MM_SetPurge(&MainMemPages[i],level); + { +#ifdef __DEBUG_PM__ + printf("PM_SetMainMemPurge() info of gvar->pm.mm.MainMemPages[i]\n"); + printf("& %Fp, %Fp\n", &gvar->pm.mm.MainMemPages[i], &(gvar->pm.mm.MainMemPages[i])); +#endif + if (gvar->pm.mm.MainMemPages[i]) + MM_SetPurge(&(gvar->pm.mm.MainMemPages[i]),level, gvar); + } + + else + { + Quit("MainPresent IS NULL\n"); + } } // @@ -351,7 +656,7 @@ PM_SetMainMemPurge(int level) // program makes allocation requests of the Memory Mgr. // void -PM_CheckMainMem(void) +PM_CheckMainMem(global_game_variables_t *gvar) { boolean allocfailed; int i,n; @@ -359,15 +664,15 @@ PM_CheckMainMem(void) PMBlockAttr *used; PageListStruct far *page; - if (!MainPresent) + if (!gvar->pm.mm.MainPresent) return; - for (i = 0,page = PMPages;i < ChunksInFile;i++,page++) + for (i = 0,page = gvar->pm.PMPages;i < gvar->pm.fi.ChunksInFile;i++,page++) { n = page->mainPage; if (n != -1) // Is the page using main memory? { - if (!MainMemPages[n]) // Yep, was the block purged? + if (!gvar->pm.mm.MainMemPages[n]) // Yep, was the block purged? { page->mainPage = -1; // Yes, mark page as purged & unlocked page->locked = pml_Unlocked; @@ -376,41 +681,41 @@ PM_CheckMainMem(void) } // Prevent allocation attempts from purging any of our other blocks - PM_LockMainMem(); + PM_LockMainMem(gvar); allocfailed = false; - for (i = 0,p = MainMemPages,used = MainMemUsed;i < PMMaxMainMem;i++,p++,used++) + for (i = 0,p = gvar->pm.mm.MainMemPages,used = gvar->pm.mm.MainMemUsed; i < PMMaxMainMem;i++,p++,used++) { if (!*p) // If the page got purged { if (*used & pmba_Allocated) // If it was allocated { *used &= ~pmba_Allocated; // Mark as unallocated - MainPagesAvail--; // and decrease available count + gvar->pm.mm.MainPagesAvail--; // and decrease available count } if (*used & pmba_Used) // If it was used { *used &= ~pmba_Used; // Mark as unused - MainPagesUsed--; // and decrease used count + gvar->pm.MainPagesUsed--; // and decrease used count } if (!allocfailed) { - MM_BombOnError(false); - MM_GetPtr(p,PMPageSize); // Try to reallocate - if (mmerror) // If it failed, + MM_BombOnError(false, gvar); + MM_GetPtr(p,PMPageSize, gvar); // Try to reallocate + if (gvar->mm.mmerror) // If it failed, allocfailed = true; // don't try any more allocations else // If it worked, { *used |= pmba_Allocated; // Mark as allocated - MainPagesAvail++; // and increase available count + gvar->pm.mm.MainPagesAvail++; // and increase available count } - MM_BombOnError(true); + MM_BombOnError(true, gvar); } } } - if (mmerror) - mmerror = false; + if (gvar->mm.mmerror) + gvar->mm.mmerror = false; } // @@ -420,28 +725,32 @@ PM_CheckMainMem(void) // needs to be called. // void -PML_StartupMainMem(void) +PML_StartupMainMem(global_game_variables_t *gvar) { int i,n; memptr *p; - MainPagesAvail = 0; - MM_BombOnError(false); - for (i = 0,p = MainMemPages;i < PMMaxMainMem;i++,p++) + gvar->pm.mm.MainPagesAvail = 0; + gvar->pm.mm.MainPresent = false; + MM_BombOnError(false, gvar); + for (i = 0,p = gvar->pm.mm.MainMemPages;i < PMMaxMainMem;i++,p++) { - MM_GetPtr(p,PMPageSize); - if (mmerror) + MM_GetPtr(p,PMPageSize, gvar); + if (gvar->mm.mmerror) break; - MainPagesAvail++; - MainMemUsed[i] = pmba_Allocated; + gvar->pm.mm.MainPagesAvail++; + gvar->pm.mm.MainMemUsed[i] = pmba_Allocated; } - MM_BombOnError(true); - if (mmerror) - mmerror = false; - if (MainPagesAvail < PMMinMainMem) + MM_BombOnError(true, gvar); + if (gvar->mm.mmerror) + gvar->mm.mmerror = false; + if (gvar->pm.mm.MainPagesAvail < PMMinMainMem) + { Quit("PM_SetupMainMem: Not enough main memory"); - MainPresent = true; + //return; + } + gvar->pm.mm.MainPresent = true; } // @@ -449,15 +758,15 @@ PML_StartupMainMem(void) // Page Mgr. // void -PML_ShutdownMainMem(void) +PML_ShutdownMainMem(global_game_variables_t *gvar) { int i; memptr *p; // DEBUG - mark pages as unallocated & decrease page count as appropriate - for (i = 0,p = MainMemPages;i < PMMaxMainMem;i++,p++) + for (i = 0,p = gvar->pm.mm.MainMemPages;i < PMMaxMainMem;i++,p++) if (*p) - MM_FreePtr(p); + MM_FreePtr(p, gvar); } ///////////////////////////////////////////////////////////////////////////// @@ -470,80 +779,102 @@ PML_ShutdownMainMem(void) // PML_ReadFromFile() - Reads some data in from the page file // void -PML_ReadFromFile(byte far *buf,long offset,word length) +PML_ReadFromFile(byte far *buf,long offset,word length, global_game_variables_t *gvar) { if (!buf) + { Quit("PML_ReadFromFile: Null pointer"); + //return; + } if (!offset) + { Quit("PML_ReadFromFile: Zero offset"); - if (lseek(PageFile,offset,SEEK_SET) != offset) + //return; + } + if (lseek(gvar->pm.fi.PageFile,offset,SEEK_SET) != offset) + { Quit("PML_ReadFromFile: Seek failed"); - if (!CA_FarRead(PageFile,buf,length)) + //return; + } + if (!CA_FarRead(gvar->pm.fi.PageFile,buf,length, gvar)) + { Quit("PML_ReadFromFile: Read failed"); + //return; + } } // // PML_OpenPageFile() - Opens the page file and sets up the page info // void -PML_OpenPageFile(void) +PML_OpenPageFile(global_game_variables_t *gvar) { int i; long size; - void _seg *buf; - longword far *offsetptr; + //__SEGA buf; + memptr buf; + dword far *offsetptr; word far *lengthptr; PageListStruct far *page; - PageFile = open(PageFileName,O_RDONLY + O_BINARY); - if (PageFile == -1) + gvar->pm.fi.PageFile = open(gvar->pm.fi.PageFileName,O_RDONLY + O_BINARY); + if (gvar->pm.fi.PageFile == -1) + { Quit("PML_OpenPageFile: Unable to open page file"); + //return; + } // Read in header variables - read(PageFile,&ChunksInFile,sizeof(ChunksInFile)); - read(PageFile,&PMSpriteStart,sizeof(PMSpriteStart)); - read(PageFile,&PMSoundStart,sizeof(PMSoundStart)); + read(gvar->pm.fi.PageFile,&gvar->pm.fi.ChunksInFile,sizeof(gvar->pm.fi.ChunksInFile)); + read(gvar->pm.fi.PageFile,&gvar->pm.fi.PMSpriteStart,sizeof(gvar->pm.fi.PMSpriteStart)); + read(gvar->pm.fi.PageFile,&gvar->pm.fi.PMSoundStart,sizeof(gvar->pm.fi.PMSoundStart)); // Allocate and clear the page list - PMNumBlocks = ChunksInFile; - MM_GetPtr(&(memptr)PMSegPages,sizeof(PageListStruct) * PMNumBlocks); - MM_SetLock(&(memptr)PMSegPages,true); - PMPages = (PageListStruct far *)PMSegPages; - _fmemset(PMPages,0,sizeof(PageListStruct) * PMNumBlocks); + gvar->pm.PMNumBlocks = gvar->pm.fi.ChunksInFile; + MM_GetPtr((memptr *)gvar->pm.PMSegPages, sizeof(PageListStruct) * (gvar->pm.PMNumBlocks), gvar); + MM_SetLock((memptr *)gvar->pm.PMSegPages,true, gvar); + gvar->pm.PMPages = (PageListStruct far *)gvar->pm.PMSegPages; + _fmemset(gvar->pm.PMPages,0,sizeof(PageListStruct) * gvar->pm.PMNumBlocks); // Read in the chunk offsets - size = sizeof(longword) * ChunksInFile; - MM_GetPtr(&buf,size); - if (!CA_FarRead(PageFile,(byte far *)buf,size)) + size = sizeof(dword) * gvar->pm.fi.ChunksInFile; + MM_GetPtr(&buf, size, gvar); + if (!CA_FarRead(gvar->pm.fi.PageFile,(byte far *)buf,size, gvar)) + { Quit("PML_OpenPageFile: Offset read failed"); - offsetptr = (longword far *)buf; - for (i = 0,page = PMPages;i < ChunksInFile;i++,page++) + //return; + } + offsetptr = (dword far *)buf; + for (i = 0,page = gvar->pm.PMPages;i < gvar->pm.fi.ChunksInFile;i++,page++) page->offset = *offsetptr++; - MM_FreePtr(&buf); + MM_FreePtr(&buf, gvar); // Read in the chunk lengths - size = sizeof(word) * ChunksInFile; - MM_GetPtr(&buf,size); - if (!CA_FarRead(PageFile,(byte far *)buf,size)) + size = sizeof(word) * gvar->pm.fi.ChunksInFile; + MM_GetPtr(&buf,size, gvar); + if (!CA_FarRead(gvar->pm.fi.PageFile,(byte far *)buf,size, gvar)) + { Quit("PML_OpenPageFile: Length read failed"); + //return; + } lengthptr = (word far *)buf; - for (i = 0,page = PMPages;i < ChunksInFile;i++,page++) + for (i = 0,page = gvar->pm.PMPages;i < gvar->pm.fi.ChunksInFile;i++,page++) page->length = *lengthptr++; - MM_FreePtr(&buf); + MM_FreePtr(&buf, gvar); } // // PML_ClosePageFile() - Closes the page file // void -PML_ClosePageFile(void) +PML_ClosePageFile(global_game_variables_t *gvar) { - if (PageFile != -1) - close(PageFile); - if (PMSegPages) + if (gvar->pm.fi.PageFile != -1) + close(gvar->pm.fi.PageFile); + if (gvar->pm.PMSegPages) { - MM_SetLock(&(memptr)PMSegPages,false); - MM_FreePtr(&(void _seg *)PMSegPages); + MM_SetLock((memptr)gvar->pm.PMSegPages,false, gvar); + MM_FreePtr((memptr)gvar->pm.PMSegPages, gvar); } } @@ -560,10 +891,10 @@ PML_ClosePageFile(void) // to map our page in. If normal page, use EMS physical page 3, else // use the physical page specified by the lock type // -#if 1 +#ifndef __DEBUG_2__ #pragma argsused // DEBUG - remove lock parameter memptr -PML_GetEMSAddress(int page,PMLockType lock) +PML_GetEMSAddress(int page,PMLockType lock, global_game_variables_t *gvar) { int i,emspage; word emsoff,emsbase,offset; @@ -575,7 +906,7 @@ PML_GetEMSAddress(int page,PMLockType lock) // See if this page is already mapped in for (i = 0;i < EMSFrameCount;i++) { - if (EMSList[i].baseEMSPage == emsbase) + if (gvar->pm.emm.EMSList[i].baseEMSPage == emsbase) { emspage = i; // Yep - don't do a redundant remapping break; @@ -585,31 +916,31 @@ PML_GetEMSAddress(int page,PMLockType lock) // If page isn't already mapped in, find LRU EMS frame, and use it if (emspage == -1) { - longword last = MAXLONG; + dword last = LONG_MAX; for (i = 0;i < EMSFrameCount;i++) { - if (EMSList[i].lastHit < last) + if (gvar->pm.emm.EMSList[i].lastHit < last) { emspage = i; - last = EMSList[i].lastHit; + last = gvar->pm.emm.EMSList[i].lastHit; } } - EMSList[emspage].baseEMSPage = emsbase; - PML_MapEMS(page / PMEMSSubPage,emspage); + gvar->pm.emm.EMSList[emspage].baseEMSPage = emsbase; + PML_MapEMS(page / PMEMSSubPage,emspage, gvar); } if (emspage == -1) Quit("PML_GetEMSAddress: EMS find failed"); - EMSList[emspage].lastHit = PMFrameCount; + gvar->pm.emm.EMSList[emspage].lastHit = gvar->pm.PMFrameCount; offset = emspage * EMSPageSizeSeg; offset += emsoff * PMPageSizeSeg; - return((memptr)(EMSPageFrame + offset)); + return((memptr)(gvar->pm.emm.EMSPageFrame + offset)); } #else memptr -PML_GetEMSAddress(int page,PMLockType lock) +PML_GetEMSAddress(int page,PMLockType lock, global_game_variables_t *gvar) { word emspage; @@ -629,15 +960,15 @@ PML_GetEMSAddress(int page,PMLockType lock) // // memptr -PM_GetPageAddress(int pagenum) +PM_GetPageAddress(int pagenum, global_game_variables_t *gvar) { PageListStruct far *page; - page = &PMPages[pagenum]; + page = &gvar->pm.PMPages[pagenum]; if (page->mainPage != -1) - return(MainMemPages[page->mainPage]); + return(gvar->pm.mm.MainMemPages[page->mainPage]); else if (page->emsPage != -1) - return(PML_GetEMSAddress(page->emsPage,page->locked)); + return(PML_GetEMSAddress(page->emsPage,page->locked, gvar)); else return(nil); } @@ -647,13 +978,13 @@ PM_GetPageAddress(int pagenum) // present & unlocked main/EMS page (or main page if mainonly is true) // int -PML_GiveLRUPage(boolean mainonly) +PML_GiveLRUPage(boolean mainonly, global_game_variables_t *gvar) { int i,lru; long last; PageListStruct far *page; - for (i = 0,page = PMPages,lru = -1,last = MAXLONG;i < ChunksInFile;i++,page++) + for (i = 0,page = gvar->pm.PMPages,lru = -1,last = LONG_MAX;i < gvar->pm.fi.ChunksInFile;i++,page++) { if ( @@ -679,19 +1010,19 @@ PML_GiveLRUPage(boolean mainonly) // This routine won't return the XMS page protected (by XMSProtectPage) // int -PML_GiveLRUXMSPage(void) +PML_GiveLRUXMSPage(global_game_variables_t *gvar) { int i,lru; long last; PageListStruct far *page; - for (i = 0,page = PMPages,lru = -1,last = MAXLONG;i < ChunksInFile;i++,page++) + for (i = 0,page = gvar->pm.PMPages,lru = -1,last = LONG_MAX;i < gvar->pm.fi.ChunksInFile;i++,page++) { if ( (page->xmsPage != -1) && (page->lastHit < last) - && (i != XMSProtectPage) + && (i != gvar->pm.xmm.XMSProtectPage) ) { last = page->lastHit; @@ -706,29 +1037,29 @@ PML_GiveLRUXMSPage(void) // it with the main/EMS page // void -PML_PutPageInXMS(int pagenum) +PML_PutPageInXMS(int pagenum, global_game_variables_t *gvar) { int usexms; PageListStruct far *page; - if (!XMSPresent) + if (!gvar->pm.xmm.XMSPresent) return; - page = &PMPages[pagenum]; + page = &gvar->pm.PMPages[pagenum]; if (page->xmsPage != -1) return; // Already in XMS - if (XMSPagesUsed < XMSPagesAvail) - page->xmsPage = XMSPagesUsed++; + if (gvar->pm.XMSPagesUsed < gvar->pm.xmm.XMSPagesAvail) + page->xmsPage = gvar->pm.XMSPagesUsed++; else { - usexms = PML_GiveLRUXMSPage(); + usexms = PML_GiveLRUXMSPage(gvar); if (usexms == -1) Quit("PML_PutPageInXMS: No XMS LRU"); - page->xmsPage = PMPages[usexms].xmsPage; - PMPages[usexms].xmsPage = -1; + page->xmsPage = gvar->pm.PMPages[usexms].xmsPage; + gvar->pm.PMPages[usexms].xmsPage = -1; } - PML_CopyToXMS(PM_GetPageAddress(pagenum),page->xmsPage,page->length); + PML_CopyToXMS(PM_GetPageAddress(pagenum, gvar),page->xmsPage,page->length, gvar); } // @@ -736,7 +1067,7 @@ PML_PutPageInXMS(int pagenum) // the old one's address space. Returns the address of the new page. // memptr -PML_TransferPageSpace(int orig,int new) +PML_TransferPageSpace(int orig,int new, global_game_variables_t *gvar) { memptr addr; PageListStruct far *origpage,far *newpage; @@ -744,8 +1075,8 @@ PML_TransferPageSpace(int orig,int new) if (orig == new) Quit("PML_TransferPageSpace: Identity replacement"); - origpage = &PMPages[orig]; - newpage = &PMPages[new]; + origpage = &gvar->pm.PMPages[orig]; + newpage = &gvar->pm.PMPages[new]; if (origpage->locked != pml_Unlocked) Quit("PML_TransferPageSpace: Killing locked page"); @@ -754,10 +1085,10 @@ PML_TransferPageSpace(int orig,int new) Quit("PML_TransferPageSpace: Reusing non-existent page"); // Copy page that's about to be purged into XMS - PML_PutPageInXMS(orig); + PML_PutPageInXMS(orig, gvar); // Get the address, and force EMS into a physical page if necessary - addr = PM_GetPageAddress(orig); + addr = PM_GetPageAddress(orig, gvar); // Steal the address newpage->emsPage = origpage->emsPage; @@ -781,24 +1112,24 @@ PML_TransferPageSpace(int orig,int new) // will be looked at by PML_GiveLRUPage(). // byte far * -PML_GetAPageBuffer(int pagenum,boolean mainonly) +PML_GetAPageBuffer(int pagenum,boolean mainonly, global_game_variables_t *gvar) { byte far *addr = nil; int i,n; PMBlockAttr *used; PageListStruct far *page; - page = &PMPages[pagenum]; - if ((EMSPagesUsed < EMSPagesAvail) && !mainonly) + page = &gvar->pm.PMPages[pagenum]; + if ((gvar->pm.EMSPagesUsed < gvar->pm.emm.EMSPagesAvail) && !mainonly) { // There's remaining EMS - use it - page->emsPage = EMSPagesUsed++; - addr = PML_GetEMSAddress(page->emsPage,page->locked); + page->emsPage = gvar->pm.EMSPagesUsed++; + addr = PML_GetEMSAddress(page->emsPage,page->locked, gvar); } - else if (MainPagesUsed < MainPagesAvail) + else if (gvar->pm.MainPagesUsed < gvar->pm.mm.MainPagesAvail) { // There's remaining main memory - use it - for (i = 0,n = -1,used = MainMemUsed;i < PMMaxMainMem;i++,used++) + for (i = 0,n = -1,used = gvar->pm.mm.MainMemUsed;i < PMMaxMainMem;i++,used++) { if ((*used & pmba_Allocated) && !(*used & pmba_Used)) { @@ -809,14 +1140,14 @@ PML_GetAPageBuffer(int pagenum,boolean mainonly) } if (n == -1) Quit("PML_GetPageBuffer: MainPagesAvail lied"); - addr = MainMemPages[n]; + addr = gvar->pm.mm.MainMemPages[n]; if (!addr) Quit("PML_GetPageBuffer: Purged main block"); page->mainPage = n; - MainPagesUsed++; + gvar->pm.MainPagesUsed++; } else - addr = PML_TransferPageSpace(PML_GiveLRUPage(mainonly),pagenum); + addr = PML_TransferPageSpace(PML_GiveLRUPage(mainonly, gvar),pagenum, gvar); if (!addr) Quit("PML_GetPageBuffer: Search failed"); @@ -833,22 +1164,22 @@ PML_GetAPageBuffer(int pagenum,boolean mainonly) // (pages that are being purged are copied into XMS, if possible) // memptr -PML_GetPageFromXMS(int pagenum,boolean mainonly) +PML_GetPageFromXMS(int pagenum,boolean mainonly, global_game_variables_t *gvar) { byte far *checkaddr; memptr addr = nil; PageListStruct far *page; - page = &PMPages[pagenum]; - if (XMSPresent && (page->xmsPage != -1)) + page = &gvar->pm.PMPages[pagenum]; + if (gvar->pm.xmm.XMSPresent && (page->xmsPage != -1)) { - XMSProtectPage = pagenum; - checkaddr = PML_GetAPageBuffer(pagenum,mainonly); + gvar->pm.xmm.XMSProtectPage = pagenum; + checkaddr = PML_GetAPageBuffer(pagenum,mainonly, gvar); if (FP_OFF(checkaddr)) Quit("PML_GetPageFromXMS: Non segment pointer"); addr = (memptr)FP_SEG(checkaddr); - PML_CopyFromXMS(addr,page->xmsPage,page->length); - XMSProtectPage = -1; + PML_CopyFromXMS(addr,page->xmsPage,page->length, gvar); + gvar->pm.xmm.XMSProtectPage = -1; } return(addr); @@ -860,14 +1191,14 @@ PML_GetPageFromXMS(int pagenum,boolean mainonly) // only be loaded into main. // void -PML_LoadPage(int pagenum,boolean mainonly) +PML_LoadPage(int pagenum,boolean mainonly, global_game_variables_t *gvar) { byte far *addr; PageListStruct far *page; - addr = PML_GetAPageBuffer(pagenum,mainonly); - page = &PMPages[pagenum]; - PML_ReadFromFile(addr,page->offset,page->length); + addr = PML_GetAPageBuffer(pagenum,mainonly, gvar); + page = &gvar->pm.PMPages[pagenum]; + PML_ReadFromFile(addr,page->offset,page->length, gvar); } // @@ -878,49 +1209,52 @@ PML_LoadPage(int pagenum,boolean mainonly) // #pragma warn -pia memptr -PM_GetPage(int pagenum) +PM_GetPage(int pagenum, global_game_variables_t *gvar) { memptr result; - if (pagenum >= ChunksInFile) + if (pagenum >= gvar->pm.fi.ChunksInFile) Quit("PM_GetPage: Invalid page request"); -#if 0 // for debugging -asm mov dx,STATUS_REGISTER_1 -asm in al,dx -asm mov dx,ATR_INDEX -asm mov al,ATR_OVERSCAN -asm out dx,al -asm mov al,10 // bright green -asm out dx,al +#ifdef __DEBUG_2__ // for debugging + __asm { + mov dx,STATUS_REGISTER_1 + in al,dx + mov dx,ATR_INDEX + mov al,ATR_OVERSCAN + out dx,al + mov al,10 // bright green + out dx,al + } #endif - if (!(result = PM_GetPageAddress(pagenum))) + if (!(result = PM_GetPageAddress(pagenum, gvar))) { - boolean mainonly = (pagenum >= PMSoundStart); -if (!PMPages[pagenum].offset) // JDC: sparse page + boolean mainonly = (pagenum >= gvar->pm.fi.PMSoundStart); +if (!gvar->pm.PMPages[pagenum].offset) // JDC: sparse page Quit ("Tried to load a sparse page!"); - if (!(result = PML_GetPageFromXMS(pagenum,mainonly))) + if (!(result = PML_GetPageFromXMS(pagenum,mainonly, gvar))) { - if (PMPages[pagenum].lastHit == PMFrameCount) - PMThrashing++; + if (gvar->pm.PMPages[pagenum].lastHit == gvar->pm.PMFrameCount) + gvar->pm.PMThrashing++; - PML_LoadPage(pagenum,mainonly); - result = PM_GetPageAddress(pagenum); + PML_LoadPage(pagenum,mainonly, gvar); + result = PM_GetPageAddress(pagenum, gvar); } } - PMPages[pagenum].lastHit = PMFrameCount; - -#if 0 // for debugging -asm mov dx,STATUS_REGISTER_1 -asm in al,dx -asm mov dx,ATR_INDEX -asm mov al,ATR_OVERSCAN -asm out dx,al -asm mov al,3 // blue -asm out dx,al -asm mov al,0x20 // normal -asm out dx,al + gvar->pm.PMPages[pagenum].lastHit = gvar->pm.PMFrameCount; + +#ifdef __DEBUG_2__ // for debugging + __asm{ + mov dx,STATUS_REGISTER_1 + in al,dx + mov dx,ATR_INDEX + mov al,ATR_OVERSCAN + out dx,al + mov al,3 // blue + out dx,al + mov al,0x20 // normal + out dx,al #endif return(result); @@ -935,12 +1269,12 @@ asm out dx,al // specified when returning the address. For sound stuff. // void -PM_SetPageLock(int pagenum,PMLockType lock) +PM_SetPageLock(int pagenum,PMLockType lock, global_game_variables_t *gvar) { - if (pagenum < PMSoundStart) + if (pagenum < gvar->pm.fi.PMSoundStart) Quit("PM_SetPageLock: Locking/unlocking non-sound page"); - PMPages[pagenum].locked = lock; + gvar->pm.PMPages[pagenum].locked = lock; } // @@ -949,7 +1283,7 @@ PM_SetPageLock(int pagenum,PMLockType lock) // page, and the total pages that need to be loaded (for thermometer). // void -PM_Preload(boolean (*update)(word current,word total)) +PM_Preload(boolean (*update)(word current,word total), global_game_variables_t *gvar) { int i,j, page,oogypage; @@ -961,17 +1295,17 @@ PM_Preload(boolean (*update)(word current,word total)) memptr addr; PageListStruct far *p; - mainfree = (MainPagesAvail - MainPagesUsed) + (EMSPagesAvail - EMSPagesUsed); - xmsfree = (XMSPagesAvail - XMSPagesUsed); + mainfree = (gvar->pm.mm.MainPagesAvail - gvar->pm.MainPagesUsed) + (gvar->pm.emm.EMSPagesAvail - gvar->pm.EMSPagesUsed); + xmsfree = (gvar->pm.xmm.XMSPagesAvail - gvar->pm.XMSPagesUsed); xmstotal = maintotal = 0; - for (i = 0;i < ChunksInFile;i++) + for (i = 0;i < gvar->pm.fi.ChunksInFile;i++) { - if (!PMPages[i].offset) + if (!gvar->pm.PMPages[i].offset) continue; // sparse - if ( PMPages[i].emsPage != -1 || PMPages[i].mainPage != -1 ) + if ( gvar->pm.PMPages[i].emsPage != -1 || gvar->pm.PMPages[i].mainPage != -1 ) continue; // already in main mem if ( mainfree ) @@ -979,7 +1313,7 @@ PM_Preload(boolean (*update)(word current,word total)) maintotal++; mainfree--; } - else if ( xmsfree && (PMPages[i].xmsPage == -1) ) + else if ( xmsfree && (gvar->pm.PMPages[i].xmsPage == -1) ) { xmstotal++; xmsfree--; @@ -1000,14 +1334,14 @@ PM_Preload(boolean (*update)(word current,word total)) // while (maintotal) { - while ( !PMPages[page].offset || PMPages[page].mainPage != -1 - || PMPages[page].emsPage != -1 ) + while ( !gvar->pm.PMPages[page].offset || gvar->pm.PMPages[page].mainPage != -1 + || gvar->pm.PMPages[page].emsPage != -1 ) page++; - if (page >= ChunksInFile) - Quit ("PM_Preload: Pages>=ChunksInFile"); + if (page >= gvar->pm.fi.ChunksInFile) + Quit ("PM_Preload: Pages>=gvar->pm.fi.ChunksInFile"); - PM_GetPage(page); + PM_GetPage(page, gvar); page++; current++; @@ -1020,30 +1354,30 @@ PM_Preload(boolean (*update)(word current,word total)) // if (xmstotal) { - for (oogypage = 0 ; PMPages[oogypage].mainPage == -1 ; oogypage++) + for (oogypage = 0 ; gvar->pm.PMPages[oogypage].mainPage == -1 ; oogypage++) ; - addr = PM_GetPage(oogypage); + addr = PM_GetPage(oogypage, gvar); if (!addr) Quit("PM_Preload: XMS buffer failed"); while (xmstotal) { - while ( !PMPages[page].offset || PMPages[page].xmsPage != -1 ) + while ( !gvar->pm.PMPages[page].offset || gvar->pm.PMPages[page].xmsPage != -1 ) page++; - if (page >= ChunksInFile) - Quit ("PM_Preload: Pages>=ChunksInFile"); + if (page >= gvar->pm.fi.ChunksInFile) + Quit ("PM_Preload: Pages>=gvar->pm.fi.ChunksInFile"); - p = &PMPages[page]; + p = &gvar->pm.PMPages[page]; - p->xmsPage = XMSPagesUsed++; - if (XMSPagesUsed > XMSPagesAvail) + p->xmsPage = gvar->pm.XMSPagesUsed++; + if (gvar->pm.XMSPagesUsed > gvar->pm.xmm.XMSPagesAvail) Quit("PM_Preload: Exceeded XMS pages"); if (p->length > PMPageSize) Quit("PM_Preload: Page too long"); - PML_ReadFromFile((byte far *)addr,p->offset,p->length); - PML_CopyToXMS((byte far *)addr,p->xmsPage,p->length); + PML_ReadFromFile((byte far *)addr,p->offset,p->length, gvar); + PML_CopyToXMS((byte far *)addr,p->xmsPage,p->length, gvar); page++; current++; @@ -1051,8 +1385,8 @@ PM_Preload(boolean (*update)(word current,word total)) update(current,total); } - p = &PMPages[oogypage]; - PML_ReadFromFile((byte far *)addr,p->offset,p->length); + p = &gvar->pm.PMPages[oogypage]; + PML_ReadFromFile((byte far *)addr,p->offset,p->length, gvar); } update(total,total); @@ -1074,63 +1408,66 @@ PM_Preload(boolean (*update)(word current,word total)) // // void -PM_NextFrame(void) +PM_NextFrame(global_game_variables_t *gvar) { int i; // Frame count overrun - kill the LRU hit entries & reset frame count - if (++PMFrameCount >= MAXLONG - 4) + if (++gvar->pm.PMFrameCount >= LONG_MAX - 4) { - for (i = 0;i < PMNumBlocks;i++) - PMPages[i].lastHit = 0; - PMFrameCount = 0; + for (i = 0;i < gvar->pm.PMNumBlocks;i++) + gvar->pm.PMPages[i].lastHit = 0; + gvar->pm.PMFrameCount = 0; } -#if 0 - for (i = 0;i < PMSoundStart;i++) +//#if 0 + for (i = 0;i < gvar->pm.fi.PMSoundStart;i++) { - if (PMPages[i].locked) + if (gvar->pm.PMPages[i].locked) { char buf[40]; sprintf(buf,"PM_NextFrame: Page %d is locked",i); Quit(buf); } } -#endif +//#endif - if (PMPanicMode) + if (gvar->pm.PMPanicMode) { // DEBUG - set border color - if ((!PMThrashing) && (!--PMPanicMode)) + if ((!gvar->pm.PMThrashing) && (!--gvar->pm.PMPanicMode)) { // DEBUG - reset border color } } - if (PMThrashing >= PMThrashThreshold) - PMPanicMode = PMUnThrashThreshold; - PMThrashing = false; + if (gvar->pm.PMThrashing >= PMThrashThreshold) + gvar->pm.PMPanicMode = PMUnThrashThreshold; + gvar->pm.PMThrashing = false; } // // PM_Reset() - Sets up caching structures // void -PM_Reset(void) +PM_Reset(global_game_variables_t *gvar) { int i; PageListStruct far *page; - XMSPagesAvail = XMSAvail / PMPageSizeKB; + gvar->pm.xmm.XMSPagesAvail = gvar->pm.xmm.XMSAvail / PMPageSizeKB; + + gvar->pm.emm.EMSPagesAvail = gvar->pm.emm.EMSAvail * (EMSPageSizeKB / PMPageSizeKB); + gvar->pm.emm.EMSPhysicalPage = 0; - EMSPagesAvail = EMSAvail * (EMSPageSizeKB / PMPageSizeKB); - EMSPhysicalPage = 0; + gvar->pm.MainPagesUsed = gvar->pm.EMSPagesUsed = gvar->pm.XMSPagesUsed = 0; - MainPagesUsed = EMSPagesUsed = XMSPagesUsed = 0; + gvar->pm.PMPanicMode = false; - PMPanicMode = false; + gvar->pm.fi.PageFile = -1; + gvar->pm.xmm.XMSProtectPage = -1; // Initialize page list - for (i = 0,page = PMPages;i < PMNumBlocks;i++,page++) + for (i = 0,page = gvar->pm.PMPages;i < gvar->pm.PMNumBlocks;i++,page++) { page->mainPage = -1; page->emsPage = -1; @@ -1143,14 +1480,16 @@ PM_Reset(void) // PM_Startup() - Start up the Page Mgr // void -PM_Startup(void) +PM_Startup(global_game_variables_t *gvar) { boolean nomain,noems,noxms; int i; - if (PMStarted) + if (gvar->pm.PMStarted) return; + //strcpy(&(gvar->pm.fi.PageFileName), "VSWAP."); + nomain = noems = noxms = false; for (i = 1;i < _argc;i++) { @@ -1168,39 +1507,39 @@ PM_Startup(void) } } - PML_OpenPageFile(); + //0000+=+=PML_OpenPageFile(gvar); - if (!noems) - PML_StartupEMS(); - if (!noxms) - PML_StartupXMS(); + if (!noems && MML_CheckForEMS()) + PML_StartupEMS(gvar); + if (!noxms && MML_CheckForXMS()) + PML_StartupXMS(gvar); + if(!nomain) + PML_StartupMainMem(gvar); - if (nomain && !EMSPresent) + if (!gvar->pm.mm.MainPresent && !gvar->pm.emm.EMSPresent && !gvar->pm.xmm.XMSPresent) { - printf("PM_Startup: No main or EMS\n"); - return; + Quit("PM_Startup: No main or EMS\n"); + //return; } - else - PML_StartupMainMem(); - PM_Reset(); + PM_Reset(gvar); - PMStarted = true; + gvar->pm.PMStarted = true; } // // PM_Shutdown() - Shut down the Page Mgr // void -PM_Shutdown(void) +PM_Shutdown(global_game_variables_t *gvar) { - PML_ShutdownXMS(); - PML_ShutdownEMS(); + if(MML_CheckForXMS()) PML_ShutdownXMS(gvar); + if(MML_CheckForEMS()) PML_ShutdownEMS(gvar); - if (!PMStarted) + if (!gvar->pm.PMStarted) return; - PML_ClosePageFile(); + //PML_ClosePageFile(gvar); - PML_ShutdownMainMem(); + PML_ShutdownMainMem(gvar); } diff --git a/src/lib/16_pm.h b/src/lib/16_pm.h index 54f1600b..4c015e98 100755 --- a/src/lib/16_pm.h +++ b/src/lib/16_pm.h @@ -1,3 +1,28 @@ +/* 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 , or + * write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef __16_PM__ +#define __16_PM__ + // // ID_PM.H // Header file for Id Engine's Page Manager @@ -6,8 +31,14 @@ #include "src/lib/16_head.h" #include "src/lib/16_hc.h" #include "src/lib/16_mm.h" +#include "src/lib/16_ca.h" +#include + +#ifdef __DEBUG__ +extern boolean dbg_debugpm; +#endif -// NOTE! PMPageSize must be an even divisor of EMSPageSize, and >= 1024 +/*// NOTE! PMPageSize must be an even divisor of EMSPageSize, and >= 1024 #define EMSPageSize 16384 #define EMSPageSizeSeg (EMSPageSize >> 4) #define EMSPageSizeKB (EMSPageSize >> 10) @@ -38,7 +69,7 @@ typedef enum typedef struct { - longword offset; // Offset of chunk into file + dword offset; // Offset of chunk into file word length; // Length of the chunk int xmsPage; // If in XMS, (xmsPage * PMPageSize) gives offset into XMS handle @@ -47,13 +78,13 @@ typedef struct int emsPage; // If in EMS, logical page/offset into page int mainPage; // If in Main, index into handle array - longword lastHit; // Last frame number of hit + dword lastHit; // Last frame number of hit } PageListStruct; typedef struct { int baseEMSPage; // Base EMS page for this phys frame - longword lastHit; // Last frame number of hit + dword lastHit; // Last frame number of hit } EMSListStruct; extern boolean XMSPresent,EMSPresent; @@ -61,27 +92,29 @@ extern word XMSPagesAvail,EMSPagesAvail; extern word ChunksInFile, PMSpriteStart,PMSoundStart; -extern PageListStruct far *PMPages; +extern PageListStruct far *PMPages;*///moved to src/lib/typdefst.h #define PM_GetSoundPage(v) PM_GetPage(PMSoundStart + (v)) #define PM_GetSpritePage(v) PM_GetPage(PMSpriteStart + (v)) -#define PM_LockMainMem() PM_SetMainMemPurge(0) -#define PM_UnlockMainMem() PM_SetMainMemPurge(3) +#define PM_LockMainMem(gvar) PM_SetMainMemPurge(0, gvar) +#define PM_UnlockMainMem(gvar) PM_SetMainMemPurge(3, gvar) extern char PageFileName[13]; -extern void PM_Startup(void), - PM_Shutdown(void), - PM_Reset(void), - PM_Preload(boolean (*update)(word current,word total)), - PM_NextFrame(void), - PM_SetPageLock(int pagenum,PMLockType lock), +extern void PM_Startup(global_game_variables_t *gvar), + PM_Shutdown(global_game_variables_t *gvar), + PM_Reset(global_game_variables_t *gvar), + PM_Preload(boolean (*update)(word current,word total), global_game_variables_t *gvar), + PM_NextFrame(global_game_variables_t *gvar), + PM_SetPageLock(int pagenum,PMLockType lock, global_game_variables_t *gvar), PM_SetMainPurge(int level), - PM_CheckMainMem(void); -extern memptr PM_GetPageAddress(int pagenum), - PM_GetPage(int pagenum); // Use this one to cache page + PM_CheckMainMem(global_game_variables_t *gvar); +extern memptr PM_GetPageAddress(int pagenum, global_game_variables_t *gvar), + PM_GetPage(int pagenum, global_game_variables_t *gvar); // Use this one to cache page -void PM_SetMainMemPurge(int level); +void PM_SetMainMemPurge(int level, global_game_variables_t *gvar); +void PML_StartupMainMem(global_game_variables_t *gvar); +#endif diff --git a/src/lib/16_sprit.c b/src/lib/16_sprit.c index c5158dc5..c59590ce 100755 --- a/src/lib/16_sprit.c +++ b/src/lib/16_sprit.c @@ -1,118 +1,118 @@ -#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" + +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; + } +} diff --git a/src/lib/16_sprit.h b/src/lib/16_sprit.h index a93838ac..555e8d1c 100755 --- a/src/lib/16_sprit.h +++ b/src/lib/16_sprit.h @@ -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 , 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~ + * 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 , 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 diff --git a/src/lib/16_tail.c b/src/lib/16_tail.c new file mode 100755 index 00000000..f63dddc1 --- /dev/null +++ b/src/lib/16_tail.c @@ -0,0 +1,207 @@ +/* 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 , or + * write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +/* + * 16 library + */ + +#include "src/lib/16_tail.h" + +/* +========================== += += Startup16 += += Load a few things right away += +========================== +*/ + +void Startup16(global_game_variables_t *gvar) +{ +#ifdef __WATCOMC__ + // 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); +#endif + gvar->mm.mmstarted=0; + gvar->pm.PMStarted=0; + MM_Startup(gvar); + IN_Startup(gvar); + PM_Startup(gvar); + PM_UnlockMainMem(gvar); + CA_Startup(gvar); +#ifdef __WATCOMC__ + start_timer(gvar); + +#endif + +} + +//=========================================================================== + +/* +========================== += += Shutdown16 += += Shuts down all ID_?? managers += +========================== +*/ + +void Shutdown16(global_game_variables_t *gvar) +{ + PM_Shutdown(gvar); + IN_Shutdown(gvar); + CA_Shutdown(gvar); + MM_Shutdown(gvar); +} + + +//=========================================================================== + +/* +================== += += DebugMemory += +================== +*/ + +void DebugMemory_(global_game_variables_t *gvar, boolean q) +{ + /*VW_FixRefreshBuffer (); + US_CenterWindow (16,7); + + US_CPrint ("Memory Usage"); + US_CPrint ("------------"); + US_Print ("Total :"); + US_PrintUnsigned (mminfo.mainmem/1024); + US_Print ("k\nFree :"); + US_PrintUnsigned (MM_UnusedMemory()/1024); + US_Print ("k\nWith purge:"); + US_PrintUnsigned (MM_TotalFree()/1024); + US_Print ("k\n"); + VW_UpdateScreen();*/ + if(q){ + printf("========================================\n"); + printf(" DebugMemory_\n"); + printf("========================================\n");} + if(q) { printf("Memory Usage\n"); + printf("------------\n"); }else printf(" %c%c", 0xD3, 0xC4); + printf("Total: "); if(q) printf(" "); printf("%uk", gvar->mmi.mainmem/1024); + if(q) printf("\n"); else printf(" "); + printf("Free: "); if(q) printf(" "); printf("%uk", MM_UnusedMemory(gvar)/1024); + if(q) printf("\n"); else printf(" "); + printf("With purge:"); if(q) printf(" "); printf("%uk\n", MM_TotalFree(gvar)/1024); + if(q) printf("------------\n"); +#ifdef __WATCOMC__ + IN_Ack (); +#endif + if(q) MM_ShowMemory (gvar); +} +#ifdef __WATCOMC__ +/* +========================== += += Quit += +========================== +*/ + +void Quit (char *error) +{ + unsigned finscreen; + memptr screen; + union REGS in, out; + + //ClearMemory (); + if (!*error) + { + //WriteConfig (); + } + else + { + //CA_CacheGrChunk (ERRORSCREEN); + //screen = grsegs[ERRORSCREEN]; + } + + //ShutdownId (); + IN_Shutdown(); + //modexLeave(); + in.h.ah = 0x00; + in.h.al = 0x3; + int86(0x10, &in, &out); + + if (error && *error) + { + //movedata ((unsigned)screen,7,0xb800,0,7*160); + //gotoxy (10,4); + fprintf(stderr, "%s\n", error); + //gotoxy (1,8); + exit(1); + } + else + if (!error || !(*error)) + { + //clrscr(); + //#ifndef JAPAN + movedata ((unsigned)screen,7,0xb800,0,4000); + //gotoxy(1,24); + //#endif +//asm mov bh,0 +//asm mov dh,23 // row +//asm mov dl,0 // collumn +//asm mov ah,2 +//asm int 0x10 + } + + exit(0); +} +#endif + +//=========================================================================== diff --git a/src/lib/16_tail.h b/src/lib/16_tail.h new file mode 100755 index 00000000..d9d37b16 --- /dev/null +++ b/src/lib/16_tail.h @@ -0,0 +1,41 @@ +/* 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 , or + * write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef __16_TAIL__ +#define __16_TAIL__ + +#include "src/lib/16_head.h" +#include "src/lib/16_pm.h" +#include "src/lib/16_mm.h" +#include "src/lib/16_ca.h" +#include "src/lib/16_in.h" + +extern boolean dbg_debugpm; + +void DebugMemory_(global_game_variables_t *gvar, boolean q); +void Shutdown16(global_game_variables_t *gvar); +void Startup16(global_game_variables_t *gvar); +#ifdef __WATCOMC__ +void Quit (char *error); +#endif + +#endif diff --git a/src/lib/16_vrs.c b/src/lib/16_vrs.c index 5dc525e1..595489d6 100755 --- a/src/lib/16_vrs.c +++ b/src/lib/16_vrs.c @@ -1,139 +1,139 @@ -/* 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 , 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~ + * 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 , 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; +} diff --git a/src/lib/16_vrs.h b/src/lib/16_vrs.h index 381b7108..cdeb81a0 100755 --- a/src/lib/16_vrs.h +++ b/src/lib/16_vrs.h @@ -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 , 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 -//#include -#include -#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~ + * 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 , 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 +//#include +#include +#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 diff --git a/src/lib/_croll16.c b/src/lib/_croll16.c index 2dc6f5aa..e152ce18 100755 --- a/src/lib/_croll16.c +++ b/src/lib/_croll16.c @@ -1,925 +1,925 @@ -/* 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 , 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; yheight; y++) { - //for(x=0; xwidth; x++) { - i=0; - for(yy=0; yytiles->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; yheight; y++) { - for(x=0; xwidth; 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; xpage->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; ypage->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~ + * 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 , 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; yheight; y++) { + //for(x=0; xwidth; x++) { + i=0; + for(yy=0; yytiles->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; yheight; y++) { + for(x=0; xwidth; 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; xpage->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; ypage->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; +} diff --git a/src/lib/bakapee.c b/src/lib/bakapee.c index 3f8ab3e5..ee209e36 100755 --- a/src/lib/bakapee.c +++ b/src/lib/bakapee.c @@ -1,278 +1,278 @@ -/* 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 , 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 ‚Ä‚·‚Æ -void colortest(page_t *page, bakapee_t *pee) -{ - //if(pee->coor < 256) - //{ - modexcls(page, pee->coor, VGA); - pee->coor++; - //}else pee->coor = 0; -} - -//color ‚Ä‚·‚Æ -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->gqgq++; - } - 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~ + * 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 , 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 ‚Ä‚·‚Æ +void colortest(page_t *page, bakapee_t *pee) +{ + //if(pee->coor < 256) + //{ + modexcls(page, pee->coor, VGA); + pee->coor++; + //}else pee->coor = 0; +} + +//color ‚Ä‚·‚Æ +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->gqgq++; + } + 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++; +} diff --git a/src/lib/ems.c b/src/lib/ems.c index 9d371053..4bbfefd6 100755 --- a/src/lib/ems.c +++ b/src/lib/ems.c @@ -1,5 +1,5 @@ -/* - +/* + THE IBM PC PROGRAMMER'S GUIDE TO C @@ -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 given to both this work and the author. Source code occuring in this work may be used within commercial and non-commercial applications without -charge and without reference to the author. -*/ +charge and without reference to the author. +*/ /* Various functions for using Expanded memory */ @@ -178,4 +178,4 @@ charge and without reference to the author. regs.x.dx = handle; int86(EMM,®s,®s); return (regs.h.ah == 0); - } + } diff --git a/src/lib/ems.h b/src/lib/ems.h index b288a548..33d24d06 100755 --- a/src/lib/ems.h +++ b/src/lib/ems.h @@ -1,5 +1,5 @@ -/* - +/* + THE IBM PC PROGRAMMER'S GUIDE TO C @@ -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 given to both this work and the author. Source code occuring in this work may be used within commercial and non-commercial applications without -charge and without reference to the author. - */ - -#ifndef __EMS_H_ -#define __EMS_H_ - +charge and without reference to the author. + */ + +#ifndef __EMS_H_ +#define __EMS_H_ + #include #define EMM 0x67 -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; + +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_ diff --git a/src/lib/jsmn b/src/lib/jsmn index 6021415c..1682c32e 160000 --- a/src/lib/jsmn +++ b/src/lib/jsmn @@ -1 +1 @@ -Subproject commit 6021415cc75e7922d45b12935f56348b064d8a7f +Subproject commit 1682c32e9ae5990ddd0f0e907270a0f6dde5cbe9 diff --git a/src/lib/mapread.c b/src/lib/mapread.c index 8a8d5d87..5421d9dd 100755 --- a/src/lib/mapread.c +++ b/src/lib/mapread.c @@ -1,245 +1,245 @@ -/* 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 , 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~ + * 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 , 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; +} diff --git a/src/lib/midi.c b/src/lib/midi.c index 760906c8..7e6ac1c5 100755 --- a/src/lib/midi.c +++ b/src/lib/midi.c @@ -1,730 +1,730 @@ -/* 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. - * - * - * 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 + * + * 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. + * + * + * 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; +} diff --git a/src/lib/midi.h b/src/lib/midi.h index ac740c80..356255d2 100755 --- a/src/lib/midi.h +++ b/src/lib/midi.h @@ -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. - * - * - * Compiles for intended target environments: - * - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box] - */ - +/* 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. + * + * + * Compiles for intended target environments: + * - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box] + */ + #ifndef __MIDI__ -#define __MIDI__ - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -//#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__ + +#include +#include /* this is where Open Watcom hides the outp() etc. functions */ +#include +#include +#include +#include +#include +#include +#include +#include + +//#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__ */ diff --git a/src/lib/modex16.h b/src/lib/modex16.h index 23202f2d..3467a77d 100755 --- a/src/lib/modex16.h +++ b/src/lib/modex16.h @@ -1,192 +1,192 @@ -/* 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 , 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 -#include -#include -#include -#include -#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~ + * 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 , 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 +#include +#include +#include +#include +#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 diff --git a/src/lib/scroll16.c b/src/lib/scroll16.c index eca613a8..b94e768a 100755 --- a/src/lib/scroll16.c +++ b/src/lib/scroll16.c @@ -1,916 +1,916 @@ -/* 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 , 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; yheight; y++) { - //for(x=0; xwidth; x++) { - i=0; - for(yy=0; yytiles->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; yheight; y++) { - for(x=0; xwidth; 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; xpage->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; ypage->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~ + * 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 , 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; yheight; y++) { + //for(x=0; xwidth; x++) { + i=0; + for(yy=0; yytiles->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; yheight; y++) { + for(x=0; xwidth; 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; xpage->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; ypage->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; +} diff --git a/src/lib/scroll16.h b/src/lib/scroll16.h index a3402a02..1f609670 100755 --- a/src/lib/scroll16.h +++ b/src/lib/scroll16.h @@ -1,95 +1,96 @@ -/* 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 , 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 -#include -#include -#include - -#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~ + * 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 , 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 "src/lib/16_tail.h" + +#include +#include +#include +#include + +#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_*/ diff --git a/src/lib/typdefst.h b/src/lib/typdefst.h index fdf96a27..32aaed26 100755 --- a/src/lib/typdefst.h +++ b/src/lib/typdefst.h @@ -120,7 +120,7 @@ typedef struct } pan_t; //video -#define NUMCHUNKS 3016 //keen +#define NUMCHUNKS 416 //keen typedef struct { @@ -135,6 +135,12 @@ typedef struct //0000word startclk; float clk, tickclk; //timer } video_t; +//from 16_mm +//========================================================================== + +#define MAXBLOCKS 1024 +#define MAXUMBS 12 + typedef struct mmblockstruct { word start,length; @@ -146,15 +152,10 @@ typedef struct mmblockstruct struct mmblockstruct far *next; } mmblocktype; -//from 16_mm -//========================================================================== - -#define MAXBLOCKS 1024 -#define MAXUMBS 12 - typedef struct { dword nearheap,farheap,EMSmem,XMSmem,mainmem; +// boolean PMStarted, MainPresent, EMSPresent, XMSPresent; } mminfotype; typedef struct @@ -169,10 +170,9 @@ typedef struct #ifdef __WATCOMC__ void __near *nearheap; #endif - //byte EMS_status; - unsigned totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle; - unsigned int EMSVer; + unsigned int EMSVer; word numUMBs,UMBbase[MAXUMBS]; + word totalEMSpages, freeEMSpages, EMSpagesmapped, EMSHandle, EMSPageFrame; //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; @@ -180,6 +180,118 @@ typedef struct //========================================================================== + +//from 16_pm +//========================================================================== + +// NOTE! PMPageSize must be an even divisor of EMSPageSize, and >= 1024 +#define EMSPageSize 16384 +#define EMSPageSizeSeg (EMSPageSize >> 4) +#define EMSPageSizeKB (EMSPageSize >> 10) +#define EMSFrameCount 4 +#define PMPageSize 4096 +#define PMPageSizeSeg (PMPageSize >> 4) +#define PMPageSizeKB (PMPageSize >> 10) +#define PMEMSSubPage (EMSPageSize / PMPageSize) + +#define PMMinMainMem 10 // Min acceptable # of pages from main +#define PMMaxMainMem 100 // Max number of pages in main memory + +#define PMThrashThreshold 1 // Number of page thrashes before panic mode +#define PMUnThrashThreshold 5 // Number of non-thrashing frames before leaving panic mode + +typedef enum + { + pml_Unlocked, + pml_Locked + } PMLockType; + +typedef enum + { + pmba_Unused = 0, + pmba_Used = 1, + pmba_Allocated = 2 + } PMBlockAttr; + +typedef struct + { + dword offset; // Offset of chunk into file + word length; // Length of the chunk + + int xmsPage; // If in XMS, (xmsPage * PMPageSize) gives offset into XMS handle + + PMLockType locked; // If set, this page can't be purged + int emsPage; // If in EMS, logical page/offset into page + int mainPage; // If in Main, index into handle array + + dword lastHit; // Last frame number of hit + } PageListStruct; + +typedef struct + { + int baseEMSPage; // Base EMS page for this phys frame + dword lastHit; // Last frame number of hit + } EMSListStruct; + +// Main Mem specific variables +typedef struct +{ + boolean MainPresent; + memptr MainMemPages[PMMaxMainMem]; + PMBlockAttr MainMemUsed[PMMaxMainMem]; + int MainPagesAvail; +} pm_mmi_t; + +// EMS specific variables +typedef struct +{ + boolean EMSPresent; + unsigned int EMSVer; + word EMSAvail,EMSPagesAvail,EMSHandle, + EMSPageFrame,EMSPhysicalPage; + word totalEMSpages, freeEMSpages, EMSpagesmapped; + EMSListStruct EMSList[EMSFrameCount]; +} pm_emmi_t; + +// XMS specific variables +typedef struct +{ + boolean XMSPresent; + word XMSAvail,XMSPagesAvail,XMSHandle;//,XMSVer; + dword XMSDriver; + int XMSProtectPage;// = -1; +} pm_xmmi_t; + +// File specific variables +typedef struct +{ + char PageFileName[13];// = {"VSWAP."}; + int PageFile;// = -1; + word ChunksInFile; + word PMSpriteStart,PMSoundStart; +} pm_fi_t; + +// General usage variables +typedef struct +{ + boolean PMStarted, + PMPanicMode, + PMThrashing; + word XMSPagesUsed, + EMSPagesUsed, + MainPagesUsed, + PMNumBlocks; + long PMFrameCount; + PageListStruct far *PMPages; + __SEGA *PMSegPages; + pm_mmi_t mm; + pm_emmi_t emm; + pm_xmmi_t xmm; + pm_fi_t fi; +} pm_t; + +//========================================================================== + //from 16_ca //========================================================================== @@ -209,9 +321,9 @@ typedef struct byte ca_levelbit,ca_levelnum; ca_handle_t file; //files to open ca_mapinfo_t camap; - //_seg *grsegs[NUMCHUNKS]; - //byte far grneeded[NUMCHUNKS]; - //huffnode huffnode; + __SEGA *grsegs[NUMCHUNKS]; + byte far grneeded[NUMCHUNKS]; + huffnode huffnode; } ca_t; //========================================================================== @@ -221,6 +333,7 @@ typedef struct { video_t video; // video settings variable ca_t ca; // ca stuff + pm_t pm; // pm stuff byte *pee; // message for fps loghandle_t handle; //handles for file logging kurokku_t kurokku; //clock struct diff --git a/src/lib/types.h b/src/lib/types.h index 9d0e7b3b..884aaea9 100755 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -57,4 +57,7 @@ typedef void _seg * memptr; #define __SEGA _seg #endif +#define _argv __argv +#define _argc __argc + #endif/*_TYPE_H_*/ diff --git a/src/lib/xms.c b/src/lib/xms.c index 1781754f..7464a32f 100755 --- a/src/lib/xms.c +++ b/src/lib/xms.c @@ -1,187 +1,187 @@ -/* 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. + * 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; +}*/ diff --git a/src/lib/xms.h b/src/lib/xms.h index b6587494..b1bdb012 100755 --- a/src/lib/xms.h +++ b/src/lib/xms.h @@ -1,28 +1,28 @@ -#ifndef _XMS_H_ -#define _XMS_H_ -#include /* Definition of NULL */ -#include /* Definition of UINT_MAX */ -#include /* 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_ +#define _XMS_H_ +#include /* Definition of NULL */ +#include /* Definition of UINT_MAX */ +#include /* 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_*/ diff --git a/src/lib/zcroll16.c b/src/lib/zcroll16.c new file mode 100755 index 00000000..12a5ee1b --- /dev/null +++ b/src/lib/zcroll16.c @@ -0,0 +1,360 @@ +/* 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 , 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; +} diff --git a/src/lib/zcroll16.h b/src/lib/zcroll16.h new file mode 100755 index 00000000..6f663429 --- /dev/null +++ b/src/lib/zcroll16.h @@ -0,0 +1,116 @@ +/* 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 , 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 +#include +#include +#include + +#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_*/ diff --git a/src/midi.c b/src/midi.c index e36a8532..04126d4e 100755 --- a/src/midi.c +++ b/src/midi.c @@ -1,870 +1,870 @@ -/* 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. - * - * - * Compiles for intended target environments: - * - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box] - */ - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#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 + * + * 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. + * + * + * Compiles for intended target environments: + * - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box] + */ + +#include +#include /* this is where Open Watcom hides the outp() etc. functions */ +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/src/miditest.c b/src/miditest.c index 73b47057..ade69519 100755 --- a/src/miditest.c +++ b/src/miditest.c @@ -1,112 +1,112 @@ -/* 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. - * - * - * 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 + * + * 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. + * + * + * 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; +} diff --git a/src/scroll.c b/src/scroll.c index 2746ca4f..e638df1b 100755 --- a/src/scroll.c +++ b/src/scroll.c @@ -1,368 +1,368 @@ -/* 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 , 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;idata, 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~ + * 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 , 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;idata, 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 +} diff --git a/src/testemm.c b/src/testemm.c index b78f449e..40a2ac41 100755 --- a/src/testemm.c +++ b/src/testemm.c @@ -1,275 +1,275 @@ -/* testemm.c - * - * Test program: Expanded Memory Manager functions - * (C) 2011-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -//#include "src/lib/doslib/cpu.h" -#include "src/lib/doslib/dos.h" -#include "src/lib/doslib/emm.h" -//#include - -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 + * + * Test program: Expanded Memory Manager functions + * (C) 2011-2012 Jonathan Campbell. + * Hackipedia DOS library. + * + * This code is licensed under the LGPL. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +//#include "src/lib/doslib/cpu.h" +#include "src/lib/doslib/dos.h" +#include "src/lib/doslib/emm.h" +//#include + +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; +} + diff --git a/src/testemm0.c b/src/testemm0.c index 16f5654b..a83564e7 100755 --- a/src/testemm0.c +++ b/src/testemm0.c @@ -1,276 +1,276 @@ -/* testemm.c - * - * Test program: Expanded Memory Manager functions - * (C) 2011-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -//#include "src/lib/doslib/cpu.h" -#include "src/lib/doslib/dos.h" -#include "src/lib/doslib/emm.h" -//#include - -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 + * + * Test program: Expanded Memory Manager functions + * (C) 2011-2012 Jonathan Campbell. + * Hackipedia DOS library. + * + * This code is licensed under the LGPL. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +//#include "src/lib/doslib/cpu.h" +#include "src/lib/doslib/dos.h" +#include "src/lib/doslib/emm.h" +//#include + +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; +} diff --git a/src/testsnd.c b/src/testsnd.c index 4c5f6534..43dae78e 100755 --- a/src/testsnd.c +++ b/src/testsnd.c @@ -1,450 +1,450 @@ -/* 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. - * - * - * 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 -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include /* 8254 timer */ -#include -#include -#include - -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 + * + * Adlib OPL2/OPL3 FM synthesizer chipset test program. + * (C) 2010-2012 Jonathan Campbell. + * Hackipedia DOS library. + * + * This code is licensed under the LGPL. + * + * + * 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 +#include /* this is where Open Watcom hides the outp() etc. functions */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include /* 8254 timer */ +#include +#include +#include + +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; +} + diff --git a/src/tesuto.c b/src/tesuto.c index 83f3712e..ab7e2db6 100755 --- a/src/tesuto.c +++ b/src/tesuto.c @@ -1,344 +1,344 @@ -#include -#include -#include -#include - -#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 \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 +#include +#include +#include + +#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 \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; +} diff --git a/src/tesuto.h b/src/tesuto.h index dbe0bfc7..d1f8bbbe 100755 --- a/src/tesuto.h +++ b/src/tesuto.h @@ -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 -#include -#include -#include - -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__ +#define __TESUTO_H__ + +#include "src/lib/16_head.h" +#include "src/lib/modex16.h" +#include "src/lib/16_in.h" +#include +#include +#include +#include + +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 diff --git a/src/tsthimem.c b/src/tsthimem.c index 7476b7ea..245a5335 100755 --- a/src/tsthimem.c +++ b/src/tsthimem.c @@ -1,295 +1,295 @@ -/* tsthimem.c - * - * Test program: HIMEM.SYS functions - * (C) 2010-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include -#include -#include -#include -#include -#include - -//#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 + * + * Test program: HIMEM.SYS functions + * (C) 2010-2012 Jonathan Campbell. + * Hackipedia DOS library. + * + * This code is licensed under the LGPL. + * + */ + +#include +#include +#include +#include +#include +#include + +//#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; +} + diff --git a/src/vrstest.c b/src/vrstest.c index 0e9020d9..cdba1e9b 100755 --- a/src/vrstest.c +++ b/src/vrstest.c @@ -1,177 +1,180 @@ -/* 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 , or - * write to the Free Software Foundation, Inc., 51 Franklin Street, - * Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include -#include -#include -#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.mm, &gvar.mmi); - 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, &gvar.mm); - MM_DumpData(&gvar.mm); - free(spri.sprite_vrl_cont); - MM_FreePtr(&bigbuffer, &gvar.mm); - //MM_FreePtr(&((void __based(sega)*)spri.spritesheet->buffer), &mm); - CA_Shutdown(&gvar); - MM_Shutdown(&gvar.mm); - //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~ + * 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 , 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_tail.h" +#include "src/lib/16_pm.h" +#include "src/lib/16_ca.h" +#include "src/lib/16_mm.h" + +void main() { + static global_game_variables_t gvar; + __segment sega; + memptr bigbuffer; + int i; + word start; + float t1, t2; + boolean baka; + byte *pal; + int size; + 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; + word w=0; + + gvar.mm.mmstarted=0; + dbg_debugpm=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; + } + + //gvar.video.page[0]=modexDefaultPage(&gvar.video.page[0]); + + MM_Startup(&gvar); + PM_Startup(&gvar); + PM_UnlockMainMem(&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); + MM_Report_(&gvar); + free(spri.sprite_vrl_cont); + MM_FreePtr(&bigbuffer, &gvar); + //MM_FreePtr(&((void __based(sega)*)spri.spritesheet->buffer), &mm); + PM_Shutdown(&gvar); + 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); +//0000 printf("gvar.video.page[0].width: %u\n", gvar.video.page[0].width); +//0000 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"); +} diff --git a/src/zcroll.c b/src/zcroll.c index e69de29b..31623367 100755 --- a/src/zcroll.c +++ b/src/zcroll.c @@ -0,0 +1,302 @@ +/* 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 , 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" + +//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,baka=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; + + Startup16(&gvar); + + pan.pn=1; + + /* 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 */ + ptr = map.data; + //mappalptr = map.tiles->btdata->palette; + + /* data */ + if(CA_LoadFile("data/spri/chikyuu.vrs", &(player[0].gr), &gvar)) baka=1; else baka=0; + + /* create the planar buffer */ +////++++ (player[0].data) = *planar_buf_from_bitmap(&p); + /*++++printf("load pee!! "); + pp = planar_buf_from_bitmap(&p); + printf("done!\n");*/ + + /* input! */ + IN_Default(0,&player,ctrl_Joystick); + //IN_Default(1,&player,ctrl_Joystick); + + /* save the palette */ + dpal = modexNewPal(); + modexPalSave(dpal); + modexFadeOff(4, dpal); + + textInit(); + VGAmodeX(bakapee, 1, &gvar); +// printf("%dx%d\n", gvar.video.page[0].sw, gvar.video.page[0].sh); + modexPalBlack(); //reset the palette~ + +// 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"); + + gpal = modexNewPal(); + modexPalSave(gpal); + modexSavePalFile("data/g.pal", gpal); + modexPalBlack(); //so player will not see loadings~ + + /* setup camera and screen~ */ + modexHiganbanaPageSetup(&gvar.video); + for(i=0;idata, 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); + + modexFadeOn(4, gpal); + 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 + 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("2paloffset = %d\n", paloffset/3); + modexpdump(mv[0].page); modexpdump(mv[1].page); + IN_UserInput(1,1); + } + + //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~ */ + modexPalSave(gpal); + modexSavePalFile("data/g.pal", gpal); + modexFadeOff(4, gpal); + VGAmodeX(0, 1, &gvar); + Shutdown16(&gvar); + 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("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); + modexFadeOn(4, dpal); +} diff --git a/test.exe b/test.exe new file mode 100755 index 00000000..c26af169 Binary files /dev/null and b/test.exe differ diff --git a/test0.exe b/test0.exe new file mode 100755 index 00000000..a8a34c97 Binary files /dev/null and b/test0.exe differ diff --git a/vgmtest.exe b/vgmtest.exe new file mode 100755 index 00000000..d4aeea4b Binary files /dev/null and b/vgmtest.exe differ diff --git a/wolf3dpm.png b/wolf3dpm.png new file mode 100755 index 00000000..28444566 Binary files /dev/null and b/wolf3dpm.png differ