]> 4ch.mooo.com Git - 16.git/blobdiff - 16/keen456/KEEN4-6/CK_STATE.C
added keen 4-6 rebuild code for reference.... i need to stop doing this... xD
[16.git] / 16 / keen456 / KEEN4-6 / CK_STATE.C
diff --git a/16/keen456/KEEN4-6/CK_STATE.C b/16/keen456/KEEN4-6/CK_STATE.C
deleted file mode 100755 (executable)
index 25d3be6..0000000
+++ /dev/null
@@ -1,1968 +0,0 @@
-/* Reconstructed Commander Keen 4-6 Source Code\r
- * Copyright (C) 2021 K1n9_Duk3\r
- *\r
- * This file is loosely based on:\r
- * Keen Dreams Source Code\r
- * Copyright (C) 2014 Javier M. Chavez\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License along\r
- * with this program; if not, write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
- */\r
-\r
-#include "CK_DEF.H"\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                GLOBAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-Sint16 wallclip[8][16] = {                     // the height of a given point in a tile\r
-{ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256},\r
-{   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0},\r
-{   0,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78},\r
-{0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8,0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8},\r
-{   0,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0},\r
-{0x78,0x70,0x68,0x60,0x58,0x50,0x48,0x40,0x38,0x30,0x28,0x20,0x18,0x10,0x08,   0},\r
-{0xf8,0xf0,0xe8,0xe0,0xd8,0xd0,0xc8,0xc0,0xb8,0xb0,0xa8,0xa0,0x98,0x90,0x88,0x80},\r
-{0xf0,0xe0,0xd0,0xc0,0xb0,0xa0,0x90,0x80,0x70,0x60,0x50,0x40,0x30,0x20,0x10,   0}\r
-};\r
-\r
-Sint16 xtry, ytry;\r
-boolean playerkludgeclipcancel;\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                LOCAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-Uint16 oldtileleft, oldtiletop, oldtileright, oldtilebottom, oldtilemidx;\r
-Uint16 oldleft, oldtop, oldright, oldbottom, oldmidx;\r
-Sint16 leftmoved, topmoved, rightmoved, bottommoved, midxmoved;\r
-\r
-//==========================================================================\r
-\r
-/*\r
-====================\r
-=\r
-= MoveObjVert\r
-=\r
-====================\r
-*/\r
-\r
-void MoveObjVert(objtype *ob, Sint16 ymove)\r
-{\r
-       ob->y += ymove;\r
-       ob->top += ymove;\r
-       ob->bottom += ymove;\r
-       ob->tiletop = CONVERT_GLOBAL_TO_TILE(ob->top);\r
-       ob->tilebottom = CONVERT_GLOBAL_TO_TILE(ob->bottom);\r
-}\r
-\r
-/*\r
-====================\r
-=\r
-= MoveObjHoriz\r
-=\r
-====================\r
-*/\r
-\r
-void MoveObjHoriz(objtype *ob, Sint16 xmove)\r
-{\r
-       //BUG? ob->midx is not adjusted in Keen 4 & 5\r
-       ob->x += xmove;\r
-       ob->left += xmove;\r
-       ob->right += xmove;\r
-#ifdef KEEN6\r
-       ob->midx += xmove;      //BUG? ob->tilemidx is not updated\r
-#endif\r
-       ob->tileleft = CONVERT_GLOBAL_TO_TILE(ob->left);\r
-       ob->tileright = CONVERT_GLOBAL_TO_TILE(ob->right);\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-====================\r
-=\r
-= PlayerBottomKludge\r
-=\r
-====================\r
-*/\r
-\r
-void PlayerBottomKludge(objtype *ob)\r
-{\r
-       Uint16 far *map;\r
-       Uint16 wall, clip, xpix;\r
-       Sint16 xmove, ymove;\r
-\r
-       map = (Uint16 far *)mapsegs[1] + mapbwidthtable[ob->tilebottom-1]/2;\r
-       if (ob->xdir == 1)\r
-       {\r
-               xpix = 0;\r
-               map += ob->tileright;\r
-               xmove = ob->right - ob->midx;\r
-               if (tinf[*(map-mapwidth)+WESTWALL] || tinf[*map+WESTWALL])\r
-               {\r
-                       return;\r
-               }\r
-       }\r
-       else\r
-       {\r
-               xpix = 15;\r
-               map += ob->tileleft;\r
-               xmove = ob->left - ob->midx;\r
-               if (tinf[*(map-mapwidth)+EASTWALL] || tinf[*map+EASTWALL])\r
-               {\r
-                       return;\r
-               }\r
-       }\r
-       if ((_AX = tinf[*map+NORTHWALL]) != 0)  // the _AX = ... part is just to recreate the original code's quirks, feel free to delete this\r
-       {\r
-               return;\r
-       }\r
-       map += mapwidth;\r
-       if ((wall = tinf[*map+NORTHWALL]) != 1)\r
-       {\r
-               return;\r
-       }\r
-       clip = wallclip[wall&7][xpix];\r
-       ymove = CONVERT_TILE_TO_GLOBAL(ob->tilebottom) + clip - 1 -ob->bottom;\r
-       if (ymove <= 0 && ymove >= -bottommoved)\r
-       {\r
-               ob->hitnorth = wall;\r
-               MoveObjVert(ob, ymove);\r
-               MoveObjHoriz(ob, xmove);\r
-       }\r
-}\r
-\r
-/*\r
-====================\r
-=\r
-= PlayerTopKludge\r
-=\r
-====================\r
-*/\r
-\r
-void PlayerTopKludge(objtype *ob)\r
-{\r
-       Uint16 far *map;\r
-       Uint16 xpix, wall, clip;\r
-       Sint16 move;\r
-\r
-       map = (Uint16 far *)mapsegs[1] + mapbwidthtable[ob->tiletop+1]/2;\r
-       if (ob->xdir == 1)\r
-       {\r
-               xpix = 0;\r
-               map += ob->tileright;\r
-               if (tinf[*(map+mapwidth)+WESTWALL] || tinf[*(map+2*mapwidth)+WESTWALL])\r
-               {\r
-                       return;\r
-               }\r
-       }\r
-       else\r
-       {\r
-               xpix = 15;\r
-               map += ob->tileleft;\r
-               if (tinf[*(map+mapwidth)+EASTWALL] || tinf[*(map+2*mapwidth)+EASTWALL])\r
-               {\r
-                       return;\r
-               }\r
-       }\r
-       if ((_AX = tinf[*map+SOUTHWALL]) != 0)  // the _AX = ... part is just to recreate the original code's quirks, feel free to delete this\r
-       {\r
-               return;\r
-       }\r
-       map -= mapwidth;\r
-       if ((wall = tinf[*map+SOUTHWALL]) != 0)\r
-       {\r
-               clip = wallclip[wall&7][xpix];\r
-               move = CONVERT_TILE_TO_GLOBAL(ob->tiletop+1) - clip - ob->top;\r
-               if (move >= 0 && move <= -topmoved)\r
-               {\r
-                       ob->hitsouth = wall;\r
-                       MoveObjVert(ob, move);\r
-               }\r
-       }\r
-}\r
-\r
-/*\r
-===========================\r
-=\r
-= ClipToEnds\r
-=\r
-===========================\r
-*/\r
-\r
-void ClipToEnds(objtype *ob)\r
-{\r
-       Uint16 far *map;\r
-       Uint16 wall, y, clip;\r
-       Sint16 totalmove, maxmove, move;\r
-       Uint16 midxpix;\r
-       \r
-       midxpix = CONVERT_GLOBAL_TO_PIXEL(ob->midx & 0xF0);\r
-       maxmove = -abs(midxmoved)-bottommoved-16;\r
-       map = (Uint16 far *)mapsegs[1] + (mapbwidthtable-1)[oldtilebottom]/2 + ob->tilemidx;\r
-       for (y=oldtilebottom-1; y <= ob->tilebottom; y++,map+=mapwidth)\r
-       {\r
-               if ((wall = tinf[*map + NORTHWALL]) != 0)\r
-               {\r
-                       clip = wallclip[wall&7][midxpix];\r
-                       move = (CONVERT_TILE_TO_GLOBAL(y) + clip)-1-ob->bottom;\r
-                       if (move < 0 && move >= maxmove)\r
-                       {\r
-                               ob->hitnorth = wall;\r
-                               MoveObjVert(ob, move);\r
-                               return;\r
-                       }\r
-               }\r
-       }\r
-       maxmove = abs(midxmoved)-topmoved+16;\r
-       map = (Uint16 far *)mapsegs[1] + (mapbwidthtable+1)[oldtiletop]/2 + ob->tilemidx;\r
-       for (y=oldtiletop+1; y >= ob->tiletop; y--,map-=mapwidth)       // BUG: unsigned comparison - loop never ends if ob->tiletop is 0\r
-       {\r
-               if ((wall = tinf[*map + SOUTHWALL]) != 0)\r
-               {\r
-                       clip = wallclip[wall&7][midxpix];\r
-                       move = CONVERT_TILE_TO_GLOBAL(y+1) - clip - ob->top;\r
-                       if (move > 0 && move <= maxmove)\r
-                       {\r
-                               totalmove = ytry+move;\r
-                               if (totalmove < 0x100 && totalmove > -0x100)\r
-                               {\r
-                                       ob->hitsouth = wall;\r
-                                       MoveObjVert(ob, move);\r
-                                       //BUG? no return here\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-/*\r
-===========================\r
-=\r
-= ClipToSides\r
-=\r
-===========================\r
-*/\r
-\r
-void ClipToSides(objtype *ob)\r
-{\r
-       Sint16 move, y, top, bottom;\r
-       Uint16 far *map;\r
-       \r
-       top = ob->tiletop;\r
-       if (ob->hitsouth > 1)\r
-       {\r
-               top++;\r
-       }\r
-       bottom = ob->tilebottom;\r
-       if (ob->hitnorth > 1)\r
-       {\r
-               bottom--;\r
-       }\r
-       for (y=top; y<=bottom; y++)\r
-       {\r
-               map = (Uint16 far *)mapsegs[1] + mapbwidthtable[y]/2 + ob->tileleft;\r
-               if ((ob->hiteast = tinf[*map+EASTWALL]) != 0)\r
-               {\r
-                       move = CONVERT_TILE_TO_GLOBAL(ob->tileleft+1) - ob->left;\r
-                       MoveObjHoriz(ob, move);\r
-                       return;\r
-               }\r
-       }\r
-       for (y=top; y<=bottom; y++)\r
-       {\r
-               map = (Uint16 far *)mapsegs[1] + mapbwidthtable[y]/2 + ob->tileright;\r
-               if ((ob->hitwest = tinf[*map+WESTWALL]) != 0)\r
-               {\r
-                       move = (CONVERT_TILE_TO_GLOBAL(ob->tileright)-1)-ob->right;\r
-                       MoveObjHoriz(ob, move);\r
-                       return;\r
-               }\r
-       }\r
-}\r
-\r
-/*\r
-===========================\r
-=\r
-= CheckPosition\r
-=\r
-===========================\r
-*/\r
-\r
-boolean CheckPosition(objtype *ob)\r
-{\r
-#ifdef KEEN6Ev15\r
-       // This version is pretty much a compiler-optimized version of the other\r
-       // version below, but I simply could not get the compiler to optimize it\r
-       // in exactly the same way.\r
-\r
-       Uint16 tile, x, tileright;\r
-       Uint16 far *map;\r
-       Uint16 rowdiff;\r
-       Uint16 tileleft, y, tilebottom;\r
-       \r
-       map = (Uint16 far *)mapsegs[1] + mapbwidthtable[ob->tiletop]/2 + ob->tileleft;\r
-       rowdiff = mapwidth-(ob->tileright-ob->tileleft+1);\r
-\r
-       y = ob->tiletop;\r
-       tileleft = ob->tileleft;\r
-       tileright = _AX = ob->tileright;\r
-       tilebottom = ob->tilebottom;\r
-\r
-       for (; tilebottom>=y; y++,map+=rowdiff)\r
-       {\r
-               for (x=tileleft; tileright>=x; x++)\r
-               {\r
-                       tile = *(map++);\r
-                       if (tinf[tile+NORTHWALL] || tinf[tile+EASTWALL] || tinf[tile+SOUTHWALL] || tinf[tile+WESTWALL])\r
-                       {\r
-                               return false;\r
-                       }\r
-               }\r
-       }\r
-       return true;\r
-#else\r
-       Uint16 tile, x, y;\r
-       Uint16 far *map;\r
-       Uint16 rowdiff;\r
-       \r
-       map = (Uint16 far *)mapsegs[1] + mapbwidthtable[ob->tiletop]/2 + ob->tileleft;\r
-       rowdiff = mapwidth-(ob->tileright-ob->tileleft+1);\r
-       for (y=ob->tiletop; y<=ob->tilebottom; y++,map+=rowdiff)\r
-       {\r
-               for (x=ob->tileleft; x<=ob->tileright; x++)\r
-               {\r
-                       tile = *(map++);\r
-                       if (tinf[tile+NORTHWALL] || tinf[tile+EASTWALL] || tinf[tile+SOUTHWALL] || tinf[tile+WESTWALL])\r
-                       {\r
-                               return false;\r
-                       }\r
-               }\r
-       }\r
-       return true;\r
-#endif\r
-}\r
-\r
-/*\r
-===========================\r
-=\r
-= StatePositionOk\r
-=\r
-===========================\r
-*/\r
-\r
-boolean StatePositionOk(objtype *ob, statetype *state)\r
-{\r
-       spritetabletype far *shape;\r
-\r
-       if (ob->xdir > 0)\r
-       {\r
-               ob->shapenum = state->rightshapenum;\r
-       }\r
-       else\r
-       {\r
-               ob->shapenum = state->leftshapenum;\r
-       }\r
-       shape = &spritetable[ob->shapenum-STARTSPRITES];\r
-       ob->left = ob->x + shape->xl;\r
-       ob->right = ob->x + shape->xh;\r
-       ob->top = ob->y + shape->yl;\r
-       ob->bottom = ob->y + shape->yh;\r
-       ob->midx = ob->left + (ob->right-ob->left)/2;\r
-       ob->tileleft = CONVERT_GLOBAL_TO_TILE(ob->left);\r
-       ob->tileright = CONVERT_GLOBAL_TO_TILE(ob->right);\r
-       ob->tiletop = CONVERT_GLOBAL_TO_TILE(ob->top);\r
-       ob->tilebottom = CONVERT_GLOBAL_TO_TILE(ob->bottom);\r
-       ob->tilemidx = CONVERT_GLOBAL_TO_TILE(ob->midx);\r
-       return CheckPosition(ob);\r
-}\r
-\r
-#ifdef KEEN5\r
-/*\r
-===========================\r
-=\r
-= CalcBounds\r
-=\r
-===========================\r
-*/\r
-\r
-void CalcBounds(objtype *ob)   //not present in Keen 4 & 6\r
-{\r
-       spritetabletype far *shape;\r
-\r
-       shape = &spritetable[ob->shapenum-STARTSPRITES];\r
-       ob->left = ob->x + shape->xl;\r
-       ob->right = ob->x + shape->xh;\r
-       ob->top = ob->y + shape->yl;\r
-       ob->bottom = ob->y + shape->yh;\r
-       ob->midx = ob->left + (ob->right-ob->left)/2;\r
-}\r
-#endif\r
-\r
-//==========================================================================\r
-\r
-/*\r
-================\r
-=\r
-= ClipToWalls\r
-=\r
-= Moves the current object xtry/ytry units, clipping to walls\r
-=\r
-================\r
-*/\r
-\r
-void ClipToWalls(objtype *ob)\r
-{\r
-       Uint16 oldx, oldy;\r
-#ifdef KEEN6\r
-       Uint16 y;\r
-#endif\r
-       spritetabletype far *shape;\r
-       boolean pushed;\r
-\r
-       oldx = ob->x;\r
-       oldy = ob->y;\r
-       pushed = false;\r
-\r
-//\r
-// make sure it stays in contact with a 45 degree slope\r
-//\r
-       if (ob->state->pushtofloor)\r
-       {\r
-               if (ob->hitnorth == 25)\r
-               {\r
-                       ytry = 145;\r
-               }\r
-               else\r
-               {\r
-                       if (xtry > 0)\r
-                       {\r
-                               ytry = xtry+16;\r
-                       }\r
-                       else\r
-                       {\r
-                               ytry = -xtry+16;\r
-                       }\r
-                       pushed = true;\r
-               }\r
-       }\r
-\r
-//\r
-// move the shape\r
-//\r
-       if (xtry > 239)\r
-       {\r
-               xtry = 239;\r
-       }\r
-       else if (xtry < -239)\r
-       {\r
-               xtry = -239;\r
-       }\r
-       if (ytry > 255)                 // +16 for push to floor\r
-       {\r
-               ytry = 255;\r
-       }\r
-       else if (ytry < -239)\r
-       {\r
-               ytry = -239;\r
-       }\r
-\r
-       ob->x += xtry;\r
-       ob->y += ytry;\r
-\r
-       ob->needtoreact = true;\r
-\r
-       if (!ob->shapenum)                              // can't get a hit rect with no shape!\r
-       {\r
-               return;\r
-       }\r
-\r
-       shape = &spritetable[ob->shapenum-STARTSPRITES];\r
-\r
-       oldtileright = ob->tileright;\r
-       oldtiletop = ob->tiletop;\r
-       oldtileleft = ob->tileleft;\r
-       oldtilebottom = ob->tilebottom;\r
-       oldtilemidx = ob->tilemidx;\r
-\r
-       oldright = ob->right;\r
-       oldtop = ob->top;\r
-       oldleft = ob->left;\r
-       oldbottom = ob->bottom;\r
-       oldmidx = ob->midx;\r
-\r
-       ob->left = ob->x + shape->xl;\r
-       ob->right = ob->x + shape->xh;\r
-       ob->top = ob->y + shape->yl;\r
-       ob->bottom = ob->y + shape->yh;\r
-       ob->midx = ob->left + (ob->right-ob->left)/2;\r
-\r
-       ob->tileleft = CONVERT_GLOBAL_TO_TILE(ob->left);\r
-       ob->tileright = CONVERT_GLOBAL_TO_TILE(ob->right);\r
-       ob->tiletop = CONVERT_GLOBAL_TO_TILE(ob->top);\r
-       ob->tilebottom = CONVERT_GLOBAL_TO_TILE(ob->bottom);\r
-       ob->tilemidx = CONVERT_GLOBAL_TO_TILE(ob->midx);\r
-\r
-       ob->hitnorth=ob->hiteast=ob->hitsouth=ob->hitwest=0;\r
-\r
-       if (ob->needtoclip)\r
-       {\r
-               leftmoved = ob->left - oldleft;\r
-               rightmoved = ob->right - oldright;\r
-               topmoved = ob->top - oldtop;\r
-               bottommoved = ob->bottom - oldbottom;\r
-               midxmoved = ob->midx - oldmidx;\r
-\r
-       //\r
-       // clip it\r
-       //\r
-               ClipToEnds(ob);\r
-\r
-               if (ob == player && !playerkludgeclipcancel)    // zero tolerance near the edge when player gets pushed!\r
-               {\r
-                       if (!ob->hitnorth && bottommoved > 0)\r
-                       {\r
-                               PlayerBottomKludge(ob);\r
-                       }\r
-                       if (!ob->hitsouth && topmoved < 0)\r
-                       {\r
-                               PlayerTopKludge(ob);\r
-                       }\r
-               }\r
-               ClipToSides(ob);\r
-\r
-#ifdef KEEN6\r
-               //\r
-               // special hack to prevent player from getting stuck on slopes?\r
-               //\r
-               if (ob == player && (ob->hitnorth & 7) > 1 && (ob->hiteast || ob->hitwest))\r
-               {\r
-                       Uint16 far *map;\r
-                       Uint16 pixx, clip, move;\r
-                       Uint16 wall;\r
-\r
-                       pixx = CONVERT_GLOBAL_TO_PIXEL(ob->midx & (15*PIXGLOBAL));\r
-                       map = (Uint16 far *)mapsegs[1] + mapbwidthtable[oldtilebottom]/2 + ob->tilemidx;\r
-\r
-                       for (y=oldtilebottom; ob->tilebottom+1 >= y; y++, map+=mapwidth)\r
-                       {\r
-                               if ((wall = tinf[*map + NORTHWALL]) != 0)\r
-                               {\r
-                                       clip = wallclip[wall & 7][pixx];\r
-                                       move = CONVERT_TILE_TO_GLOBAL(y) + clip - 1 - ob->bottom;\r
-                                       ob->hitnorth = wall;\r
-                                       MoveObjVert(ob, move);\r
-                                       return;\r
-                               }\r
-                       }\r
-               }\r
-#endif\r
-       }\r
-       if (pushed && !ob->hitnorth)\r
-       {\r
-               ob->y = oldy;\r
-               ob->x = oldx + xtry;\r
-\r
-               ob->left = ob->x + shape->xl;\r
-               ob->right = ob->x + shape->xh;\r
-               ob->top = ob->y + shape->yl;\r
-               ob->bottom = ob->y + shape->yh;\r
-               ob->midx = ob->left + (ob->right-ob->left)/2;\r
-\r
-               ob->tileleft = CONVERT_GLOBAL_TO_TILE(ob->left);\r
-               ob->tileright = CONVERT_GLOBAL_TO_TILE(ob->right);\r
-               ob->tiletop = CONVERT_GLOBAL_TO_TILE(ob->top);\r
-               ob->tilebottom = CONVERT_GLOBAL_TO_TILE(ob->bottom);\r
-               ob->tilemidx = CONVERT_GLOBAL_TO_TILE(ob->midx);\r
-       }\r
-\r
-       ob->xmove = ob->xmove + (ob->x - oldx);\r
-       ob->ymove = ob->ymove + (ob->y - oldy);\r
-}\r
-\r
-/*\r
-================\r
-=\r
-= FullClipToWalls\r
-=\r
-= Moves the current object xtry/ytry units, clipping to walls\r
-=\r
-================\r
-*/\r
-\r
-void FullClipToWalls(objtype *ob)\r
-{\r
-       Uint16 oldx, oldy, w, h;\r
-       spritetabletype far *shape;\r
-\r
-       oldx = ob->x;\r
-       oldy = ob->y;\r
-\r
-//\r
-// move the shape\r
-//\r
-       if (xtry > 239)\r
-       {\r
-               xtry = 239;\r
-       }\r
-       else if (xtry < -239)\r
-       {\r
-               xtry = -239;\r
-       }\r
-       if (ytry > 239)\r
-       {\r
-               ytry = 239;\r
-       }\r
-       else if (ytry < -239)\r
-       {\r
-               ytry = -239;\r
-       }\r
-\r
-       ob->x += xtry;\r
-       ob->y += ytry;\r
-\r
-       ob->needtoreact = true;\r
-\r
-       shape = &spritetable[ob->shapenum-STARTSPRITES];\r
-\r
-       switch (ob->obclass)\r
-       {\r
-#if defined KEEN4\r
-       case keenobj:\r
-               w = 40*PIXGLOBAL;\r
-               h = 24*PIXGLOBAL;\r
-               break;\r
-       case eggbirdobj:\r
-               w = 64*PIXGLOBAL;\r
-               h = 32*PIXGLOBAL;\r
-               break;\r
-       case dopefishobj:\r
-               w = 88*PIXGLOBAL;\r
-               h = 64*PIXGLOBAL;\r
-               break;\r
-       case schoolfishobj:\r
-               w = 16*PIXGLOBAL;\r
-               h = 8*PIXGLOBAL;\r
-               break;\r
-#elif defined KEEN5\r
-       case slicestarobj:\r
-       case spherefulobj:\r
-               w = h = 32*PIXGLOBAL;\r
-               break;\r
-#elif defined KEEN6\r
-       case blorbobj:\r
-               w = h = 32*PIXGLOBAL;\r
-               break;\r
-#endif\r
-\r
-       default:\r
-               Quit("FullClipToWalls: Bad obclass");\r
-               break;\r
-       }\r
-\r
-       ob->right = ob->x + w;\r
-       ob->left = ob->x;\r
-       ob->top = ob->y;\r
-       ob->bottom = ob->y + h;\r
-\r
-       ob->tileleft = CONVERT_GLOBAL_TO_TILE(ob->left);\r
-       ob->tileright = CONVERT_GLOBAL_TO_TILE(ob->right);\r
-       ob->tiletop = CONVERT_GLOBAL_TO_TILE(ob->top);\r
-       ob->tilebottom = CONVERT_GLOBAL_TO_TILE(ob->bottom);\r
-\r
-       ob->hitnorth=ob->hiteast=ob->hitsouth=ob->hitwest=0;\r
-\r
-//\r
-// clip it\r
-//\r
-       if (!CheckPosition(ob))\r
-       {\r
-               MoveObjHoriz(ob, -xtry);        //undo x movement\r
-               if (CheckPosition(ob))\r
-               {\r
-                       if (xtry > 0)\r
-                       {\r
-                               ob->hitwest = 1;\r
-                       }\r
-                       else\r
-                       {\r
-                               ob->hiteast = 1;\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       if (ytry > 0)\r
-                       {\r
-                               ob->hitnorth = 1;\r
-                       }\r
-                       else\r
-                       {\r
-                               ob->hitsouth = 1;\r
-                       }\r
-                       MoveObjHoriz(ob, xtry); //redo x movement\r
-                       MoveObjVert(ob, -ytry); //undo y movement\r
-                       if (!CheckPosition(ob))\r
-                       {\r
-                               MoveObjHoriz(ob, -xtry);        //undo x movement\r
-                               if (xtry > 0)\r
-                               {\r
-                                       ob->hitwest = 1;\r
-                               }\r
-                               else\r
-                               {\r
-                                       ob->hiteast = 1;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-       ob->xmove = ob->xmove + (ob->x - oldx);\r
-       ob->ymove = ob->ymove + (ob->y - oldy);\r
-\r
-       ob->left = ob->x + shape->xl;\r
-       ob->right = ob->x + shape->xh;\r
-       ob->top = ob->y + shape->yl;\r
-       ob->bottom = ob->y + shape->yh;\r
-       ob->midx = ob->left + (ob->right-ob->left)/2;\r
-}\r
-\r
-/*\r
-================\r
-=\r
-= PushObj\r
-=\r
-= Moves the current object xtry/ytry units, clipping to walls\r
-=\r
-================\r
-*/\r
-\r
-void PushObj(objtype *ob)\r
-{\r
-       Uint16 oldx, oldy;\r
-       spritetabletype far *shape;\r
-       \r
-       oldx = ob->x;\r
-       oldy = ob->y;\r
-\r
-//\r
-// move the shape\r
-//\r
-       ob->x += xtry;\r
-       ob->y += ytry;\r
-\r
-       ob->needtoreact = true;\r
-\r
-       if (!ob->shapenum)                              // can't get a hit rect with no shape!\r
-       {\r
-               return;\r
-       }\r
-\r
-       shape = &spritetable[ob->shapenum-STARTSPRITES];\r
-\r
-       oldtileright = ob->tileright;\r
-       oldtiletop = ob->tiletop;\r
-       oldtileleft = ob->tileleft;\r
-       oldtilebottom = ob->tilebottom;\r
-       oldtilemidx = ob->tilemidx;\r
-\r
-       oldright = ob->right;\r
-       oldtop = ob->top;\r
-       oldleft = ob->left;\r
-       oldbottom = ob->bottom;\r
-       oldmidx = ob->midx;\r
-\r
-       ob->left = ob->x + shape->xl;\r
-       ob->right = ob->x + shape->xh;\r
-       ob->top = ob->y + shape->yl;\r
-       ob->bottom = ob->y + shape->yh;\r
-       ob->midx = ob->left + (ob->right-ob->left)/2;\r
-\r
-       ob->tileleft = CONVERT_GLOBAL_TO_TILE(ob->left);\r
-       ob->tileright = CONVERT_GLOBAL_TO_TILE(ob->right);\r
-       ob->tiletop = CONVERT_GLOBAL_TO_TILE(ob->top);\r
-       ob->tilebottom = CONVERT_GLOBAL_TO_TILE(ob->bottom);\r
-       ob->tilemidx = CONVERT_GLOBAL_TO_TILE(ob->midx);\r
-\r
-       if (ob->needtoclip)\r
-       {\r
-               leftmoved = ob->left - oldleft;\r
-               rightmoved = ob->right - oldright;\r
-               topmoved = ob->top - oldtop;\r
-               bottommoved = ob->bottom - oldbottom;\r
-               midxmoved = ob->midx - oldmidx;\r
-\r
-               ClipToEnds(ob);\r
-               ClipToSides(ob);\r
-       }\r
-\r
-       ob->xmove = ob->xmove + (ob->x - oldx);\r
-       ob->ymove = ob->ymove + (ob->y - oldy);\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-==================\r
-=\r
-= ClipToSpriteSide\r
-=\r
-= Clips push to solid\r
-=\r
-==================\r
-*/\r
-\r
-void ClipToSpriteSide(objtype *push, objtype *solid)\r
-{\r
-       Sint16 xmove, leftinto, rightinto;\r
-\r
-       //\r
-       // amount the push shape can be pushed\r
-       //\r
-       xmove = solid->xmove - push->xmove;\r
-\r
-       //\r
-       // amount it is inside\r
-       //\r
-       leftinto = solid->right - push->left;\r
-       rightinto = push->right - solid->left;\r
-\r
-       if (leftinto > 0 && leftinto <= xmove)\r
-       {\r
-               xtry = leftinto;\r
-               if (push->state->pushtofloor)\r
-               {\r
-                       ytry = leftinto+16;\r
-               }\r
-               ClipToWalls(push);\r
-               push->hiteast = 1;\r
-       }\r
-       else if (rightinto > 0 && rightinto <= -xmove)\r
-       {\r
-               xtry = -rightinto;\r
-               if (push->state->pushtofloor)\r
-               {\r
-                       ytry = rightinto+16;\r
-               }\r
-               ClipToWalls(push);\r
-               push->hitwest = 1;\r
-       }\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-==================\r
-=\r
-= ClipToSpriteTop\r
-=\r
-= Clips push to solid\r
-=\r
-==================\r
-*/\r
-\r
-void ClipToSpriteTop(objtype *push, objtype *solid)\r
-{\r
-       Sint16 temp, ymove, bottominto;\r
-\r
-       //\r
-       // amount the push shape can be pushed\r
-       //\r
-       ymove = push->ymove - solid->ymove;\r
-\r
-       //\r
-       // amount it is inside\r
-       //\r
-       bottominto = push->bottom - solid->top;\r
-\r
-       if (bottominto >= 0 && bottominto <= ymove)\r
-       {\r
-               if (push == player)\r
-               {\r
-                       gamestate.riding = solid;\r
-               }\r
-               ytry = -bottominto;\r
-               temp = push->state->pushtofloor;\r
-               push->state->pushtofloor = false;\r
-               ClipToWalls(push);\r
-               push->state->pushtofloor = temp;\r
-               if (!push->hitsouth)\r
-               {\r
-                       push->hitnorth = 25;\r
-               }\r
-       }\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-==================\r
-=\r
-= ClipToSprite\r
-=\r
-= Clips push to solid\r
-=\r
-==================\r
-*/\r
-\r
-void ClipToSprite(objtype *push, objtype *solid, boolean squish)\r
-{\r
-       Sint16 xmove, ymove, leftinto, rightinto, topinto, bottominto;\r
-       \r
-       xmove = solid->xmove - push->xmove;\r
-       xtry = ytry = 0;\r
-\r
-       //\r
-       // left / right\r
-       //\r
-       leftinto = solid->right - push->left;\r
-       rightinto = push->right - solid->left;\r
-\r
-       if (leftinto > 0 && xmove+1 >= leftinto)\r
-       {\r
-               xtry = leftinto;\r
-               push->xspeed = 0;\r
-               PushObj(push);\r
-               if (squish && push->hitwest)\r
-               {\r
-                       KillKeen();\r
-               }\r
-               push->hiteast = 1;\r
-               return;\r
-       }\r
-       else if (rightinto > 0 && -xmove+1 >= rightinto)\r
-       {\r
-               xtry = -rightinto;\r
-               push->xspeed = 0;\r
-               PushObj(push);\r
-               if (squish && push->hiteast)\r
-               {\r
-                       KillKeen();\r
-               }\r
-               push->hitwest = 1;\r
-               return;\r
-       }\r
-\r
-       //\r
-       // top / bottom\r
-       //\r
-       ymove = push->ymove - solid->ymove;\r
-       topinto = solid->bottom - push->top;\r
-       bottominto = push->bottom - solid->top;\r
-       if (bottominto >= 0 && bottominto <= ymove)\r
-       {\r
-               if (push == player)\r
-               {\r
-                       gamestate.riding = solid;\r
-               }\r
-               ytry = -bottominto;\r
-               PushObj(push);\r
-               if (squish && push->hitsouth)\r
-               {\r
-                       KillKeen();\r
-               }\r
-               if (!push->hitsouth)\r
-               {\r
-                       push->hitnorth = 25;\r
-               }\r
-               return;\r
-       }\r
-       else if (topinto >= 0 && topinto <= ymove)      // BUG: should be 'topinto <= -ymove'\r
-       {\r
-               ytry = topinto;\r
-               ClipToWalls(push);\r
-               if (squish && push->hitnorth)\r
-               {\r
-                       KillKeen();\r
-               }\r
-               push->hitsouth = 25;\r
-       }\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-==================\r
-=\r
-= DoActor\r
-=\r
-= Moves an actor in its current state by a given number of tics.\r
-= If that time takes it into the next state, it changes the state\r
-= and returns the number of excess tics after the state change\r
-=\r
-==================\r
-*/\r
-\r
-Sint16 DoActor(objtype *ob, Sint16 numtics)\r
-{\r
-       Sint16 ticcount, usedtics, excesstics;\r
-       statetype *state;\r
-       \r
-       state = ob->state;\r
-\r
-       if (state->progress == think)\r
-       {\r
-               if (state->think)\r
-               {\r
-                       if (ob->nothink)\r
-                       {\r
-                               ob->nothink--;\r
-                       }\r
-                       else\r
-                       {\r
-                               state->think(ob);\r
-                       }\r
-               }\r
-               return 0;\r
-       }\r
-\r
-       ticcount = ob->ticcount + numtics;\r
-\r
-       if (state->tictime > ticcount || state->tictime == 0)\r
-       {\r
-               ob->ticcount = ticcount;\r
-               if (state->progress == slide || state->progress == slidethink)\r
-               {\r
-                       if (ob->xdir)\r
-                       {\r
-                               xtry += ob->xdir == 1? numtics*state->xmove : -numtics*state->xmove;\r
-                       }\r
-                       if (ob->ydir)\r
-                       {\r
-                               ytry += ob->ydir == 1? numtics*state->ymove : -numtics*state->ymove;\r
-                       }\r
-               }\r
-               if ((state->progress == slidethink || state->progress == stepthink) && state->think)\r
-               {\r
-                       if (ob->nothink)\r
-                       {\r
-                               ob->nothink--;\r
-                       }\r
-                       else\r
-                       {\r
-                               state->think(ob);\r
-                       }\r
-               }\r
-               return 0;\r
-       }\r
-       else\r
-       {\r
-               usedtics = state->tictime - ob->ticcount;\r
-               excesstics = ticcount - state->tictime;\r
-               ob->ticcount = 0;\r
-               if (state->progress == slide || state->progress == slidethink)\r
-               {\r
-                       if (ob->xdir)\r
-                       {\r
-                               xtry += ob->xdir == 1? usedtics*state->xmove : -usedtics*state->xmove;\r
-                       }\r
-                       if (ob->ydir)\r
-                       {\r
-                               ytry += ob->ydir == 1? usedtics*state->ymove : -usedtics*state->ymove;\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       if (ob->xdir)\r
-                       {\r
-                               xtry += ob->xdir == 1? state->xmove : -state->xmove;\r
-                       }\r
-                       if (ob->ydir)\r
-                       {\r
-                               ytry += ob->ydir == 1? state->ymove : -state->ymove;\r
-                       }\r
-               }\r
-\r
-               if (state->think)\r
-               {\r
-                       if (ob->nothink)\r
-                       {\r
-                               ob->nothink--;\r
-                       }\r
-                       else\r
-                       {\r
-                               state->think(ob);\r
-                       }\r
-               }\r
-\r
-               if (state == ob->state)\r
-               {\r
-                       ob->state = state->nextstate;   // go to next state\r
-               }\r
-               else if (!ob->state)\r
-               {\r
-                       return 0;                       // object removed itself\r
-               }\r
-               return excesstics;\r
-       }\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-====================\r
-=\r
-= StateMachine\r
-=\r
-= Change state and give directions\r
-=\r
-====================\r
-*/\r
-\r
-void StateMachine(objtype *ob)\r
-{\r
-       Sint16 excesstics, oldshapenum;\r
-       statetype *state;\r
-       \r
-       ob->xmove=ob->ymove=xtry=ytry=0;\r
-       oldshapenum = ob->shapenum;\r
-\r
-       state = ob->state;\r
-\r
-       excesstics = DoActor(ob, tics);\r
-       if (ob->state != state)\r
-       {\r
-               ob->ticcount = 0;               // start the new state at 0, then use excess\r
-               state = ob->state;\r
-       }\r
-\r
-       while (excesstics)\r
-       {\r
-       //\r
-       // passed through to next state\r
-       //\r
-               if (!state->skippable && state->tictime <= excesstics)\r
-               {\r
-                       excesstics = DoActor(ob, state->tictime-1);\r
-               }\r
-               else\r
-               {\r
-                       excesstics = DoActor(ob, excesstics);\r
-               }\r
-               if (ob->state != state)\r
-               {\r
-                       ob->ticcount = 0;               // start the new state at 0, then use excess\r
-                       state = ob->state;\r
-               }\r
-       }\r
-\r
-       if (!state)                     // object removed itself\r
-       {\r
-               RemoveObj(ob);\r
-               return;\r
-       }\r
-\r
-       //\r
-       // if state->rightshapenum == NULL, the state does not have a standard\r
-       // shape (the think routine should have set it)\r
-       //\r
-       if (state->rightshapenum)\r
-       {\r
-               if (ob->xdir > 0)\r
-               {\r
-                       ob->shapenum = state->rightshapenum;\r
-               }\r
-               else\r
-               {\r
-                       ob->shapenum = state->leftshapenum;\r
-               }\r
-       }\r
-       if ((Sint16)ob->shapenum == -1)\r
-       {\r
-               ob->shapenum = 0;               // make it invisable this time\r
-       }\r
-\r
-       if (xtry || ytry || ob->shapenum != oldshapenum || ob->hitnorth == 25)\r
-       {\r
-       //\r
-       // actor moved or changed shape\r
-       // make sure the movement is within limits (one tile)\r
-       //\r
-               if (ob->needtoclip == cl_fullclip)\r
-               {\r
-                       FullClipToWalls(ob);\r
-               }\r
-               else\r
-               {\r
-                       ClipToWalls(ob);\r
-               }\r
-       }\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-====================\r
-=\r
-= NewState\r
-=\r
-====================\r
-*/\r
-\r
-void NewState(objtype *ob, statetype *state)\r
-{\r
-       Sint16 temp;\r
-       \r
-       ob->state = state;\r
-\r
-       if (state->rightshapenum)\r
-       {\r
-               if (ob->xdir > 0)\r
-               {\r
-                       ob->shapenum = state->rightshapenum;\r
-               }\r
-               else\r
-               {\r
-                       ob->shapenum = state->leftshapenum;\r
-               }\r
-       }\r
-\r
-       if ((Sint16)ob->shapenum == -1)\r
-       {\r
-               ob->shapenum = 0;\r
-       }\r
-\r
-       temp = ob->needtoclip;\r
-       ob->needtoclip = cl_noclip;\r
-\r
-       xtry = ytry = 0;                                        // no movement\r
-       ClipToWalls(ob);                                        // just calculate values\r
-\r
-       ob->needtoclip = temp;\r
-\r
-       if (ob->needtoclip == cl_fullclip)\r
-       {\r
-               FullClipToWalls(ob);\r
-       }\r
-       else if (ob->needtoclip == cl_midclip)\r
-       {\r
-               ClipToWalls(ob);\r
-       }\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-====================\r
-=\r
-= ChangeState\r
-=\r
-====================\r
-*/\r
-\r
-void ChangeState(objtype *ob, statetype *state)\r
-{\r
-       ob->state = state;\r
-       ob->ticcount = 0;\r
-       if (state->rightshapenum)\r
-       {\r
-               if (ob->xdir > 0)\r
-               {\r
-                       ob->shapenum = state->rightshapenum;\r
-               }\r
-               else\r
-               {\r
-                       ob->shapenum = state->leftshapenum;\r
-               }\r
-       }\r
-\r
-       if ((Sint16)ob->shapenum == -1)\r
-       {\r
-               ob->shapenum = 0;\r
-       }\r
-\r
-       ob->needtoreact = true;                 // it will need to be redrawn this frame\r
-\r
-       xtry = ytry = 0;                                        // no movement\r
-\r
-       if (ob->hitnorth != 25)\r
-       {\r
-               ClipToWalls(ob);\r
-       }\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-====================\r
-=\r
-= OnScreen\r
-=\r
-====================\r
-*/\r
-\r
-boolean OnScreen(objtype *ob)\r
-{\r
-       if (ob->tileright < originxtile || ob->tilebottom < originytile\r
-               || ob->tileleft > originxtilemax || ob->tiletop > originytilemax)\r
-       {\r
-               return false;\r
-       }\r
-       return true;\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-====================\r
-=\r
-= DoGravity\r
-=\r
-====================\r
-*/\r
-\r
-void DoGravity(objtype *ob)\r
-{\r
-       Sint32 i;\r
-//\r
-// only accelerate on odd tics, because of limited precision\r
-//\r
-       for (i = lasttimecount-tics; i<lasttimecount; i++)\r
-       {\r
-               if (i&1)\r
-               {\r
-                       if (ob->yspeed < 0 && ob->yspeed >= -4)\r
-                       {\r
-                               ytry += ob->yspeed;\r
-                               ob->yspeed = 0;\r
-                               return;\r
-                       }\r
-                       ob->yspeed += 4;\r
-                       if (ob->yspeed > 70)\r
-                       {\r
-                               ob->yspeed = 70;\r
-                       }\r
-               }\r
-               ytry += ob->yspeed;\r
-       }\r
-}\r
-\r
-\r
-/*\r
-====================\r
-=\r
-= DoWeakGravity\r
-=\r
-====================\r
-*/\r
-\r
-void DoWeakGravity(objtype *ob)\r
-{\r
-       Sint32 i;\r
-//\r
-// only accelerate on odd tics, because of limited precision\r
-//\r
-       for (i = lasttimecount-tics; i<lasttimecount; i++)\r
-       {\r
-               if (i&1)\r
-               {\r
-                       if (ob->yspeed < 0 && ob->yspeed >= -3)\r
-                       {\r
-                               ytry += ob->yspeed;\r
-                               ob->yspeed = 0;\r
-                               return;\r
-                       }\r
-                       ob->yspeed += 3;\r
-                       if (ob->yspeed > 70)\r
-                       {\r
-                               ob->yspeed = 70;\r
-                       }\r
-               }\r
-               ytry += ob->yspeed;\r
-       }\r
-}\r
-\r
-\r
-/*\r
-====================\r
-=\r
-= DoTinyGravity\r
-=\r
-====================\r
-*/\r
-\r
-void DoTinyGravity(objtype *ob)\r
-{\r
-       Sint32 i;\r
-//\r
-// only accelerate every 4 tics, because of limited precision\r
-//\r
-       for (i = lasttimecount-tics; i<lasttimecount; i++)\r
-       {\r
-               if (!i & 3)     //BUG: this is equal to ((!i) & 3), not (!(i & 3))\r
-               {\r
-                       ob->yspeed++;\r
-                       if (ob->yspeed > 70)\r
-                       {\r
-                               ob->yspeed = 70;\r
-                       }\r
-               }\r
-               ytry += ob->yspeed;\r
-       }\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= AccelerateX\r
-=\r
-===============\r
-*/\r
-\r
-void AccelerateX(objtype *ob, Sint16 dir, Sint16 maxspeed)\r
-{\r
-       Sint32 i;\r
-       Uint16 oldsign;\r
-       \r
-       oldsign = ob->xspeed & 0x8000;\r
-//\r
-// only accelerate on odd tics, because of limited precision\r
-//\r
-       for (i=lasttimecount-tics; i<lasttimecount; i++)\r
-       {\r
-               if (i & 1)\r
-               {\r
-                       ob->xspeed += dir;\r
-                       if ((ob->xspeed & 0x8000) != oldsign)\r
-                       {\r
-                               oldsign = ob->xspeed & 0x8000;\r
-                               ob->xdir = oldsign? -1 : 1;\r
-                       }\r
-                       if (ob->xspeed > maxspeed)\r
-                       {\r
-                               ob->xspeed = maxspeed;\r
-                       }\r
-                       else if (ob->xspeed < -maxspeed)\r
-                       {\r
-                               ob->xspeed = -maxspeed;\r
-                       }\r
-               }\r
-               xtry += ob->xspeed;\r
-       }\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= AccelerateXv\r
-=\r
-= Doesn't change object's xdir\r
-=\r
-===============\r
-*/\r
-\r
-void AccelerateXv(objtype *ob, Sint16 dir, Sint16 maxspeed)\r
-{\r
-       Sint32 i;\r
-\r
-//\r
-// only accelerate on odd tics, because of limited precision\r
-//\r
-       for (i=lasttimecount-tics; i<lasttimecount; i++)\r
-       {\r
-               if (i & 1)\r
-               {\r
-                       ob->xspeed += dir;\r
-                       if (ob->xspeed > maxspeed)\r
-                       {\r
-                               ob->xspeed = maxspeed;\r
-                       }\r
-                       else if (ob->xspeed < -maxspeed)\r
-                       {\r
-                               ob->xspeed = -maxspeed;\r
-                       }\r
-               }\r
-               xtry += ob->xspeed;\r
-       }\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= AccelerateY\r
-=\r
-===============\r
-*/\r
-\r
-void AccelerateY(objtype *ob, Sint16 dir, Sint16 maxspeed)\r
-{\r
-       Sint32 i;\r
-\r
-//\r
-// only accelerate on odd tics, because of limited precision\r
-//\r
-       for (i=lasttimecount-tics; i<lasttimecount; i++)\r
-       {\r
-               if (i & 1)\r
-               {\r
-                       ob->yspeed += dir;\r
-                       if (ob->yspeed > maxspeed)\r
-                       {\r
-                               ob->yspeed = maxspeed;\r
-                       }\r
-                       else if (ob->yspeed < -maxspeed)\r
-                       {\r
-                               ob->yspeed = -maxspeed;\r
-                       }\r
-               }\r
-               ytry += ob->yspeed;\r
-       }\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= FrictionX\r
-=\r
-===============\r
-*/\r
-\r
-void FrictionX(objtype *ob)\r
-{\r
-       Sint16 friction, oldsign;\r
-       Sint32 i;\r
-\r
-       oldsign = ob->xspeed & 0x8000;\r
-       if (ob->xspeed > 0)\r
-       {\r
-               friction = -1;\r
-       }\r
-       else if (ob->xspeed < 0)\r
-       {\r
-               friction = 1;\r
-       }\r
-       else\r
-       {\r
-               friction = 0;\r
-       }\r
-//\r
-// only accelerate on odd tics, because of limited precision\r
-//\r
-\r
-       for (i=lasttimecount-tics; i<lasttimecount; i++)\r
-       {\r
-               if (i & 1)\r
-               {\r
-                       ob->xspeed += friction;\r
-                       if ((ob->xspeed & 0x8000) != oldsign)\r
-                       {\r
-                               ob->xspeed = 0;\r
-                       }\r
-               }\r
-               xtry += ob->xspeed;\r
-       }\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= FrictionY\r
-=\r
-===============\r
-*/\r
-\r
-void FrictionY(objtype *ob)\r
-{\r
-       Sint16 friction, oldsign;\r
-       Sint32 i;\r
-\r
-       if (ob->yspeed > 0)\r
-       {\r
-               friction = -1;\r
-       }\r
-       else if (ob->yspeed < 0)\r
-       {\r
-               friction = 1;\r
-       }\r
-       else\r
-       {\r
-               friction = 0;\r
-       }\r
-//\r
-// only accelerate on odd tics, because of limited precision\r
-//\r
-       for (i=lasttimecount-tics; i<lasttimecount; i++)\r
-       {\r
-               if (i & 1)\r
-               {\r
-                       ob->yspeed += friction;\r
-                       if ((ob->yspeed & 0x8000) != oldsign)   //BUG: oldsign is not initialized!\r
-                       {\r
-                               ob->yspeed = 0;\r
-                       }\r
-               }\r
-               ytry += ob->yspeed;\r
-       }\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= StunObj\r
-=\r
-===============\r
-*/\r
-\r
-void StunObj(objtype *ob, objtype *shot, statetype *stunstate)\r
-{\r
-       ExplodeShot(shot);\r
-       ob->temp1 = ob->temp2 = ob->temp3 = 0;  // Note: ob->nothink should also be set to 0\r
-       ob->temp4 = ob->obclass;\r
-       ChangeState(ob, stunstate);\r
-       ob->obclass = stunnedobj;\r
-#ifndef KEEN4\r
-       ob->yspeed -= 24;\r
-       if (ob->yspeed < -48)\r
-               ob->yspeed = -48;\r
-#endif\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-===============\r
-=\r
-= T_Projectile\r
-=\r
-===============\r
-*/\r
-\r
-void T_Projectile(objtype *ob)\r
-{\r
-       DoGravity(ob);\r
-       xtry = ob->xspeed*tics;\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= T_WeakProjectile\r
-=\r
-===============\r
-*/\r
-\r
-void T_WeakProjectile(objtype *ob)\r
-{\r
-       DoWeakGravity(ob);\r
-       xtry = ob->xspeed*tics;\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= T_Velocity\r
-=\r
-===============\r
-*/\r
-\r
-void T_Velocity(objtype *ob)\r
-{\r
-       xtry = ob->xspeed*tics;\r
-       ytry = ob->yspeed*tics;\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= SetReactThink\r
-=\r
-===============\r
-*/\r
-\r
-void SetReactThink(objtype *ob)\r
-{\r
-       ob->needtoreact = true;\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= T_Stunned\r
-=\r
-===============\r
-*/\r
-\r
-void T_Stunned(objtype *ob)\r
-{\r
-       ob->temp1 = 0;\r
-       ob->needtoreact = true;\r
-       if (++ob->temp2 == 3)\r
-               ob->temp2 = 0;\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= C_Lethal\r
-=\r
-===============\r
-*/\r
-\r
-void C_Lethal(objtype *ob, objtype *hit)\r
-{\r
-       ob++;                   // shut up compiler\r
-       if (hit->obclass == keenobj)\r
-       {\r
-               KillKeen();\r
-       }\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= R_Draw\r
-=\r
-===============\r
-*/\r
-\r
-void R_Draw(objtype *ob)\r
-{\r
-       RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= R_Walk\r
-=\r
-===============\r
-*/\r
-\r
-void R_Walk(objtype *ob)\r
-{\r
-       if (ob->xdir == 1 && ob->hitwest)\r
-       {\r
-               ob->x -= ob->xmove;\r
-               ob->xdir = -1;\r
-               ob->nothink = US_RndT() >> 5;\r
-               ChangeState(ob, ob->state);\r
-       }\r
-       else if (ob->xdir == -1 && ob->hiteast)\r
-       {\r
-               ob->x -= ob->xmove;\r
-               ob->xdir = 1;\r
-               ob->nothink = US_RndT() >> 5;\r
-               ChangeState(ob, ob->state);\r
-       }\r
-       else if (!ob->hitnorth)\r
-       {\r
-               ob->x -= ob->xmove;\r
-               ob->xdir = -ob->xdir;\r
-               ob->nothink = US_RndT() >> 5;\r
-               ChangeState(ob, ob->state);\r
-       }\r
-       RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= R_WalkNormal\r
-=\r
-= Actor will not walk onto tiles with special (e.g. deadly) north walls\r
-=\r
-===============\r
-*/\r
-\r
-void R_WalkNormal(objtype *ob)\r
-{\r
-       if (ob->xdir == 1 && ob->hitwest)\r
-       {\r
-               ob->x -= ob->xmove;\r
-               ob->xdir = -1;\r
-               ob->nothink = US_RndT() >> 5;\r
-               ChangeState(ob, ob->state);\r
-       }\r
-       else if (ob->xdir == -1 && ob->hiteast)\r
-       {\r
-               ob->x -= ob->xmove;\r
-               ob->xdir = 1;\r
-               ob->nothink = US_RndT() >> 5;\r
-               ChangeState(ob, ob->state);\r
-       }\r
-       else if (!ob->hitnorth || (ob->hitnorth & ~7))\r
-       {\r
-               ob->x -= ob->xmove*2;\r
-               ob->xdir = -ob->xdir;\r
-               ob->nothink = US_RndT() >> 5;\r
-               ChangeState(ob, ob->state);\r
-       }\r
-       RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= BadState\r
-=\r
-===============\r
-*/\r
-\r
-void BadState(void)\r
-{\r
-       Quit("Object with bad state!");\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= R_Stunned\r
-=\r
-===============\r
-*/\r
-\r
-void R_Stunned(objtype *ob)\r
-{\r
-       Sint16 starx, stary;\r
-\r
-       if (ob->hitwest || ob->hiteast)\r
-               ob->xspeed = 0;\r
-\r
-       if (ob->hitsouth)\r
-               ob->yspeed = 0;\r
-\r
-       if (ob->hitnorth)\r
-       {\r
-               ob->xspeed = ob->yspeed = 0;\r
-               if (ob->state->nextstate)\r
-                       ChangeState(ob, ob->state->nextstate);\r
-       }\r
-\r
-       RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
-\r
-       starx = stary = 0;\r
-       switch (ob->temp4)\r
-       {\r
-#if defined KEEN4\r
-       case mimrockobj:\r
-               stary = -4*PIXGLOBAL;\r
-               break;\r
-       case eggobj:\r
-               starx = 8*PIXGLOBAL;\r
-               stary = -8*PIXGLOBAL;\r
-               break;\r
-       case treasureeaterobj:\r
-               starx = 8*PIXGLOBAL;\r
-               break;\r
-       case bounderobj:\r
-               starx = 4*PIXGLOBAL;\r
-               stary = -8*PIXGLOBAL;\r
-               break;\r
-       case wormouthobj:\r
-               starx = 4*PIXGLOBAL;\r
-               stary = -350;   // -21.875 pixels (this one is a bit strange)\r
-               break;\r
-       case lickobj:\r
-               stary = -8*PIXGLOBAL;\r
-               break;\r
-       case inchwormobj:\r
-               starx = -4*PIXGLOBAL;\r
-               stary = -8*PIXGLOBAL;\r
-               break;\r
-       case slugobj:\r
-               stary = -8*PIXGLOBAL;\r
-               break;\r
-#elif defined KEEN5\r
-       case sparkyobj:\r
-               starx += 4*PIXGLOBAL;\r
-               break;\r
-       case amptonobj:\r
-               stary -= 8*PIXGLOBAL;\r
-               asm jmp done;           // just to recreate the original code's quirks, feel free to delete this\r
-               break;\r
-       case scottieobj:\r
-               stary -= 8*PIXGLOBAL;\r
-               break;\r
-#elif defined KEEN6\r
-       case blooguardobj:\r
-               starx = 16*PIXGLOBAL;\r
-               stary = -4*PIXGLOBAL;\r
-               break;\r
-       case flectobj:\r
-               starx = 4*PIXGLOBAL;\r
-               stary = -4*PIXGLOBAL;\r
-               break;\r
-       case bloogobj:\r
-       case nospikeobj:\r
-               starx = 8*PIXGLOBAL;\r
-               stary = -4*PIXGLOBAL;\r
-               break;\r
-       case bloogletobj:\r
-       case babobbaobj:\r
-               stary = -8*PIXGLOBAL;\r
-               break;\r
-       case fleexobj:\r
-               starx = 16*PIXGLOBAL;\r
-               stary = 8*PIXGLOBAL;\r
-               break;\r
-       case ceilickobj:\r
-               stary = 12*PIXGLOBAL;\r
-               break;\r
-       default:\r
-               Quit("No star spec for object!");\r
-#endif\r
-       }\r
-done:\r
-\r
-       ob->temp1 = ob->temp1 + tics;\r
-       if (ob->temp1 > 10)\r
-       {\r
-               ob->temp1 -= 10;\r
-               if (++ob->temp2 == 3)\r
-                       ob->temp2 = 0;\r
-       }\r
-\r
-       RF_PlaceSprite((void **)&ob->temp3, ob->x+starx, ob->y+stary, ob->temp2+STUNSTARS1SPR, spritedraw, 3);\r
-}\r
-\r
-//==========================================================================\r
-\r
-statetype sc_deadstate = {0, 0, think, false, false, 0, 0, 0, NULL, NULL, NULL, NULL};\r
-#pragma warn -sus      //BadState is not a valid think/contact/react function. Nobody cares.\r
-statetype sc_badstate  = {0, 0, think, false, false, 0, 0, 0, &BadState, &BadState, &BadState, NULL};\r
-#pragma warn +sus
\ No newline at end of file