GLOBAL TRUE, FALSE TRUE = -1 DIM GLOBAL PXL_MASKS(159),PXL_MASKX(159),PXL_MASKR(159),PXL_MASKW(159),PXL_MASKL(159) DIM GLOBAL PXL_XADDR(159),PXL_YADDR(127), PXL_RSRC(127), PXL_RDST(127) GLOBAL PXL_RBUFADDR,PXL_RBUFSIZE,PXL_RBUFDATASIZE,PXL_RBUFDATASTEP,PXL_RCOPYSIZE,PXL_RFULL GLOBAL PXL_PXHI,PXL_PYHI,PXL_FXHI,PXL_FYHI,PXL_PAL1,PXL_PAL2,PXL_DIRADDR,PXL_DIRSIZE 'PXL LIBRARY 2.0, BY NATHANIEL R. BABIAK, ED. NOVEMBER 16, 2020. DIM GLOBAL RC_ADD1(159),RC_ADD2(159),RC_ADD3(159),RC_SUB1(159),RC_SUB2(159) DIM GLOBAL MAP_C(63,63),MAP_P(63,63),SKY_N(7),SKY_C(7),SKY_S(9),SKY_L(9),SKY_R(9),SKY_P(9) DIM GLOBAL SKY_T(9),SKY_V(9) GLOBAL RC_PROJA,RC_LOCX,RC_LOCY,RC_DSCREENX,RC_DSCREENY,RC_RAYX,RC_RAYY,RC_RAYM GLOBAL RC_X,RC_Y,RC_DX,RC_DY,RC_MAPX,RC_MAPY,RC_DMAPX,RC_DMAPY GLOBAL RC_INTERLEAVE,RC_FOV5,RC_DSCREENF,RC_COL,RC_SIDE,RC_WALL,RC_BOXC,RC_BOXP,SKY_F GLOBAL SKY_ITER,MOV_FWD0,MOV_BAK0,MOV_ROT0,MOV_STR0,MOV_FWD1,MOV_BAK1,MOV_ROT1,MOV_STR1 GLOBAL MOV_NEG_ROT0,MOV_NEG_STR0,MOV_NEG_ROT1,MOV_NEG_STR1,MOV_RAD,MOV_INC_RAD,MOV_ITER GLOBAL BOX_W,BOX_H,BOX_H5 GLOBAL A0Y,A1Y,A2Y,A3Y,A4Y,A5Y,A6Y,A7Y,B0Y,B1Y,B2Y,B3Y,B4Y,B5Y,B6Y,B7Y GLOBAL A0M,A1M,A2M,A3M,A4M,A5M,A6M,A7M,B0M,B1M,B2M,B3M,B4M,B5M,B6M,B7M 'RAY CASTING DEMO, BY NATHANIEL R. BABIAK, ED. NOVEMBER 22, 2020. GLOBAL FPS_CLS$,FPS_FRAMES,FPS_TIME ' VECTOR NOTATION: ' VECTOR "NAME", RECTANGULAR IS NAMEX AND NAMEY, ANGLE IS NAMEA ' || MAGNITUDE OF THE VECTOR, NAMEM ' <> UNIT VECTOR, USED IN COMMENTS ONLY ' PRE-CALC'D OPTIMIZATION NOTATION: ' ONE ITERATION "STEP", DNAMEX AND DNAMEY ' ADD TERM NAMET, NAMETX, NAMETY, NAMETM, NAMETA ' MULT FACTOR NAMEF, NAMEFX, NAMEFY, NAMEFM, NAMEFA ' NAME * 2.0 NAME2, NAME2X, NAME2Y, NAME2M, NAME2A ' NAME * 0.5 NAME5, NAME5X, NAME5Y, NAME5M, NAME5A ' TO DO, BUT NOT YET... ' SQUARE PANELS. ' SOUNDS. FOUR VOICES AVAILABLE: ' * PLAYER CENTRIC (FOOTSTEPS, TAKING DAMAGER, HEALING, AND PAUSE MENU) ' * NPC CENTRIC (ENEMY NOISES, HURT REACTION TO DAMAGE, BOTH AMBIENT AND ACTIVE) ' * PLAYER CAUSED (DOORS MOVING, SWITCHES, BUTTONS, EXPLODING WALLS, WEAPON NOISES) ' * NPC CAUSED (MUSIC COULD CHANGE IN PROXIMITY OF NPC) ' RAY CASTING DOORS: ' * (DOORS CAN'T BE CLOSED, TOO MANY CC TO RENDER DOORS ON JUST ONE SIDE OF A BOX.) ' * DOORS OPEN BY SLIDING LEFT OR RIGHT DUE TO HORZ. SPLIT SCREEN. ' * JUST IMPLEMENT "OPEN" FRACTION OF WALLX IN GAME ENGINE AND SIDE (LEFT/RIGHT). ' * BEFORE AND AFTER OPENING ANIMATION, RENDER NORMALLY. ' * WHEN A RAY IS CAST AND IT HITS THE BOX, WALLX IS CHECKED. IF WALLX IS WITHIN THE OPEN ' FRACTION OF THE DOOR ON THE OPEN SIDE OF THE DOOR, THE RAY CONTINUES. IF NOT, THE SHADER ' IS PASSED AN OFFSET (LIKE WALLX-OPEN_FRAC) SO THE WALL PATTERN WILL BE OFFSET TOO. ' TRY DITHERING PANELS FOR DOORS, SWITCHES, BUTTONS, WHICH WOULD ALLOW ANIMATION. GAMEPAD 1 PAUSE OFF CALL INIT_DISPLAY CALL INIT_MOVE CALL INIT_RAYCAST( %11 ) CALL INIT_SKYBOX CALL INIT_HUD CALL LOAD_RAYCAST( ROM(6) ) CALL LOAD_SKYBOX( 1 ) CALL LOAD_HUD( 10.5, -20.0 ) CALL LOAD_DISPLAY CALL INIT_DEBUG_FPS IF RC_INTERLEAVE = %00 THEN DO CALL DRAW_SKYBOX CALL DRAW_HUD CALL DRAW_RAYCAST00 CALL INPUT_MOVE CALL DRAW_DEBUG_FPS LOOP ELSE IF RC_INTERLEAVE = %01 THEN DO CALL DRAW_SKYBOX CALL DRAW_HUD CALL DRAW_RAYCAST01 CALL INPUT_MOVE CALL DRAW_DEBUG_FPS LOOP ELSE IF RC_INTERLEAVE = %10 THEN DO CALL DRAW_SKYBOX CALL DRAW_HUD CALL DRAW_RAYCAST10 CALL INPUT_MOVE CALL DRAW_DEBUG_FPS LOOP ELSE IF RC_INTERLEAVE = %11 THEN DO CALL DRAW_SKYBOX CALL DRAW_HUD CALL DRAW_RAYCAST11 CALL INPUT_MOVE CALL DRAW_DEBUG_FPS LOOP END IF SUB INIT_RAYCAST( INTERLEAVE ) 'SET INTERLEAVE, %00=OFF, %01=SMALL, %10=MEDIUM, %11=LARGE. MAIN GAME LOOP TOGGLES SIGN. RC_INTERLEAVE = INTERLEAVE ' @@| | | | VECTORS: ' |@@@@| | | | | TAIL TIP NAME ' ---(R)-+----+----+----+----+-- 0 L (LOCATION) OF BIOLOGICAL EYE ' | |\ | | | | | L P <> (PROJECTION) (NOT TO SCALE) ' | | \| | | | | @ S SCREEN, DEFINED BY <> AND FOV ' ---+-|--\----+----+----+----+--- L R RAY, CAST PATH ' | | |\ @----@ | | * R RAY, EFFECTIVE DEPTH ' | | | \ |\XXX| | | TRIANGLES: ' ---+-|-@+--Y-+-\XX|----+----+--- POINTS NAME ' | | |\ \| \X| | | L@S PROJECTION ' | | |Y\ X \| | | XXX CAST X, HYPOTINUSE IS UNIT DIST. ON X-AXIS ' ---+-|-@--@--+\---@----+----+--- Y CAST Y, HYPOTINUSE IS UNIT DIST. ON Y-AXIS ' | | | | @-----(P)----(S) NOTES: ' | | | | \ | || / * AND <> ALSO DEFINE IN-GAME USER. ' ---+-|--+----+---\+---|+---/+--- MOVING AND ROTATING PROJECTION TRIANGLE CHANGES ' | | | | \ _|_ / | IN-GAME USER POSITION AND DIRECTION. ' | | | | |\/ | \/FOV * FIRST RAY IS CAST ALONG PATH L-@, LAST RAY IS CAST ' ---+-|--+----+----+-\-|-/---+--- ALONG PATH L-S. PATH STARTS AT , AND MIGHT HIT ' | | | | | \|/ | A BOX EVEN BEFORE REACHING THE SCREEN PLANE. (NOTE ' | *---------------(L) | <> IS A UNIT B/C RAY CAN HIT BEFORE SCREEN.) ' --+----+----+----+--/-+----+-- * TRIANGLES XXX AND Y ARE SHOWN ALIGNED WITH THE ' | | | ^ / | | BACKGROUND GRID'S UNIT SPACING, BUT THIS IS ONLY ' | | |/ | FOR CLARITY AND NOT A RESTRICTION. ' --0--> * ALL UNITS ARE "BOXES" OR RADIANS UNLESS COMMENTED. ' | RC_FOV5 = 66 / 57.2957795 * 0.5 SCREENM = TAN( RC_FOV5 ) * 1.0 * 2 'PRE-CALC, USEFUL IN SUB CALC_RC_COL, UNITS PXL, PXL/BOX, (1 UNIT) BOX. BOX_W = PXL_PXHI / SCREENM * 1 'PRE-CALC, UNITS PXL. SEE CALC_RC_COL (USED FOR MOULDING SIZE). BOX_H = BOX_W * 1.00 'PRE-CALC, UNITS PXL. SEE CALC_RC_COL (USED FOR BOX HEIGHT). BOX_H5 = BOX_W * 0.75 * 0.5 'THIS FACTOR OF HAS UNITS OF BOX/PXL. NO CLUE WHY SQR REQUIRED. RC_DSCREENF = SQR( SCREENM ) / PXL_PXHI IF RC_INTERLEAVE AND 1 THEN ADD RC_DSCREENF, RC_DSCREENF RC_LOCX = 0.0 RC_LOCY = 0.0 RC_PROJA = 0.0 'NOTE CALL CAL_MOVE WILL INITIALIZE . CALL CALC_MOVE( 0, 0, 6.28318531 ) 'PRECALC BITMASKS USED BY CALC_COLUMN. FOR PX = 0 TO 159 BIT = 7 - PX MOD 8 RC_ADD1( PX ) = 2 ^ BIT 'INTERLEAVE AND 1 WILL ONLY USE EVEN VALUES OF PX NOT ODD. IF RC_INTERLEAVE AND 1 THEN ADD RC_ADD1( PX ), RC_ADD1( PX ) \ 2 RC_ADD2( PX ) = RC_ADD1( PX ) * 256 RC_ADD3( PX ) = RC_ADD1( PX ) + RC_ADD2( PX ) RC_SUB1( PX ) = -RC_ADD1( PX ) RC_SUB2( PX ) = -RC_ADD2( PX ) NEXT PX END SUB SUB LOAD_RAYCAST( R ) DIM B(15) 'LOWRES NX GFX TOOL IS LIMITED, I'D REALLY LIKE TO USE PAGE 4 TO START, BUT NOT YET... CHR_PAGE = 2 CHR_NUM = 64 * ( CHR_PAGE - 1 ) LO = CHR_NUM + 4 HI = CHR_NUM + 12 B( 1) = CHR_NUM + 24 B( 2) = CHR_NUM + 25 B( 3) = CHR_NUM + 26 B( 4) = CHR_NUM + 27 B( 5) = CHR_NUM + 28 B( 6) = CHR_NUM + 29 B( 7) = CHR_NUM + 30 B( 8) = CHR_NUM + 57 B( 9) = CHR_NUM + 58 B(10) = CHR_NUM + 59 B(11) = CHR_NUM + 60 B(12) = CHR_NUM + 61 B(13) = CHR_NUM + 62 B(14) = CHR_NUM + 63 B(15) = CHR_NUM + 54 MAPW = PEEK( R + 2 ) MAPH = PEEK( R + 3 ) A = R + 4 'Y NEEDS TO STEP BACKWARDS TO MATCH ORIENTATION BETWEEN ROM AND MAP ARRAYS. FOR Y = MAPH - 1 TO 0 STEP -1 FOR X = 0 TO MAPW - 1 C = PEEK( A ) INC A MAP_P( X, Y ) = PEEK( A ) INC A IF C >= LO AND C <= HI THEN MAP_C( X, Y ) = 0 'SET PLAYER'S STARTING POSITING . RC_LOCX = X + 0.5 RC_LOCY = Y + 0.5 RC_PROJA = 0.0 'DETERMINE ANGLE OF PLAYER'S STARTING POSITION. UNITS DEG. DEG = 11.25 * ( C - LO ) FX = ( PEEK( A ) AND 8 ) <> 0 FY = ( PEEK( A ) AND 16 ) <> 0 IF FX XOR FY THEN DEG = 90 - DEG IF FX AND NOT FY THEN ADD DEG, 90 IF FX AND FY THEN ADD DEG, 180 IF NOT FX AND FY THEN ADD DEG, 270 ADD DEG, 360 CALL CALC_MOVE( 0, 0, DEG / 57.2957795 ) ELSE 'FIGURE OUT WHICH BOX NUMBER THE CHARACTER REPRESENTS. FOR I = 1 TO 15 IF C = B( I ) THEN EXIT NEXT I 'NOTE IF A CHARACTER WAS FOUND, THEN 1<=I<=15. IF NOT, THEN I=16. MAP_C( X, Y ) = I MOD 16 END IF NEXT X NEXT Y END SUB SUB DRAW_RAYCAST00 RC_RAYX = COS( RC_PROJA + RC_FOV5 ) RC_RAYY = SIN( RC_PROJA + RC_FOV5 ) 'UNITS PXL. RC_COL = 0 REPEAT CALL CALC_RC_BEG CALL CALC_RC_COL( A0Y, A0M, B0Y, B0M ) CALL CALC_RC_END0 CALL CALC_RC_BEG CALL CALC_RC_COL( A1Y, A1M, B1Y, B1M ) CALL CALC_RC_END0 CALL CALC_RC_BEG CALL CALC_RC_COL( A2Y, A2M, B2Y, B2M ) CALL CALC_RC_END0 CALL CALC_RC_BEG CALL CALC_RC_COL( A3Y, A3M, B3Y, B3M ) CALL CALC_RC_END0 CALL CALC_RC_BEG CALL CALC_RC_COL( A4Y, A4M, B4Y, B4M ) CALL CALC_RC_END0 CALL CALC_RC_BEG CALL CALC_RC_COL( A5Y, A5M, B5Y, B5M ) CALL CALC_RC_END0 CALL CALC_RC_BEG CALL CALC_RC_COL( A6Y, A6M, B6Y, B6M ) CALL CALC_RC_END0 CALL CALC_RC_BEG CALL CALC_RC_COL( A7Y, A7M, B7Y, B7M ) CALL CALC_RC_END0 CALL MNPEN0 UNTIL RC_COL = PXL_PXHI END SUB SUB DRAW_RAYCAST01 RC_RAYX = COS( RC_PROJA + RC_FOV5 ) RC_RAYY = SIN( RC_PROJA + RC_FOV5 ) 'UNITS PXL. RC_COL = 0 REPEAT CALL CALC_RC_BEG CALL CALC_RC_COL( A0Y, A0M, B0Y, B0M ) CALL CALC_RC_END1 CALL CALC_RC_BEG CALL CALC_RC_COL( A2Y, A2M, B2Y, B2M ) CALL CALC_RC_END1 CALL CALC_RC_BEG CALL CALC_RC_COL( A4Y, A4M, B4Y, B4M ) CALL CALC_RC_END1 CALL CALC_RC_BEG CALL CALC_RC_COL( A6Y, A6M, B6Y, B6M ) CALL CALC_RC_END1 CALL MNPEN1 UNTIL RC_COL = PXL_PXHI END SUB SUB DRAW_RAYCAST10 IF RC_INTERLEAVE > 0 THEN RC_RAYX = COS( RC_PROJA + RC_FOV5 ) RC_RAYY = SIN( RC_PROJA + RC_FOV5 ) 'UNITS PXL. RC_COL = 0 COLHI = PXL_PXHI \ 2 ELSE RC_RAYX = COS( RC_PROJA + RC_FOV5 ) + RC_DSCREENX * PXL_PXHI / 2 RC_RAYY = SIN( RC_PROJA + RC_FOV5 ) + RC_DSCREENY * PXL_PXHI / 2 'UNITS PXL. RC_COL = PXL_PXHI \ 2 COLHI = PXL_PXHI END IF RC_INTERLEAVE = -RC_INTERLEAVE REPEAT CALL CALC_RC_BEG CALL CALC_RC_COL( A0Y, A0M, B0Y, B0M ) CALL CALC_RC_END0 CALL CALC_RC_BEG CALL CALC_RC_COL( A1Y, A1M, B1Y, B1M ) CALL CALC_RC_END0 CALL CALC_RC_BEG CALL CALC_RC_COL( A2Y, A2M, B2Y, B2M ) CALL CALC_RC_END0 CALL CALC_RC_BEG CALL CALC_RC_COL( A3Y, A3M, B3Y, B3M ) CALL CALC_RC_END0 CALL CALC_RC_BEG CALL CALC_RC_COL( A4Y, A4M, B4Y, B4M ) CALL CALC_RC_END0 CALL CALC_RC_BEG CALL CALC_RC_COL( A5Y, A5M, B5Y, B5M ) CALL CALC_RC_END0 CALL CALC_RC_BEG CALL CALC_RC_COL( A6Y, A6M, B6Y, B6M ) CALL CALC_RC_END0 CALL CALC_RC_BEG CALL CALC_RC_COL( A7Y, A7M, B7Y, B7M ) CALL CALC_RC_END0 CALL MNPEN0 UNTIL RC_COL = COLHI END SUB SUB DRAW_RAYCAST11 IF RC_INTERLEAVE > 0 THEN RC_RAYX = COS( RC_PROJA + RC_FOV5 ) RC_RAYY = SIN( RC_PROJA + RC_FOV5 ) 'UNITS PXL. RC_COL = 0 COLHI = PXL_PXHI \ 2 ELSE RC_RAYX = COS( RC_PROJA + RC_FOV5 ) + RC_DSCREENX * PXL_PXHI / 4 RC_RAYY = SIN( RC_PROJA + RC_FOV5 ) + RC_DSCREENY * PXL_PXHI / 4 'UNITS PXL. RC_COL = PXL_PXHI \ 2 COLHI = PXL_PXHI END IF RC_INTERLEAVE = -RC_INTERLEAVE REPEAT CALL CALC_RC_BEG CALL CALC_RC_COL( A0Y, A0M, B0Y, B0M ) CALL CALC_RC_END1 CALL CALC_RC_BEG CALL CALC_RC_COL( A2Y, A2M, B2Y, B2M ) CALL CALC_RC_END1 CALL CALC_RC_BEG CALL CALC_RC_COL( A4Y, A4M, B4Y, B4M ) CALL CALC_RC_END1 CALL CALC_RC_BEG CALL CALC_RC_COL( A6Y, A6M, B6Y, B6M ) CALL CALC_RC_END1 CALL MNPEN1 UNTIL RC_COL = COLHI END SUB SUB CALC_RC_BEG RC_MAPX = INT( RC_LOCX ) RC_MAPY = INT( RC_LOCY ) IF RC_RAYX > 0 THEN IF RC_RAYY > 0 THEN RC_DX = 1 / RC_RAYX RC_DY = 1 / RC_RAYY RC_Y = ( RC_MAPY + 1 - RC_LOCY ) * RC_DY RC_DMAPY = 1 ELSE IF RC_RAYY THEN RC_DX = 1 / RC_RAYX RC_DY = TRUE / RC_RAYY RC_Y = ( RC_LOCY - RC_MAPY ) * RC_DY RC_DMAPY = TRUE ELSE RC_DX = 0 RC_DY = 1 RC_Y = ( RC_MAPY + 1 - RC_LOCY ) * RC_DY RC_DMAPY = 0 END IF RC_X = ( RC_MAPX + 1 - RC_LOCX ) * RC_DX RC_DMAPX = 1 ELSE IF RC_RAYX THEN IF RC_RAYY > 0 THEN RC_DX = TRUE / RC_RAYX RC_DY = 1 / RC_RAYY RC_Y = ( RC_MAPY + 1 - RC_LOCY ) * RC_DY RC_DMAPY = 1 ELSE IF RC_RAYY THEN RC_DX = TRUE / RC_RAYX RC_DY = TRUE / RC_RAYY RC_Y = ( RC_LOCY - RC_MAPY ) * RC_DY RC_DMAPY = TRUE ELSE RC_DX = 0 RC_DY = 1 RC_Y = ( RC_MAPY + 1 - RC_LOCY ) * RC_DY RC_DMAPY = 0 END IF RC_X = ( RC_LOCX - RC_MAPX ) * RC_DX RC_DMAPX = TRUE ELSE RC_DX = 1 RC_DY = 0 IF RC_RAYY > 0 THEN RC_Y = ( RC_MAPY + 1 - RC_LOCY ) * RC_DY RC_DMAPY = 1 ELSE IF RC_RAYY THEN RC_Y = ( RC_LOCY - RC_MAPY ) * RC_DY RC_DMAPY = TRUE ELSE RC_Y = ( RC_MAPY + 1 - RC_LOCY ) * RC_DY RC_DMAPY = 0 END IF RC_X = ( RC_MAPX + 1 - RC_LOCX ) * RC_DX RC_DMAPX = 0 END IF REPEAT IF RC_X < RC_Y THEN ADD RC_X, RC_DX ADD RC_MAPX, RC_DMAPX RC_SIDE = 0 ELSE ADD RC_Y, RC_DY ADD RC_MAPY, RC_DMAPY RC_SIDE = 1 END IF UNTIL MAP_C( RC_MAPX, RC_MAPY ) RC_BOXC = MAP_C( RC_MAPX, RC_MAPY ) RC_BOXP = MAP_P( RC_MAPX, RC_MAPY ) CALL RC_CALC_BOX END SUB SUB CALC_RC_MID REPEAT IF RC_X < RC_Y THEN ADD RC_X, RC_DX ADD RC_MAPX, RC_DMAPX RC_SIDE = 0 ELSE ADD RC_Y, RC_DY ADD RC_MAPY, RC_DMAPY RC_SIDE = 1 END IF UNTIL MAP_C( RC_MAPX, RC_MAPY ) RC_BOXC = MAP_C( RC_MAPX, RC_MAPY ) RC_BOXP = MAP_P( RC_MAPX, RC_MAPY ) CALL RC_CALC_BOX END SUB SUB CALC_RC_INC IF RC_X < RC_Y THEN ADD RC_X, RC_DX ADD RC_MAPX, RC_DMAPX RC_SIDE = 0 ELSE ADD RC_Y, RC_DY ADD RC_MAPY, RC_DMAPY RC_SIDE = 1 END IF CALL RC_CALC_BOX END SUB SUB RC_CALC_BOX IF RC_SIDE = 1 THEN IF RC_RAYY < 0 THEN RC_RAYM = MAX( 0.0001, ( RC_MAPY - RC_LOCY + 1 ) / RC_RAYY ) RC_WALL = RC_LOCX + RC_RAYM * RC_RAYX RC_WALL = RC_WALL - INT( RC_WALL ) RC_WALL = 1 - RC_WALL ELSE RC_RAYM = MAX( 0.0001, ( RC_MAPY - RC_LOCY ) / RC_RAYY ) RC_WALL = RC_LOCX + RC_RAYM * RC_RAYX RC_WALL = RC_WALL - INT( RC_WALL ) '(NOTHING HERE.) END IF ELSE IF RC_SIDE = 0 THEN IF RC_RAYX < 0 THEN RC_RAYM = MAX( 0.0001, ( RC_MAPX - RC_LOCX + 1 ) / RC_RAYX ) RC_WALL = RC_LOCY + RC_RAYM * RC_RAYY RC_WALL = RC_WALL - INT( RC_WALL ) '(NOTHING HERE.) ELSE RC_RAYM = MAX( 0.0001, ( RC_MAPX - RC_LOCX ) / RC_RAYX ) RC_WALL = RC_LOCY + RC_RAYM * RC_RAYY RC_WALL = RC_WALL - INT( RC_WALL ) RC_WALL = 1 - RC_WALL END IF END IF END SUB SUB CALC_RC_END0 ADD RC_RAYX, RC_DSCREENX ADD RC_RAYY, RC_DSCREENY INC RC_COL END SUB SUB CALC_RC_END1 ADD RC_RAYX, RC_DSCREENX ADD RC_RAYY, RC_DSCREENY ADD RC_COL, 2 END SUB SUB CALC_RC_COL( RETURN_PY1, RETURN_PC1, RETURN_PY2, RETURN_PC2 ) 'FOR EACH (1 PXL WIDE) VERTICAL SLICE (ALONG THE SAME VALUE OF PX), DRAW A TRANSPARENT 'LINE FROM 0 TO PY1-1. THEN, DRAW A COLORED LINE FROM PY1 TO PY2-1. FINALLY, DRAW ANOTHER 'COLORED LINE FROM PY2 TO PXL_PYHI-1. NOTE PXL_PYHI-1 IS AT THE DISPLAY'S HORIZON LINE, 'AND THE PXL DISPLAY WILL AUTOMATICALLY MIRROR THIS "WINDOW" ABOUT THE HORIZON. ALSO, FOR 'SPEED, THE CALC'D BITMASKS WILL BE ADDATIVE NOT "REPLACING". IF RC_BOXC AND %1000 THEN 'BINARY SEARCH THROUGH THE RC_BOXC VALUES FOR SPEED. FOR ANY BOX, RENDER WITH RC_COL, 'RC_SIDE, AND RC_WALL. BOX PROPERTIES ARE STORED IN RC_BOXP. MODIFY MAP_C OR MAP_P USING '. IF RC_BOXC AND %0100 THEN IF RC_BOXC AND %0010 THEN IF RC_BOXC AND %0001 THEN 'NOTE RC_BOXC=%1111=15. RETURN_PY1 = PXL_PYHI / 2 RETURN_PC1 = 0 RETURN_PY2 = RETURN_PY1 RETURN_PC2 = 0 ELSE 'NOTE RC_BOXC=%1110=14. '"I" SHAPE, MUST BE SURROUNDED BY TWO OTHER BOXES. RC_DMAPX = RC_DMAPX * 0.5 ADD RC_X, -ABS(RC_DMAPX) CALL CALC_RC_INC RC_BOXC = 1 CALL CALC_RC_COL( RETURN_PY1, RETURN_PC1, RETURN_PY2, RETURN_PC2 ) END IF ELSE IF RC_BOXC AND %0001 THEN 'NOTE RC_BOXC=%1101=13. RETURN_PY1 = PXL_PYHI / 2 RETURN_PC1 = 0 RETURN_PY2 = RETURN_PY1 RETURN_PC2 = 0 ELSE 'NOTE RC_BOXC=%1100=12. RETURN_PY1 = PXL_PYHI / 2 RETURN_PC1 = 0 RETURN_PY2 = RETURN_PY1 RETURN_PC2 = 0 END IF END IF ELSE IF RC_BOXC AND %0010 THEN IF RC_BOXC AND %0001 THEN 'NOTE RC_BOXC=%1011=11. '"H" SHAPE, MUST BE SURROUNDED BY TWO OTHER BOXES. RC_DMAPY = RC_DMAPY * 0.5 ADD RC_Y, -ABS(RC_DMAPY) CALL CALC_RC_INC RC_BOXC = 1 CALL CALC_RC_COL( RETURN_PY1, RETURN_PC1, RETURN_PY2, RETURN_PC2 ) ELSE 'NOTE RC_BOXC=%1010=10. RETURN_PY1 = PXL_PYHI / 2 RETURN_PC1 = 0 RETURN_PY2 = RETURN_PY1 RETURN_PC2 = 0 END IF ELSE IF RC_BOXC AND %0001 THEN 'NOTE RC_BOXC=%1001=9. RETURN_PY1 = PXL_PYHI / 2 RETURN_PC1 = 0 RETURN_PY2 = RETURN_PY1 RETURN_PC2 = 0 ELSE 'NOTE RC_BOXC=%1000=8. IF RC_WALL < 0.500 THEN CALL CALC_RC_INC IF RC_WALL >= 0.500 THEN CALL CALC_RC_MID CALL CALC_RC_COL( RETURN_PY1, RETURN_PC1, RETURN_PY2, RETURN_PC2 ) ELSE RC_WALL = 1 - RC_WALL - 0.5 RC_BOXC = 5 CALL CALC_RC_COL( RETURN_PY1, RETURN_PC1, RETURN_PY2, RETURN_PC2 ) END IF ELSE RC_WALL = RC_WALL - 0.5 RC_BOXC = 5 CALL CALC_RC_COL( RETURN_PY1, RETURN_PC1, RETURN_PY2, RETURN_PC2 ) END IF END IF END IF END IF ELSE IF RC_BOXC AND %0100 THEN IF RC_BOXC AND %0010 THEN IF RC_BOXC AND %0001 THEN 'NOTE RC_BOXC=%0111=7. RETURN_PY1 = PXL_PYHI / 2 RETURN_PC1 = 0 RETURN_PY2 = RETURN_PY1 RETURN_PC2 = 0 ELSE 'NOTE RC_BOXC=%0110=6. RETURN_PY1 = PXL_PYHI / 2 RETURN_PC1 = 0 RETURN_PY2 = RETURN_PY1 RETURN_PC2 = 0 END IF ELSE IF RC_BOXC AND %0001 THEN 'NOTE RC_BOXC=%0101=5. RETURN_PY1 = PXL_PYHI - BOX_H5 / RC_RAYM RETURN_PC1 = RC_ADD3(RC_COL) 'NOTE EXPRESSION IS 1 CC FASTER THAN "RC_WALL > 0.075 AND RC_WALL < 0.925". IF ABS( RC_WALL - 0.500 ) < 0.425 THEN IF RC_BOXP AND $8 THEN RC_WALL = 1 - RC_WALL RETURN_PY2=RETURN_PY1+0.075*BOX_H/RC_RAYM+0.315*RC_WALL*BOX_H/RC_RAYM IF RC_BOXP AND 1 THEN RETURN_PC2=RC_SUB1(RC_COL) ELSE RETURN_PC2=RC_SUB2(RC_COL) ELSE RETURN_PY2 = RETURN_PY1 RETURN_PC2 = 0 END IF ELSE 'NOTE RC_BOXC=%0100=4. RETURN_PY1 = PXL_PYHI / 2 RETURN_PC1 = 0 RETURN_PY2 = RETURN_PY1 RETURN_PC2 = 0 END IF END IF ELSE IF RC_BOXC AND %0010 THEN IF RC_BOXC AND %0001 THEN 'NOTE RC_BOXC=%0011=3. RETURN_PY1 = PXL_PYHI / 2 RETURN_PC1 = 0 RETURN_PY2 = RETURN_PY1 RETURN_PC2 = 0 ELSE 'NOTE RC_BOXC=%0010=2. RETURN_PY1 = PXL_PYHI / 2 RETURN_PC1 = 0 RETURN_PY2 = RETURN_PY1 RETURN_PC2 = 0 END IF ELSE IF RC_BOXC AND %0001 THEN 'NOTE RC_BOXC=%0001=1. RETURN_PY1 = PXL_PYHI - BOX_H5 / RC_RAYM RETURN_PC1 = RC_ADD3(RC_COL) 'NOTE EXPRESSION IS 1 CC FASTER THAN "RC_WALL > 0.075 AND RC_WALL < 0.925". IF ABS( RC_WALL - 0.500 ) < 0.425 THEN RETURN_PY2 = RETURN_PY1 + 0.075 * BOX_H / RC_RAYM IF RC_BOXP AND 1 THEN RETURN_PC2=RC_SUB1(RC_COL) ELSE RETURN_PC2=RC_SUB2(RC_COL) ELSE RETURN_PY2 = RETURN_PY1 RETURN_PC2 = 0 END IF ELSE 'NOTE RC_BOXC=%0000=0. RETURN_PY1 = PXL_PYHI / 2 RETURN_PC1 = 0 RETURN_PY2 = RETURN_PY1 RETURN_PC2 = 0 END IF END IF END IF END IF 'SUB MNPEN LOOPS PY FROM 0, AND IT WON'T DRAW UNLESS ROW=PY# EXACTLY. NOTE SHOULD ROUND BY 'ADDING 0.5 BEFORE TAKING INT, BUT COSTS TOO MANY CC FOR NO VISIBLE GAIN IN IMAGE QUALITY. RETURN_PY1 = MAX( 0, INT( RETURN_PY1 ) ) RETURN_PY2 = MAX( 0, INT( RETURN_PY2 ) ) 'TO DO, BUT NOT YET... 'BOX 1, BUT MODIFIED SO ONLY INSIDE/OUTSIDE CORNERS HAVE MOULDING. 'SHAPES CAN HAVE X SMALL/LARGE SCALE, SAME FOR Y. BOTH-SMALL COULD ALSO HAVE DUAL/PAIRS. 'DOORS ARE BOTH-LARGE. KEYS CAN MATCH. TRY TOGGLE SWITCHES WITH MOULDING DITHER/BANDS. 'USE DOOR TRANSPARENCY (CALL RC_CONTINUE) FOR OTHER RAYS (SECRETES, WINDOWS, BEAMS, ETC). 'USE ARROWS TO DECORATE DOOR FRAMES. 'TRY DOORS WITH MOULDING DITHER/BANDS. 'PATTERNS CAN BE MODIFIED BY SIN, COS, RND, OR MOD. APPLY TO WALLX IF RELATIVE TO PANEL. 'APPLY TO RC_COL IF RELATIVE TO PXL, BUT THIS SHOULD ONLY BE APPLIED ACROSS ALL PANELS, '(E.G. FOR PLAYER STATUS EFFECTS). PROJECT TO 3D WITH /RC_RAYM, SKIP IF SCREEN TRANSITION. END SUB SUB MNPEN0 'A MULTI-PEN HAS MORE THAN ONE INK COLOR (GOOGLE IT). A MUSIC STAFF NIB IS A PEN WITH MANY 'TIPS (GOOGLE IT). SO I CALL THIS SUB THE MULTI (M) NIB (N) PEN. IT DRAWS EIGHT VERTICAL 'LINES AT ONCE FROM 0 TO PXL_PYHI-1. INITIALLY, THE MULTI-PEN COLOR=0. FOR EACH OF THE 'EIGHT LINES, WHEN ROW=A#Y, THE COLOR CHANGES TO THE FIRST MASK (A#M) COLOR. THIS IS 'REPEATED WHEN ROW=B#Y. ENSURE A#Y<=B#Y FOR EXPECTED RESULTS. FOR SPEED, THE SECOND 'MASK COLOR (B#M) IS AN OFFSET FROM THE FIRST (A#M), NOT ABSOLUTE. AFTER ROW=B#Y, THE 'COLOR IS CONSTANT AND THE PEN TIP IS DRAGGED DOWN THE DISPLAY UNTIL ROW=PXL_PYHI-1. DSTBASE = PXL_XADDR( RC_COL - 8 ) DSTBASE2 = DSTBASE + 8 'SINCE THERE'S EIGHT MULTI-PENS IN PARALLEL (LIKE MUSIC STAFF NIBS), AND SINCE AT THE TOP 'COLOR=0, THERE'S NO NEED TO SET THE COLUMN COLORS INDIVIDUALLY UNTIL THE TOP A#Y ROW. SO, 'CELL-BY-CELL, FILL THE TOP ROWS WITH COLOR=0. CALC THE MIN PXL ROW WHERE THE PATTERN 'BEGINS. MEMORY-ALIGN IT WITH THE CELL. DEC HERE, AVOID USING CC OF "FOR" LOOP. LO=(MIN(MIN(MIN(MIN(MIN(MIN(MIN(A0Y,A1Y),A2Y),A3Y),A4Y),A5Y),A6Y),A7Y) AND %11111000)-1 FOR ROW = 0 TO LO STEP 8 FILL DSTBASE + PXL_YADDR( ROW ), 16 'UNCOMMENT AND RUN TO SEE WHAT'S HAPPENING HERE. 'FILL DSTBASE + PXL_YADDR( ROW ), 16, $FF NEXT ROW 'CHANGE ALL EIGHT MULTI-PEN COLORS AT ROW=A#Y, THEN AT ROW=B#Y. 'CALC THE MAX PXL ROW WHERE THE PATTERN CHANGES, ALSO MEMORY-ALIGN IT WITH THE CELL. 'ADD SEVEN HERE RATHER THAN USING THE CLOCK CYCLES OF THE "FOR" LOOP EVALUATION. HI=(MAX(MAX(MAX(MAX(MAX(MAX(MAX(B0Y,B1Y),B2Y),B3Y),B4Y),B5Y),B6Y),B7Y) AND %11111000)+7 MASK = %0000000000000000 FOR ROW = ROW TO HI IF ROW = A0Y THEN ADD MASK, A0M IF ROW = A1Y THEN ADD MASK, A1M IF ROW = A2Y THEN ADD MASK, A2M IF ROW = A3Y THEN ADD MASK, A3M IF ROW = A4Y THEN ADD MASK, A4M IF ROW = A5Y THEN ADD MASK, A5M IF ROW = A6Y THEN ADD MASK, A6M IF ROW = A7Y THEN ADD MASK, A7M IF ROW = B0Y THEN ADD MASK, B0M IF ROW = B1Y THEN ADD MASK, B1M IF ROW = B2Y THEN ADD MASK, B2M IF ROW = B3Y THEN ADD MASK, B3M IF ROW = B4Y THEN ADD MASK, B4M IF ROW = B5Y THEN ADD MASK, B5M IF ROW = B6Y THEN ADD MASK, B6M IF ROW = B7Y THEN ADD MASK, B7M POKE DSTBASE + PXL_YADDR( ROW ), MASK AND $FF POKE DSTBASE2 + PXL_YADDR( ROW ), MASK \ 256 NEXT ROW 'SINCE THERE'S EIGHT MULTI-PENS IN PARALLEL (LIKE MUSIC STAFF NIBS), AND SINCE THE COLORS 'OF THE BOTTOM ROWS WON'T CHANGE ANYMORE (BELOW B#Y), JUST GO CELL-BY-CELL WITH THE FINAL 'MASK COLORS. DEC PXL_PYHI TO AVOID USING CC OF "FOR" LOOP, RESTORE IT BELOW. MASK2 = MASK \ 256 MASK = MASK AND $FF DEC PXL_PYHI FOR ROW = ROW TO PXL_PYHI STEP 8 FILL DSTBASE + PXL_YADDR( ROW ), 8, MASK FILL DSTBASE2 + PXL_YADDR( ROW ), 8, MASK2 'UNCOMMENT AND RUN TO SEE WHAT'S HAPPENING HERE. 'FILL DSTBASE + PXL_YADDR( ROW ), 16, $FF NEXT ROW INC PXL_PYHI END SUB SUB MNPEN1 'SEE MNPEN DESCRIPTION FIRST. IT'S LIKE THAT, BUT ODD COLUMNS MATCH EVEN COLUMNS. DSTBASE = PXL_XADDR( RC_COL - 8 ) DSTBASE2 = DSTBASE + 8 LO=(MIN(MIN(MIN(A0Y,A2Y),A4Y),A6Y) AND %11111000)-1 FOR ROW = 0 TO LO STEP 8 FILL DSTBASE + PXL_YADDR( ROW ), 16 NEXT ROW HI=(MAX(MAX(MAX(B0Y,B2Y),B4Y),B6Y) AND %11111000)+7 MASK = %0000000000000000 FOR ROW = ROW TO HI IF ROW = A0Y THEN ADD MASK, A0M IF ROW = A2Y THEN ADD MASK, A2M IF ROW = A4Y THEN ADD MASK, A4M IF ROW = A6Y THEN ADD MASK, A6M IF ROW = B0Y THEN ADD MASK, B0M IF ROW = B2Y THEN ADD MASK, B2M IF ROW = B4Y THEN ADD MASK, B4M IF ROW = B6Y THEN ADD MASK, B6M POKE DSTBASE + PXL_YADDR( ROW ), MASK AND $FF POKE DSTBASE2 + PXL_YADDR( ROW ), MASK \ 256 NEXT ROW MASK2 = MASK \ 256 MASK = MASK AND $FF DEC PXL_PYHI FOR ROW = ROW TO PXL_PYHI STEP 8 FILL DSTBASE + PXL_YADDR( ROW ), 8, MASK FILL DSTBASE2 + PXL_YADDR( ROW ), 8, MASK2 NEXT ROW INC PXL_PYHI END SUB SUB INIT_MOVE 'DEFINE RUNNING INCREMENTS. MOV_FWD0 = 0.225 MOV_BAK0 = -0.159 MOV_STR0 = 0.060 MOV_ROT0 = 6.000 / 57.2957795 'DEFINE WALKING INCREMENTS. MOV_FWD1 = 0.100 MOV_BAK1 = -0.071 MOV_STR1 = 0.040 MOV_ROT1 = 2.000 / 57.2957795 'DEFINE CLIPPING COLLISION "CYLINDER" (DIAMOND) RADIUS. MOV_RAD = 0.100 'DIVIDE INCREMENTS FOR USE LATER WITH CALC_MOVE LOOP. FOR MOV_ITER = 1 TO 99 'STILL NOT SURE WHAT FRACTION TO USE HERE, CALC WITH 95% FOR NOW. IF SQR( (MOV_FWD0/MOV_ITER)^2 + (MOV_STR0/MOV_ITER)^2 ) < 0.95 * MOV_RAD THEN EXIT NEXT MOV_ITER MOV_FWD0 = MOV_FWD0 / MOV_ITER MOV_BAK0 = MOV_BAK0 / MOV_ITER MOV_STR0 = MOV_STR0 / MOV_ITER MOV_ROT0 = MOV_ROT0 / MOV_ITER MOV_FWD1 = MOV_FWD1 / MOV_ITER MOV_BAK1 = MOV_BAK1 / MOV_ITER MOV_STR1 = MOV_STR1 / MOV_ITER MOV_ROT1 = MOV_ROT1 / MOV_ITER 'PRE-CALCS FOR SPEED. MOV_NEG_STR0 = -MOV_STR0 MOV_NEG_ROT0 = -MOV_ROT0 MOV_NEG_STR1 = -MOV_STR1 MOV_NEG_ROT1 = -MOV_ROT1 MOV_INC_RAD = MOV_RAD + 1 END SUB SUB CALC_MOVE( FWD, STR, ROT ) IF ROT THEN ADD RC_PROJA, ROT PROJX = COS( RC_PROJA ) PROJY = SIN( RC_PROJA ) RC_DSCREENX = PROJY * RC_DSCREENF RC_DSCREENY = -PROJX * RC_DSCREENF ELSE PROJX = COS( RC_PROJA ) PROJY = SIN( RC_PROJA ) END IF IF FWD <> 0 OR STR <> 0 THEN 'MODEL A "CYLINDER" (DIAMOND) "IN FRONT OF" + (ORIENTATION OF <>). CYLX = RC_LOCX + FWD * PROJX + STR * PROJY + MOV_RAD * PROJX CYLY = RC_LOCY + FWD * PROJY - STR * PROJX + MOV_RAD * PROJY IF MAP_C( CYLX + MOV_RAD, CYLY ) THEN NEWCYLX = INT( CYLX + MOV_RAD ) - MOV_RAD ELSE IF MAP_C( CYLX - MOV_RAD, CYLY ) THEN NEWCYLX = INT( CYLX - MOV_RAD ) + MOV_INC_RAD ELSE NEWCYLX = CYLX END IF IF MAP_C( CYLX, CYLY + MOV_RAD) THEN NEWCYLY = INT( CYLY + MOV_RAD ) - MOV_RAD ELSE IF MAP_C( CYLX, CYLY - MOV_RAD ) THEN NEWCYLY = INT( CYLY - MOV_RAD ) + MOV_INC_RAD ELSE NEWCYLY = CYLY END IF RC_LOCX = NEWCYLX - MOV_RAD * PROJX RC_LOCY = NEWCYLY - MOV_RAD * PROJY END IF END SUB SUB INPUT_MOVE USE_INPUT = FALSE IF LEFT(0) THEN IF BUTTON(0,1) THEN ROT = MOV_ROT1 STR = MOV_STR1 IF UP(0) THEN FWD = MOV_FWD1 ELSE IF DOWN(0) THEN FWD = MOV_BAK1 ELSE FWD = 0.00 END IF ELSE ROT = MOV_ROT0 STR = MOV_STR0 IF UP(0) THEN FWD = MOV_FWD0 ELSE IF DOWN(0) THEN FWD = MOV_BAK0 ELSE FWD = 0.00 END IF END IF USE_INPUT = TRUE ELSE IF RIGHT(0) THEN IF BUTTON(0,1) THEN ROT = MOV_NEG_ROT1 STR = MOV_NEG_STR1 IF UP(0) THEN FWD = MOV_FWD1 ELSE IF DOWN(0) THEN FWD = MOV_BAK1 ELSE FWD = 0.00 END IF ELSE ROT = MOV_NEG_ROT0 STR = MOV_NEG_STR0 IF UP(0) THEN FWD = MOV_FWD0 ELSE IF DOWN(0) THEN FWD = MOV_BAK0 ELSE FWD = 0.00 END IF END IF USE_INPUT = TRUE ELSE IF UP(0) THEN ROT = 0.00 STR = 0.00 IF BUTTON(0,1) THEN FWD = MOV_FWD1 ELSE FWD = MOV_FWD0 USE_INPUT = TRUE ELSE IF DOWN(0) THEN ROT = 0.00 STR = 0.00 IF BUTTON(0,1) THEN FWD = MOV_BAK1 ELSE FWD = MOV_BAK0 USE_INPUT = TRUE ELSE IF PAUSE THEN CALL PAUSE_MENU END IF IF USE_INPUT THEN FOR ITER = 1 TO MOV_ITER CALL CALC_MOVE( FWD, STR, ROT ) NEXT ITER END IF END SUB SUB INIT_SKYBOX 'UNITS PXL. PROJM = ( PXL_PXHI / 2 ) / TAN( RC_FOV5 ) 'LET RANGE BE ALLOWABLE ANGLES (+/-). THEN SKYBOX IS COL=PROJM*TAN(RANGE) AT CENTER, UNITS 'PXL. (OFFSET LATER SINCE COL ISN'T MEASURED FROM CENTER OF SPRITE.) NOTE TAN(RANGE)~= 'SLOPE*RANGE, SO PRE-CALC SLOPE FACTOR, UNITS (1) PER-RAD. SKY_F = TAN( RC_FOV5 ) / RC_FOV5 'NOW FORMULA IS COL=PROJM*SKY_F*RANGE. 'FINAL FORMULA IS COL=SKY_F*RANGE, UNITS ARE PXL, PXL/RAD, AND RAD. SKY_F = PROJM * SKY_F END SUB SUB LOAD_SKYBOX( LEVEL ) 'UNITS PXL. PROJM = ( PXL_PXHI / 2 ) / TAN( RC_FOV5 ) ROT = MOV_ITER * MAX( MOV_ROT0, MOV_ROT1 ) IF LEVEL = 1 THEN RESTORE SKY_DATA1 READ SKY_ITER FOR I = 1 TO SKY_ITER READ SKY_N(I), SKY_C(I), SKY_S(I), SKY_L(I), SKY_R(I), SKY_P(I) SKY_L(I) = SKY_L(I) / 57.2957795 'TEMP-CALC SPRITE CENTER, UNITS PXL. COL = 4 * SKY_S(I) + 4 'PRE-CALC OFFSET TERM DUE TO SPRITE WIDTH. UNITS PXL. SKY_T(I) = PXL_PXHI / 2 - COL 'TEMP-CALC SPRITE HORZ OFFSET, UNITS PXL. COL = COL + SKY_F * ( RC_FOV5 + ROT ) 'PRE-CALC SPRITE VIEW RANGE. SKY_V(I) = COL / SKY_F NEXT I SKY_DATA1: 'SKY_ITER DATA 5 'SPRITE, CHAR, SIZE, LOC DEG (NOT RAD), PXL ROW, PAL DATA 50, 128, 1, 90, 0, 2 DATA 51, 132, 3, 180, 30, 2 DATA 52, 130, 1, 0, 0, 2 DATA 52, 130, 1, 360, 0, 2 DATA 53, 160, 1, 270, 0, 2 END SUB SUB DRAW_SKYBOX IF RC_PROJA < 0 THEN ADD RC_PROJA, 6.28318531 IF RC_PROJA >= 6.28318531 THEN ADD RC_PROJA, -6.28318531 FOR I = 1 TO SKY_ITER RANGE = SKY_L(I) - RC_PROJA IF ABS(RANGE) <= SKY_V(I) THEN SPRITE SKY_N(I) PAL SKY_P(I) SIZE SKY_S(I) SPRITE SKY_N(I), SKY_T(I) - SKY_F * RANGE, SKY_R(I), SKY_C(I) END IF NEXT I END SUB SUB INIT_HUD 'ANY NECESSARY RE-CALCS FOR SPEED. BUT NOT YET... END SUB SUB LOAD_HUD( LOCX, LOCY ) 'DEVELOP TRANSFORMATION SO THAT EACH ANGLE OF RC_PROJA YEILDS A HUD SPRITE X AND Y VALUE 'AROUND EDGE OF SCREEN. WILL BE BASED ON CURRENT RC_LOCX AND RC_LOCY. WILL NEED UPDATED AS 'MOVES THROUGHOUT LEVEL. PARALLAX COULD BE BAD, DON'T LET PLAYER GET WITHIN ~10 BOX UNITS. END SUB SUB DRAW_HUD 'SHOW SPRITE 0 WITH LOOKUP ARRAYS FOR SPRITE X AND Y LOCATION. END SUB SUB PAUSE_MENU 'LOWRES NX GFX TOOL IS LIMITED, I'D REALLY LIKE TO USE PAGE 4 TO START, BUT NOT YET... CHR_PAGE = 2 CHR_NUM = 64 * ( CHR_PAGE - 1 ) BUF_ADDR = 16 * ( CHR_NUM + 24 ) SPR_ADDR = 16 * ( 128 ) 'THIS SUB WILL CORRUPT SOME SPRITE CHAR AND PAL DATA. DON'T SHOW ANY CORRUPTED SPRITES. 'CHECK THAT P4SAVE WORKS, BUT NOT YET... P4SAVE = PEEKL( $FF00 + 4 * 4 ) SPRITE VIEW OFF PALETTE 4, , %000001, %000010, 'COPY THE PXL DISPLAY OVER TO THE PAUSE MENU'S BORDER. DST1 = $8000 + 16 * 128 DST2 = $8000 + 16 * 136 SRCBASE1 = PXL_XADDR( 0 ) SRCBASE2 = PXL_XADDR( 152 ) FOR PY = 0 TO 63 STEP 8 COPY SRCBASE1 + PXL_YADDR( PY ), 16 TO DST1 COPY SRCBASE2 + PXL_YADDR( PY ), 16 TO DST2 ADD DST1, 16 ADD DST2, 16 NEXT PY 'NOTE DST2=$8000+16*144. SRCBASE2 = PXL_YADDR( 0 ) FOR PX = 8 TO 151 STEP 8 COPY PXL_XADDR( PX ) + SRCBASE2, 16 TO DST2 ADD DST2, 16 NEXT PX 'PAUSE THE PXL DISPLAY. ON RASTER OFF 'COPY THE CHAR DATA FROM ROM (THE PXL DISPLAY BUFFER CORRUPTED IT). NOTE 16*40=640. COPY ROM(2) + BUF_ADDR, 640 TO $8000 + BUF_ADDR 'SHOW THE PAUSE MENU. SCROLL 0, 0, 128 SCROLL 1, 0, 128 'WRITE THE USER INPUTS FOR PAUSE, BUT NOT YET... REPEAT WAIT VBL UNTIL PAUSE 'RESET THE CHAR DATA BUFFER (THE PAUSE MENU CORRUPTED IT). NOTE 16*40=640. FILL $8000 + BUF_ADDR, 640 'SHOW THE PXL DISPLAY SCROLL 0, 0, 0 SCROLL 1, 0, 0 IF PXL_RCOPYSIZE THEN IF PXL_RFULL THEN ON RASTER CALL PXL_RBUF1 ELSE ON RASTER CALL PXL_RBUF0 END IF 'COPY THE SPRITE DATA FROM ROM (THE PAUSE MENU CORRUPTED IT). NOTE 16*34=544. 34 IS THE 'LENGTH OF THE FRAME ALONG THREE SIDES OF THE PAUSE MENU (8+8+18). COPY ROM(2) + SPR_ADDR, 544 TO $8000 + SPR_ADDR POKEL $FF00 + 4 * 4, P4SAVE SPRITE VIEW ON END SUB SUB INIT_DISPLAY 'DON'T SHOW ANYTHING DURING INIT. THESE WILL BE TURNED ON DURING LOAD. BG VIEW OFF 0 BG VIEW OFF 1 SPRITE VIEW OFF 'ON TOP HALF OF BG 1, PREPARE BACKGROUND OF PXL DISPLAY. BG 1 BG COPY 0, 0, 20, 16 TO 0, 0 'ON BOTTOM HALF OF BG 1, PREPARE BACKGROUND OF PAUSE MENU. BG COPY 0, 32, 20, 16 TO 0, 16 'ON BOTTOM HALF OF BG 0, PREPARE FOREGROUND OF PAUSE MENU. BG 0 BG COPY 0, 16, 20, 16 TO 0, 16 'ON TOP HALF OF BG 0, PREPARE FOREGROUND OF PXL DISPLAY. BG SOURCE ROM(4) CALL PXL_INIT( ROM(5) ) 'SET PRIO 1 FOR FUTURE SPRITE COMMMANDS SINCE PXL LIBRARY DOESN'T CONSIDER PRIO. BG TINT 0, 0 TO 19, 15 PRIO 1 END SUB SUB LOAD_DISPLAY CALL DRAW_SKYBOX CALL DRAW_HUD IF RC_INTERLEAVE AND 1 THEN CALL DRAW_RAYCAST01 ELSE CALL DRAW_RAYCAST00 BG VIEW ON 0 BG VIEW ON 1 SPRITE VIEW ON END SUB SUB DIGIT3EXTRACT 'N=NUMBER, F=ZERO CHAR, D2,D1,D0=THREE DIGITS D0 = N MOD 10 + F IF N < 100 THEN IF N < 10 THEN D1 = 0 ELSE D1 = N \ 10 MOD 10 + F D2 = 0 ELSE D1 = N \ 10 MOD 10 + F D2 = N \ 100 MOD 10 + F END IF END SUB SUB INIT_DEBUG_FPS FPS_CLS$ = "" FOR P = 1 TO 14 FPS_CLS$ = FPS_CLS$ + CHR$(10) NEXT P FPS_FRAMES = 90.00 FPS_TIME = TIMER - 60 END SUB SUB DRAW_DEBUG_FPS VBLS = TIMER - FPS_TIME INC FPS_FRAMES IF VBLS >= 60 THEN TRACE "_FPS_" TRACE MID$( STR$( FPS_FRAMES * VBLS / 60 + 100.001 ), 2, 5 ), FPS_CLS$ FPS_FRAMES = 0 FPS_TIME = TIMER END IF END SUB SUB PXL_INIT( R ) FOR PX = 0 TO 159 BIT = 7 - PX MOD 8 PXL_MASKS( PX ) = 2 ^ BIT PXL_MASKX( PX ) = 2 ^ BIT XOR $FF PXL_MASKR( PX ) = 2 ^ ( BIT + 1 ) - 1 PXL_MASKW( PX ) = PXL_MASKR( PX ) XOR $FF PXL_MASKL( PX ) = 2 ^ BIT - 1 XOR $FF NEXT PX PXL_PXHI = PEEK( R + 2 ) PXL_PYHI = PEEK( R + 3 ) PXL_FXHI = PXL_PXHI + 0.5 PXL_FYHI = PXL_PYHI + 0.5 PXL_PAL1 = PEEK( R + 4 ) PXL_PAL2 = PEEK( R + 5 ) PXL_DIRADDR = PEEKW( R + 6 ) + 32768 PXL_DIRSIZE = PEEKW( R + 8 ) + 32768 PXL_RBUFADDR = PEEKW( R + 10 ) + 32768 PXL_RBUFSIZE = PEEKW( R + 12 ) + 32768 PXL_RBUFDATASIZE = PEEKW( R + 14 ) + 32768 PXL_RBUFDATASTEP = PEEKW( R + 16 ) + 32768 PXL_RCOPYSIZE = PEEK( R + 18 ) PXL_RFULL = PEEK( R + 19 ) A = R + 20 FOR C = 0 TO 159 STEP 8 FOR P = 0 TO 7 PXL_XADDR( C + P ) = PEEKW( A ) + 32768 IF C <= 127 THEN PXL_YADDR( C + P ) = PEEKW( A + 2 ) + P + 32768 NEXT P IF C <= 127 THEN ADD A, 4 ELSE ADD A, 2 NEXT C IF PXL_RCOPYSIZE THEN FOR CR = 0 TO 120 STEP 8 PXL_RSRC( CR ) = PEEKW( A ) + 32768 PXL_RDST( CR ) = PEEKW( A + 2 ) + 32768 IF PXL_RDST( CR ) THEN FOR P = 1 TO 7 PXL_RSRC( CR + P ) = PXL_RSRC( CR ) + P * PXL_RCOPYSIZE PXL_RDST( CR + P ) = PXL_RDST( CR ) + P * PXL_RCOPYSIZE NEXT P END IF ADD A, 4 NEXT CR IF PXL_RFULL THEN ON RASTER CALL PXL_RBUF1 ELSE ON RASTER CALL PXL_RBUF0 END IF CALL PXL_CLS BG COPY 0, 0, 20, 16 TO 0, 0 END SUB SUB PXL_RBUF1 COPY PXL_RSRC( RASTER ), PXL_RCOPYSIZE TO PXL_RDST( RASTER ) END SUB SUB PXL_RBUF0 IF PXL_RDST( RASTER ) THEN COPY PXL_RSRC( RASTER ), PXL_RCOPYSIZE TO PXL_RDST( RASTER ) END SUB SUB PXL_CLS FILL PXL_DIRADDR, PXL_DIRSIZE IF PXL_RBUFDATASIZE THEN A2 = PXL_RBUFADDR + PXL_RBUFSIZE - 1 FOR A = PXL_RBUFADDR TO A2 STEP PXL_RBUFDATASTEP FILL A, PXL_RBUFDATASIZE NEXT A ELSE FILL PXL_RBUFADDR, PXL_RBUFSIZE END IF END SUB ' #1:MAIN PALETTES. ' PAL 0 1 CEILING, 2 TRANSITION, 3 FLOOR, 0 COMMON AMONG THESE THREE ' PAL 1 1 'A' PANELS, 2 'B' PANELS, 3 'C' MOULDING ' PAL 2 MISC. SPRITES ' PAL 3 MISC. SPRITES ' PAL 4 MISC. SPRITES, ALSO GETS MODIFIED FOR USE BY IN-GAME MENUS, BUT THEN RESTORED ' PAL 5 GREEN HUD ARROW AND GREEN HUD-NOTE FOR HUD OBJECTS OF INTEREST ' PAL 6 RED HEALTH NUMERALS AND RED HUD-NOTE FOR ANGLE OF ATTACK ' PAL 7 BLUE AMMO NUMERALS ' #2:MAIN CHARACTERS. ' CHR QTY DESCRIPTION ' 0 1 BLANK (FOR PLAIN BACKGROUND, LEADING ZEROS OF NUMBERS, ETC) ' 1 1 SKY DITHER ' 2 1 TRANSITION DITHER ' 3 1 GROUND DITHER ' 4 9 HUD-ARROW (PLAYER STARTING POINT AND DIRECTION IN BG, NOTE 1) ' 13 1 HUD-NOTE ' 14 10 NUMERALS 0 TO 9 ' 24 40 DISPLAY BUFFER, NOTE 2 ' 24 7 (LEVEL PANELS IN BG, NOTE 1) ' 31 26 LETTERS A TO Z ' 54 1 (LEVEL PANEL IN BG, NOTE 1) ' 57 7 (LEVEL PANELS IN BG, NOTE 1) ' NOTES: ' 1. SEE #6:LEVEL1 BG NOTES. ' 2. THESE CHARS GET OVERWRITTEN AFTER BEING COPIED TO RAM (BUT THE ROM REMAINS). THEY GET ' RESTORED TO SHOW THE PAUSE SCREEN AND EACH LEVEL'S COMPLETION SCREEN. ' 3. ADD 64 TO ALL CHR VALUES. SAVED ON PAGE 2 DUE TO GFX EDITOR LIMITATIONS. ' #3:MAIN BG. ' ROW DESCRIPTION ' 0-15 THE BACKGROUND (BG 1) OF THE PXL DISPLAY ' 16-31 THE FOREGROUND (BG 0) OF THE PAUSE SCREEN ' 32-47 THE BACKGROUND (BG 1) OF THE PAUSE SCREEN ' 48-63 THE FOREGROUND (BG 0) OF THE LEVEL COMPLETION SCREEN ' 64-79 THE BACKGROUND (BG 1) OF THE LEVEL COMPLETION SCREEN ' #4:PXL BG. ' THIS IS THE FOREGROUND WHERE PANELS ARE DRAWN. IT WAS DEVELOPED WITH THE PXL LIBRARY'S PXL ' BG TOOL. ' #5:PXL METADATA. ' THIS IS THE METADATA ASSOCIATED WITH THE PXL BACKGROUND. ' #6:LEVEL1 BG. ' CHR QTY DESCRIPTION ' 4 9 PLAYER START ' OTHERS BOX 0 ' 24 7 BOX 1 TO 7 ' 57 7 BOX 8 TO 14 ' 54 1 BOX 15 ' NOTES: ' 1. THIS ROM IS NOT USED AS A BACKGROUND, THE LOWRES NX GFX EDITOR IS THE LEVEL EDITOR. ' 2. PLAYER START CALC'D IN SUB LOAD_MAP, AND WILL CONSIDER ROTATION FROM FLIP (FX/FY). ' 3. CONVERSION FROM CHR TO BOX PERFORMED IN SUB LOAD_MAP. ' 4. BOX VALUES RENDERED WITH SUB CALC_COLUMN. DEPENDING ON BOX VALUE, RENDERING MIGHT USE ' RED/GREEN/BLUE COLOR (PAL 5/6/7), FLIP (FX/FY), AND/OR PRIORITY (0/1). ' 5. RECOMMEND USING RED/BLUE (PAL 6/7) FOR SOLID BOXES, GREEN FOR LOCATIONS. ' 6. ADD 64 TO ALL CHR VALUES. SAVED ON PAGE 2 DUE TO GFX EDITOR LIMITATIONS. #1:MAIN PALETTES 000116020005242A0001021200152A3F 00152A3F0004192E0010203A00050A2F #2:MAIN CHARACTERS 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 88002200880022000000000000000000 AA00AA00AA00AA00AA00AA00AA00AA00 00000000000000000000000000000000 0040687C7C6840000000707E7E700000 0000D87F787800000000607E7C706000 00007EFC7C3830000000007E78702000 0000167CFC30302000000EFC78783000 00062E7C7C38180000001C3CF8783010 00041C187CF8181000040C3C78783808 00041C3C7C7C1C080008081838783800 0808083C3C383C0400081818387C7C00 0000183C183C7E00001818183C3C3C00 3C5A99998199423C003C7E7E7E7E3C00 002058110119031E003C666E76663C00 001024040404403F0018381818187E00 00205833060C003F003C660C18307E00 002058330041031E003C660C06663C00 00665501390101030066667E06060600 00605F003801433E007E607C06067C00 00102E001811031E001C307C66663C00 00603903060C0818007E060C18303000 002058031811031E003C663C66663C00 002040010141031E003C663E06663C00 007F41414141417FC0FF7F7F7F7F7F7F 007F63414141637FC0FF7F7F7F7F7F7F 0077634100416377C0FF7F7F7F7F7F7F 0063630000006363C0FF7F7F7F7F7F7F 007E78600060787EC0FF7F7F7F7F7F7F 007F77674167777FC0FF7F7F7F7F7F7F 003E1C0800081C3EC0FF7F7F7F7F7F7F 001020180111113300183C667E666600 006058031811033E007C667C66667C00 002058131010031E003C666060663C00 006050101113063C00786C66666C7800 00605F001C10003F007E607860607E00 00605F001C101030007E607860606000 00205E1C1111031E003C606E66663C00 00665501191111330066667E66666600 003006040404001E003C181818183C00 001C09010141031E001E060606663C00 00645B060410103300666C78786C6600 006050101010003F0060606060607E00 00424509011911330042667E7E666600 00664501111111330066767E6E666600 002058111111031E003C666666663C00 006058031E101030007C667C60606000 002058111111001F003C66666A6C3E00 0060580306101033007C667C786C6600 00205F001801433E003E603C06067C00 007027040404040C007E181818181800 006655111111031E0066666666663C00 006655111103060C00666666663C1800 00665515011931210066667E7E664200 00640B060018113300663C183C666600 0066550B0604040C0066663C18181800 006033060C58003F007E0C1830607E00 007B73034160676FC0F901014140404F 007F55555555557FC0FF7F7F7F7F7F7F 0800220088002200C080000000000000 004141417F414141C0C141417F414141 FFFFFFFFFFFFFFFF0000000000000000 0000000000000000FFFFFFFFFFFFFFFF 007F08080808087FC0FF08080808087F 00387C7C7E7F7F7F000038383C3E3F3F 003C7A7A7A7AFAFA00003C3C3C3C3CBC 00071F3F3F7F7F7F071B234541818280 00E0F8FCFCFEFEDAE0F89C0E0E9FFF7F 00000000000000000000000000000000 1F3F7FFFFBFBFF7F1F3970E4CECECE40 0487C7C4C4C4C4C40487C7C4C4C4C444 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 7B7B7B7A7A7A423C3F3D3C3C3C3C3C00 FAFAFAFAFA7A423CFCFCFC7C3C3C3C00 7F7F7E3D3D1E07008080814242231907 FEFEEEFCFCF8E0007FFF7F3E3E7CF8E0 191F1F1F1F1F1F1F191F1E1818191818 FFFFFFFFFFFFFFFF99FF660000240009 99FFFFFFFFFFFFFF99FF660000240010 98F8F8F8F8F8F8F898F8781818981818 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00010103037F3D1D01020204FC804222 008080C0C0FEBCB8804040203F014244 00000000000000000000000000000000 00000000000000000000000000000000 1F1FCFFFFFFFFFFF1910CCFFF3C0C0FF F7F7F7F7FFFFFFFF1C1CDCDDDCC0C0FF EFEFEFEFFFFFFFFF38B83B3B3B8303FF F8F8F3FFFFFFFFFF980833FFCF0303FF 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 0D0F1F1F3E38600012102020414698E0 B0F0F8F87C1C06004808040482621907 00000000000000000000000000000000 00000000000000000000000000000000 FF3F3F3F3F3F3F3FFF30363634343430 FFFFFFFFFFFFFFFFFFC0C0C7C8CFC8CF FFFFFFFFFFFFFFFFFF0303E313F313F3 FFFCFCFCFCFCFCFCFF0C6C6C2C2C2C0C #3:MAIN BG 00001450410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041004100 41004100420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200800190019101920193019401 950196019701980199019A019B019C01 9D019E019F01A001A101880181010000 000000000000000075076D076A076407 00075107620700000000000000000000 0000890182016A076307740763076A07 00004E0700000000000000006A076707 74076307710700004E078A0183016907 63077707710700007B057B057B050000 00000000710761076D07700763070000 00078B01840100000000000000000000 00000000000000000000000000000000 00000007000700074E078C0185017507 63075F076E076D076C07710700000000 00000007000700070007000700070007 00008D018601000069076C0767076407 63070000000000000000000700077107 6E0763076307620700008E0187015F06 6E076707710772076D076A0700000000 4E07000700070000600675075F076A07 69078F0187110000710566056D057205 650573056C0500000000000500070000 0000700773076C0700008F1186110000 6B056E0552054E050000000000000000 00000000000500000000000000000000 00008E11851100000000000000000000 00000000000000000000000000000000 000000000000000000008D1184116207 6707640764076707610773076A077207 7707000000007107720770075F076407 63078C1183114C0663075F0771077707 00000000000000000000000000000000 710767077807630700008B1182110000 6B076307620700004D0F000000000000 000000000000440E00004F074E070000 44068A1181114C1666075F0770076207 00000000000000000000000000000000 00000000000000000000891180119011 91119211931194119511961197119811 99119A119B119C119D119E119F11A011 A1118811410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041007E04 7E047E047E047E047E047E047E047E04 7E047E047E047E047E047E047E047E04 7E04410041007D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D04410041007D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D04410041007D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D04410041007E04 7E047E047E047E047E047E047E047E04 7E047D047D047D047D047D047D047D04 7D04410041007D047D047D047D047D04 7D047D047D047D047D047D047D047E04 7E047E047E047E047E04410041007D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D04410042007D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D04420042007D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D04420042007D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D04420042007E04 7E047E047E047E047E047E047E047E04 7E047D047D047E047E047E047E047E04 7E04420042007D047D047D047D047D04 7D047D047D047D047D047D047D047E04 7E047E047E047E047E04420042007D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D04420042007D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D04420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200800190019101920193019401 950196019701980199019A019B019C01 9D019E019F01A001A101880181010000 000000000000000075076D076A076407 00075107620700000000000000000000 0000890182010000000063076C076207 00006D07640700006A07630774076307 6A0700004E07000000008A0183010000 00000000000000000000000000000000 00000000000000000000000000000000 00078B01840100000000000000000000 00000000000000000000000000007107 61076D077007630700008C0185010000 00000000000000000000000000000000 00000007000700070007400740074007 4E078D01860100006E075F0770070000 000000004E076B074E074E0700070000 000000000000000000008E0187017207 67076B0763070000000000004E076B07 4E074E07000700000000000040074007 4E078F0187116E076D0767076C077207 7107000000004F074E074E076E070000 00000000400740074E078F1186116907 67076A076A0771070000000000004F07 4E074E076E0700000000000040074007 4E078E11851171076307610770076307 7207710700004F074E074E076E070000 00000000400740074E078D1184110000 00000000000000000000000000006B07 63076207000000000000000040074007 4E078C11831100000000000000000000 00000000000000000000000000000000 000000000000000000008B1182116A07 67077407630771070000000000000000 00000000000000000000000000000000 00008A11811100000000000000000000 4E070000000000000000000000000000 00000000000000004007891180119011 91119211931194119511961197119811 99119A119B119C119D119E119F11A011 A1118811410041004100410041004100 41004100410041004100410041004100 41004100410041004100410041007E04 7E047E047E047E047E047E047E047E04 7E047E047E047E047E047E047E047E04 7E04410041007D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D04410041007D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D04410041007D047D047D047D047D04 7D047D047D047D047D047D047D047E04 7E047E047E047E047E04410041007D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D04410041007D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D04410041007D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D04410042007D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D04420042007D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D04420042007D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D04420042007D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D04420042007D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D04420042007E04 7E047E047E047E047E047D047D047D04 7D047D047D047D047D047D047D047D04 7D04420042007D047D047D047D047D04 7D047D047D047D047D047D047D047D04 7D047D047D047D047D04420042004200 42004200420042004200420042004200 42004200420042004200420042004200 42004200 #4:PXL BG 00001410580159015A015B015C015D01 5E015F01600161016201630164016501 66016701680169016A016B016C016D01 6E016F01700171017201730174017501 76017701780179017A017B017C017D01 7E017F01580159015A015B015C015D01 5E015F01600161016201630164016501 66016701680169016A016B016C016D01 6E016F01700171017201730174017501 76017701780179017A017B017C017D01 7E017F01580159015A015B015C015D01 5E015F01600161016201630164016501 66016701680169016A016B016C016D01 6E016F01700171017201730174017501 76017701780179017A017B017C017D01 7E017F01580159015A015B015C015D01 5E015F01600161016201630164016501 66016701680169016A016B016C016D01 6E016F01700171017201730174017501 76017701780179017A017B017C017D01 7E017F01581159115A115B115C115D11 5E115F11601161116211631164116511 66116711681169116A116B116C116D11 6E116F11701171117211731174117511 76117711781179117A117B117C117D11 7E117F11581159115A115B115C115D11 5E115F11601161116211631164116511 66116711681169116A116B116C116D11 6E116F11701171117211731174117511 76117711781179117A117B117C117D11 7E117F11581159115A115B115C115D11 5E115F11601161116211631164116511 66116711681169116A116B116C116D11 6E116F11701171117211731174117511 76117711781179117A117B117C117D11 7E117F11581159115A115B115C115D11 5E115F11601161116211631164116511 66116711681169116A116B116C116D11 6E116F11701171117211731174117511 76117711781179117A117B117C117D11 7E117F11 #5:PXL METADATA 4E42A0400101008000800020008A0080 00802801002000801020408120208082 3020C083402000855020408660208087 7020C0888020008090200080A0200080 B0200080C0200080D0200080E0200080 F020008000211021202130214021C006 80228005C023C006002580054026C006 80278005C028C006C02880058027C006 402680050025C006C02380058022C006 402180050020C00600208005 #6:LEVEL1 BG 00001410580758065807580658075806 58075806580758065807580658075806 58075806580758065807580658070000 00000000000000000000000000000000 00000000000000000000000000000000 00005806580600000006000600000006 00060006000600060006000600065807 58065807580658070000580758070000 00060000000000000006000000060006 00000006000600000006580600005806 00005806580600000000000000000000 00000000000000000000000000005807 58065807000058070000580758070000 00060000000600000006000600000000 00000006000600060006000000000000 00005806580600000006000600000006 00060006000600060000000600060006 00060000000000000000580758070000 00000000000000000000000000000000 00000000000000000000000000007907 00005806580600000000580700000000 00000000000000000000000000000000 00000000000000000000580758070000 00007F070000000058067C0658060000 00000000000000000006000000007906 00005806580600000000580700000000 01060000000000000000000000000000 00060000000000000000580758070000 00000000000000000000000000000000 0000000000005C065C0600005C075C07 00005806580600000000000000000000 00000000000000000000000000060006 00060000000000000000580758070000 00000000000000000000000000000000 0000000000065C0E5C0E00005C0F5C0F 00005806580646050000000000000000 00000000000000000000000000060006 00060000000000000000580758065807 58065807580658075806580758065807 58065807580658075806580758065807 58065807