]> 4ch.mooo.com Git - 16.git/blobdiff - src/lib/16_rf.c
[16_ca needs huge amounts of work and I should remember what needs to be done soon...
[16.git] / src / lib / 16_rf.c
index 05ea5ae597463a0086b87789c56a8f8ffd276ae8..46400385631dd51e43858d4839d72842b245e047 100755 (executable)
@@ -76,6 +76,8 @@ unsigned      SX_T_SHIFT;             // screen x >> ?? = tile EGA = 1, CGA = 2;
 #define        UPDATESPARESIZE         (UPDATEWIDE*2+4)\r
 #define UPDATESIZE                     (UPDATESCREENSIZE+2*UPDATESPARESIZE)\r
 \r
+#define MAXSCROLLEDGES 6\r
+\r
 /*\r
 =============================================================================\r
 \r
@@ -230,7 +232,9 @@ void RFL_NewTile (unsigned updateoffset);
 void RFL_MaskForegroundTiles (void);\r
 void RFL_UpdateTiles (void);\r
 \r
+void RFL_BoundScroll (int x, int y);//++++??\r
 void RFL_CalcOriginStuff (long x, long y);\r
+void RFL_ClearScrollBlocks (void);//++++??\r
 void RFL_InitSpriteList (void);\r
 void RFL_InitAnimList (void);\r
 void RFL_CheckForAnimTile (unsigned x, unsigned y);\r
@@ -338,6 +342,40 @@ void RF_Shutdown (void)
 \r
 }\r
 \r
+//===========================================================================\r
+\r
+\r
+/*\r
+=====================\r
+=\r
+= RF_FixOfs\r
+=\r
+= Sets bufferofs,displayofs, and masterofs to regular values, for the\r
+= occasions when you have moved them around manually\r
+=\r
+=====================\r
+*/\r
+\r
+void RF_FixOfs (void)\r
+{\r
+       if (grmode == EGAGR)\r
+       {\r
+               screenpage = 0;\r
+               otherpage = 1;\r
+               panx = pany = pansx = pansy = panadjust = 0;\r
+               displayofs = screenstart[screenpage];\r
+               bufferofs = screenstart[otherpage];\r
+               masterofs = screenstart[2];\r
+               VW_SetScreen (displayofs,0);\r
+       }\r
+       else\r
+       {\r
+               bufferofs = 0;\r
+               masterofs = 0x8000;\r
+       }\r
+}\r
+\r
+\r
 //===========================================================================\r
 \r
 /*\r
@@ -364,6 +402,8 @@ void RF_NewMap (void)
 //\r
 // make a lookup table for the maps left edge\r
 //\r
+       if (mapheight > MAXMAPHEIGHT)\r
+       Quit ("RF_NewMap: Map too tall!");\r
        spot = 0;\r
        for (i=0;i<mapheight;i++)\r
        {\r
@@ -379,7 +419,6 @@ void RF_NewMap (void)
                for (x=0;x<UPDATEWIDE;x++)\r
                        *table++ = mapbwidthtable[y]+x*2;\r
 \r
-\r
 //\r
 // the y max value clips off the bottom half of a tile so a map that is\r
 // 13 + MAPBORDER*2 tile high will not scroll at all vertically\r
@@ -396,6 +435,11 @@ void RF_NewMap (void)
 //\r
        RFL_InitSpriteList ();\r
        RFL_InitAnimList ();\r
+       RFL_ClearScrollBlocks ();\r
+       RF_SetScrollBlock (0,MAPBORDER-1,true);\r
+       RF_SetScrollBlock (0,mapheight-MAPBORDER,true);\r
+       RF_SetScrollBlock (MAPBORDER-1,0,false);\r
+       RF_SetScrollBlock (mapwidth-MAPBORDER,0,false);\r
 \r
 \r
        lasttimecount = TimeCount;              // setup for adaptive timing\r
@@ -458,7 +502,7 @@ void RF_MarkTileGraphics (void)
                                // new chain of animating tiles\r
 \r
                                if (i>=MAXANIMTYPES)\r
-                                       //Quit ("RF_MarkTileGraphics: Too many unique animated tiles!");\r
+                                       Quit ("RF_MarkTileGraphics: Too many unique animated tiles!");\r
                                allanims[i].current = tile;\r
                                allanims[i].count = tinf[SPEED+tile];\r
 \r
@@ -472,7 +516,7 @@ void RF_MarkTileGraphics (void)
                                        CA_MarkGrChunk(STARTTILE16+next);\r
                                        next += (signed char)(tinf[ANIM+next]);\r
                                        if (++anims > 20)\r
-                                               //Quit ("MarkTileGraphics: Unending animation!");\r
+                                               Quit ("MarkTileGraphics: Unending animation!");\r
                                }\r
 \r
                        }\r
@@ -508,7 +552,7 @@ nextback:
                                // new chain of animating tiles\r
 \r
                                if (i>=MAXANIMTYPES)\r
-                                       //Quit ("RF_MarkTileGraphics: Too many unique animated tiles!");\r
+                                       Quit ("RF_MarkTileGraphics: Too many unique animated tiles!");\r
                                allanims[i].current = tilehigh;\r
                                allanims[i].count = tinf[MSPEED+tile];\r
 \r
@@ -522,7 +566,7 @@ nextback:
                                        CA_MarkGrChunk(STARTTILE16M+next);\r
                                        next += (signed char)(tinf[MANIM+next]);\r
                                        if (++anims > 20)\r
-                                               //Quit ("MarkTileGraphics: Unending animation!");\r
+                                               Quit ("MarkTileGraphics: Unending animation!");\r
                                }\r
 \r
                        }\r
@@ -586,10 +630,10 @@ void RFL_CheckForAnimTile (unsigned x, unsigned y)
 //\r
        map = mapsegs[0]+offset;\r
        tile = *map;\r
-       if (tinf[ANIM+tile])\r
+       if (tinf[ANIM+tile] && tinf[SPEED+tile])\r
        {\r
                if (!animfreeptr)\r
-                       //Quit ("RF_CheckForAnimTile: No free spots in tilearray!");\r
+                       Quit ("RF_CheckForAnimTile: No free spots in tilearray!");\r
                anim = animfreeptr;\r
                animfreeptr = animfreeptr->nexttile;\r
                next = animhead;                                // stick it at the start of the list\r
@@ -611,10 +655,10 @@ void RFL_CheckForAnimTile (unsigned x, unsigned y)
 //\r
        map = mapsegs[1]+offset;\r
        tile = *map;\r
-       if (tinf[MANIM+tile])\r
+       if (tinf[MANIM+tile] && tinf[MSPEED+tile])\r
        {\r
                if (!animfreeptr)\r
-                       //Quit ("RF_CheckForAnimTile: No free spots in tilearray!");\r
+                       Quit ("RF_CheckForAnimTile: No free spots in tilearray!");\r
                anim = animfreeptr;\r
                animfreeptr = animfreeptr->nexttile;\r
                next = animhead;                                // stick it at the start of the list\r
@@ -696,6 +740,37 @@ void RFL_RemoveAnimsOnY (unsigned y)
 }\r
 \r
 \r
+/*\r
+====================\r
+=\r
+= RFL_RemoveAnimsInBlock\r
+=\r
+====================\r
+*/\r
+\r
+void RFL_RemoveAnimsInBlock (unsigned x, unsigned y, unsigned width, unsigned height)\r
+{\r
+       animtiletype *current,*next;\r
+\r
+       current = animhead;\r
+       while (current)\r
+       {\r
+               if (current->x - x < width && current->y - y < height)\r
+               {\r
+                       *(void **)current->prevptr = current->nexttile;\r
+                       if (current->nexttile)\r
+                               current->nexttile->prevptr = current->prevptr;\r
+                       next = current->nexttile;\r
+                       current->nexttile = animfreeptr;\r
+                       animfreeptr = current;\r
+                       current = next;\r
+               }\r
+               else\r
+                       current = current->nexttile;\r
+       }\r
+}\r
+\r
+\r
 /*\r
 ====================\r
 =\r
@@ -766,7 +841,7 @@ void RFL_AnimateTiles (void)
                        y = current->y-originytile;\r
 \r
                        if (x>=PORTTILESWIDE || y>=PORTTILESHIGH)\r
-                               //Quit ("RFL_AnimateTiles: Out of bounds!");\r
+                               Quit ("RFL_AnimateTiles: Out of bounds!");\r
 \r
                        updateofs = uwidthtable[y] + x;\r
                        RFL_NewTile(updateofs);                         // puts "1"s in both pages\r
@@ -853,6 +928,115 @@ void RFL_CalcOriginStuff (long x, long y)
 \r
 }\r
 \r
+\r
+/*\r
+=================\r
+=\r
+= RFL_ClearScrollBlocks\r
+=\r
+=================\r
+*/\r
+\r
+void RFL_ClearScrollBlocks (void)\r
+{\r
+       hscrollblocks = vscrollblocks = 0;\r
+}\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= RF_SetScrollBlock\r
+=\r
+= Sets a horizontal or vertical scroll block\r
+= a horizontal block is ----, meaning it blocks up/down movement\r
+=\r
+=================\r
+*/\r
+\r
+void RF_SetScrollBlock (int x, int y, boolean horizontal)\r
+{\r
+       if (horizontal)\r
+       {\r
+               hscrolledge[hscrollblocks] = y;\r
+               if (hscrollblocks++ == MAXSCROLLEDGES)\r
+                       Quit ("RF_SetScrollBlock: Too many horizontal scroll blocks");\r
+       }\r
+       else\r
+       {\r
+               vscrolledge[vscrollblocks] = x;\r
+               if (vscrollblocks++ == MAXSCROLLEDGES)\r
+                       Quit ("RF_SetScrollBlock: Too many vertical scroll blocks");\r
+       }\r
+}\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= RFL_BoundScroll\r
+=\r
+= Bound a given x/y movement to scroll blocks\r
+=\r
+=================\r
+*/\r
+\r
+void RFL_BoundScroll (int x, int y)\r
+{\r
+       int     check,newxtile,newytile;\r
+\r
+       originxglobal += x;\r
+       originyglobal += y;\r
+\r
+       newxtile= originxglobal >> G_T_SHIFT;\r
+       newytile = originyglobal >> G_T_SHIFT;\r
+\r
+       if (x>0)\r
+       {\r
+               newxtile+=SCREENTILESWIDE;\r
+               for (check=0;check<vscrollblocks;check++)\r
+                       if (vscrolledge[check] == newxtile)\r
+                       {\r
+                               originxglobal = originxglobal&0xff00;\r
+                               break;\r
+                       }\r
+       }\r
+       else if (x<0)\r
+       {\r
+               for (check=0;check<vscrollblocks;check++)\r
+                       if (vscrolledge[check] == newxtile)\r
+                       {\r
+                               originxglobal = (originxglobal&0xff00)+0x100;\r
+                               break;\r
+                       }\r
+       }\r
+\r
+\r
+       if (y>0)\r
+       {\r
+               newytile+=SCREENTILESHIGH;\r
+               for (check=0;check<hscrollblocks;check++)\r
+                       if (hscrolledge[check] == newytile)\r
+                       {\r
+                               originyglobal = originyglobal&0xff00;\r
+                               break;\r
+                       }\r
+       }\r
+       else if (y<0)\r
+       {\r
+               for (check=0;check<hscrollblocks;check++)\r
+                       if (hscrolledge[check] == newytile)\r
+                       {\r
+                               originyglobal = (originyglobal&0xff00)+0x100;\r
+                               break;\r
+                       }\r
+       }\r
+\r
+\r
+       RFL_CalcOriginStuff (originxglobal, originyglobal);\r
+}\r
+\r
+\r
 //===========================================================================\r
 \r
 /*\r
@@ -869,6 +1053,7 @@ void RF_SetRefreshHook (void (*func) (void) )
 }\r
 \r
 \r
+//===========================================================================\r
 \r
 /*\r
 =================\r
@@ -926,8 +1111,8 @@ void       RFL_NewRow (int dir)
                ystep = 1;\r
                count = PORTTILESHIGH;\r
                break;\r
-       //default:\r
-               //Quit ("RFL_NewRow: Bad dir!");\r
+       default:\r
+               Quit ("RFL_NewRow: Bad dir!");\r
        }\r
 \r
        while (count--)\r
@@ -957,7 +1142,336 @@ void RF_ForceRefresh (void)
        RF_Refresh ();\r
 }\r
 \r
+//===========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= RF_MapToMap\r
+=\r
+= Copies a block of tiles (all three planes) from one point\r
+= in the map to another, accounting for animating tiles\r
+=\r
+=====================\r
+*/\r
+\r
+void RF_MapToMap (unsigned srcx, unsigned srcy,\r
+                                 unsigned destx, unsigned desty,\r
+                                 unsigned width, unsigned height)\r
+{\r
+       int                     x,y;\r
+       unsigned        source,destofs,xspot,yspot;\r
+       unsigned        linedelta,p0,p1,p2,updatespot;\r
+       unsigned        far *source0, far *source1, far *source2;\r
+       unsigned        far *dest0, far *dest1, far *dest2;\r
+       boolean         changed;\r
+\r
+       RFL_RemoveAnimsInBlock (destx,desty,width,height);\r
+\r
+       source = mapbwidthtable[srcy]/2 + srcx;\r
+\r
+       source0 = mapsegs[0]+source;\r
+       source1 = mapsegs[1]+source;\r
+       source2 = mapsegs[2]+source;\r
+\r
+       destofs = mapbwidthtable[desty]/2 + destx;\r
+       destofs -= source;\r
+\r
+       linedelta = mapwidth - width;\r
+\r
+       for (y=0;y<height;y++,source0+=linedelta,source1+=linedelta,source2+=linedelta)\r
+               for (x=0;x<width;x++,source0++,source1++,source2++)\r
+               {\r
+                       p0 = *source0;\r
+                       p1 = *source1;\r
+                       p2 = *source2;\r
+\r
+                       dest0 = source0 + destofs;\r
+                       dest1 = source1 + destofs;\r
+                       dest2 = source2 + destofs;\r
+\r
+//\r
+// only make a new tile if it is different\r
+//\r
+                       if (p0 != *dest0 || p1 != *dest1 || p2 != *dest2)\r
+                       {\r
+                               *dest0 = p0;\r
+                               *dest1 = p1;\r
+                               *dest2 = p2;\r
+                               changed = true;\r
+                       }\r
+                       else\r
+                               changed = false;\r
+\r
+//\r
+// if tile is on the view port\r
+//\r
+                       xspot = destx+x-originxtile;\r
+                       yspot = desty+y-originytile;\r
+                       if (yspot < PORTTILESHIGH && xspot < PORTTILESWIDE)\r
+                       {\r
+                               if (changed)\r
+                               {\r
+                                       updatespot = uwidthtable[yspot]+xspot;\r
+                                       RFL_NewTile(updatespot);\r
+                               }\r
+                               RFL_CheckForAnimTile (destx+x,desty+y);\r
+                       }\r
+               }\r
+}\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+=====================\r
+=\r
+= RF_MemToMap\r
+=\r
+= Copies a string of tiles from main memory to the map,\r
+= accounting for animating tiles\r
+=\r
+=====================\r
+*/\r
+\r
+void RF_MemToMap (unsigned far *source, unsigned plane,\r
+                                 unsigned destx, unsigned desty,\r
+                                 unsigned width, unsigned height)\r
+{\r
+       int                     x,y;\r
+       unsigned        xspot,yspot;\r
+       unsigned        linedelta,updatespot;\r
+       unsigned        far *dest,old,new;\r
+       boolean         changed;\r
+\r
+       RFL_RemoveAnimsInBlock (destx,desty,width,height);\r
+\r
+       dest = mapsegs[plane] + mapbwidthtable[desty]/2 + destx;\r
+\r
+       linedelta = mapwidth - width;\r
+\r
+       for (y=0;y<height;y++,dest+=linedelta)\r
+               for (x=0;x<width;x++)\r
+               {\r
+                       old = *dest;\r
+                       new = *source++;\r
+                       if (old != new)\r
+                       {\r
+                               *dest = new;\r
+                               changed = true;\r
+                       }\r
+                       else\r
+                               changed = false;\r
+\r
+                       dest++;\r
+                       xspot = destx+x-originxtile;\r
+                       yspot = desty+y-originytile;\r
+                       if (yspot < PORTTILESHIGH && xspot < PORTTILESWIDE)\r
+                       {\r
+                               if (changed)\r
+                               {\r
+                                       updatespot = uwidthtable[yspot]+xspot;\r
+                                       RFL_NewTile(updatespot);\r
+                               }\r
+                               RFL_CheckForAnimTile (destx+x,desty+y);\r
+                       }\r
+               }\r
+}\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+=====================\r
+=\r
+= RFL_BoundNewOrigin\r
+=\r
+= Copies a string of tiles from main memory to the map,\r
+= accounting for animating tiles\r
+=\r
+=====================\r
+*/\r
+\r
+void RFL_BoundNewOrigin (unsigned orgx,unsigned orgy)\r
+{\r
+       int     check,edge;\r
+\r
+//\r
+// calculate new origin related globals\r
+//\r
+       if (orgx<originxmin)\r
+         orgx=originxmin;\r
+       else if (orgx>originxmax)\r
+         orgx=originxmax;\r
+\r
+       if (orgy<originymin)\r
+         orgy=originymin;\r
+       else if (orgy>originymax)\r
+         orgy=originymax;\r
+\r
+       originxtile = orgx>>G_T_SHIFT;\r
+       originytile = orgy>>G_T_SHIFT;\r
+\r
+       for (check=0;check<vscrollblocks;check++)\r
+       {\r
+               edge = vscrolledge[check];\r
+               if (edge>=originxtile && edge <=originxtile+10)\r
+               {\r
+                       orgx = (edge+1)*TILEGLOBAL;\r
+                       break;\r
+               }\r
+               if (edge>=originxtile+11 && edge <=originxtile+20)\r
+               {\r
+                       orgx = (edge-20)*TILEGLOBAL;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       for (check=0;check<hscrollblocks;check++)\r
+       {\r
+               edge = hscrolledge[check];\r
+               if (edge>=originytile && edge <=originytile+6)\r
+               {\r
+                       orgy = (edge+1)*TILEGLOBAL;\r
+                       break;\r
+               }\r
+               if (edge>=originytile+7 && edge <=originytile+13)\r
+               {\r
+                       orgy = (edge-13)*TILEGLOBAL;\r
+                       break;\r
+               }\r
+       }\r
+\r
+\r
+       RFL_CalcOriginStuff (orgx,orgy);\r
+}\r
+\r
 \r
+//===========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= RF_ClearBlock\r
+=\r
+= Posts erase blocks to clear a certain area of the screen to the master\r
+= screen, to erase text or something draw directly to the screen\r
+=\r
+= Parameters in pixels, but erasure is byte bounded\r
+=\r
+=====================\r
+*/\r
+\r
+void RF_ClearBlock (int        x, int y, int width, int height)\r
+{\r
+       eraseblocktype block;\r
+\r
+#if GRMODE == EGAGR\r
+       block.screenx = x/8+originxscreen;\r
+       block.screeny = y+originyscreen;\r
+       block.width = (width+(x&7)+7)/8;\r
+       block.height = height;\r
+       memcpy (eraselistptr[0]++,&block,sizeof(block));\r
+       memcpy (eraselistptr[1]++,&block,sizeof(block));\r
+#endif\r
+\r
+#if GRMODE == CGAGR\r
+       block.screenx = x/4+originxscreen;\r
+       block.screeny = y+originyscreen;\r
+       block.width = (width+(x&3)+3)/4;\r
+       block.height = height;\r
+       memcpy (eraselistptr[0]++,&block,sizeof(block));\r
+#endif\r
+\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= RF_RedrawBlock\r
+=\r
+= Causes a number of tiles to be redrawn to the master screen and updated\r
+=\r
+= Parameters in pixels, but erasure is tile bounded\r
+=\r
+=====================\r
+*/\r
+\r
+void RF_RedrawBlock (int x, int y, int width, int height)\r
+{\r
+       int     xx,yy,xl,xh,yl,yh;\r
+\r
+       xl=(x+panx)/16;\r
+       xh=(x+panx+width+15)/16;\r
+       yl=(y+pany)/16;\r
+       yh=(y+pany+height+15)/16;\r
+       for (yy=yl;yy<=yh;yy++)\r
+               for (xx=xl;xx<=xh;xx++)\r
+                       RFL_NewTile (yy*UPDATEWIDE+xx);\r
+}\r
+\r
+\r
+//===========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= RF_CalcTics\r
+=\r
+=====================\r
+*/\r
+\r
+void RF_CalcTics (void)\r
+{\r
+       long    newtime,oldtimecount;\r
+\r
+//\r
+// calculate tics since last refresh for adaptive timing\r
+//\r
+       if (lasttimecount > TimeCount)\r
+               TimeCount = lasttimecount;              // if the game was paused a LONG time\r
+\r
+       if (DemoMode)                                   // demo recording and playback needs\r
+       {                                                               // to be constant\r
+//\r
+// take DEMOTICS or more tics, and modify Timecount to reflect time taken\r
+//\r
+               oldtimecount = lasttimecount;\r
+               while (TimeCount<oldtimecount+DEMOTICS*2)\r
+               ;\r
+               lasttimecount = oldtimecount + DEMOTICS;\r
+               TimeCount = lasttimecount + DEMOTICS;\r
+               tics = DEMOTICS;\r
+       }\r
+       else\r
+       {\r
+//\r
+// non demo, so report actual time\r
+//\r
+               do\r
+               {\r
+                       newtime = TimeCount;\r
+                       tics = newtime-lasttimecount;\r
+               } while (tics<MINTICS);\r
+               lasttimecount = newtime;\r
+\r
+#ifdef PROFILE\r
+                       strcpy (scratch,"\tTics:");\r
+                       itoa (tics,str,10);\r
+                       strcat (scratch,str);\r
+                       strcat (scratch,"\n");\r
+                       write (profilehandle,scratch,strlen(scratch));\r
+#endif\r
+\r
+               if (tics>MAXTICS)\r
+               {\r
+                       TimeCount -= (tics-MAXTICS);\r
+                       tics = MAXTICS;\r
+               }\r
+       }\r
+}\r
 \r
 /*\r
 =============================================================================\r
@@ -969,6 +1483,39 @@ void RF_ForceRefresh (void)
 \r
 #if GRMODE == EGAGR\r
 \r
+/*\r
+=====================\r
+=\r
+= RF_FindFreeBuffer\r
+=\r
+= Finds the start of unused, non visable buffer space\r
+=\r
+=====================\r
+*/\r
+\r
+unsigned RF_FindFreeBuffer (void)\r
+{\r
+       unsigned        spot,i,j;\r
+       boolean         ok;\r
+\r
+       for (i=0;i<3;i++)\r
+       {\r
+               spot = screenstart[i]+SCREENSPACE;\r
+               ok = true;\r
+               for (j=0;j<3;j++)\r
+                       if (spot == screenstart[j])\r
+                       {\r
+                               ok = false;\r
+                               break;\r
+                       }\r
+               if (ok)\r
+                       return spot;\r
+       }\r
+\r
+       return 0;       // never get here...\r
+}\r
+\r
+//===========================================================================\r
 \r
 /*\r
 =====================\r
@@ -984,10 +1531,11 @@ void RF_NewPosition (unsigned x, unsigned y)
        byte    *page0ptr,*page1ptr;\r
        unsigned        updatenum;\r
 \r
-//\r
+       RFL_BoundNewOrigin (x,y);\r
+/*??\r
 // calculate new origin related globals\r
 //\r
-       RFL_CalcOriginStuff (x,y);\r
+       RFL_CalcOriginStuff (x,y);*/\r
 \r
 //\r
 // clear out all animating tiles\r
@@ -997,10 +1545,11 @@ void RF_NewPosition (unsigned x, unsigned y)
 //\r
 // set up the new update arrays at base position\r
 //\r
-       memset (tilecache,0,sizeof(tilecache));         // old cache is invalid\r
+//??   memset (tilecache,0,sizeof(tilecache));         // old cache is invalid\r
 \r
        updatestart[0] = baseupdatestart[0];\r
        updatestart[1] = baseupdatestart[1];\r
+       updateptr = updatestart[otherpage];\r
 \r
        page0ptr = updatestart[0]+PORTTILESWIDE;        // used to stick "0"s after rows\r
        page1ptr = updatestart[1]+PORTTILESWIDE;\r
@@ -1233,10 +1782,11 @@ void RF_PlaceSprite (void **user,unsigned globalx,unsigned globaly,
 {\r
        spritelisttype  register *sprite,*next;\r
        spritetabletype far *spr;\r
-       spritetype /*_seg*/     *block;\r
+       spritetype _seg *block;\r
        unsigned        shift,pixx;\r
+       char            str[80],str2[10];\r
 \r
-       if (!spritenumber)\r
+       if (!spritenumber || spritenumber == (unsigned)-1)\r
        {\r
                RF_RemoveSprite (user);\r
                return;\r
@@ -1276,7 +1826,7 @@ void RF_PlaceSprite (void **user,unsigned globalx,unsigned globaly,
        // this is a brand new sprite, so allocate a block from the array\r
 \r
                if (!spritefreeptr)\r
-                       //Quit ("RF_PlaceSprite: No free spots in spritearray!");\r
+                       Quit ("RF_PlaceSprite: No free spots in spritearray!");\r
 \r
                sprite = spritefreeptr;\r
                spritefreeptr = spritefreeptr->nextsprite;\r
@@ -1294,7 +1844,15 @@ linknewspot:
 // write the new info to the sprite\r
 //\r
        spr = &spritetable[spritenumber-STARTSPRITES];\r
-       block = (spritetype /*_seg*/ *)grsegs[spritenumber];\r
+       block = (spritetype _seg *)grsegs[spritenumber];\r
+\r
+       if (!block)\r
+       {\r
+               strcpy (str,"RF_PlaceSprite: Placed an uncached sprite:");\r
+               itoa (spritenumber,str2,10);\r
+               strcat (str,str2);\r
+               Quit (str);\r
+       }\r
 \r
        globaly+=spr->orgy;\r
        globalx+=spr->orgx;\r
@@ -1646,7 +2204,6 @@ redraw:
 void RF_Refresh (void)\r
 {\r
        byte    *newupdate;\r
-       long    newtime;\r
 \r
        updateptr = updatestart[otherpage];\r
 \r
@@ -1703,28 +2260,7 @@ asm      mov     [WORD PTR es:di],UPDATETERMINATE
 //\r
 // calculate tics since last refresh for adaptive timing\r
 //\r
-       if (lasttimecount > TimeCount)\r
-               lasttimecount = TimeCount;              // if the game was paused a LONG time\r
-       do\r
-       {\r
-               newtime = TimeCount;\r
-               tics = newtime-lasttimecount;\r
-       } while (tics<MINTICS);\r
-       lasttimecount = newtime;\r
-\r
-#ifdef PROFILE\r
-       strcpy (scratch,"\tTics:");\r
-       itoa (tics,str,10);\r
-       strcat (scratch,str);\r
-       strcat (scratch,"\n");\r
-       write (profilehandle,scratch,strlen(scratch));\r
-#endif\r
-\r
-       if (tics>MAXTICS)\r
-       {\r
-               TimeCount -= (tics-MAXTICS);\r
-               tics = MAXTICS;\r
-       }\r
+       RF_CalcTics ();\r
 }\r
 \r
 #endif         // GRMODE == EGAGR\r
@@ -1754,10 +2290,11 @@ void RF_NewPosition (unsigned x, unsigned y)
        byte    *spotptr;\r
        unsigned        updatenum;\r
 \r
-//\r
+       RFL_BoundNewOrigin (x,y);\r
+/*??\r
 // calculate new origin related globals\r
 //\r
-       RFL_CalcOriginStuff (x,y);\r
+       RFL_CalcOriginStuff (x,y);*/\r
 \r
 //\r
 // clear out all animating tiles\r
@@ -1922,10 +2459,11 @@ void RF_PlaceSprite (void **user,unsigned globalx,unsigned globaly,
 {\r
        spritelisttype  register *sprite,*next;\r
        spritetabletype far *spr;\r
-       spritetype /*_seg*/     *block;\r
+       spritetype _seg *block;\r
        unsigned        shift,pixx;\r
+       char            str[80],str2[10];\r
 \r
-       if (!spritenumber)\r
+       if (!spritenumber || spritenumber == (unsigned)-1)\r
        {\r
                RF_RemoveSprite (user);\r
                return;\r
@@ -1961,7 +2499,7 @@ void RF_PlaceSprite (void **user,unsigned globalx,unsigned globaly,
        // this is a brand new sprite, so allocate a block from the array\r
 \r
                if (!spritefreeptr)\r
-                       //Quit ("RF_PlaceSprite: No free spots in spritearray!");\r
+                       Quit ("RF_PlaceSprite: No free spots in spritearray!");\r
 \r
                sprite = spritefreeptr;\r
                spritefreeptr = spritefreeptr->nextsprite;\r
@@ -1979,7 +2517,16 @@ linknewspot:
 // write the new info to the sprite\r
 //\r
        spr = &spritetable[spritenumber-STARTSPRITES];\r
-       block = (spritetype /*_seg*/ *)grsegs[spritenumber];\r
+       block = (spritetype _seg *)grsegs[spritenumber];\r
+\r
+       if (!block)\r
+       {\r
+               strcpy (str,"RF_PlaceSprite: Placed an uncached sprite!");\r
+               itoa (spritenumber,str2,10);\r
+               strcat (str,str2);\r
+               Quit (str);\r
+       }\r
+\r
 \r
        globaly+=spr->orgy;\r
        globalx+=spr->orgx;\r
@@ -2336,29 +2883,7 @@ void RF_Refresh (void)
 //\r
 // calculate tics since last refresh for adaptive timing\r
 //\r
-       if (lasttimecount > TimeCount)\r
-               lasttimecount = TimeCount;              // if the game was paused a LONG time\r
-       do\r
-       {\r
-               newtime = TimeCount;\r
-               tics = newtime-lasttimecount;\r
-       } while (tics<MINTICS);\r
-       lasttimecount = newtime;\r
-\r
-#ifdef PROFILE\r
-       itoa (tics,str,10);\r
-       strcat (str,"\t");\r
-       ltoa (TimeCount,str2,10);\r
-       strcat (str,str2);\r
-       strcat (str,"\t");\r
-       ltoa (LocalTime,str2,10);\r
-       strcat (str,str2);\r
-       strcat (str,"\n");\r
-       write (profile,str,strlen(str));\r
-#endif\r
-       if (tics>MAXTICS)\r
-               tics = MAXTICS;\r
-\r
+       RF_CalcTics ();\r
 }\r
 \r
 #endif         // GRMODE == CGAGR\r