DEFINT A-Z 'FLRMAP2 - simple floormapper with diagram and explanation. 'by Toshi Horie March 2001 'based on Floormapper Ecliptorial and 'Qasir's constant-z optimization explanation. SCREEN 13 CONST sc = 78 'fixed point scaling factor CONST sc2 = 500 'fixed point scaling factor CONST omax = 64 * sc2 'generate texture DIM tex(63, 63) FOR v = 0 TO 63 FOR u = 0 TO 63 tex(u, v) = u XOR v NEXT NEXT 'For coordinate system with the origin at the + sign, 'and up is +, and right is +, units in pixels. h = -18 CONST d = 300 CONST ytop = 0, ybot = 99 'For coordinate system with the origin at B, 'and up direction is +, and right is positive. ' 'eye at y = h * = screen pixel to be plotted with texel o. 'screen at z = d o = floormap texel hit by ray from eye. 'floor at y = 0 v = non-tiled v texel coordinate of floormap. ' ' eye screen ' : | \ # ' : | \ # ' : | \ # ' : | \# ' : +---d----* ' h | # \ ' : | # \ ' : | y # \ ' : | # \ ' : | # \ ' : B========#===========o================floor ' <---------- v -------> ' ' From this diagram, we can derive the equation for v ' using similar triangles. u can be derived likewise. ' u = x* h/(h-y) ' v = d* h/(h-y) ' In the lut!() array, we calculate the values for h/(h-y) ' for all y values inside the screen. The result is that ' only two (none if you use three tables) multiplications are ' needed per scanline. DIM lut(ytop TO ybot) FOR y = ytop TO ybot lut(y) = CINT(sc2 * CSNG(h) / (h - y)) NEXT DIM ulut(ytop TO ybot) FOR y = ytop TO ybot u! = -160& * CSNG(h) / (h - y) IF u! < 0 THEN DO u! = u! + 64 LOOP UNTIL u! >= 0 ELSE DO u! = u! - 64 LOOP UNTIL u! < 64 END IF ulut(y) = CINT(u! * sc2) NEXT DIM vlut(ytop TO ybot) FOR y = ytop TO ybot vlut(y) = CINT(sc * d * CSNG(h) / (h - y)) NEXT '$DYNAMIC DIM divs(0 TO 32000) FOR y = 0 TO 32000 divs(y) = (y \ sc) AND 63 NEXT DIM uu(0 TO omax) FOR y = 0 TO omax uu(y) = (y \ sc2) AND 63 NEXT y DIM olut(0 TO 100) FOR vofs = 0 TO 100 olut(vofs) = (vofs * sc) NEXT vofs DEF SEG = &HA7D0 'start at x=0,y=100 'move forward in the z direction t1! = TIMER FOR q = 1 TO 50 FOR vofs = 1 TO 64 p% = 0 FOR y = ytop TO ybot vv = divs(olut(vofs) + vlut(y)) du = lut(y): u = ulut(y) FOR x = 0 TO 319 IF u > omax THEN u = u - omax POKE p%, tex(uu(u), vv) u = u + du p% = p% + 1 NEXT x NEXT y NEXT vofs IF LEN(INKEY$) THEN EXIT FOR NEXT q t1! = TIMER - t1! SCREEN 0: WIDTH 80 PRINT "FLRMAP2 - fixed point floormapper by Toshi" PRINT vofs * q / (t1!); "fps" END