/* Copyright (C) 1998 BJ Eirich (aka vecna) 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 Lic 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // CHANGELOG: // // + added ScreenShot() on F11 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #define ENGINE_H #include "verge.h" // ================================= Data ==================================== typedef struct { word start; // strand start word finish; // strand end word delay; // tile-switch delay word mode; // tile-animation mode } vspanim_r; typedef struct { char pmultx,pdivx; // parallax multiplier/divisor for X char pmulty,pdivy; // parallax multiplier/divisor for Y unsigned short sizex, sizey; // layer dimensions. unsigned char trans, hline; // transparency flag | hline (raster fx) } layer_r; typedef struct { char name[40]; // zone name/desc unsigned short script; // script to call thingy unsigned short percent; // chance of executing unsigned short delay; // step-delay unsigned short aaa; // Accept Adjacent Activation unsigned short entityscript; // script to call for entities } zoneinfo; zoneinfo zones[256]; // zone data records layer_r layer[6]; // Array of layer data vspanim_r vspanim[100]; // tile animation data unsigned short vadelay[100]; // Tile animation delay ctr char mapname[60]; // MAP filename char vspname[60]; // VSP filemap char musname[60]; // MAP bkgrd music default filename char rstring[20]; // render-order string char numlayers; // number of layers in map byte *obstruct, *zone; // obstruction and zone buffers char layertoggle[8]; // layer visible toggles word xstart, ystart; // MAP start x/y location int bufsize; // how many bytes need to be written int numzones; // number of active zones word *layers[6]; // Raw layer data int xwin=0, ywin=0; // camera offset // -- vsp data -- byte *vsp=0,*vspmask; // VSP data buffer. unsigned short numtiles; // number of tiles in VSP. unsigned short *tileidx; // tile index thingamajig char *flipped; // bi-direction looping flag // entity stuffs char *msbuf[100]; // ptr-table to script offset char *ms; // script text buffer byte nms; // number of movescripts char numfollowers=0; // number of party followers byte follower[10]; // maximum of 10 followers. char laststeps[10]={ 0 }; // record of last movements int lastent; // -- stuff -- byte movegranularity; // means nothing now, please remove byte movectr=0; byte phantom=0; // walk-through-walls byte speeddemon=0; // doublespeed cheat int bindarray[128]; // bind script offset // ================================= Code ==================================== void ReadCompressedLayer1(byte *dest, int len, char *buf) { int j,n; byte run, w; n=0; do { w=*buf; buf++; if (w==0xFF) { run=*buf; buf++; w=*buf; buf++; for (j=0; jtx, player->ty+1)) return 1; break; case 1: if (ObstructionAt(player->tx, player->ty-1)) return 1; break; case 2: if (ObstructionAt(player->tx-1, player->ty)) return 1; break; case 3: if (ObstructionAt(player->tx+1, player->ty)) return 1; break; } switch (dir) { case 0: if (EntityObsAt(player->tx, player->ty+1)) return 1; break; case 1: if (EntityObsAt(player->tx, player->ty-1)) return 1; break; case 2: if (EntityObsAt(player->tx-1, player->ty)) return 1; break; case 3: if (EntityObsAt(player->tx+1, player->ty)) return 1; break; } return 0; } void CheckZone() { int curzone; static int lz=0, zonedelay=0; curzone=zone[(player->ty * layer[0].sizex) + player->tx]; if (lz!=curzone) { zonedelay=0; lz=curzone; } if (!zones[curzone].percent) return; if (zonedelay < zones[curzone].delay) { zonedelay++; return; } if (curzone) if (zones[curzone].script && zones[curzone].percent >= rnd(0,255)) { ExecuteEvent(zones[curzone].script); zonedelay=0; } } int InvFace() { switch(player -> facing) { case 0: return 1; case 1: return 0; case 2: return 3; case 3: return 2; } return -1; } void Activate() { byte tz; int ax=0, ay=0; switch(player->facing) { case 0: ax=player->tx; ay=player->ty+1; break; case 1: ax=player->tx; ay=player->ty-1; break; case 2: ax=player->tx-1; ay=player->ty; break; case 3: ax=player->tx+1; ay=player->ty; break; } tz=zone[(ay*layer[0].sizex)+ax]; if (zones[tz].aaa) { ExecuteEvent(zones[tz].script); return; } if ((tz=EntityAt(ax, ay))) { tz--; if (entity[tz].face) { entity[tz].facing=InvFace(); AnimateEntity(&entity[tz]); } if (entity[tz].actscript) { lastent=tz; ExecuteEvent(entity[tz].actscript); } } } void ResetFollowers() { int i; player->x=player->tx<<4; player->y=player->ty<<4; player->moving=0; player->movecnt=0; player->reset=1; for (i=0; ix; entity[follower[i]].y=player->y; entity[follower[i]].tx=player->tx; entity[follower[i]].ty=player->ty; entity[follower[i]].facing=player->facing; entity[follower[i]].reset=1; } memset(laststeps, 0, 10); } void MoveFollowers() { int i; for (i=0; ianimofs=chr[player->chrindex].uanim; entity[follower[i]].delayct=0; entity[follower[i]].reset=0; } entity[follower[i]].facing=laststeps[i+1]-1; } } //--- zero 5.7.99 void WritePalette(FILE *f) { char b; int i; byte pal3[768]; for (i=0; i<768; i++) pal3[i]=pal2[i] << 2; b=12; fwrite(&b, 1, 1, f); fwrite(pal3, 1, 768, f); } void WritePCXLine(unsigned char *p,int len,FILE *pcxf) { int i; unsigned char byt, samect, repcode; i=0; do { byt=p[i++]; samect=1; while (samect<(unsigned) 63 && i1 || (byt & 0xC0) != 0) { repcode=0xC0 | samect; fwrite(&repcode,1,1,pcxf); } fwrite(&byt,1,1,pcxf); } while (i16 colors b1=1; fwrite(&b1, 1, 1, pcxf); // encoding always = 1 b1=8; fwrite(&b1, 1, 1, pcxf); // 8 bits per pixel, for 256 colors w1=0; fwrite(&w1, 1, 2, pcxf); // xmin = 0; w1=0; fwrite(&w1, 1, 2, pcxf); // ymin = 0; w1=sx-1; fwrite(&w1, 1, 2, pcxf); // xmax = 319; w1=sy-1; fwrite(&w1, 1, 2, pcxf); // ymax = 199; w1=sx; fwrite(&w1, 1, 2, pcxf); // hres = 320; w1=sy; fwrite(&w1, 1, 2, pcxf); // vres = 200; fwrite(screen,1,48,pcxf); b1=0; fwrite(&b1, 1, 1, pcxf); // reserved always = 0. b1=1; fwrite(&b1, 1, 1, pcxf); // number of color planes. Just 1 for 8bit. w1=sx; fwrite(&w1, 1, 2, pcxf); // number of bytes per line w1=0; fwrite(&w1, 1, 1, pcxf); fwrite(screen, 1, 59, pcxf); // filler for (w1=0; w1moving) { if (down && !PlayerObstructed(0)) { player->ty++; player->moving=1; player->movecnt=15; player->y++; if (player->reset || player->facing != 0) { player->animofs=chr[player->chrindex].danim; player->delayct=0; player->reset=0; } player->facing=0; LastMove(1); return; } if (up && !PlayerObstructed(1)) { player->ty--; player->moving=2; player->movecnt=15; player->y--; if (player->reset || player->facing != 1) { player->animofs=chr[player->chrindex].uanim; player->delayct=0; player->reset=0; } player->facing=1; LastMove(2); return; } if (left && !PlayerObstructed(2)) { player->tx--; player->moving=3; player->movecnt=15; player->x--; if (player->reset || player->facing != 2) { player->animofs=chr[player->chrindex].lanim; player->delayct=0; player->reset=0; } player->facing=2; LastMove(3); return; } if (right && !PlayerObstructed(3)) { player->tx++; player->moving=4; player->movecnt=15; player->x++; if (player->reset || player->facing != 3) { player->animofs=chr[player->chrindex].ranim; player->delayct=0; player->reset=0; } player->facing=3; LastMove(4); return; } if (down) player->facing=0; if (up) player->facing=1; if (left) player->facing=2; if (right) player->facing=3; } switch (player->moving) { case 0: player->reset=1; player->animofs=0; player->delayct=0; break; case 1: player->y++; player->movecnt--; break; case 2: player->y--; player->movecnt--; break; case 3: player->x--; player->movecnt--; break; case 4: player->x++; player->movecnt--; break; } if (!player->movecnt && player->moving) { player->moving=0; CheckZone(); } if (!player->movecnt && b1) Activate(); } void ProcessControls() { int i; if (key[SCAN_RQUOTA]) { key[SCAN_RQUOTA]=0; last_pressed=0; ActivateConsole(); } if (key[SCAN_ALT] && key[SCAN_X]) err("Exiting: ALT-X pressed."); //--- zero 5.7.99 if (key[SCAN_F11]) { Message("ss",50); ScreenShot(); key[SCAN_F11]=0; } //--- if (!player) return; if (player->speed<4) { switch (player->speed) { case 1: if (player->speedct<3) { player->speedct++; return; } break; case 2: if (player->speedct<2) { player->speedct++; return; } break; case 3: if (player->speedct<1) { player->speedct++; return; } break; } } if (player->speed<5) { ProcessControls1(); player->speedct=0; AnimateEntity(player); } switch (player->speed) { case 5: for (i=0; i<2; i++) { ProcessControls1(); AnimateEntity(player); } return; case 6: for (i=0; i<3; i++) { ProcessControls1(); AnimateEntity(player); } return; case 7: for (i=0; i<4; i++) { ProcessControls1(); AnimateEntity(player); } return; } } void GameTick() { UpdateControls(); CheckMessages(); if (bindarray[last_pressed]) HookKey(bindarray[last_pressed]); ProcessControls(); if (speeddemon && key[SCAN_CTRL]) ProcessControls(); ProcessEntities(); }