'WOLF3D, ED. 2022-11-01 BY NATHANIEL BABIAK. REPEAT 'GAME ENGINE. GLOBAL G_HOLD_A_FRAMES, G_HOLD_B_FRAMES, G_DOOR$, G_HIDE$, G_PCT_FLUSH0, G_PCT_FLUSH1 DIM GLOBAL G_IS_DOOR(255), G_IS_PLAIN(255), G_IS_BOOL(255) DIM GLOBAL G_MAP(63,63), G_SX(7,2), G_SY(7,2) DIM GLOBAL G_DOORT(15), G_DOORX(15), G_DOORY(15) DIM GLOBAL G_HIDET(15), G_HIDEX(15,2), G_HIDEY(15,2) GLOBAL G_AREA_HI DIM GLOBAL G_AREAX(63), G_AREAY(63), G_AREA2INDEX(63,1), G_U(255,4) 'RAYCAST. DIM GLOBAL R_MAP(63,63) GLOBAL R_LOCX, R_LOCY, R_ROTA, R_ROTX, R_ROTY, R_DSCREENX, R_DSCREENY GLOBAL R_SCREENM5, R_BOXHEIGHT5 GLOBAL R_LOC_IN_DOOR, R_TILE_DOOR_JAMB, R_RAYX, R_RAYY GLOBAL R_MAPX, R_MAPY, R_DMAPX, R_DMAPY, R_DSX, R_DSY, R_SX, R_SY GLOBAL R_TILE, R_SIDE, R_RAYM, R_WALL 'DISPLAY. FOR DISPLAY COLUMNS OF VARYING WIDTH, BX IS "BLOCK X" (ANALOGUS TO PX "PIXEL X"). DIM GLOBAL D_TXY2CLR(15,15,15), D_TILE2TEX(191) DIM GLOBAL D_CXPY2DST0(19,95), D_CXPY2DST8(19,95), D_BXCLR2ADDMASK(159,3) GLOBAL D_BX, D_TEXSIZE, D_TEXSIZE5, D_YMIN, D_YMAX 'MOVEMENT. GLOBAL M_FWD0,M_STR0,M_ROT0,M_STR1,M_RAD1,M_RAD2,M_ITER GLOBAL M_PAUSE DIM GLOBAL M_MAP(63,63) 'INTERRUPTS. GLOBAL I_INC_TIME0, I_TIME0 DIM GLOBAL I_P0C0(127), I_JUMP(127), I_BEACON(255) 'SPRITES. GLOBAL S_LOCX, S_LOCY, S_ROTA, S_HLTH, S_AMMO, S_GOALX, S_GOALY, S_REDRAW_MAP DIM GLOBAL S_8080(3),S_4040(3),S_2020(3),S_1010(3),S_0808(3),S_0404(3),S_0202(3),S_0101(3) DIM GLOBAL S_MAP(127,95), S_ADR0(7,31), S_ADR8(7,31), S_TILE2CLR(255) 'SCREEN TRANSITIONS. DIM GLOBAL T_BXY2RAM(39, 95), T_BX2RAM(39) 'FPS. GLOBAL F_FRAMES, F_TIME0, F_STR$, F_WAIT0, F_TIME1 'PXL LIBRARY. DIM GLOBAL PXL_MASKS(159),PXL_MASKX(159) GLOBAL PXL_DIRADDR, PXL_DIRSIZE, PXL_RBUFADDR, PXL_RBUFSIZE GLOBAL PXL_RBUFDATASIZE, PXL_RBUFDATASTEP, PXL_RCOPYSIZE DIM GLOBAL PXL_XADDR( 159 ), PXL_YADDR( 127 ), PXL_RSRC( 127 ), PXL_RDST( 127 ) 'DO IT! CALL MAIN END UNTIL 1 SUB MAIN BG SOURCE ROM( 6 ) CALL PXL_INIT( ROM(7) ) CALL D_INIT CALL G_LOAD( ROM( 3 ) ) CALL R_LOAD RESTORE MAIN0 MAIN0: 'DATA 0, 7.999, 3.9995, 1 DATA 1, 15.999, 7.9995, 2 READ TEX_SIZE, D_TEXSIZE, D_TEXSIZE5, F_WAIT0 CALL D_LOAD_TEX( ROM( 4 + TEX_SIZE ), 0, 15, TEX_SIZE ) CALL D_LOAD_TILES 'CALL S_LOAD CALL M_LOAD CALL G_INIT CALL R_INIT 'CALL S_INIT CALL M_INIT CALL T_INIT CALL I_INIT CALL F_INIT INTERLEAVE = 0 BX1 = 0 BX2 = 0 DO CALL G_UPDATE CALL START_R_AND_D( INTERLEAVE, BX1, BX2 ) FOR D_BX = BX1 TO BX2 'NOTE D_BX MANIPULATED WITHIN SUB. CALL CALC_R_SHOW_D NEXT D_BX 'CALL S_UPDATE CALL M_INPUT CALL F_UPDATE LOOP END SUB SUB START_R_AND_D( INTERLEAVE, BX1, BX2 ) R_LOC_IN_DOOR = G_IS_DOOR( R_MAP( R_LOCX, R_LOCY ) ) R_TILE_DOOR_JAMB = R_MAP( R_LOCX, R_LOCY ) + 48 INTERLEAVE = NOT INTERLEAVE IF INTERLEAVE THEN BX1 = 0 BX2 = 39 R_RAYX = R_ROTX - R_ROTY * R_SCREENM5 R_RAYY = R_ROTY + R_ROTX * R_SCREENM5 ELSE BX1 = 40 BX2 = 79 R_RAYX = R_ROTX - R_ROTY * R_SCREENM5 + 40 * R_DSCREENX R_RAYY = R_ROTY + R_ROTX * R_SCREENM5 + 40 * R_DSCREENY END IF END SUB SUB CALC_R_SHOW_D 'FAST RE-INITIALIZE TO ALL-ZEROS. DIM PY2MASK( 95 ) BYTE_WIDTH = D_BX + 3 D_YMIN = 47 D_YMAX = 47 FOR D_BX = D_BX TO BYTE_WIDTH CALL R_UPDATE CALL D_TEXTURIZE( PY2MASK() ) NEXT D_BX DEC D_BX CALL D_SHOW( PY2MASK() ) EXIT SUB END SUB SUB D_INIT FOR CX1 = 0 TO 19 BASE0 = PXL_XADDR( 8 * CX1 ) BASE8 = BASE0 + 8 FOR PY1 = 0 TO 95 D_CXPY2DST0( CX1, PY1 ) = BASE0 + PXL_YADDR( PY1 ) D_CXPY2DST8( CX1, PY1 ) = BASE8 + PXL_YADDR( PY1 ) NEXT PY1 NEXT CX1 RESTORE D_INI4 FOR BX = 0 TO 3 READ D_BXCLR2ADDMASK( BX, 1 ), D_BXCLR2ADDMASK( BX, 2 ), D_BXCLR2ADDMASK( BX, 3 ) NEXT BX FOR BX = 4 TO 79 D_BXCLR2ADDMASK( BX, 1 ) = D_BXCLR2ADDMASK( BX - 4, 1 ) D_BXCLR2ADDMASK( BX, 2 ) = D_BXCLR2ADDMASK( BX - 4, 2 ) D_BXCLR2ADDMASK( BX, 3 ) = D_BXCLR2ADDMASK( BX - 4, 3 ) NEXT BX D_INI4: DATA $C000, $00C0, $C0C0 DATA $3000, $0030, $3030 DATA $0C00, $000C, $0C0C DATA $0300, $0003, $0303 D_INI8: DATA $8000, $0080, $8080 DATA $4000, $0040, $4040 DATA $2000, $0020, $2020 DATA $1000, $0010, $1010 DATA $0800, $0008, $0808 DATA $0400, $0004, $0404 DATA $0200, $0002, $0202 DATA $0100, $0001, $0101 END SUB SUB D_LOAD_TEX( SRC, TEX1, TEX2, TEX_SIZE ) DIM MASK( 7 ), MULT2( 1 ) RESTORE P_LOAD_TE1 P_LOAD_TE1: DATA $80, $40, $20, $10, $08, $04, $02, $01 READ MASK(0), MASK(1), MASK(2), MASK(3), MASK(4), MASK(5), MASK(6), MASK(7) MULT2( 1 ) = 2 IF TEX_SIZE = 0 THEN M2 = 15 ELSE IF TEX_SIZE = 1 THEN M2 = 7 IF TEX_SIZE = 0 THEN XX = 0 ELSE IF TEX_SIZE = 1 THEN XX = 1 C2 = 8 * XX LEFT2DOWN1 = ( -$20 + $100 ) * XX RIGHT2UP2 = ( $20 - $200 ) * XX DOWN1 = ( $100 ) * XX FOR MY = 0 TO M2 FOR MX = 0 TO M2 FOR CY = 0 TO C2 STEP 8 FOR CX = 0 TO C2 STEP 8 FOR PY = 0 TO 7 TY = CY + PY VAL0 = PEEK( SRC ) VAL8 = PEEK( SRC + 8 ) FOR PX = 0 TO 7 TX = CX + PX CLR = SGN( VAL0 AND MASK( PX ) ) + MULT2( SGN( VAL8 AND MASK( PX ) ) ) D_TXY2CLR( TEX1, TX, TY ) = CLR NEXT PX INC SRC NEXT PY ADD SRC, 8 NEXT CX ADD SRC, LEFT2DOWN1 NEXT CY IF TEX1 = TEX2 THEN EXIT SUB INC TEX1 ADD SRC, RIGHT2UP2 NEXT MX ADD SRC, DOWN1 NEXT MY END SUB SUB D_LOAD_TILES RESTORE P_LOAD_TILE1 P_LOAD_TILE1: 'TILE2TEX, SEE GFX DESIGNER PAGE THREE AND ROM 4-5 136 137 138 139 140 141 142 143 DATA -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 1, 1, 1, 1, 2, 2 'TILE2TEX (DON'T USE LEFT-HALF OF PAGE THREE) 152 153 154 155 156 157 158 159 DATA -1, -1, -1, -1, -1, -1, -1, -1, 3, 4, 8, 6, 7, 11, 5, 6 'TILE2TEX 168 169 170 171 172 173 174 175 DATA -1, -1, -1, -1, -1, -1, -1, -1, 7, 12, 13, 14, 0, 0, 0, 0 'TILE2TEX 184 185 186 187 188 189 190 191 DATA -1, -1, -1, -1, -1, -1, -1, -1, 15, 15, 15, 15, 15, 15, 15, 15 FOR TILE = 128 TO 191 READ D_TILE2TEX( TILE ) NEXT TILE END SUB SUB D_TEXTURIZE( PY2MASK() ) PHEIGHT5 = R_BOXHEIGHT5 / R_RAYM PY1 = 48.0 - PHEIGHT5 PY2 = 47.0 + PHEIGHT5 D_YMIN = MIN( D_YMIN, MAX( 0, PY1 ) ) TE1 = D_TILE2TEX( R_TILE ) TX1 = INT( D_TEXSIZE * R_WALL ) OLD_MASK = 0 DPY = PHEIGHT5 / D_TEXSIZE5 FOR TY1 = 0 TO D_TEXSIZE IF PY1 >= 96.0 THEN EXIT 'ADD_MASK = D_CLR2ADDMASK( D_TXY2CLR( TE1, TX1, TY1 ) ) ADD_MASK = D_BXCLR2ADDMASK( D_BX, D_TXY2CLR( TE1, TX1, TY1 ) ) ADD PY2MASK( MAX( 0, PY1 ) ), ADD_MASK - OLD_MASK OLD_MASK = ADD_MASK ADD PY1, DPY NEXT TY1 IF PY1 < 96.0 THEN ADD PY2MASK( PY1 ), -OLD_MASK D_YMAX = MAX( D_YMAX, MIN( 95, PY1 ) ) END SUB SUB D_SHOW( PY2MASK() ) D_YMAX = D_YMAX OR 7 CX1 = D_BX \ 4 WORD = $0000 FOR PY1 = D_YMIN AND $F8 TO D_YMAX IF PY2MASK( PY1 ) THEN ADD WORD, PY2MASK( PY1 ) POKE D_CXPY2DST0( CX1, PY1 ), WORD POKE D_CXPY2DST8( CX1, PY1 ), WORD \ $100 NEXT PY1 CY1 = D_YMIN \ 8 CY2 = D_YMAX \ 8 IF CY1 THEN BG FILL CX1, 0 TO CX1, CY1 - 1 CHAR 0 IF CY2 < 11 THEN BG FILL CX1, CY2 + 1 TO CX1, 11 CHAR 0 BG COPY CX1, CY1, 1, CY2 - CY1 + 1 TO CX1, CY1 END SUB SUB G_LOAD( SRC0 ) RESTORE G_LOAD0 G_LOAD0: 'NUMBER OF HIDDEN PANEL AREAS IN LEVEL THAT WILL YIELD MAP UPDATES. DATA 7 'FOR EACH AREA (CX0, CY0, RECT_QTY), THEN FOR EACH RECT (CX1 ,CY1, CX2, CY2, USE_GOAL). DATA 30,48, 1, 27,44,30,49, 0 DATA 10,57, 1, 5,58,11,62, 0 DATA 18,21, 1, 17,19,20,20, 0 DATA 17,20, 1, 9,17,17,20, 1 DATA 13,17, 1, 12,14,15,17, 0 DATA 27,13, 4, 10,5,24,11, 0, 0,0,0,20, 0, 0,0,63,0, 0, 61,0,63,25, 0 DATA 41,13, 4, 10,5,24,11, 0, 0,0,0,20, 0, 0,0,63,0, 0, 61,0,63,25, 0 READ AREA_QTY G_AREA_HI = AREA_QTY - 1 INDEX1 = 0 FOR A1 = 0 TO G_AREA_HI READ G_AREAX( A1 ), G_AREAY( A1 ), RECT_QTY G_AREA2INDEX( A1, 0 ) = INDEX1 G_AREA2INDEX( A1, 1 ) = INDEX1 + RECT_QTY - 1 ADD INDEX1, RECT_QTY FOR R1 = G_AREA2INDEX( A1, 0 ) TO G_AREA2INDEX( A1, 1 ) READ G_U(R1,0), G_U(R1,1), G_U(R1,2), G_U(R1,3), G_U(R1,4) NEXT R1 NEXT A1 DATA 136, 137, 138, 139, 140, 141, 142, 143 REPEAT READ TILE0 G_IS_DOOR( TILE0 ) = -1 UNTIL TILE0 = 143 FOR TILE0 = 1 TO 255 G_IS_PLAIN( TILE0 ) = NOT G_IS_DOOR( TILE0 ) NEXT TILE0 DATA 170, 171, 172, 173, 174, 175 REPEAT READ TILE0 G_IS_BOOL( TILE0 ) = -1 UNTIL TILE0 = 175 CY2 = PEEK( SRC0 + 3 ) - 1 CX2 = PEEK( SRC0 + 2 ) - 1 SRC1 = SRC0 + 4 FOR CY1= CY2 TO 0 STEP -1 FOR CX1 = 0 TO CX2 'PEEKW ALWAYS POSITIVE BECAUSE BG DATA ATTRIBUTE BIT 7 UNUSED. WORD = PEEKW( SRC1 ) G_MAP( CX1, CY1 ) = WORD ADD SRC1, 2 NEXT CX1 NEXT CY1 END SUB SUB G_INIT G_DOOR$ = "FFFFFFFFFFFFFFF" G_HIDE$ = "FFFFFFFFFFFFFFF" RESTORE G_INIT0 G_INIT0: 'S_ROTA 0 1 2 3 DATA 1,-1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, -1, 1, 0, 1, 1, 1, -1, 0, -1, 1, 0, 1 'S_ROTA 4 5 6 7 DATA -1,-1, -1, 0, -1, 1, -1, 0, -1,-1, 0,-1, -1,-1, 0,-1, 1,-1, 0,-1, 1,-1, 1, 0 FOR ROTA = 0 TO 7 READ G_SX(ROTA,0),G_SY(ROTA,0), G_SX(ROTA,1),G_SY(ROTA,1), G_SX(ROTA,2),G_SY(ROTA,2) NEXT ROTA END SUB SUB G_UPDATE 'ALTERNATIVE TO 'TAP' KEYWORD AS RENDERING SPEED IS 15 TO 30 FPS (NOT 60). IF BUTTON(0,0) THEN INC G_HOLD_A_FRAMES ELSE G_HOLD_A_FRAMES = 0 IF BUTTON(0,1) THEN INC G_HOLD_B_FRAMES ELSE G_HOLD_B_FRAMES = 0 'CHECK FOR [B] 'USE' BUTTON PRESS. IF G_HOLD_B_FRAMES = 1 THEN FOR CHECK = 0 TO 2 CX = INT( R_LOCX ) + G_SX( S_ROTA, CHECK ) CY = INT( R_LOCY ) + G_SY( S_ROTA, CHECK ) IF G_IS_DOOR( R_MAP( CX, CY ) ) THEN REPEAT 'STEP THROUGH USED MEMORY TO PREVENT MEMORY LEAKS. USED = INSTR( G_DOOR$, "U" ) WHILE USED IF CX = G_DOORX( USED ) AND CY = G_DOORY( USED ) THEN GOTO G_UPDATE_CYCLE2 USED = INSTR( G_DOOR$, "U", USED + 1 ) WEND 'SEARCH FOR FREE MEMORY. FREE = INSTR( G_DOOR$, "F" ) IF FREE THEN G_DOORX( FREE ) = CX G_DOORY( FREE ) = CY VOLUME 0, 15, PLAY 0, 66, 60 SOUND 0 'VBL INTERRUPT MIGHT OCCUR AFTER THIS LINE (BEFORE SIGNAL ON NEXT LINE). G_DOORT( FREE ) = I_TIME0 'RECORD USED MEMORY. THIS ALSO SIGNALS THE VBL INTERRUPT, SO MUST OCCUR LAST. MID$( G_DOOR$, FREE, 1 ) = "U" END IF UNTIL 1 ELSE IF G_MAP( CX, CY ) AND $2000 THEN REPEAT 'STEP THROUGH USED MEMORY TO PREVENT MEMORY LEAKS. USED = INSTR( G_HIDE$, "U" ) WHILE USED IF CX = G_HIDEX( USED, 0 ) AND CY = G_HIDEY( USED, 0 ) THEN GOTO G_UPDATE_CYCLE2 USED = INSTR( G_HIDE$, "U", USED + 1 ) WEND 'SEARCH FOR FREE MEMORY. FREE = INSTR( G_HIDE$, "F" ) IF FREE THEN 'PREVENT ANY SUBSEQUENT PRESSES OF THE HIDDEN PANEL. G_MAP( CX, CY ) = G_MAP( CX, CY ) XOR $2000 'SHOW HIDDEN PANEL'S AREA, IF ANY. FOR A1 = 0 TO G_AREA_HI IF CX = G_AREAX( A1 ) AND CY = G_AREAY( A1 ) THEN FOR R1 = G_AREA2INDEX( A1, 0 ) TO G_AREA2INDEX( A1, 1 ) CALL S_MAP_LOAD( G_U(R1,0), G_U(R1,1), G_U(R1,2), G_U(R1,3), -1, G_U(R1,4) ) NEXT R1 EXIT END IF NEXT A1 INC S_REDRAW_MAP CALL S_MAP 'SET INITIAL LOCATION OF HIDDEN PANEL. G_HIDEX( FREE, 0 ) = CX G_HIDEY( FREE, 0 ) = CY 'CALC DIRECTION VIA ATTRIBUTES. $00 INC X, $08 DEC X, $10 INC Y, $18 DEC Y. IF G_MAP( CX, CY ) AND $0800 THEN SIGN = -1 ELSE SIGN = 1 IF G_MAP( CX, CY ) AND $1000 THEN SX = 0 SY = SIGN ELSE SX = SIGN SY = 0 END IF 'SET SUBSEQUENT LOCATIONS OF HIDDEN PANEL. G_HIDEX( FREE, 1 ) = CX + SX G_HIDEY( FREE, 1 ) = CY + SY G_HIDEX( FREE, 2 ) = CX + SX * 2 G_HIDEY( FREE, 2 ) = CY + SY * 2 VOLUME 2, 15, PLAY 2, 30, 120 SOUND 1 'VBL INTERRUPT MIGHT OCCUR AFTER THIS LINE (BEFORE SIGNAL ON NEXT LINE). G_HIDET( FREE ) = I_TIME0 'RECORD USED MEMORY. THIS ALSO SIGNALS THE VBL INTERRUPT, SO MUST OCCUR LAST. MID$( G_HIDE$, FREE, 1 ) = "U" END IF UNTIL 1 ELSE IF G_IS_BOOL( R_MAP( CX, CY ) ) THEN END IF G_UPDATE_CYCLE2: NEXT CHECK END IF END SUB SUB R_LOAD 'CALL R_LOAD BEFORE CALL M_INIT (INIT PLAYER ROTATION BEFORE ROTATING). FOR CY = 0 TO 63 FOR CX = 0 TO 63 WORD = G_MAP( CX, CY ) TILE0 = WORD MOD $100 IF TILE0 = 130 OR TILE0 = 131 THEN IF TILE0 = 130 THEN FLIP_FX = WORD AND $0800 IF FLIP_FX THEN DEGREES = 180 ELSE DEGREES = 0 ELSE FLIP_FY = WORD AND $1000 IF FLIP_FY THEN DEGREES = 270 ELSE DEGREES = 90 END IF R_LOCX = CX + 0.5 R_LOCY = CY + 0.5 R_ROTA = DEGREES * PI / 180 TILE0 = 0 ELSE IF TILE0 = 132 OR TILE0 = 146 THEN TILE0 = 0 END IF R_MAP( CX, CY ) = TILE0 NEXT CX NEXT CY END SUB SUB R_INIT FOV = 90 * PI / 180 'SCREENM DEFINED IN COMMENTS AT END OF FILE BEFORE ROMS. SCREENM = TAN( FOV / 2 ) * 1.0 * 2 'THUS SCREENM IS THE WIDTH-IN-BOXES OF THE SCREEN, AT A DISTANCE OF 1.0 BOX. BOX_PXL_WIDTH = 160 / SCREENM BOX_PXL_HEIGHT = BOX_PXL_WIDTH R_SCREENM5 = SCREENM * 0.5 R_BOXHEIGHT5 = BOX_PXL_HEIGHT * 0.5 R_SIDE_T: DATA 1 R_SIDE_F: DATA 0 END SUB SUB R_UPDATE CALL R_MAIN_CALC ADD R_RAYX, R_DSCREENX ADD R_RAYY, R_DSCREENY END SUB SUB R_MAIN_CALC CALL R_PREP_MAPXY IF R_LOC_IN_DOOR THEN 'CAST ONCE. CALL R_INC_MAPXY_SIDE 'IF RAY HIT DOOR JAM THEN CALC AND EXIT. IF R_MAP( R_MAPX, R_MAPY ) THEN R_TILE = R_TILE_DOOR_JAMB CALL R_CALC_RAYM_WALL EXIT SUB END IF '(PROCEED ASSUMING RAY EXITED DOOR JAM, DROP INTO DO-LOOP.) END IF DO R_MAIN_CALC_CYCLE: 'CAST ANY LENGTH. CALL R_REPEAT_MAPXY_SIDE R_TILE = R_MAP( R_MAPX, R_MAPY ) 'IF TILE IS PLAIN (NOT A DOOR) AND AN INT (NOT A HIDDEN PANEL), THEN CALC AND EXIT. IF G_IS_PLAIN( R_TILE ) THEN IF R_TILE = INT( R_TILE ) THEN CALL R_CALC_RAYM_WALL EXIT SUB END IF '(PROCEED ASSUMING TILE IS PLAIN, BUT ALSO A HIDDEN PANEL.) CAST INTO SEMI-PLANE. G_PCT_FLUSH0 = R_TILE - INT( R_TILE ) G_PCT_FLUSH1 = 1 - G_PCT_FLUSH0 'BACKUP VARIABLES, AS R_SEMI_MAPXY_SIDE'S CONVOLUTION PRECLUDES CALCULATION LATER. SIDE0 = R_SIDE TILE0 = R_TILE CALL R_SEMI_MAPXY_SIDE 'IF RAY HIT SEMI-PLANE, RESTORE TILE*. IF RAY HIT DOOR JAMB, UPDATE TILE*. PRESUME RAY EXITED DOOR JAMB, CAST OUT OF SEMI-PLANE. IF SIDE0 = R_SIDE THEN R_TILE = TILE0 ELSE IF R_MAP( R_MAPX, R_MAPY ) THEN R_TILE = R_MAP( R_MAPX, R_MAPY ) ELSE GOTO R_MAIN_CALC_CYCLE 'NOTE (*) ALSO CALC AND EXIT. CALL R_CALC_RAYM_WALL EXIT SUB END IF '(PROCEED ASSUMING TILE IS DOOR.) CAST INTO SEMI-PLANE. G_PCT_FLUSH0 = 0.50 G_PCT_FLUSH1 = 0.50 'PRECALCULATE PCT_OPEN, R_SEMI_MAPXY_SIDE'S CONVOLUTION PRECLUDES CALCULATION LATER. PCT_OPEN = 1.0 - M_MAP( R_MAPX, R_MAPY ) CALL R_SEMI_MAPXY_SIDE 'IF RAY HIT DOOR JAMB THEN CALC AND EXIT. IF R_SIDE <> R_TILE MOD 2 THEN 'BOTH SIDE=0, TILE MOD 2=0 IMPLY RAY HIT X AXIS, I.E. A VERTICAL AXIS INTERCEPT. ADD R_TILE, 48 'BOTH SIDE=1, TILE MOD 2=1 IMPLY RAY HIT Y AXIS, I.E. A HORIZONTAL AXIS INTERCEPT. CALL R_CALC_RAYM_WALL EXIT SUB END IF '(PROCEED ASSUMING RAY HIT SEMI-PLANE.) IF RAY HIT DOOR (ITSELF) THEN CALC AND EXIT. CALL R_CALC_RAYM_WALL IF R_WALL >= PCT_OPEN THEN ADD R_WALL, -PCT_OPEN EXIT SUB END IF '(PROCEED ASSUMING RAY HIT OPENING.) CAST OUT OF SEMI-PLANE. CALL R_SEMI_MAPXY_SIDE 'IF RAY HIT DOOR JAMB THEN CALC AND EXIT. (SAME AS ABOVE.) IF R_SIDE <> R_TILE MOD 2 THEN ADD R_TILE, 48 CALL R_CALC_RAYM_WALL EXIT SUB END IF '(PROCEED ASSUMING RAY EXITED DOOR JAM, LOOP.) LOOP END SUB SUB R_PREP_MAPXY R_MAPX = INT( R_LOCX ) R_MAPY = INT( R_LOCY ) IF R_RAYX > 0 THEN R_SX = (R_MAPX-R_LOCX+1)/R_RAYX ELSE IF R_RAYX THEN R_SX = (R_MAPX-R_LOCX)/R_RAYX ELSE R_SX = 999999 IF R_RAYY > 0 THEN R_SY = (R_MAPY-R_LOCY+1)/R_RAYY ELSE IF R_RAYY THEN R_SY = (R_MAPY-R_LOCY)/R_RAYY ELSE R_SY = 999999 R_DMAPX = SGN( R_RAYX ) R_DMAPY = SGN( R_RAYY ) IF R_RAYX THEN R_DSX = R_DMAPX / R_RAYX IF R_RAYY THEN R_DSY = R_DMAPY / R_RAYY END SUB SUB R_REPEAT_MAPXY_SIDE REPEAT IF R_SX < R_SY THEN ADD R_MAPX, R_DMAPX ADD R_SX, R_DSX RESTORE R_SIDE_F ELSE ADD R_MAPY, R_DMAPY ADD R_SY, R_DSY RESTORE R_SIDE_T END IF UNTIL R_MAP( R_MAPX, R_MAPY ) READ R_SIDE END SUB SUB R_INC_MAPXY_SIDE IF R_SX < R_SY THEN ADD R_MAPX, R_DMAPX ADD R_SX, R_DSX RESTORE R_SIDE_F ELSE ADD R_MAPY, R_DMAPY ADD R_SY, R_DSY RESTORE R_SIDE_T END IF READ R_SIDE END SUB SUB R_SEMI_MAPXY_SIDE 'CONVOLUTED DUE TO INTEGER ROUNDING (+1/-1) WITHIN R_CALC_RAYM_WALL. IF R_SIDE = 0 THEN IF R_SX - R_DSX * G_PCT_FLUSH0 < R_SY THEN 'RAY HIT SEMI-PLANE (OLD SIDE = NEW SIDE). ADD R_MAPX, R_DMAPX * G_PCT_FLUSH1 ADD R_SX, R_DSX * G_PCT_FLUSH1 R_SIDE = 0 ELSE 'RAY HIT DOOR JAMB (OLD SIDE <> NEW SIDE). ADD R_MAPY, R_DMAPY ADD R_SY, R_DSY R_SIDE = 1 END IF ELSE IF R_SX < R_SY - R_DSY * G_PCT_FLUSH0 THEN 'RAY HIT DOOR JAMB (OLD SIDE <> NEW SIDE). ADD R_MAPX, R_DMAPX ADD R_SX, R_DSX R_SIDE = 0 ELSE 'RAY HIT SEMI-PLANE (OLD SIDE = NEW SIDE). ADD R_MAPY, R_DMAPY * G_PCT_FLUSH1 ADD R_SY, R_DSY * G_PCT_FLUSH1 R_SIDE = 1 END IF END IF END SUB SUB R_CALC_RAYM_WALL 'THE MAX INSTRUCTION ALLOWS STRAFE=0 AND ILL-DEFINED TILES (EX. DOORS) IN SUB R_UPDATE. IF R_SIDE THEN 'THE MAX INSTRUCITON AVOIDS CRASHING, BUT GRAPHIC ARTIFACTS OCCUR. IF R_RAYY < 0 THEN 'IF CRASHING OCCURS, THEN REPLACE "=" WITH "=MAX(0.0001," AND APPEND SUFFIX ")". R_RAYM = ( R_MAPY - R_LOCY + 1 ) / R_RAYY R_WALL = R_LOCX + R_RAYM * R_RAYX R_WALL = 1 - ( INT( R_WALL ) - R_WALL + 1 ) ELSE 'HERE TOO. R_RAYM = ( R_MAPY - R_LOCY ) / R_RAYY R_WALL = R_LOCX + R_RAYM * R_RAYX ADD R_WALL, -INT( R_WALL ) END IF ELSE IF R_RAYX < 0 THEN 'HERE TOO. R_RAYM = ( R_MAPX - R_LOCX + 1 ) / R_RAYX R_WALL = R_LOCY + R_RAYM * R_RAYY R_WALL = 1 - ( R_WALL - INT( R_WALL ) ) ELSE 'HERE TOO. FOUR LINES WOULD BE MODIFIED IN TOTAL. R_RAYM = ( R_MAPX - R_LOCX ) / R_RAYX R_WALL = R_LOCY + R_RAYM * R_RAYY R_WALL = INT( R_WALL ) - R_WALL + 1 END IF END IF END SUB SUB M_LOAD FOR CY = 0 TO 63 FOR CX = 0 TO 63 TILE0 = G_MAP( CX, CY ) MOD $100 IF TILE0 = 130 OR TILE0 = 131 THEN TILE0 = 0 IF TILE0 = 132 OR TILE0 = 146 THEN TILE0 = 0 M_MAP( CX, CY ) = SGN( TILE0 ) NEXT CX NEXT CY END SUB SUB M_INIT GAMEPAD 1 'CALL R_LOAD BEFORE CALL M_INIT (INIT PLAYER ROTATION BEFORE ROTATING). PAUSE OFF 'DEFINE RUNNING INCREMENTS. STRAFE MUST BE NON-ZERO (AVOID BACK-TO-WALL-180-CLIP). M_FWD0 = 0.130 M_ROT0 = 3.750 * PI / 180 M_STR0 = 0.001 'DEFINE AIMING INCREMENTS. STRAFE MUST BE NON-ZERO (AVOID BACK-TO-WALL-180-CLIP). M_STR1 = 0.050 'DEFINE CLIPPING COLLISION DIAMOND/CYLINDER RADIUS. IS A POINT ON THIS CIRCLE'S RAD. M_RAD1 = 0.075 'RAD2 IS A BUFFER RADIUS, CENTERED ON SAME CIRCLE AS ABOVE. MUST BE NON-ZERO (AVOID DOOR HASTY RENDER). M_RAD2 = 0.125 'DIVIDE INCREMENTS FOR USE LATER WITH M_INPUT LOOP. FOR M_ITER = 1 TO 10 'STILL NOT SURE WHAT FRACTION TO USE HERE, CALC WITH 95% FOR NOW. IF SQR( (M_FWD0/M_ITER)^2 + (M_STR0/M_ITER)^2 ) < 0.95 * M_RAD1 THEN EXIT NEXT M_ITER M_FWD0 = M_FWD0 / M_ITER M_STR0 = M_STR0 / M_ITER M_STR1 = M_STR1 / M_ITER 'SET PLAYER ROTATION (SUB R_LOAD SETS R_ROTA, R_LOCX, AND R_LOCY). CALL M_CALC_ROT( 0 ) END SUB SUB M_INPUT TURN = RIGHT( 0 ) - LEFT( 0 ) ROT = TURN * M_ROT0 IF G_HOLD_B_FRAMES THEN STR = TURN * M_STR1 ELSE STR = TURN * M_STR0 MOVE = DOWN( 0 ) - UP( 0 ) FWD = MOVE * M_FWD0 IF ROT THEN CALL M_CALC_ROT( ROT ) IF SGN( FWD ) OR SGN( STR ) THEN FOR J = 1 TO M_ITER CALL M_CALC_TRN( FWD, STR ) NEXT J END IF IF PAUSE THEN CALL M_PAUSE END SUB SUB M_CALC_TRN( FWD, STR ) '=++M_RAD1*<> (M_RAD1*<> ALLOWS BACK-TO-WALL BUT NOT NOSE). DMDX = R_LOCX + ( FWD + M_RAD1 ) * R_ROTX + STR * R_ROTY 'A DIAMOND ORIENTED ON BOX AXIS (NOT ORIENTED BY <>) *IS* A CYLINDER. DMDY = R_LOCY + ( FWD + M_RAD1 ) * R_ROTY - STR * R_ROTX 'DIAMOND , SIZE 2*M_RAD1, LOCATION ROTATED ABOVE (ORIENTATION NOT ROTATED BELOW). IF M_MAP( DMDX + M_RAD2, DMDY ) THEN '(ABOVE) IF RIGHT HITS THEN (BELOW) REVERSE FROM DIAMOND'S POINT LEFTWARDS. R_LOCX = INT( DMDX + M_RAD2 ) - M_RAD2 - M_RAD1 * R_ROTX ELSE IF M_MAP( DMDX - M_RAD2, DMDY ) THEN '(ABOVE) IF LEFT HITS THEN (BELOW) REVERSE FROM DIAMOND'S POINT RIGHTWARDS. R_LOCX = INT( DMDX - M_RAD2 ) + 1 + M_RAD2 - M_RAD1 * R_ROTX ELSE 'NO HIT, IN X, =+. R_LOCX = DMDX - M_RAD1 * R_ROTX END IF IF M_MAP( DMDX, DMDY + M_RAD2 ) THEN '(ABOVE) IF UP HITS THEN (BELOW) REVERSE FROM DIAMOND'S POINT DOWNWARDS. R_LOCY = INT( DMDY + M_RAD2 ) - M_RAD2 - M_RAD1 * R_ROTY ELSE IF M_MAP( DMDX, DMDY - M_RAD2 ) THEN '(ABOVE) IF DOWN HITS THEN (BELOW) REVERSE FROM DIAMOND'S POINT UPWARDS. R_LOCY = INT( DMDY - M_RAD2 ) + 1 + M_RAD2 - M_RAD1 * R_ROTY ELSE 'NO HIT, IN Y, =+. R_LOCY = DMDY - M_RAD1 * R_ROTY END IF 'I WOULD LOVE TO IMPELEMNT A "NOTCH" (JOHN CARMACK, IPHONE 2009) BUT CAN'T FIGURE IT OUT. END SUB SUB M_CALC_ROT( RADIANS ) ADD R_ROTA, RADIANS ADD R_ROTA, 6.283185 * -INT( R_ROTA / 6.283185 ) R_ROTX = COS( R_ROTA ) R_ROTY = SIN( R_ROTA ) 'R_ROT * "UNITS ARE BOXES PER COLUMN" (40 COLUMNS COVERS HALF THE SCREEN). R_DSCREENX = R_ROTY * R_SCREENM5 / 40 R_DSCREENY = -R_ROTX * R_SCREENM5 / 40 END SUB SUB M_PAUSE I_INC_TIME0 = 0 ADD M_PAUSE, 1, 1 TO 15 FOR IS_OUT = -1 TO 0 IF M_PAUSE = 1 THEN CALL T_FADE ( IS_OUT ) IF M_PAUSE = 2 THEN CALL T_WIPE_CELL ( IS_OUT ) IF M_PAUSE = 3 THEN CALL T_WIPE_BLOCK( IS_OUT ) IF M_PAUSE = 4 THEN CALL T_DITHER ( IS_OUT, $10 ) IF M_PAUSE = 5 THEN CALL T_DITHER ( IS_OUT, $2A ) IF M_PAUSE = 6 THEN CALL T_DIFFUSE ( IS_OUT, $10 ) IF M_PAUSE = 7 THEN CALL T_DIFFUSE ( IS_OUT, $2A ) IF M_PAUSE = 8 THEN CALL T_COLR ( IS_OUT, $03 ) IF M_PAUSE = 9 THEN CALL T_COLR ( IS_OUT, $0C ) IF M_PAUSE = 10 THEN CALL T_COLR ( IS_OUT, $0F ) IF M_PAUSE = 11 THEN CALL T_COLR ( IS_OUT, $30 ) IF M_PAUSE = 12 THEN CALL T_COLR ( IS_OUT, $33 ) IF M_PAUSE = 13 THEN CALL T_COLR ( IS_OUT, $3C ) IF M_PAUSE = 14 THEN CALL T_COLR ( IS_OUT, $15 ) IF M_PAUSE = 15 THEN CALL T_COLR ( IS_OUT, $2A ) IF IS_OUT THEN FLUSH_PAUSE_QUEUE = PAUSE PAUSE END IF NEXT IS_OUT I_INC_TIME0 = 1 END SUB SUB I_INIT 'CEILING,FLOOR PAIRS: -1 CEILING ONLY, $00, $01, $04, $05, $10, $11, $14, $15, $2A, $3F. CEILING_CLR = -1 FLOOR_CLR = $11 RESTORE I_INIT0 I_INIT0: DATA %111111, %111111, %101111, %111111, %101111, %111111 DATA %101111, %101111, %011111, %101111, %011111, %101111 DATA %011111, %011111, %001111, %011111, %001111, %011111 DATA %001111, %001111, %001011, %001111, %001011, %001111 DATA %001011, %001011, %000111, %001011, %000111, %001011 DATA %000111, %000111, %000010, %000111, %000010, %000111 DATA %000010, %000010, %000001, %000010, %000001, %000010 DATA %000001, %000001, %000000, %000001, %000000, %000001 FOR RY = 0 TO 47 IF CEILING_CLR = -1 THEN READ I_P0C0( RY ) ELSE I_P0C0( RY ) = CEILING_CLR NEXT RY FOR RY = 48 TO 95 I_P0C0( RY ) = FLOOR_CLR NEXT RY I_JUMP(48)=1 I_JUMP(95)=1 RESTORE I_INIT1 I_INIT1: DATA 0, 151, 167, 183, 183, 167, 151, 0 TIME0 = 0 FOR J = 1 TO 8 READ CH FOR FRAME = 1 TO 32 I_BEACON( TIME0 ) = CH INC TIME0 NEXT FRAME NEXT J I_INC_TIME0 = 1 I_TIME0 = 0 ON VBL CALL I_VBL END SUB SUB I_VBL IF I_INC_TIME0 THEN INC I_TIME0 ON RASTER CALL I_RASTER1 SPRITE 0, , , I_BEACON( I_TIME0 MOD 256 ) 'UPDATE DOORS. STEP THROUGH USED MEMORY. USED = INSTR( G_DOOR$, "U" ) WHILE USED LAP = I_TIME0 - ABS( G_DOORT( USED ) ) IF G_DOORT( USED ) > 0 THEN M_MAP( G_DOORX( USED ), G_DOORY( USED ) ) = MAX( 0.0, 1.0 - LAP / 60.0 ) IF LAP = 180 THEN G_DOORT( USED ) = 0 ELSE IF G_DOORT( USED ) = 0 THEN DISTX = ABS(G_DOORX( USED )+0.5-R_LOCX) DISTY = ABS(G_DOORY( USED )+0.5-R_LOCY) FREE = DISTX > 0.75 OR DISTY > 0.75 IF FREE THEN G_DOORT( USED ) = -I_TIME0 FOR CODE_WRAP = 1 TO 0 SPL1 = 48.0 RAD1 = 1.25 RAD2 = MAX( SQR( DISTX ^ 2 + DISTY ^ 2 ), RAD1 ) 'SOUND PRESSURE LEVEL (SPL) SOUND ATTENUATION FORMULA. SPL2 = SPL1 - 20 * LOG( RAD2 / RAD1 ) / LOG( 10 ) 'APPROXIMATE RELATIONSHIP BETWEEN SPL (UNITS DBA) AND CONSOLE'S VOLUME SETTINGS. VOL2 = 1.339 * SPL2 - 39.818 NEXT CODE_WRAP FOR CODE_WRAP = 1 TO 1 RAD = SQR( DISTX ^ 2 + DISTY ^ 2 ) VOL2 = 15 - 1.5 * RAD NEXT CODE_WRAP PLAY 1, 54, 60 SOUND 0 END IF ELSE IF G_DOORT( USED ) < 0 THEN M_MAP( G_DOORX( USED ), G_DOORY( USED ) ) = MIN( LAP / 60.0, 1.0 ) IF LAP = 60 THEN MID$( G_DOOR$, USED, 1 ) = "F" END IF USED = INSTR( G_DOOR$, "U", USED + 1 ) WEND 'UPDATE HIDDEN PANELS. STEP THROUGH USED MEMORY. USED = INSTR( G_HIDE$, "U" ) WHILE USED IF G_HIDET( USED ) = INT( G_HIDET( USED ) ) THEN LAP = I_TIME0 - ABS( G_HIDET( USED ) ) IF G_HIDET( USED ) > 0 THEN POS = 0 IF LAP = 59 THEN G_HIDET( USED ) = 0.3125 ELSE POS = 1 IF LAP = 59 THEN G_HIDET( USED ) = 0.6875 END IF 'UPDATE SEMI-PLANE. CX1 = G_HIDEX( USED, POS ) CY1 = G_HIDEY( USED, POS ) R_MAP( CX1, CY1 ) = INT( R_MAP( CX1, CY1 ) ) + MAX( 0.0, 1.0 - LAP / 60.0 ) 'UPDATE S_MAP. IF LAP = 30 THEN INC POS CX2 = G_HIDEX( USED, POS ) CY2 = G_HIDEY( USED, POS ) SWAP S_MAP( CX2 + 32, CY2 + 16 ), S_MAP( CX1 + 32, CY1 + 16 ) INC S_REDRAW_MAP END IF ELSE 'UPDATE MAPS. IF G_HIDET( USED ) = 0.3125 THEN CX1 = G_HIDEX( USED, 0 ) CY1 = G_HIDEY( USED, 0 ) CX2 = G_HIDEX( USED, 1 ) CY2 = G_HIDEY( USED, 1 ) G_HIDET( USED ) = -I_TIME0 ELSE CX1 = G_HIDEX( USED, 1 ) CY1 = G_HIDEY( USED, 1 ) CX2 = G_HIDEX( USED, 2 ) CY2 = G_HIDEY( USED, 2 ) MID$( G_HIDE$, USED, 1 ) = "F" END IF SWAP G_MAP( CX2, CY2 ), G_MAP( CX1, CY1 ) SWAP R_MAP( CX2, CY2 ), R_MAP( CX1, CY1 ) R_MAP( CX2, CY2 ) = INT( R_MAP( CX2, CY2 ) ) SWAP M_MAP( CX2, CY2 ), M_MAP( CX1, CY1 ) END IF USED = INSTR( G_HIDE$, "U", USED + 1 ) WEND END SUB SUB I_RASTER1 COPY PXL_RSRC( RASTER ), PXL_RCOPYSIZE TO PXL_RDST( RASTER ) PALETTE 0, I_P0C0( RASTER ), , , IF I_JUMP( RASTER ) THEN ON RASTER CALL I_RASTER2 END SUB SUB I_RASTER2 COPY PXL_RSRC( RASTER ), PXL_RCOPYSIZE TO PXL_RDST( RASTER ) IF I_JUMP( RASTER ) THEN ON RASTER CALL I_RASTER3 END SUB SUB I_RASTER3 COPY PXL_RSRC( RASTER ), PXL_RCOPYSIZE TO PXL_RDST( RASTER ) PALETTE 0, I_P0C0( RASTER ), , , ON RASTER CALL I_RASTER4 END SUB SUB I_RASTER4 COPY PXL_RSRC( RASTER ), PXL_RCOPYSIZE TO PXL_RDST( RASTER ) END SUB SUB S_LOAD RESTORE S_LOAD0 'TILE2CLR, SEE GFX DESIGNER PAGE THREE S_LOAD0: 'TILE2CLR, 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 DATA 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 'TILE2CLR 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 DATA 0, 0, 2, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 'TILE2CLR 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 DATA 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 'TILE2CLR 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 DATA 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 S_TILE2CLR( 0 ) = 0 FOR TILE0 = 128 TO 191 READ S_TILE2CLR( TILE0 ) NEXT TILE0 CALL S_MAP_LOAD( 0, 0, 63, 63, $0300, 1 ) END SUB SUB S_INIT RESTORE S_INIT0 S_INIT0: ' 63 MIPMAP 62 MIPMAP 61 MIPMAP 60 MIPMAP 59 C1/C2/C3 DATA 0,0,192,$E0, 0,0,196,$E0, 0,0,200,$E0, 0,0,204,$E0, 0,0,0,$20,-15 ' 44 SX-LIB 38 MIPMAP 37 MIPMAP 36 MIPMAP 35 MIPMAP 34 C1/C2/C3 DATA 0,0,0,$00,-6, 0,0,192,$E0, 0,0,196,$E0, 0,0,200,$E0, 0,0,204,$E0, 0,0,0,$20,-15 ' 19 HUD MASK 18 HUD MASK 17 HUD MASK 16 HUD MASK 15 HUD MASK 14 HUD MASK DATA 0,96,68,$E7, 0,96,68,$FF, 32,96,68,$E7, 32,96,68,$FF, 96,96,64,$E7, 96,96,64,$FF ' 13 HUD MASK 12 HUD MASK 11 HEART 10 BULLET 9 NUMBERS DATA 128,96,64,$E7, 128,96,64,$FF, 2,96,128,$60, 2,112,160,$60, 21,96,130,$E0 ' 8 DARK KEY HI 7 DARK KEY LO 6 LITE KEY HI 5 LITE KEY LO 4 WEAPONS DATA 50,96,134,$20, 50,104,150,$20, 50,112,166,$20, 50,120,182,$20, 64,96,76,$E0 ' 3 MAP LEFT 2 MAP RIGHT 1 MAP AVATAR 0 MAP GOAL DATA 100,98,136,$E0, 132,98,140,$E0,127,111,135,$20, 0,0,0,$20 FOR SN = 63 TO 0 STEP -1 READ UNION IF UNION >= 0 THEN PX = UNION READ PY, CH, ATR SPRITE SN, PX, PY, CH SPRITE.A SN, ATR ELSE FOR ITER = UNION + 2 TO 0 SPRITE SN, PX, PY, CH SPRITE.A SN, ATR DEC SN NEXT ITER INC SN END IF NEXT SN DATA 1, 2, 3, 9, 35, 36, 37, 38, 60, 61, 62, 63 REPEAT READ SN CALL S_WIPE( SN ) UNTIL SN = 63 'CALCULATE LOOKUP BITMAPS AND ADDRESSES FOR LEFT AND RIGHT MAP SPRITES. DATA $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000 DATA $0080, $0040, $0020, $0010, $0008, $0004, $0002, $0001 DATA $8000, $4000, $2000, $1000, $0800, $0400, $0200, $0100 DATA $8080, $4040, $2020, $1010, $0808, $0404, $0202, $0101 FOR CLR = 0 TO 3 READ S_8080(CLR), S_4040(CLR), S_2020(CLR), S_1010(CLR) READ S_0808(CLR), S_0404(CLR), S_0202(CLR), S_0101(CLR) NEXT CLR CX0 = 0 FOR MAP_SN = 3 TO 2 STEP -1 ADR = $8000 + 16 * SPRITE.C( MAP_SN ) FOR CY0 = 0 TO 24 STEP 8 FOR CX1 = CX0 TO CX0 + 3 FOR PY0 = 0 TO 7 PY1 = CY0 + PY0 S_ADR0( CX1, PY1 ) = ADR S_ADR8( CX1, PY1 ) = ADR + 8 INC ADR NEXT PY0 ADD ADR, 8 NEXT CX1 ADD ADR, $100 - $40 NEXT CY0 ADD CX0, 4 NEXT MAP_SN 'SIGNAL TO S_AVATAR TO FORCE UPDATE. S_ROTA = -1 'RESET S_MAP. S_LOCX = 0 S_LOCY = 0 END SUB SUB S_WIPE( SN ) CH = 16 * SPRITE.C( SN ) PSZ = SPRITE.A( SN ) \ 64 * 8 FOR CY = 0 TO PSZ STEP 8 FOR CX = 0 TO PSZ STEP 8 FILL 32 * CY + 2 * CX + CH + $8000, 16 NEXT CX NEXT CY END SUB SUB S_UPDATE CALL S_MAP CALL S_HEART CALL S_BULLET CALL S_AVATAR END SUB SUB S_HEART NUM = INT( 100 * R_LOCX + 0.5 ) IF S_HLTH <> NUM THEN S_HLTH = NUM CALL S_NUMBER( 3, S_HLTH ) END IF END SUB SUB S_BULLET NUM = INT( 100 * R_LOCY + 0.5 ) IF S_AMMO <> NUM THEN S_AMMO = NUM CALL S_NUMBER( 19, S_AMMO ) END IF END SUB SUB S_NUMBER( PY0, NUM ) T$ = STR$( INT( MIN( MAX( 0, NUM ), 9999 ) ) ) T$ = LEFT$( " ", 3 - MIN( LEN( T$ ), 3 ) ) + T$ + " " SRC0 = ROM( 2 ) + 16 * 196 SRC8 = SRC0 + 8 NUMBERS_SN = 9 DST0 = $8000 + 16 * SPRITE.C( NUMBERS_SN ) + PY0 \ 8 * $100 + PY0 MOD 8 DST8 = DST0 + 8 FOR POS = 1 TO 4 SRC1 = SRC0 SRC2 = SRC8 DST1 = DST0 DST2 = DST8 C$ = MID$( T$, POS, 1 ) IF C$ = " " THEN DIGIT = 10 ELSE DIGIT = VAL( C$ ) FOR PY1 = 0 TO 9 POKE DST1, PEEK( SRC1 + 16 * DIGIT ) POKE DST2, PEEK( SRC2 + 16 * DIGIT ) IF PY1 = 7 THEN ADD SRC1, $100 - 7 ADD SRC2, $100 - 7 ELSE INC SRC1 INC SRC2 END IF IF DST1 MOD 8 = 7 THEN ADD DST1, $100 - 7 ADD DST2, $100 - 7 ELSE INC DST1 INC DST2 END IF NEXT PY1 ADD DST0, 16 ADD DST8, 16 NEXT POS END SUB SUB S_AVATAR ROTA0 = ( R_ROTA + 0.3926991 ) / 0.785382 MOD 8 IF S_ROTA <> ROTA0 THEN S_ROTA = ROTA0 AVATAR_SN = 1 DST = $8000 + 16 * SPRITE.C( AVATAR_SN ) SRC = ROM( 2 ) + 16 * ( S_ROTA + 244 ) COPY SRC, 11 TO DST END IF END SUB SUB S_MAP EXIT SUB DIM BYTE(7) STEP_X = INT( R_LOCX ) - S_LOCX STEP_Y = INT( R_LOCY ) - S_LOCY IF STEP_X = 1 THEN 'SCROLL RIGHT. ADD S_LOCX, STEP_X PY1 = 27 LOCY2 = S_LOCY + 30 LOCX0 = S_LOCX + 59 FOR MAPY = S_LOCY + 3 TO LOCY2 CX0 = 6 CLR = S_MAP( LOCX0, MAPY ) BYTE0 = PEEK( S_ADR0( CX0, PY1 ) ) BYTE8 = PEEK( S_ADR8( CX0, PY1 ) ) POKE S_ADR0( CX0, PY1 ), BYTE0 * 2 + CLR MOD 2 POKE S_ADR8( CX0, PY1 ), BYTE8 * 2 + CLR \ 2 FOR CX0 = 5 TO 0 STEP -1 BIT0 = BYTE0 \ $80 BIT8 = BYTE8 \ $80 BYTE0 = PEEK( S_ADR0( CX0, PY1 ) ) BYTE8 = PEEK( S_ADR8( CX0, PY1 ) ) POKE S_ADR0( CX0, PY1 ), BYTE0 * 2 + BIT0 POKE S_ADR8( CX0, PY1 ), BYTE8 * 2 + BIT8 NEXT CX0 DEC PY1 NEXT MAPY ELSE IF STEP_X = -1 THEN 'SCROLL LEFT. ADD S_LOCX, STEP_X PY1 = 27 LOCY2 = S_LOCY + 30 LOCX0 = S_LOCX + 4 FOR MAPY = S_LOCY + 3 TO LOCY2 CX0 = 0 CLR = S_MAP( LOCX0, MAPY ) BYTE0 = PEEK( S_ADR0( CX0, PY1 ) ) BYTE8 = PEEK( S_ADR8( CX0, PY1 ) ) POKE S_ADR0( CX0, PY1 ), BYTE0 \ 2 + CLR * $80 POKE S_ADR8( CX0, PY1 ), BYTE8 \ 2 + CLR \ 2 * $80 FOR CX0 = 1 TO 6 BIT0 = BYTE0 MOD 2 BIT8 = BYTE8 MOD 2 BYTE0 = PEEK( S_ADR0( CX0, PY1 ) ) BYTE8 = PEEK( S_ADR8( CX0, PY1 ) ) POKE S_ADR0( CX0, PY1 ), BYTE0 \ 2 + BIT0 * $80 POKE S_ADR8( CX0, PY1 ), BYTE8 \ 2 + BIT8 * $80 NEXT CX0 DEC PY1 NEXT MAPY ELSE IF ABS( STEP_Y ) = 1 THEN 'SCROLL UP OR DOWN. ADD S_LOCY, STEP_Y IF STEP_Y = 1 THEN PY_BEG = 27 PY_END = 1 MAPY = S_LOCY + 30 ELSE PY_BEG = 0 PY_END = 26 MAPY = S_LOCY + 3 END IF FOR PY1 = PY_BEG TO PY_END STEP -STEP_Y FOR CX1 = 0 TO 6 POKE S_ADR0( CX1, PY1 ), PEEK( S_ADR0( CX1, PY1 - STEP_Y ) ) POKE S_ADR8( CX1, PY1 ), PEEK( S_ADR8( CX1, PY1 - STEP_Y ) ) NEXT CX1 NEXT PY1 CX0 = 0 LOCX2 = S_LOCX + 59 FOR MAPX = S_LOCX + 4 TO LOCX2 STEP 8 FOR PX0 = 0 TO 7 BYTE( PX0 ) = S_MAP( PX0 + MAPX, MAPY ) NEXT PX0 WORD = S_8080(BYTE(0)) + S_4040(BYTE(1)) + S_2020(BYTE(2)) + S_1010(BYTE(3)) + S_0808(BYTE(4)) + S_0404(BYTE(5)) + S_0202(BYTE(6)) + S_0101(BYTE(7)) POKE S_ADR0( CX0, PY1 ), WORD POKE S_ADR8( CX0, PY1 ), WORD \ $100 INC CX0 NEXT MAPX ELSE IF STEP_X OR STEP_Y OR S_REDRAW_MAP THEN S_REDRAW_MAP = 0 'REDRAW EVERYTHING. ADD S_LOCX, STEP_X ADD S_LOCY, STEP_Y PY1 = 27 'MAPY LO AND HI OFFSET BY 3 ROWS BECAUSE SPRITES ARE CENTERED. LOCY2=S_LOCY+PY1+3. LOCY2 = S_LOCY + 30 'MAPX LO AND HI OFFSET BY 4 COLUMNS BECAUSE SPRITES ARE CENTERED. LOCX2=S_LOCX+55+4. LOCX1 = S_LOCX + 4 LOCX2 = S_LOCX + 59 FOR MAPY = S_LOCY + 3 TO LOCY2 CX0 = 0 '(DON'T PIXEL-PLOT THE BOTTOM 4 ROWS OR RIGHT 8 COLS, AS SPRITES ARE CENTERED.) FOR MAPX = LOCX1 TO LOCX2 STEP 8 FOR PX0 = 0 TO 7 BYTE( PX0 ) = S_MAP( PX0 + MAPX, MAPY ) NEXT PX0 WORD = S_8080(BYTE(0)) + S_4040(BYTE(1)) + S_2020(BYTE(2)) + S_1010(BYTE(3)) + S_0808(BYTE(4)) + S_0404(BYTE(5)) + S_0202(BYTE(6)) + S_0101(BYTE(7)) POKE S_ADR0( CX0, PY1 ), WORD POKE S_ADR8( CX0, PY1 ), WORD \ $100 INC CX0 NEXT MAPX DEC PY1 NEXT MAPY END IF 'UPDATE MAP GOAL SPRITE 0. SPRITE 0, MIN(MAX( 99, S_GOALX-INT(R_LOCX)+128), 156 ), MIN(MAX( 97, INT(R_LOCY)-S_GOALY+112), 126 ), END SUB SUB S_MAP_LOAD( CX1, CY1, CX2, CY2, PAL_HIDE, USE_GOAL ) FOR CY0 = CY1 TO CY2 FOR CX0 = CX1 TO CX2 IF ( G_MAP( CX0, CY0 ) AND $0700 ) = PAL_HIDE THEN CLR0 = S_TILE2CLR( 0 ) ELSE TILE0 = G_MAP( CX0, CY0 ) MOD $100 IF G_IS_BOOL( TILE0 ) AND USE_GOAL THEN S_MAP( S_GOALX+32, S_GOALY+16 ) = S_TILE2CLR( G_MAP(S_GOALX,S_GOALY) MOD $100 ) S_GOALX = CX0 S_GOALY = CY0 CLR0 = S_TILE2CLR( 0 ) ELSE CLR0 = S_TILE2CLR( TILE0 ) END IF END IF S_MAP( CX0 + 32, CY0 + 16 ) = CLR0 NEXT CX0 NEXT CY0 END SUB SUB T_INIT DIM BY2CY64(95), BX2BG8009000(39), BX2CX2(39) FOR BY0 = 0 TO 95 BY2CY64( BY0 ) = BY0 \ 3 * 64 NEXT BY0 FOR BX0 = 0 TO 39 BX2BG8009000( BX0 ) = ( BX0 MOD 2 ) * $800 + $9000 BX2CX2( BX0 ) = BX0 \ 2 * 2 FOR BY = 0 TO 95 T_BXY2RAM( BX0, BY ) = BX2BG8009000( BX0 ) + BY2CY64( BY ) + BX2CX2( BX0 ) NEXT BY T_BX2RAM( BX0 ) = T_BXY2RAM( BX0, 95 ) NEXT BX0 END SUB SUB T_FADE( IS_OUT ) IF IS_OUT THEN COPY $FF00, 32 TO $A000 FOR RY = 0 TO 127 B_P0C0( RY ) = I_P0C0( RY ) NEXT RY FOR ITER = 0 TO 8 FOR COLR = 0 TO 31 NUM = PEEK( $FF00 + COLR ) CALL T_FADE_OUT( NUM ) POKE $FF00 + COLR, NUM NEXT COLR FOR RY = 0 TO 127 CALL T_FADE_OUT( I_P0C0( RY ) ) NEXT RY IF ITER < 8 THEN WAIT 5 NEXT ITER ELSE FOR ITER = 0 TO 8 FOR COLR = 0 TO 31 NUM = PEEK( $FF00 + COLR ) CALL T_FADE_IN( NUM, PEEK( $A000 + COLR ) ) POKE $FF00 + COLR, NUM NEXT COLR FOR RY = 0 TO 127 CALL T_FADE_IN( I_P0C0( RY ), B_P0C0( RY ) ) NEXT RY IF ITER < 8 THEN WAIT 5 NEXT ITER END IF END SUB SUB T_FADE_OUT( NUM ) IF NUM AND $30 THEN ADD NUM, -16 ELSE IF NUM AND $0C THEN ADD NUM, -4 ELSE IF NUM AND $03 THEN DEC NUM END SUB SUB T_FADE_IN( NUM, OLD ) IF (NUM AND $03)<(OLD AND $03) THEN INC NUM ELSE IF (NUM AND $0C)<(OLD AND $0C) THEN ADD NUM, 4 ELSE IF (NUM AND $30)<(OLD AND $30) THEN ADD NUM, 16 END SUB SUB T_WIPE_CELL( IS_OUT ) 'TRACK BLOCK COLUMNS. DIM BX2CY( 39 ) FOR BX0 = 0 TO 39 BX2CY( BX0 ) = 32 NEXT BX0 IF IS_OUT THEN COPY $9000, $1000 TO $C000 FOR ITER = 0 TO 1.25 * 40 * 32 BX1 = RND( 39 ) IF BX2CY( BX1 ) THEN DEC BX2CY( BX1 ) BG BX1 AND 1 CX1 = BX1 \ 2 IF IS_OUT THEN BG SCROLL CX1, 0 TO CX1, 31 STEP 0,1 CELL CX1, 0, 0 ELSE IF BX1 AND 1 THEN BG SOURCE $C800, 32, 32 ELSE BG SOURCE $C000, 32, 32 BG COPY CX1, BX2CY( BX1 ), 1, 32 - BX2CY( BX1 ) TO CX1, 0 END IF END IF IF ITER MOD 40 = 0 THEN WAIT VBL NEXT ITER IF IS_OUT THEN BG 0 BG FILL 0, 16 TO 19, 31 CHAR 0 BG 1 BG FILL 0, 16 TO 19, 31 CHAR 0 END IF END SUB SUB T_WIPE_BLOCK( IS_OUT ) 'TRACK BLOCK COLUMNS. DIM BX2BY( 39 ) FOR BX0 = 0 TO 39 BX2BY( BX0 ) = 96 NEXT BX0 IF IS_OUT THEN CALL T_BUFFER FOR ITER = 0 TO 1.25 * 40 * 96 / 2 BX1 = RND( 39 ) IF BX2BY( BX1 ) THEN ADD BX2BY( BX1 ), -2 BY1 = BX2BY( BX1 ) IF IS_OUT THEN 'FILL TOP OF WORKING COLUMN $D000. FILL $D000, 96 - BY1 'COPY FROM TOP OF SAVED COLUMN $C000 INTO BOTTOM OF WORKING COLUMN. COPY $C000 + 96 * BX1, BY1 TO $D060 - BY1 ELSE 'COPY FROM BOTTOM OF SAVED COLUMN $C000 INTO TOP OF WORKING COLUMN. COPY $C000 + 96 * BX1 + BY1, 96 - BY1 TO $D000 'FILL BOTTOM OF WORKING COLUMN $D000. FILL $D060 - BY1, BY1 END IF BG BX1 AND 1 CX1 = BX1 \ 2 ATTR CELL.A( CX1, 0 ) 'DRAW WORKING COLUMN. CALL T_STRIP( CX1 ) END IF NEXT ITER IF IS_OUT THEN BG 0 BG FILL 0, 16 TO 19, 31 CHAR 0 BG 1 BG FILL 0, 16 TO 19, 31 CHAR 0 END IF END SUB SUB T_DITHER( IS_OUT, COLR ) IF IS_OUT THEN COPY $FF00, 32 TO $A000 FOR PL = 0 TO 7 PALETTE PL, , , , COLR NEXT PL COPY $8000, $400 TO $B000 RESTORE T_DITHER_OUT T_DITHER_OUT: DATA %10000000, %00000000, %00000000, %10000000, %00100000, %00000000 DATA %10000000, %00100000, %01000000, %10010000, %00100000, %01000000 DATA %10010000, %10100000, %01000000, %10010000, %10100000, %01010000 DATA %10110000, %10100000, %01010000, %10110000, %11100000, %01010000 DATA %10110000, %11100000, %11010000, %10110000, %11100000, %11110000 DATA %10110000, %11110000, %11110000, %11110000, %11110000, %11110000 FOR ITER = 0 TO 11 READ MASK0, MASK1, MASK2 FOR DST = $8000 TO $83FF STEP 16 POKE DST , PEEK( DST ) OR MASK0 POKE DST + 8, PEEK( DST + 8 ) OR MASK0 POKE DST + 1, PEEK( DST + 1 ) OR MASK1 POKE DST + 9, PEEK( DST + 9 ) OR MASK1 POKE DST + 2, PEEK( DST + 2 ) OR MASK2 POKE DST + 10, PEEK( DST + 10 ) OR MASK2 NEXT DST IF ITER < 11 THEN WAIT 5 NEXT ITER ELSE RESTORE T_DITHER_IN T_DITHER_IN: DATA %10110000, %11110000, %11110000, %10110000, %11100000, %11110000 DATA %10110000, %11100000, %11010000, %10110000, %11100000, %01010000 DATA %10110000, %10100000, %01010000, %10010000, %10100000, %01010000 DATA %10010000, %10100000, %01000000, %10010000, %00100000, %01000000 DATA %10000000, %00100000, %01000000, %10000000, %00100000, %00000000 DATA %10000000, %00000000, %00000000, %00000000, %00000000, %00000000 FOR ITER = 0 TO 11 READ MASK0, MASK1, MASK2 SRC = $B000 FOR DST = $8000 TO $83FF STEP 16 POKE DST , PEEK( SRC ) OR MASK0 POKE DST + 8, PEEK( SRC + 8 ) OR MASK0 POKE DST + 1, PEEK( SRC + 1 ) OR MASK1 POKE DST + 9, PEEK( SRC + 9 ) OR MASK1 POKE DST + 2, PEEK( SRC + 2 ) OR MASK2 POKE DST + 10, PEEK( SRC + 10 ) OR MASK2 ADD SRC, 16 NEXT DST IF ITER < 11 THEN WAIT 5 NEXT ITER COPY $A000, 32 TO $FF00 END IF END SUB SUB T_DIFFUSE( IS_OUT, COLR ) IF IS_OUT THEN COPY $FF00, 32 TO $A000 FOR PL = 0 TO 7 PALETTE PL, , , , COLR NEXT PL CALL T_BUFFER END IF J = 0 REPEAT IF J < 3839 THEN BX1 = J \ 96 BY1 = J MOD 96 CX1 = BX1 \ 2 CY1 = BY1 \ 3 BG BX1 AND 1 ATTR CELL.A( CX1, CY1 ) IF IS_OUT THEN BITS = $03 * 4 ^ ( BY1 MOD 3 ) CELL CX1, CY1, ( CELL.C( CX1, CY1 ) AND NOT BITS ) OR BITS ELSE CH = PEEK( $C000 + 96 * BX1 + BY1 ) IF BY1 MOD 3 = 2 THEN MASK = %001111 CH = 16 * CH ELSE IF BY1 MOD 3 THEN MASK = %110011 CH = 4 * CH ELSE MASK = %111100 END IF CELL CX1, CY1, ( CELL.C( CX1, CY1 ) AND MASK ) OR CH END IF IF J MOD 96 = 1 THEN WAIT VBL END IF INC J 'LFSR TAP BITMASK $C11 ($C11=$800+$400+$10+1, MIRROR OF $883). DEC J INTEGRATED. IF J\$800 XOR SGN(J AND $400) XOR SGN(J AND 16) XOR J AND 1 THEN J=J\2-1 ELSE J=J\2+$7FF UNTIL J = 0 IF IS_OUT = 0 THEN COPY $A000, 32 TO $FF00 END SUB SUB T_COLR( IS_OUT, COLR ) IF IS_OUT THEN COPY $FF00, 32 TO $A000 MASK = ( COLR XOR %111111 ) AND %010101 FOR DST = $FF00 TO $FF1F POKE DST, ( PEEK( DST ) AND COLR ) + ( PEEK( DST ) \ 2 AND MASK ) NEXT DST FOR RY = 0 TO 127 B_P0C0( RY ) = I_P0C0( RY ) I_P0C0( RY ) = ( I_P0C0( RY ) AND COLR ) + ( I_P0C0( RY ) \ 2 AND MASK ) NEXT RY ELSE COPY $A000, 32 TO $FF00 FOR RY = 0 TO 127 I_P0C0( RY ) = B_P0C0( RY ) NEXT RY END IF END SUB SUB T_BUFFER 'WRITE 2D BLOCK ARRAY (40X96, ROW-SEQUENTIAL) OF COLOR VALUES (0-3) TO $C000. DST = $C000 FOR CX1 = 0 TO 19 FOR BG1 = 0 TO 1 BG BG1 FOR CY1 = 0 TO 31 CH = CELL.C( CX1, CY1 ) POKE DST , CH AND 3 POKE DST + 1, CH \ 4 AND 3 POKE DST + 2, CH \ 16 AND 3 ADD DST, 3 NEXT CY1 NEXT BG1 NEXT CX1 END SUB SUB T_STRIP( CX1 ) 'SHOW 1D ARRAY (1X96) OF COLOR VALUES FROM $D000 BY_SRC = $D000 FOR CY1 = 0 TO 31 CELL CX1, CY1, PEEK( BY_SRC ) + 4 * PEEK( BY_SRC + 1 ) + 16 * PEEK( BY_SRC + 2 ) ADD BY_SRC, 3 NEXT CY1 END SUB SUB F_INIT F_STR$ = " FPS" + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) F_STR$ = F_STR$ + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) F_STR$ = F_STR$ + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) F_FRAMES = 29.0 F_TIME0 = 0 END SUB SUB F_UPDATE INC F_FRAMES LAP0 = TIMER - F_TIME0 IF LAP0 >= 60.0 THEN TRACE LEFT$(STR$( F_FRAMES / LAP0 * 60.0 + 0.0501 ),4) + F_STR$ F_FRAMES = 0 F_TIME0 = TIMER END IF FRAMES = TIMER - F_TIME1 IF FRAMES < F_WAIT0 THEN WAIT F_WAIT0 - FRAMES F_TIME1 = TIMER END SUB SUB PXL_INIT( R0 ) FOR PX1 = 0 TO 159 BIT = 7 - PX1 MOD 8 PXL_MASKS( PX1 ) = 2 ^ BIT PXL_MASKX( PX1 ) = 2 ^ BIT XOR $FF NEXT PX1 PXL_DIRADDR = PEEKW( R0 + 6 ) + 32768 PXL_DIRSIZE = PEEKW( R0 + 8 ) + 32768 PXL_RBUFADDR = PEEKW( R0 + 10 ) + 32768 PXL_RBUFSIZE = PEEKW( R0 + 12 ) + 32768 PXL_RBUFDATASIZE = PEEKW( R0 + 14 ) + 32768 PXL_RBUFDATASTEP = PEEKW( R0 + 16 ) + 32768 PXL_RCOPYSIZE = PEEK( R0 + 18 ) A1 = R0 + 20 FOR C1 = 0 TO 159 STEP 8 FOR P = 0 TO 7 PXL_XADDR( C1 + P ) = PEEKW( A1 ) + 32768 IF C1 <= 127 THEN PXL_YADDR( C1 + P ) = PEEKW( A1 + 2 ) + P + 32768 NEXT P IF C1 <= 127 THEN ADD A1, 4 ELSE ADD A1, 2 NEXT C1 FOR CR = 0 TO 120 STEP 8 PXL_RSRC( CR ) = PEEKW( A1 ) + 32768 PXL_RDST( CR ) = PEEKW( A1 + 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 A1, 4 NEXT CR CALL PXL_CLS WAIT VBL BG COPY 0, 0, 20, 16 TO 0, 0 END SUB SUB PXL_CLS FILL PXL_DIRADDR, PXL_DIRSIZE A2 = PXL_RBUFADDR + PXL_RBUFSIZE - 1 FOR A1 = PXL_RBUFADDR TO A2 STEP PXL_RBUFDATASTEP FILL A1, PXL_RBUFDATASIZE NEXT A1 END SUB SUB PXL_SETP( PX, PY, MODE, USE_HI ) DST = PXL_XADDR( PX ) + PXL_YADDR( PY ) + ( 8 AND USE_HI ) IF MODE = 1 THEN POKE DST, PEEK( DST ) OR PXL_MASKS( PX ) ELSE IF MODE THEN POKE DST, PEEK( DST ) XOR PXL_MASKS( PX ) ELSE POKE DST, PEEK( DST ) AND PXL_MASKX( PX ) END IF END SUB 'CONTROLS ' '[+] MOVE, [A] SHOOT, TAP [B] USE, [B][+] CIRCLE STRAFE, [B][A] CHANGE WEAPONS ' 'TO DO ' 'ORGANIZE G_IS_DOOR, G_IS_PLAIN, G_IS_BOOL, ETC. TO MORE APPLICABLE ENGINES ' 'UPDATE SOUNDS EVERY VBL IN VOICE-BASED ENGINE, ATTENUATE VOLUME PER DISTANCE, USE TWO 'VOICES TO ALLOW LEFT-RIGHT MIX PER DIRECTION, HALT DOOR ACTIONS DURING PAUSE ' 'WRITE TINY DISPLAY SUBPROGRAM, SHOW PAUSE ENUMERATION IN HUD 'PAUSE WILL CYCLE THROUGH EFFECTS FIRST, THEN TRANSITIONS ' 'VERIFY IF M_M_INIT M_ITER SHOULD BE BASED ON RAD2 NOT RAD1 'TOGGLE SWITCHES 'EASY ENEMY MINIMIZES LOW-DELTA FIRST, HARD ENEMY MINIMIZES HIGH-DELTA FIRST 'DAMAGE DIRECTION ON SUPERELLIPSE OF SCREEN 'HTTPS://GAFFERONGAMES.COM/POST/FIX_YOUR_TIMESTEP/ 'MIPMAPS (LAMPS) USE MANUAL BITMASK COLUMNS (DON'T USE PRIO) 'SX-LIB 3D OBJECT RENDERING TOOL WILL PRECALCULATE FIXED ROTATIONS ALONG ONE AXIS '(CAN'T USE SX-LIB AND HI-RES-LO-CLR DISPLAY SYSTEM) ' 'RAYCASTING ' ' @@| | | | VECTORS: ' |@@@@| | | | | TAIL TIP DESCRIPTION ' ---(R)-+----+----+----+----+-- O L (LOCATION) OF BIOLOGICAL EYE ' | |\ | | | | | L P <> (ROTATION) (NOT TO SCALE) ' | | \| | | | | @ S SCREEN, DEFINED BY <> AND FOV ' ---+-|--\----+----+----+----+--- L R RAY, CAST PATH ' | | |\ @----@ | | * R RAY, PERSPECTIVE-CORRECT DEPTH ' | | | \ |\XXX| | | TRIANGLES: ' ---+-|-@+--Y-+-\XX|----+----+--- POINTS DESCRIPTION ' | | |\ \| \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 UNIT SPACING, BUT THIS IS ONLY FOR ' | | |/ | CLARITY AND NOT A RESTRICTION. ' -(O)-> * ALL UNITS ARE "BOXES" OR RADIANS UNLESS COMMENTED. ' | ' 'LAYERS AND DRAW ORDER ' '(SEE S_INIT TOO) 'BG 0 AND 1 BLOXEL DISPLAY, PRIO 0/1 PER-COLUMN, VIA Z-ORDER OF BG VS SX-LIB 'MIPMAP SPRITES PRIO 0 (DUPLICATED HERE TO ALLOW Z-ORDER SORTING WITH SX-LIB SPRITES) 'SX-LIB SPRITES PRIO 0 (THE SPRITE NUMBER FOR THESE IS CONSTANT) 'MIPMAP SPRITES PRIO 1 (DUPLICATED HERE TO ALLOW Z-ORDER SORTING WITH SX-LIB SPRITES) 'ALL NON-SX-LIB SPRITES ARE PRIO 1, NOTE THIS DOES *NOT* EFFECT SPRITE-VS-SPRITE DRAW ORDER ' '#1:MAIN PALETTES ' ' PALETTES COLOR DESCRIPTION ' __IN GAME__ ' 0 GRAYSCALE TILE BACKUP PALETTE (IF NO PALETTE AVALABILE) AND STATUS BAR ' 123456 VARIES TILE DYNAMIC PALETTE ' 7 CYAN/BLUE DOOR TILE AND STATUS BAR OPAQUE MASK (OTHERWISE GARBAGE VIA BLOCKS) ' __IN GFX DESIGNER BG EDITOR__ (SEE NOTE) ' 0 GRAYSCALE TILES (DON'T CHANGE COLOR TO LIMIT CONFUSION WITH IN-GAME PALETTE) ' 12 456 VARIES TILES (PICK ANY COLORS TO ARTISTICLY INDICATE MAP) ' 3 DARK GRAY TILES, BUT *WON'T* SHOW ON STATUS BAR MAP (USE FOR HIDDEN AREAS) ' 7 CYAN/BLUE TILES (DON'T CHANGE COLOR TO LIMIT CONFUSION WITH IN-GAME PALETTE) ' NOTE: ALL PALETTES ARE OVERWRITTEN IN-GAME, SEE B_LOAD TILE2CLR ' '#2:MAIN CHARACTERS ' ' IN-GAME, I.E. ADDRESS $8000 ' ' +---------------+---------------+---------------+---------------+ ' | | PAGE 1 ' | RAYCAST COLUMN BLOCKS | ' | | ' | | ' | | ' | | ' | | ' +---------------+---------------+---------------+---------------+ ' | / | / | / | | PAGE 2 ' | SX-LIB / | SX-LIB / | SX-LIB / | WEAPONS | ' | 4X4 / | 4X4 / | 4X4 / | 4X4 | ' | / | / | / | | ' | / | / | / | | ' | / | / | / | | ' | / | / | / | | ' +-------+-------+-------+---+---+---------------+---------------+ ' | | |DK |TRI| | PAGE 3 ' | HEART | NUMERALS |KEY|---+ MAP-LEFT MAP-RIGHT | ' | 2X2 | 4X4 | |C1 | 4X4 4X4 | ' +-------+ HEALTH +---+---+ | ' | | /AMMO |LT |C2 | | ' | BULLET| |KEY|---+ | ' | 2X2 | | |C3 | | ' +-------+-------+-------+---+---+---------------+---------------+ ' | | | | | PAGE 4 ' | MIPMAP | MIPMAP | MIPMAP | MIPMAP | ' | 4X4 | 4X4 | 4X4 | 4X4 | ' | | | | | ' | | | | | ' | | | | | ' | | | | | ' +---------------+---------------+---------------+---------------+ ' ' ' ' IN GFX DESIGNER, I.E. ADDRESS ROM(2), FOR USE WITH BG EDITOR (TILEMAPS) ' ' +-------+-------+---+---+-------+---------------+---------------+ ' | | START |LMP| * | / | / | DOOR TILES (8) | PAGE 3 ' | / +---+---+---+---+---+---+---------------+---------------+ ' | |FLR| * | * | * | / | / | WALL TILES | ' +-------+---+---+---+---+---+---+ (12) +---+---+---+---+ ' | | * | * | * | * | / | / | | * | * | * | * | ' | / +---+---+---+---+---+---+-----------+---+---+---+---+---+ ' | | * | * | * | * | / | / | DOOR JAMB PSEUDO-TILES (8) | ' +-------+-------+---+---+-------+---------------+---------------+ ' ' CHARACTERS INDICATE TILES (SOME TILES DON'T HAVE TEXTURES, OR VICE VERSA) ' * INDICATES TILE AVAILABLE, / INDICATES TILE UNAVAILABLE ' START INDICATES PLAYER LEVEL STARTING POSITION, CAN USE FLIP FX AND FY ' LMP INDICATES LAMP, NOT YET USED ' FLR INDICATES FLOOR, USED IN STATUS BAR MAP ' TILE-PAIRS 170-171, 172-173, AND 173-174 ARE FOR BINARY SWITCHES, SOFTWARE WILL SWAP ' TILE NUMBERS IF [B] 'USE' OCCURS NEAR ONE. ' DOOR TILES RENDER IN-GAME AS BOTH A DOOR AND DOOR JAMB, SOFTWARE WILL ADD 48 TO DOOR TILE ' NUMBERS IF A DOOR JAMB NEEDS RENDERED. (DOOR JAMB TILES IN ROM WOULD RENDER PLAINLY.) ' '#3:MAIN BG ' 'USE THE LOWRES NX GFX DESIGNER TO EDIT TILEMAPS. SOME DATA IS INTERPRETED BY THE SOFTWARE, 'OTHER IS FOR ILLUSTRATION-ONLY, MEANING YOU CAN USE WHATEVER IS ARTISTIC, EASY TO SEE, ETC. ' 'ALL ROM PALETTES ARE FOR ILLUSTRATION-ONLY, AS COLOR REGISTERS (RAM) ARE MODIFIED IN-GAME. 'ALL TILEMAP TILE PALETTES ARE IGNORED EXCEPT PAL=3, USE FOR TILES HIDDEN FROM WORLD MAP. 'FLIP FX,FY ARE FOR ILLUSTRATION-ONLY, EXCEPT FOR STARTING TILES 130-131, AND PRIO TILES. 'ANY TILEMAP TILE WITH PRIO SET WILL BE A HIDDEN PANEL (IT MOVES TWO TILES WHEN USER ' PRESSES [B]. THE SOFTWARE USES FLIP FX AND FLIP FY TO DETERMINE DIRECTION TO MOVE THE ' WALL, WHICH *MUST* BE AWAY FROM PLAYER AND TOWARDS TWO EMPTY TILES: ' ' FX FY DIRECTION ' 0 0 POS X ' 0 1 POS Y ' 1 0 NEG X ' 1 1 NEG Y ' 'RAM ' ' ADDRESS SIZE DESCRIPTION ' $A000 8*4 TEMP STORAGE FOR PALETTES DURING TRANSITIONS ' $B000 64*16 TEMP STORAGE FOR RAYCAST CHAR DATA DURING TRANSITIONS ' $C000 4KB TEMP STORAGE FOR BACKGROUNDS DURING TRANSITIONS ' $D000 32*2 TEMP STORAGE FOR ONE BACKGROUND COLUMN, 32 ROWS HIGH, INCLUDING ATTRIBUTES ' #1:PALETTES 0014293E0010252A0024383E0000152A 00000000000000000000000000010A2A #2:MAIN CHARACTERS 00000000000000000000000000000000 FFABFDBFFDBFD5FF007E424242427E00 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000001030B070F0000010307070F1F 000080A0C0C0E0E00080C0C0E0F0F0F0 007E424242427E00FFABFDBFFDBFD5FF FFD5BFFDBFFDABFFFFABFDBFFDBFD5FF 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 2F1F5F3F001400001F3F3F7F7F080000 E8F0F4F800000000F0F8F8FCFC000000 24004900920024000000000000000000 92002400490092000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 80000000000000000000000000000000 C0C00000000000000000000000000000 49009200240049000000000000000000 24004900920024000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 0103070F1F3F7FFF0000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000103070F1F3F7FFF 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 0103070F1F3F7FFF0103070F1F3F7FFF FF8080808080809FFFFFFFFFFFFFFFE0 FE010101010141F9FFFEFEFEFEFEBE06 FF80808080888F83FFFFFFFFFFF7F0FC FE0101010121F1F1FFFEFEFEFEDE0E0E 00000000000000000000000000000000 00000000000000000000000000000000 0103070F1F3F7FFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000103070F1F3F7FFF 0000000000000000FFFFFFFFFFFFFFFF 00000000000000000000000000000000 00000000000000000000000000000000 0103070F1F3F7FFF0103070F1F3F7FFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 878080808080807FF8FFFFFFFFFFFF80 F9410101010101FF06BEFEFEFEFEFE00 808080808080807FFFFFFFFFFFFFFF80 E1613131010101FF5E9ECECEFEFEFE00 00000000000000000000000000000000 0103070F1F3F7FFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 00000000000000000000000000000000 00000000000000000103070F1F3F7FFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 00000000000000000000000000000000 0103070F1F3F7FFF0103070F1F3F7FFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FF8080808090BF82FFFFFFFFFFEFC0FD FE0101010101FDFDFFFEFEFEFEFE0202 FF8080A3FFA7FFA3FFFFFFDC80D881DC FE0101F9FDFDFDFDFFFEFE0672820202 0103070F1F3F7FFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 00000000000000000103070F1F3F7FFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0103070F1F3F7FFF0103070F1F3F7FFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 828282828080807FFDFDFDFDFFFFFF80 39190D0D010101FFD6E6F2F2FEFEFE00 818181818280807FFEFEFEFEFDFFFF80 B9998D0D010101FF566672F2FEFEFE00 00001C3E716060400000001C3E3F3F3F 0000387C8E060602000000387CFCFCFC 000000000000000000080C7E7E0C0800 000000000000000000183C7E18181800 00001818183C0000000000247E7E0000 00FE0202020202020000000000000000 007C82BABA827C2800007C44447C0010 80A080000000000080A0800000000000 382424242424241C3C38383838383820 0000FE81817F00000000FFFEFE800000 38383838383838003C2424242424243C 0000FEFEFE0000000000FF8181FF0000 001C1C1C1C1C1C1C3C38383838383820 0000007F7F7F00000000FFFEFE800000 38342C342C342C1C3C38303830383020 0000FED5AB7F00000000FFFED4800000 20100804020100001F0F070301000000 0408102040800000F8F0E0C080000000 0000000000000000FFFFFFFFFFFFFFFF 00000000000000000000000000000000 00000000000000000000000000000000 02020202020202020000000000000000 28282F292B293F001010101614160000 80000000000000000000000000000000 FFD4D497F6969C94006B6B680B6B636B FFD4C09DD4949494006B415C15555555 FFE484FF9C90FFC4007B7B006F6F007B FFE480C99480E3C4007B63085541007B FFE480D5809CE3C4007B6314415D007B FFE480DD949CE3C4007B631C555D007B 0055555555555555FFAAAAAAAAAAAAAA 0055414955414155FFAAA2889480A2AA 00030F3E7D7FFFFF000001030A185870 00F3FF0CFBFFFFFF0000F3F704000060 40404040404040400000000000000000 00000000000000220000000000000000 00000000000000000000000000000000 02020202020202020000000000000000 007CFEC6C6FE7C3800007C7C7C7C0010 00000000000000008000000000000000 00554155415D4155FFAAA294809CA2AA FFFFFFFFFFBDFFFFFFFFFFFF00FFFFFF 00183C7E81FFBDFFFFE7C3817E7E7E18 FF99BDFF817E3C18007E7E7E7E81C3E7 000201020000FF000000000000000000 329A22BA0202FE000000000000000000 D1AA8A890000FF000000000000000000 B2AAAAB22202FE000000000000000000 FFFF7B7C3F0F03000307070300000000 FFCF1F7FFFFFF30070F0E08000000000 4040404040407F000000000000000000 322A26220000FF000000000000000000 ADAAAA6A0000FF000000000000000000 1AB28AB20202FE000000000000000000 38383F3F3F3F3F001010101614160000 80000000000000008000000000000000 382424242424241CBE79BA79BA79BA61 0000FE81817F0000AA55FFFEFE80AA55 3838383838383800BE65A665A665A67D 0000FEFEFE000000AA55FF8181FFAA55 001C1C1C1C1C1C1CBE79BA79BA79BA61 0000007F7F7F0000AA55FFFEFE80AA55 38342C342C342C1CBE79B279B279B261 0000FED5AB7F0000AA55FFFED480AA55 FF8080808080809F007F7F7F7F7F7F7F FE010101010141F901FFFFFFFFFFFFFF FF80808080888F83007F7F7F7F7F7F7F FE0101010121F1F101FFFFFFFFFFFFFF 7CFEC6CEDEF6E6C67CFEC6CEDEF6E6C6 18383818181818181838381818181818 7CFEC60E1C3870E07CFEC60E1C3870E0 7CFEC6063C3C06C67CFEC6063C3C06C6 36366666FEFE060636366666FEFE0606 FEFEC0C0FCFE0606FEFEC0C0FCFE0606 7CFEC6C0FCFEC6C67CFEC6C0FCFEC6C6 FEFE06060C0C1818FEFE06060C0C1818 7CFEC6C67C7CC6C67CFEC6C67C7CC6C6 7CFEC6C6FE7E06067CFEC6C6FE7E0606 00000000000000000000000000000000 00FE0202020202020000000000000000 878080808080807F7F7F7F7F7F7F7FFF F9410101010101FFFFFFFFFFFFFFFFFF 808080808080807F7F7F7F7F7F7F7FFF A1613131010101FFFFFFFFFFFFFFFFFF FE7C000000000000FE7C000000000000 18180000000000001818000000000000 FEFE000000000000FEFE000000000000 FE7C000000000000FE7C000000000000 06060000000000000606000000000000 FEFC000000000000FEFC000000000000 FE7C000000000000FE7C000000000000 30300000000000003030000000000000 FE7C000000000000FE7C000000000000 06060000000000000606000000000000 00000000000000000000000000000000 02020202020202020000000000000000 FF8080808090BF82007F7F7F7F7F7F7F FE0101010101FDFD01FFFFFFFFFFFFFF FF8080A3FFA7FEA3007F7F7F7F7F7F7F FE0101F98D7DFDFD01FFFFFFFFFFFFFF 60A0A0C0060A0A0C60A0A0C0060A0A0C 40404040040404044040404004040404 C06080E00C06080EC06080E00C06080E C06020C00C06020CC06020C00C06020C A0E020200A0E0202A0E020200A0E0202 E0C020C00E0C020CE0C020C00E0C020C 8080E0E008080E0E8080E0E008080E0E E02040400E020404E02040400E020404 E0E0A0E00E0E0A0EE0E0A0E00E0E0A0E E0A0E0200E0A0E02E0A0E0200E0A0E02 00000040000000040000004000000004 2ABA0A8A0202FE000000000000000000 828282828080807F7F7F7F7F7F7F7FFF 29190D0D010101FFFFFFFFFFFFFFFFFF 818181818280807F7F7F7F7F7F7F7FFF A9998D0D010101FFFFFFFFFFFFFFFFFF 80A080000000000080A0800000000000 20804000000000002080400000000000 4000E000000000004000E00000000000 80204000000000008020400000000000 20A020000000000020A0200000000000 40208000000000004020800000000000 E000400000000000E000400000000000 40802000000000004080200000000000 0D0A08080000FF000000000000000000 2C8AAAAC0800FF000000000000000000 D1AA8A890000FF000000000000000000 B2AAAAB22202FE000000000000000000 #3:MAIN BG 00004040000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 0000000000000000000000009E029E02 9E029F029E029E029E029E029E029F02 9E029E029E0200000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000009A03 9A039A039A039A039A03000000000000 00000000000000000000000000000000 0000000000000000000000009E029200 92009200920092009200920092009200 920092009E0200000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000009A03 92039203920392039A03000000000000 0000000000009A009A009A009A009A00 9A009A009D009A009A009A009F029200 92009200920092009200920092009200 920092009F029E029E029E029E020000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000009A03 92039203920392039A039A0300000000 0000000000009A009200920092009200 9200920092009200920092009E029200 92009200920092009200920092009200 920092009E029200920092009E020000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000009A03 920392039203920392039A0300000000 0000000000009A009200840092009200 92009200840092009200920088079200 92009200920092008400920092009200 9200920088079200920092009F020000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000009A03 920392039203920392039A0300000000 0000000000009A009200920092009200 9200920092009200920092009E029200 92009200920092009200920092009200 920092009E029200920092009E020000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000009A00 9A009B009A009A009C309A009A009B00 9A009A0000009A009200920092009A00 9A009A009D009A009A009A00A8029200 92009200920092009200920092009200 92009200A8029E029E029E029E020000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000009A00 92009200920092009200920092009200 92009A0000009A009200920092009A00 0000000000000000000000009E029200 92009200920092009200920092009200 920092009E0200000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000009D00 92009200920092009200920092009200 92009D009A009A009200920092009A00 9A009A0000000000000000009E029E02 9E029F029E029E0289079E029E029F02 9E029E029E0200000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000009A00 92009200920092009200920092009200 92009A00920092009200920092009200 92009A00000000000000000000000000 000000009E029200920092009E020000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000009A00 92009200920092009200920092009200 92008807920092009200840092009200 92009A00000000000000000000000000 000000009E029200920092009E020000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000009A00 92009200920092009200920092009200 92009A00920092009200920092009200 92009A00000000000000000000000000 00000000A802920084009200A8020000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 000000009A009A009A009A009A009D00 92009200920092009200920092009200 92009D009A009A009A009B009A009A00 9A009A00000000000000000000000000 000000009E029200920092009E020000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 000000009A009200920092009A009A00 92009200920092009200920092009200 92009A00000000000000000000000000 00000000000000000000000000000000 000000009E029200920092009E020000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 000000009A009200840092009A009A00 9A009B009A009A0089079A009A009B00 9A009A00000000000000000000000000 000000000000000000009E039E039E03 9E029E029E029200920092009E029E02 9E020000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 000000009A009200920092009A000000 000000009A009200920092009A000000 00000000000000000000000000000000 000000000000000000009E0392039203 9F2A9200920092008400920092009200 9E020000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 000000009A009A0089079A009A000000 000000009D009200840092009D000000 00000000000000000000000000000000 000000000000000000009E0392039203 9E029E029E029200920092009E029E02 9E020000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 000000009A009200920092009A009A00 9A009A009A009200920092009A000000 00000000000000000000000000000000 000000000000000000009E0392039203 9E039E039E029200920092009E020000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 000000009A009200840092009A009200 920092009A009200920092009A000000 00000000000000000000000000000000 000000000000000000009E0392039203 9E039E039E029200920092009E020000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 000000009A0092009200920092009200 840092009D009200840092009D000000 00000000000000000000000000000000 000000000000000000009E039E039E03 9E039E039F029200840092009F020000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 000000009A009200920092009A009200 920092009A009200920092009A000000 00000000000000000000000000000000 00000000000000000000000000000000 000000009E029200920092009E020000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 000000009A009200920092009A009A00 9A009A009A009A0089079A009A009A00 9A009A00000000000000000000000000 00000000000000000000000000000000 00009A009E029F0289079F029E029A00 00000000000000000000000000000000 00000000000000000000000000009807 98079807980798079807980798079807 980700009D009200840092009D009A00 92009200920092009200920092009200 92009A00000000000000000000000000 00000000000000009A009A009A009A00 9D009A00920092009200920092009A00 9D009A009A009A009A00000000000000 00000000000000000000000000009807 92009200920092009200920092009200 980700009A009200920092009A009A00 92009200920092009200920092009200 92009D00000000000000000000000000 00000000000000009A00920092009200 92009200920092009200920092009200 92009200920092009A00000000000000 00000000000000000000000000009807 92009200920092009200920092009200 980700009A009200920092009A009A00 92009200840092009200920084009200 92009A00000000000000000000000000 00000000000000009B00920092009200 92009200920092009200920092009200 92009200920092009B00980798079807 98079807980798079807980798079807 92009200920092009200920092009200 980700009A0092009200920092009A00 92009200920092009200920092009200 92009A00000000000000000000000000 00000000000000009A00920092009200 92009200920092009200920092009200 92009200920092009200980792009200 92009200920092009200920092009807 92009200920092009200920092009200 980700009A0092009200920092008807 92009200920092009200920092009200 92009D00000000000000000000000000 00000000000000009A00920092008400 92009200920092008400920092009200 92008400920092009200880792009200 92009200920092009200920092008807 92009200920092009200920092009200 990700009A0092009200920092009A00 92009200920092009200920092009200 92009A00000000000000000000000000 00000000000000009A00920092009200 92009200920092009200920092009200 92009200920092009200980792009200 92009200920092009200920092009807 92009200920092009200920092009200 980700009A009200920092009A009A00 92009200840092009200920084009200 92009A00000000000000000000000000 00000000000000009B00920092009200 92009200920092009200920092009200 92009200920092009B00980798079807 92009200920092009807980798079807 92009200920092009200920092009200 980700009A009200920092009A009A00 92009200920092009200920092009200 92009D00000000000000000000000000 00000000000000009A00920092009200 92009200920092009200920092009200 92009200920092009A00000000009807 98079200920098079807000000009807 92009200920092009200920092009200 980700009A009200920092009A009A00 92009200920092009200920092009200 92009A00000000000000000000000000 00000000000000009A009A009C009A00 9A009A00920092009200920092009A00 9A009C009A009A009A00000000000000 98079200920098070000000000009807 92009200920092009200920092009200 980700009C009200840092009C009A00 9A009A009A009A0089079A009A009A00 9A009A00000000000000000000000000 00000000000000000000000000000000 00009A00980798078907980798079A00 00000000000000000000000000000000 98079200920098070000000000009807 98079807920098079807920098079807 980700009A009200920092009A009A00 9A009A009A009200920092009A000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000980792009200920098070000 00000000000000000000000000000000 98079200920098070000000000000000 00009807980798079807980798070000 000000009A009200920092009A009A00 9A009A009A009200920092009A000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000980792008400920098070000 00000000000000000000000000000000 98079200920098070000000000000000 00000000000000000000000000000000 000000009A009200920092009A009200 920092009A009200920092009A000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000980792009200920098070000 00000000000000000000000000000000 98079200920098070000980798079807 98079807980798079807980700000000 000000009A0092009200920092009200 840092009D009200840092009D000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000980792009200920098070000 00000000000000000000000000000000 98079200920098079807980792009807 92009807920098079200980798070000 000000009A009200920092009A009200 920092009A009200920092009A000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000980792009200920098070000 00000000000000000000000000000000 98079200920092009807920092009200 92009200920092009200920098070000 000000009A009200840092009A009A00 9A009A009A009200920092009A000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000980792008400920098070000 00000000000000000000000000000000 98079200920092008807920092009200 92009200920092009200920099070000 000000009A009200920092009A009A00 9A009A009A009200920092009A009A00 9A009A009A009A009A009A009A009B00 9A009A009A0000000000000000000000 00000000980792009200920098070000 00000000000000000000000000000000 98079200920092009807920092009200 92009200920092009200920098079A03 9A039A039A0092009200920092009200 92009200920092009200920092009200 9200920092009A009200920092009200 920092009D00A901A901000000000000 00000000980792009200920098070000 00000000000000000000000000000000 98079807980798079807980792009807 92009807920098079200980798070000 00009A039A0092009200920092009200 84009200920092009200920092009200 84009200920088079200920092009200 920092008E019200AA01000000000000 00000000980792009200920098070000 00000000000000000000000000000000 00000000000000000000980798079807 98079807980798079807980700000000 00009A039A0092009200920092009200 92009200920092009200920092009200 9200920092009A009200920092009200 920092009D00A901A901000000000000 00000000980792008400920098070000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A009A009A009A009A009A00 9A009A009A009A009C009A009A009A00 9A009A009A009A009A389A009A009B00 9A009A009A0000000000000000000000 00000000980792009200920098070000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 000000000000A903A9039D0392039203 9A03920392039A2B920392039A030000 00000000000000000000980798079807 98079807980798078907980798079807 98079807980798070000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 000000000000AA0392038E0392039203 9A03920392039A0392039A039A030000 00000000000000000000980792009200 92009200980792009200920098079200 92009200920098070000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 000000000000A903A9039D0392039203 9203920392039A039A039A0300000000 00000000000000000000980792009200 92009200880792008400920088079200 92009200920098070000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 000000000000000000009A039A039A3B 9A039A039A039A030000000000000000 00000000000000000000980792009200 92009200980792009200920098079200 92009200920098070000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 0000000000000000000000009A039203 92039A03000000000000000000000000 00000000000000000000980792009200 92009200980792009200920098079200 92009200920098070000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 0000000000000000000000009A039203 92039A03000000000000000000000000 00000000000000000000980798079807 9E329807980792009200920098079807 98079807980798070000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 0000000000000000000000009A039A03 9A039A03000000000000000000000000 00000000000000000000980792009200 92009200980792009200920098079200 92009200920098070000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 000000000000000000009E2A92008202 92009200880792008400920088079200 9200920092009E220000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000980792009200 92009200980792009200920098079200 92009200920098070000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 00000000000000009803000099030000 9A0300009B0300009C0300009D030000 9E0300009F0300000000980798079807 9E3A9807980792009200920098079807 98079807980798070000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000980792009200 92009200920092009200920092009200 92009200920098070000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 0000000000000000A8030000A9030000 AA030000AB0300000000000000000000 00000000000000000000980792008400 92009200920092008400920092009200 92008400920098070000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000980792009200 92009200920092009200920092009200 92009200920098070000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 00000000000000009A0389039A030000 9A038B039A0300009A038D039A030000 9A038F039A0300000000980799079807 98079907980798079907980798079907 98079807990798070000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 00000000000000008803000000000000 8A030000000000008C03000000000000 8E030000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 00000000000000009A03000000000000 9A030000000000009A03000000000000 9A030000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A039A0300000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00009A03980398039803980398039803 98039803980398039803980398039803 98039803980398039803980398039803 98039803980398039803980398039803 98039803980398039803980398039803 98039803980398039803980398039803 98039803980398039803980398039803 98039803980398039803980398039803 98039803 #4:TEXTURES DB7EC37272C37EDB24FF7EDFDF7EFF24 C318A53C3CBD00DB3CE75AC3D342FF24 D1040E606E0400DB2EFFFFBFBFFFFF24 EEE0CE0EECE0EECC911F39F1931F1933 00FEFEAAAAFEAAAAFFFF83D7D7ABD7D7 FFFF94B4D49C9596FF006B6B6B6B6B6B FFDBAD99BDBD99C3FFE7D3FFF7EFFFFF FFBDBDBDBDB981FFFFC3FBDBFFCFFFFF EEEE007777003B3B9911FFCC88FFE4C4 EE00BB007700DD0011FF44FF88FF22FF A28AA82AA28AA82A5D7557D55D7557D5 81FF7E7E766E7E7E7EBD8199BDBD9981 810081003C8100817EFF7EFFFF7EFF7E 180042007E3C1800E7FFBDFFFFFFFFFF 183C7E0042001800E7C381FFFFFFFFFF 997EFF7E7EFF7E9966E766E7E766E766 #5:TEXTURES 2X2 0052005F10105E1EFFADFFBFFFFFB1F5 004A00FA08080A08FFB5FFFDFFFFFDFF 0052005F1016591FFFADFFBFFFF9B6F0 004A00FA08080A08FFB5FFFDFFFFFDFF 0011387D017D3911FFFEFFFEFEFEFEFE 007D7C39399393C7FF8283C6C66C6C38 FFFF82FFFF191111007D7D00E6EEEEEE FFFD27E527E7E42400DAD81AD81BDBDB FF829FFF1A1A1A1F007D7F10F5F5F5F0 FF21FDFDAFACACAC00DEFE0654575757 FFFF00FF888A8D8800FFFF0077777777 FFFF00FF888A8D8800FFFF0077777777 FFF1C3C1DFC7C3C3FFFEFCFEE0F9FCFE FF8FC383FBE3C343FF7F3F7F871F3FFF FFC0C0C0C3C7C7C7FFFFFFFFFCFFFFFD FF030303E3E3E3E3FFFFFFFF1F9FDFDF 1E5E10105F005200F5B1FFFFBFFFADFF 080A0808FA004A00FFFDFFFFFDFFB5FF 1F5F1F105F005200F4B4F0FFBFFFADFF 080A0808FA004A00FFFDFFFFFDFFB5FF 01091D0941005500FEF6EAF6BEFFAAFF C7939339397C7D00386C6CC6C68382FF 131F11FFFD878784ECE0EE007A787B7B 242424FF3FE1E121DBDBDB00DE1EDEDE 1F1F1FFA9A9A9A9AF2F2F01575757575 ACACACAFADADADAD5757575456565656 A8D88888888A8D887777777777777777 A8D88888888A8D887777777777777777 C7CFCECECFC7C3F0FFFFF5FFFEFFFEFF E3F37373F3E3C30FFF7FFFAFFFFFFFFF C7C7C7C7C0C0C0FFFFFFF9FFFFFFFFFF E3E3E3C3030303FFFFFFFFFFFFFFFFFF FFFFE223F3F33FE7001DDDDC0CCCC01B FFFF20E03F2FE8EF00DFDF1FC0D71790 FF808080FF080808007F7F7F00F7F7F7 FF808080FF080808007F7F7F00F7F7F7 F88888888F8888880777777770777777 F88888888F8888880777777770777777 C0FFFF18080F1F1F3F9FCFE7F7F0E3E7 03FFFF1810F078F8FCF9F3E7EF0FC7E7 80000000008000007FFFFFFFFF7FFFFF 0100000000010000FEFFFFFFFFFEFFFF 000000010307101FFFFFFFFEFCF8EFE0 00000080C0E008F8FFFFFF7F3F1FF707 000F18111317101FFFF0E7EFEFEFEFE0 00F01888C8E808F8FF0FE7F7F7F7F707 8579494949CD49497AFEFEFEFE7AFEFE A19E929292B392925E7F7F7F7F5E7F7F 2426272724E7FF00DBD9D8DBDB18C0FF 6929FFFF0181FF91D6D600FEFE7E006E FF808080FF080808007F7F7F00F7F7F7 FF808080FF080808007F7F7F00F7F7F7 F88888888F8888880777777770777777 F88888888F8888880777777770777777 1F151F1E1F1E0F00EFEEEEEFE7E3F0FF 78F8A8F8F8F8F000F77777F7E7C70FFF 3F3F840000000080FFFF7BFFFFFFFF7F FCFC110000000001FFFFEEFFFFFFFFFE 1F10171311180F00E0EFEFEFEFE7F0FF F808E8C88818F00007F7F7F7F7E70FFF 1F10070301000000E0EFF8FCFEFFFFFF F808E0C08000000007F71F3F7FFFFFFF 4949CD4949497985FEFE7AFEFEFEFE7A 9292B39292929EA17F7F5E7F7F7F7F5E #6:PXL BG 000014103E003F004000410042004300 44004500460047004800EE00EF00F000 F100F200F300F400F500F60049004A00 4B004C004D004E004F00500051005200 5300F700F800F900FA00FB00FC00FD00 FE00FF00540055005600570058005900 5A005B005C005D005E00EE00EF00F000 F100F200F300F400F500F6005F006000 61006200630064006500660067006800 6900F700F800F900FA00FB00FC00FD00 FE00FF006A006B006C006D006E006F00 70007100720073007400EE00EF00F000 F100F200F300F400F500F60075007600 7700780079007A007B007C007D007E00 7F00F700F800F900FA00FB00FC00FD00 FE00FF00800081008200830084008500 86008700880089008A00EE00EF00F000 F100F200F300F400F500F6008B008C00 8D008E008F0090009100920093009400 9500F700F800F900FA00FB00FC00FD00 FE00FF0096009700980099009A009B00 9C009D009E009F00A000EE00EF00F000 F100F200F300F400F500F600A100A200 A300A400A500A600A700A800A900AA00 AB00F700F800F900FA00FB00FC00FD00 FE00FF00AC00AD00AE00AF00B000B100 B200B300B400B500B600EE00EF00F000 F100F200F300F400F500F600B700B800 B900BA00BB00BC00BD00BE00BF00C000 C100F700F800F900FA00FB00FC00FD00 FE00FF00C200C300C400C500C600C700 C800C900CA00CB00CC00EE00EF00F000 F100F200F300F400F500F600CD00CE00 CF00D000D100D200D300D400D500D600 D700F700F800F900FA00FB00FC00FD00 FE00FF00D800D900DA00DB00DC00DD00 DE00DF00E000E100E200EE00EF00F000 F100F200F300F400F500F600E300E400 E500E600E700E800E900EA00EB00EC00 ED00F700F800F900FA00FB00FC00FD00 FE00FF00 #7:PXL METADATA 4E42A0800000E003008B0020E08A9080 B0801201E0030080F003B08000046081 100410822004C0823004708340042084 5004D08460048085700430868004E086 00209087102040882020F0883020A089 4020508A5020602070208020B020700F 6021E00E1022700FC022E00E7023700F 2024E00ED024700F8025E00E3026700F E026E00E9027700F4028E00EF028700F A029E00E502A700F0020E00E #15:MAIN SOUND 3800336A000000001800846C003A0000 08006060000000002800303019FE0000 38002020000000003800505000000000 0800000F000000000800000F00000000 0800000F000000000800000F00000000 0800000F000000000800000F00000000 0800000F000000000800000F00000000 0800000F000000000800000F00000000