REM > .!RunImage LIBRARY ".GameLib" ON ERROR MODE 12: PROCGameLib_Error MODE 15: MODE 13: OFF DIM B% 1000, Stars% 40000 Table_Character% = 0 Table_Bullets% = 1 Table_Platforms% = 2 Table_Ladders% = 3 Table_Walls% = 4 Table_Enemies% = 5 Table_Xplosions% = 6 Table_Droids% = 7 Table_Items% = 8 Total_Droids% = 100 Size_Droids% = 44 PROCGameLib_Show(&80000000, "") PROCGameLib_Text("Choose a level . . .") PROCGameLib_Text(" 1 - James") PROCGameLib_Text(" 2 - James 2") Level$ = "" REPEAT a$ = GET$ CASE a$ OF WHEN "1": Level$ = "James" WHEN "2": Level$ = "James2" OTHERWISE: VDU7 ENDCASE UNTIL Level$ <> "" PROCGameLib_Show(&80008000, "Loading...") PROCMakeStars PROCAssemble PROCAmnesia_Init(500000) PROCFastSpr_Load(0, ".Grafix") PROCFastSpr_Load(1, ".Icons") PROCAmnesia_ClaimTable(Table_Character%, 1, 1, 32) PROCAmnesia_ClaimTable(Table_Bullets%, 1, 10, 32) PROCAmnesia_ClaimTable(Table_Platforms%, 0, 1000, 32) PROCAmnesia_ClaimTable(Table_Ladders%, 1, 500, 32) PROCAmnesia_ClaimTable(Table_Walls%, 1, 1000, 32) PROCAmnesia_ClaimTable(Table_Enemies%, 1, 10, 32+30*12) PROCAmnesia_ClaimTable(Table_Xplosions%, 0, 10, 32) PROCAmnesia_ClaimTable(Table_Droids%, 1, Total_Droids%, Size_Droids%) PROCAmnesia_ClaimTable(Table_Items%, 1, 100, 32) PROCAmnesia_SetGravity(0, 1 << 10) PROCLevel_Init(Level$) PROCAmnesia_SetWindow(0, 0, 0, Wide% << 16, High% << 16) PROCAmnesia_SetWindow(1, -1 << 16, -1 << 16, 20 << 16, 15 << 16) PROCAmnesia_SetWindow(2, 0, 0, Wide% << 16, High% << 16) PROCGameLib_Fade PROCFastSpr_Bank(2) PROCFastSpr_Plot(&01000000, 160, 244) PROCFastSpr_Bank(1) PROCFastSpr_Plot(&01000000, 160, 244) PROCFastSpr_SetClipWindow(0, 0, 320, 240) PROCFastSpr_SetBackdrop(0) CASE USR(Code%) OF WHEN 0: PROCGameLib_Show(&00800000, "Level Complete") WHEN 1: PROCGameLib_Show(&00008000, "Game Over") ENDCASE T% = TIME: REPEAT: UNTIL TIME > T% + 100 SYS"OS_Byte", 15, 1 IF GET THEN PROCGameLib_Fade END REM ˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜ DEF PROCAssemble fire_delay% = 10 REMrobot_timer% = &00C80001 Size% = 3 * 1024 DIM Code% Size% - 1 L% = Code% + Size% - 1 REM FOR Pass% = 8 TO 11 STEP 3 FOR Pass% = 8 TO 10 STEP 2 P% = Code% [OPT Pass% ; <- R0 = reason for end ; 0 = level complete ; 1 = game over ; -------------------------------------------------------------------------- ;initialisation STMFD R13!, {R14} STR R13, exit MOV R0, #1 STR R0, bank MOV R0, #Table_Character% BL object_find ; -------------------------------------------------------------------------- .main LDR R0, frame ADD R0, R0, #1 STR R0, frame BL swap_screen_bank BL escape BL scan_keys TST R0, #(1 << 0) : BLne move_left TST R0, #(1 << 1) : BLne move_right TST R0, #(1 << 2) : BLne move_jump TST R0, #(1 << 4) : BLne move_down TST R0, #(%11) : BLeq move_stand AND R8, R0, #%1001: CMP R8, #%1001 : BLeq fire_left AND R8, R0, #%1010: CMP R8, #%1010 : BLeq fire_right AND R8, R0, #%1000: CMP R8, #%1000 : BLeq fire_stand BL platforms BL droids BL screen_background MOV R2, #0 MOV R0, #Table_Platforms% : BL process_table MOV R0, #Table_Walls% : BL process_table MOV R0, #Table_Ladders% : BL process_table MOV R0, #Table_Items% : BL process_table MOV R0, #Table_Character% : BL process_table MOV R0, #Table_Enemies% : BL process_Enemies MOV R0, #Table_Droids% : BL process_Droids MOV R0, #Table_Xplosions% : BL process_table MOV R0, #Table_Bullets% : BL process_table BL stars BL collisions_Character_Bullets BL collisions_Bullets_Bullets BL collisions_Walls_Bullets BL collisions_Enemies_Bullets BL collisions_Droids_Bullets BL collisions_Character_Enemies BL collisions_Character_Droids BL collisions_Droids_Walls BL collisions_Character_Items B main .frame EQUD 0 ; -------------------------------------------------------------------------- .finalisation MOV R3, R0 MOV R0, #15 MOV R1, #1 SWI "OS_Byte" MOV R0, R3 LDR R13, exit LDMFD R13!, {PC}^ ; -------------------------------------------------------------------------- ; data .exit EQUD 0 .bank EQUD 0 .energy EQUD 320 ; -------------------------------------------------------------------------- .swap_screen_bank ; -> nothing ; <- no change STMFD R13!, {R0-R3} MOV R0, #19 ; WAIT SWI "OS_Byte" LDR R3, bank ; load bank from memory MOV R0, #113 ; display screen bank MOV R1, R3 SWI "OS_Byte" RSB R3, R3, #3 ; swap bank SUB R0, R3, #1 ; set bank for FastSpr SWI "FastSpr_ScreenBank" MOV R0, #112 ; VDU driver screen bank MOV R1, R3 SWI "OS_Byte" STR R3, bank ; save bank to memory LDMFD R13!, {R0-R3} MOV PC, R14 ; -------------------------------------------------------------------------- .screen_background ; -> R0 = backdrop sprite number ; <- no change STMFD R13!, {R0-R2} ;LDR R1, scroll_x ;MOV R1, R1, ASR#12 ;LDR R2, scroll_y ;MOV R2, R2, ASR#12 ;SWI "FastSpr_Plot" SWI "FastSpr_ClearWindow" LDMFD R13!, {R0-R2} MOV PC, R14 ; -------------------------------------------------------------------------- .escape ; -> nothing ; <- exits if escape was pressed STMFD R13!, {R0-R1} MOV R0, #121 MOV R1, #(112 EOR &80) SWI "OS_Byte" CMP R1, #&FF LDMneFD R13!, {R0-R1} MOVne PC, R14 MOV R0, #1 B finalisation ; -------------------------------------------------------------------------- .scan_keys ; -> nothing ; <- R0 = key flags bit key ; 0 left ; 1 right ; 2 jump ; 3 fire ; 4 down STMFD R13!, {R1-R3} MOV R3, #0 MOV R0, #121 MOV R1, #(97 EOR &80) SWI "OS_Byte" CMP R1, #&FF ORReq R3, R3, #%001 MOV R1, #(66 EOR &80) SWI "OS_Byte" CMP R1, #&FF ORReq R3, R3, #%010 CMP R3, #%11 MOVeq R3, #0 MOV R1, #(79 EOR &80) SWI "OS_Byte" CMP R1, #&FF ORReq R3, R3, #%100 MOV R1, #(73 EOR &80) SWI "OS_Byte" CMP R1, #&FF ORReq R3, R3, #%1000 MOV R1, #(104 EOR &80) SWI "OS_Byte" CMP R1, #&FF ORReq R3, R3, #%10000 MOV R0, R3 LDMFD R13!, {R1-R3} MOV PC, R14 ; -------------------------------------------------------------------------- .object_find ; -> R0 = table ; <- R1 = pointer to first object STMFD R13!, {R0, R2} MOV R1, #0 MOV R2, #1 SWI "Amnesia_SelectTable" LDMFD R13!, {R0, R2} MOV PC, R14 ; -------------------------------------------------------------------------- .move_stand ; -> R1 = pointer to character ; <- no change STMFD R13!, {R0, R2} LDR R2, move_char_now ADD R2, R2, #1 AND R2, R2, #3 STR R2, move_char_now ADR R0, move_chars LDR R0, [R0, R2, LSL #2] STR R0, [R1] LDMFD R13!, {R0, R2} MOV PC, R14 .move_char_now EQUD 0 .move_chars EQUD &00010001 ; 0 left 1 EQUD &00000001 ; 1 standard EQUD &00030001 ; 2 right 1 EQUD &00000001 ; 3 standard ; left EQUD &00030001 ; 6 right 1 EQUD &00040001 ; 7 right 2 ; right EQUD &00010001 ; 4 left 1 EQUD &00020001 ; 5 left 2 ; -------------------------------------------------------------------------- .move_left ; -> R1 = pointer to character ; <- no change STMFD R13!, {R0-R3, R14} LDR R2, move_char_now ; increment animation CMP R2, #3 MOVle R2, #3 CMP R2, #6 MOVge R2, #3 ADD R2, R2, #1 CMP R2, #6 MOVeq R2, #4 STR R2, move_char_now ADR R0, move_chars LDR R0, [R0, R2, LSL #2] STR R0, [R1] LDR R0, [R1, #8] ; move left CMP R0, #(1 << 15) LDMeqFD R13!, {R0-R3, R14} ; exit if already at furthest left MOVeq PC, R14 MOV R3, R0 SUB R0, R0, #(2 << 12) STR R0, [R1, #8] MOV R2, #0 STR R2, fire_direction STMFD R13!, {R0, R2} MOV R0, #Table_Character% MOV R2, #1 BL process_table LDMFD R13!, {R0, R2} BL collisions_Character_Walls MOVne R0, R3 STRne R0, [R1, #8] BL scroll_horizontal LDMFD R13!, {R0-R3, R14} MOV PC, R14 ; -------------------------------------------------------------------------- .move_right ; -> R1 = pointer to character ; <- no change STMFD R13!, {R0-R3, R14} LDR R2, move_char_now CMP R2, #5 MOVle R2, #5 ADD R2, R2, #1 CMP R2, #8 MOVeq R2, #6 STR R2, move_char_now ADR R0, move_chars LDR R0, [R0, R2, LSL #2] STR R0, [R1] LDR R0, [R1, #8] ; move right LDR R2, move_right_edge CMP R0, R2 LDMeqFD R13!, {R0-R3, R14} ; exit if already at furthest right MOVeq PC, R14 MOV R3, R0 ADD R0, R0, #(2 << 12) STR R0, [R1, #8] MOV R2, #1 STR R2, fire_direction STMFD R13!, {R0, R2} MOV R0, #Table_Character% MOV R2, #1 BL process_table LDMFD R13!, {R0, R2} BL collisions_Character_Walls MOVne R0, R3 STRne R0, [R1, #8] BL scroll_horizontal LDMFD R13!, {R0-R3, R14} MOV PC, R14 .move_right_edge EQUD 0 ;((Wide% - 1) << 16) + (1 << 15) ; -------------------------------------------------------------------------- .scroll_horizontal ; -> R0 = character x position ; <- no change STMFD R13!, {R0-R1} RSB R0, R0, #0 ADD R0, R0, #(160 << 12) CMP R0, #0 MOVgt R0, #0 LDR R1, scroll_x_end CMP R0, R1 MOVlt R0, R1 STR R0, scroll_x LDR R1, scroll_y SWI "Amnesia_SetPlotOffset" LDMFD R13!, {R0-R1} MOV PC, R14 .scroll_x EQUD 0 ;(Wide% << 16) - (320 << 12) .scroll_x_end EQUD 0 ;(Wide% << 16) - (320 << 12) ; -------------------------------------------------------------------------- .scroll_vertical ; -> R1 = character y position ; <- no change STMFD R13!, {R0-R1} RSB R1, R1, #0 ADD R1, R1, #(120 << 12) CMP R1, #0 MOVgt R1, #0 LDR R0, scroll_y_end CMP R1, R0 MOVlt R1, R0 STR R1, scroll_y LDR R0, scroll_x SWI "Amnesia_SetPlotOffset" LDMFD R13!, {R0-R1} MOV PC, R14 .scroll_y EQUD 0 ;-((High% << 16) - (240 << 12)) .scroll_y_end EQUD 0 ;-((High% << 16) - (240 << 12)) ; -------------------------------------------------------------------------- .move_jump ; -> R1 = pointer to character ; <- no change STMFD R13!, {R0, R14} LDR R0, [R1, #4] TST R0, #(1 << 3) LDMneFD R13!, {R0, R14} MOVne PC, R14 BL collisions_Character_Ladders Beq move_jump_1 LDR R0, [R1, #12] SUB R0, R0, #(2 << 12) STR R0, [R1, #12] STMFD R13!, {R2} MOV R0, #Table_Character% MOV R2, #1 BL process_table LDMFD R13!, {R2} LDMFD R13!, {R0, R14} MOV PC, R14 .move_jump_1 ORR R0, R0, #(1 << 3) STR R0, [R1, #4] LDR R0, move_jump_velocity STR R0, [R1, #20] LDMFD R13!, {R0, R14} MOV PC, R14 .move_jump_velocity EQUD -(4 << 12) ; -------------------------------------------------------------------------- .move_down ; -> R1 = pointer to character ; <- no change STMFD R13!, {R0, R14} LDR R0, [R1, #4] TST R0, #(1 << 3) LDMneFD R13!, {R0, R14} MOVne PC, R14 ;L collisions_1_8 ;DMeqFD R13!, {R0, R14} ;OVeq PC, R14 LDR R0, [R1, #12] ADD R0, R0, #(2 << 12) STR R0, [R1, #12] STMFD R13!, {R2} MOV R0, #Table_Character% MOV R2, #1 BL process_table LDMFD R13!, {R2} LDMFD R13!, {R0, R14} MOV PC, R14 ; -------------------------------------------------------------------------- .fire_left ; -> R1 = pointer to character ; <- no change STMFD R13!, {R0-R9} .fire_left_jump LDR R4, fired_frame LDR R5, frame ADD R4, R4, #fire_delay% CMP R5, R4 LDMltFD R13!, {R0-R9} MOVlt PC, R14 STR R5, fired_frame MOV R9, R1 MOV R0, #Table_Bullets% MOV R1, #2 LDR R2, fire_flags LDR R3, [R9, #8] SUB R3, R3, #(1 << 15) LDR R4, [R9, #12] LDR R5, fire_left_velocity MOV R6, #0 LDR R7, bullet_timer MOV R8, #0 SWI "Amnesia_MakeObject" LDMFD R13!, {R0-R9} MOV PC, R14 .fire_left_velocity EQUD -(1 << 14) .fire_flags EQUD %11000001011010101 .bullet_timer EQUD &00320001 ; -------------------------------------------------------------------------- .fire_right ; -> R1 = pointer to character ; <- no change STMFD R13!, {R0-R9} .fire_right_jump LDR R4, fired_frame LDR R5, frame ADD R4, R4, #fire_delay% CMP R5, R4 LDMltFD R13!, {R0-R9} MOVlt PC, R14 STR R5, fired_frame MOV R9, R1 MOV R0, #Table_Bullets% MOV R1, #2 LDR R2, fire_flags LDR R3, [R9, #8] ADD R3, R3, #(1 << 15) LDR R4, [R9, #12] LDR R5, fire_right_velocity MOV R6, #0 LDR R7, bullet_timer MOV R8, #0 SWI "Amnesia_MakeObject" LDMFD R13!, {R0-R9} MOV PC, R14 .fire_right_velocity EQUD (1 << 14) ; -------------------------------------------------------------------------- .fire_stand ; -> R1 = pointer to character ; <- no change STMFD R13!, {R0-R9} LDR R0, fire_direction CMP R0, #0 Beq fire_left_jump B fire_right_jump .fire_direction EQUD 1 ; 0 = left, 1 = right .fired_frame EQUD 0 ; -------------------------------------------------------------------------- .process_table ; -> R0 = table to process ; R2 = plot action (0 = plot, 1 = don't) ; <- no change STMFD R13!, {R0-R2} MOV R1, #0 SWI "Amnesia_SelectTable" .process_table_loop SWI "Amnesia_ProcessTable" CMP R2, #0 Bne process_table_loop LDMFD R13!, {R0-R2} MOV PC, R14 ; -------------------------------------------------------------------------- .process_Enemies ; -> R0 = table to process ; R2 = plot action (0 = plot, 1 = don't) ; <- no change STMFD R13!, {R0-R3} MOV R1, #0 SWI "Amnesia_SelectTable" .process_Enemies_loop SWI "Amnesia_ProcessTable" CMP R2, #0 LDMeqFD R13!, {R0-R3} MOVeq PC, R14 TST R2, #(1 << 8) Beq process_Enemies_loop STMFD R13!, {R0-R3} LDR R0, [R1, #36] ; increment move ADD R0, R0, #1 LDR R2, [R1, #32] CMP R0, R2 MOVeq R0, #0 STR R0, [R1, #36] MOV R3, #12 ; calculate position MUL R2, R0, R3 ADD R2, R2, #40 ADD R2, R1, R2 LDR R0, [R2, #00] ; copy velocity etc STR R0, [R1, #16] LDR R0, [R2, #04] STR R0, [R1, #20] LDR R0, [R2, #08] STR R0, [R1, #24] LDMFD R13!, {R0-R3} B process_Enemies_loop ; -------------------------------------------------------------------------- .process_Droids ; -> R0 = table to process ; R2 = plot action (0 = plot, 1 = don't) ; <- no change STMFD R13!, {R0-R2} MOV R1, #0 SWI "Amnesia_SelectTable" .process_Droids_loop SWI "Amnesia_ProcessTable" CMP R2, #0 LDMeqFD R13!, {R0-R2} MOVeq PC, R14 TST R2, #(1 << 8) Beq process_Droids_loop STMFD R13!, {R0-R3} LDR R0, [R1, #00] AND R0, R0, #&FF0000 LDR R2, [R1, #32] LDR R3, [R1, #36] CMP R0, #0 MOVeq R0, R2 MOVne R0, R3 STR R0, [R1, #24] LDR R0, [R1, #00] EOR R0, R0, #&10000 STR R0, [R1, #00] LDMFD R13!, {R0-R3} B process_Droids_loop ; ---------------------------------------------------------------- .platforms ; -> R1 = pointer to character ; <- no change STMFD R13!, {R0-R9, R14} MOV R8, R1 MOV R0, #Table_Platforms% MOV R1, #1 MOV R2, #8 ; find all platforms in same x position as char LDR R3, [R8, #8] MOV R3, R3, LSR #16 MOV R3, R3, LSL #16 ADD R3, R3, #(1 << 15) MOV R4, #0 SWI "Amnesia_SelectTable" .process_platforms SWI "Amnesia_ProcessTable" CMP R2, #0 Beq process_platforms_end ; examine y position LDR R5, [R8, #12] ADD R5, R5, #(1 << 16) LDR R6, [R1, #12] SUB R6, R6, #(1 << 15) CMP R5, R6 Blt process_platforms_fall SUB R5, R5, #(1 << 15) CMP R5, R6 Bgt process_platforms_fall LDR R7, [R8, #20] CMP R7, #0 ; filter out rises Blt process_platforms LDR R7, [R8, #12] MOV R7, R7, LSR #16 MOV R7, R7, LSL #16 STR R7, [R8, #12] .process_platforms_nofall LDR R7, [R8, #4] BIC R7, R7, #(1 << 3) STR R7, [R8, #4] MOV R7, #0 STR R7, [R8, #20] B process_platforms_end .process_platforms_fall BL collisions_Character_Ladders Bne process_platforms_nofall LDR R7, [R8, #4] ORR R7, R7, #(1 << 3) STR R7, [R8, #4] LDR R7, [R8, #12] LDR R9, platforms_base CMP R7, R9 LDMgtFD R13!, {R0-R9, R14} MOVgt R0, #1 Bgt finalisation B process_platforms .platforms_base EQUD 0 ;(High% << 16) .process_platforms_end LDR R1, [R8, #12] BL scroll_vertical LDMFD R13!, {R0-R9, R14} MOV PC, R14 ; -------------------------------------------------------------------------- .collisions_Character_Walls ; -> nothing ; <- flags updated STMFD R13!, {R0-R3, R14} MOV R0, #Table_Character% MOV R1, #Table_Walls% SWI "Amnesia_CollisionCheck" CMP R0, #0 LDMFD R13!, {R0-R3, R14} MOV PC, R14 ; -------------------------------------------------------------------------- .collisions_Character_Ladders ; -> nothing ; <- no change STMFD R13!, {R0-R3, R14} MOV R0, #Table_Character% MOV R1, #Table_Ladders% SWI "Amnesia_CollisionCheck" CMP R0, #0 LDMFD R13!, {R0-R3, R14} MOV PC, R14 ; -------------------------------------------------------------------------- .collisions_Character_Bullets ; -> nothing ; <- no change STMFD R13!, {R0-R4, R14} MOV R0, #Table_Character% MOV R1, #Table_Bullets% .collisions_Character_Bullets_loop SWI "Amnesia_CollisionCheck" CMP R0, #0 LDMeqFD R13!, {R0-R4, R14} MOVeq PC, R14 STMFD R13!, {R0} MOV R0, #0 ; remove bullet STR R0, [R1] MOV R0, #80 ; reduce energy BL energy_reduce LDMFD R13!, {R0} B collisions_Character_Bullets_loop ; -------------------------------------------------------------------------- .collisions_Bullets_Bullets ; -> nothing ; <- no change STMFD R13!, {R0-R4, R14} MOV R0, #Table_Bullets% MOV R1, #Table_Bullets% .collisions_Bullets_Bullets_loop SWI "Amnesia_CollisionCheck" CMP R0, #0 LDMeqFD R13!, {R0-R4, R14} MOVeq PC, R14 MOV R4, #0 STR R4, [R0] STR R4, [R1] B collisions_Bullets_Bullets_loop ; -------------------------------------------------------------------------- .collisions_Walls_Bullets ; -> nothing ; <- no change STMFD R13!, {R0-R4, R14} MOV R0, #Table_Bullets% MOV R1, #Table_Walls% .collisions_Walls_Bullets_loop SWI "Amnesia_CollisionCheck" CMP R0, #0 LDMeqFD R13!, {R0-R4, R14} MOVeq PC, R14 LDR R4, [R0, #16] RSB R4, R4, #0 STR R4, [R0, #16] B collisions_Walls_Bullets_loop ; -------------------------------------------------------------------------- .collisions_Enemies_Bullets ; -> nothing ; <- no change STMFD R13!, {R0-R4, R14} MOV R0, #Table_Bullets% MOV R1, #Table_Enemies% .collisions_Enemies_Bullets_loop SWI "Amnesia_CollisionCheck" CMP R0, #0 LDMeqFD R13!, {R0-R4, R14} MOVeq PC, R14 MOV R4, #0 ; remove bullet & enemy STR R4, [R0] STR R4, [R1] STMFD R13!, {R0-R8} LDR R3, [R1, #08] LDR R4, [R1, #12] MOV R0, #Table_Xplosions% LDR R1, Xplosion1 + 00 LDR R2, Xplosion1 + 04 MOV R5, #0 MOV R6, #0 LDR R7, Xplosion1 + 08 SWI "Amnesia_MakeObject" LDMFD R13!, {R0-R8} B collisions_Enemies_Bullets_loop .Xplosion1 EQUD &00000007 EQUD %1000001001110001 EQUD &06000080 ; -------------------------------------------------------------------------- .collisions_Droids_Bullets ; -> nothing ; <- no change STMFD R13!, {R0-R4, R14} MOV R0, #Table_Bullets% MOV R1, #Table_Droids% .collisions_Bullets_Droids_loop SWI "Amnesia_CollisionCheck" CMP R0, #0 LDMeqFD R13!, {R0-R4, R14} MOVeq PC, R14 MOV R4, #0 ; remove bullet STR R4, [R0] LDR R4, [R1, #40] ; droid lives SUB R4, R4, #1 STR R4, [R1, #40] CMP R4, #0 Bne collisions_Bullets_Droids_loop MOV R4, #0 ; remove droid STR R4, [R1] STMFD R13!, {R0-R8} LDR R3, [R1, #08] LDR R4, [R1, #12] MOV R0, #Table_Xplosions% LDR R1, Xplosion2 + 00 LDR R2, Xplosion2 + 04 MOV R5, #0 MOV R6, #0 LDR R7, Xplosion2 + 08 SWI "Amnesia_MakeObject" LDMFD R13!, {R0-R8} B collisions_Bullets_Droids_loop .Xplosion2 EQUD &00000009 EQUD %1000001001110001 EQUD &04000080 ; -------------------------------------------------------------------------- .collisions_Character_Enemies ; -> nothing ; <- no change STMFD R13!, {R0-R4, R14} MOV R0, #Table_Character% MOV R1, #Table_Enemies% .collisions_Character_Enemies_loop SWI "Amnesia_CollisionCheck" CMP R0, #0 LDMeqFD R13!, {R0-R4, R14} MOVeq PC, R14 STMFD R13!, {R0} MOV R0, #1 BL energy_reduce LDMFD R13!, {R0} B collisions_Character_Enemies_loop ; -------------------------------------------------------------------------- .collisions_Character_Droids ; -> nothing ; <- no change STMFD R13!, {R0-R4, R14} MOV R0, #Table_Character% MOV R1, #Table_Droids% .collisions_Character_Droids_loop SWI "Amnesia_CollisionCheck" CMP R0, #0 LDMeqFD R13!, {R0-R4, R14} MOVeq PC, R14 STMFD R13!, {R0} MOV R0, #2 BL energy_reduce LDMFD R13!, {R0} B collisions_Character_Droids_loop ; -------------------------------------------------------------------------- .collisions_Droids_Walls ; -> nothing ; <- no change STMFD R13!, {R0-R5, R14} MOV R0, #Table_Droids% MOV R1, #Table_Walls% .collisions_Droids_Walls_loop SWI "Amnesia_CollisionCheck" CMP R0, #0 LDMeqFD R13!, {R0-R5, R14} MOVeq PC, R14 LDR R4, [R0, #08] LDR R5, [R0, #16] SUB R4, R4, R5 STR R4, [R0, #08] B collisions_Droids_Walls_loop ; -------------------------------------------------------------------------- .collisions_Character_Items ; -> nothing ; <- no change STMFD R13!, {R0-R3, R14} MOV R0, #Table_Character% MOV R1, #Table_Items% .collisions_Character_Items_loop SWI "Amnesia_CollisionCheck" CMP R0, #0 LDMeqFD R13!, {R0-R3, R14} MOVeq PC, R14 LDR R0, [R1, #0] SUB R0, R0, #10 B finalisation ; -------------------------------------------------------------------------- .energy_reduce ; -> R0 = amount of energy to reduce by ; <- no change STMFD R13!, {R0-R4} LDR R1, energy SUB R0, R1, R0 STR R0, energy CMP R0, #0 LDMleFD R13!, {R0-R4} MOVle R0, #1 Ble finalisation MOV R1, #240 MOV R2, #320 MOV R3, #256 SWI "FastSpr_SetClipWindow" SWI "FastSpr_ClearWindow" LDR R0, bank ; load bank from memory SUB R0, R0, #1 RSB R0, R0, #1 SWI "FastSpr_ScreenBank" SWI "FastSpr_ClearWindow" LDR R0, bank ; load bank from memory SUB R0, R0, #1 ; set bank for FastSpr SWI "FastSpr_ScreenBank" MOV R0, #0 MOV R1, #0 MOV R2, #320 MOV R3, #240 SWI "FastSpr_SetClipWindow" LDMFD R13!, {R0-R4} MOV PC, R14 .energy_reduce_sprite EQUD &01000001 ; -------------------------------------------------------------------------- .droids ; -> R1 = pointer to character ; <- no change STMFD R13!, {R0-R8, R14} MOV R2, R1 ; R2 -> character MOV R0, #Table_Droids% BL object_find ; R1 -> droid MOV R0, #Total_Droids% ; R0 = droid count .droids_loop LDR R4, [R2, #0] CMP R4, #0 Beq droids_next LDR R4, [R2, #08] ; character x LDR R5, [R1, #08] ; droid x LDR R6, [R2, #12] ; character y LDR R7, [R1, #12] ; droid y LDR R3, [R1, #04] ; has it been activated? TST R3, #(1 << 2) BLeq droids_activate MOV R3, #(1 << 12) ; x CMP R4, R5 RSBlt R3, R3, #0 MOVeq R3, #0 STR R3, [R1, #16] MOV R3, #(1 << 12) ; y CMP R6, R7 RSBlt R3, R3, #0 MOVeq R3, #0 STR R3, [R1, #20] .droids_next SUB R0, R0, #1 ADD R1, R1, #Size_Droids% CMP R0, #0 Bne droids_loop LDMFD R13!, {R0-R8, R14} MOV PC, R14 .droids_activate CMP R4, R5 ; find x difference SUBge R8, R4, R5 SUBlt R8, R5, R4 CMP R8, #(1 << 19) MOVgt PC, R14 CMP R6, R7 ; find y difference SUBge R8, R6, R7 SUBlt R8, R7, R6 CMP R8, #(1 << 19) MOVgt PC, R14 ORR R3, R3, #(1 << 2) STR R3, [R1, #04] MOV PC, R14 ; -------------------------------------------------------------------------- .stars STMFD R13!, {R0-R9, R14} ADR R0, stars_block ADR R1, screen_base SWI "OS_ReadVduVariables" LDR R0, screen_base ; R0 = base of screen memory LDR R1, starfield ; R1 = starfield list LDR R2, stars_scroll ADD R2, R2, #5 CMP R2, #(320*240) MOVeq R2, #0 STR R2, stars_scroll ; R2 = offset of star start from R0 LDR R9, stars_total MVN R3, #3 ; R3 = position in starfield list .starloop ADD R3, R3, #4 CMP R3, R9 Beq stars_exit LDR R4, [R1, R3] ; get distance between stars ADD R2, R2, R4 ; add it to screen offset CMP R2, #(320*240) ; wrap round SUBgt R2, R2, #(320*240) LDRB R5, [R0, R2] CMP R5, #0 Bne starloop MOV R5, #208 STRB R5, [R0, R2] B starloop .stars_exit LDMFD R13!, {R0-R9, R14} MOV PC, R14 .starfield EQUD Stars% .stars_scroll EQUD 0 .stars_block EQUD 148 EQUD -1 .screen_base EQUD 0 .stars_total EQUD ((Star% - 1) * 4) ; -------------------------------------------------------------------------- ;.debug_r0 ; -> R0 = number to display ; <- no change ;STMFD R13!, {R0-R2} ;ADR R1, buffer ;MOV R2, #16 ;SWI "OS_ConvertHex8" ;SWI &100 + 30 ;SWI "OS_Write0" ;LDMFD R13!, {R0-R2} ;MOV PC, R14 ;.buffer ; -------------------------------------------------------------------------- ] NEXT ENDPROC REM ˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜ DEF PROCLevel_Init(Level$) Data% = OPENIN(".Levels."+Level$+".Data") Wide% = VAL(GET$#Data%) High% = VAL(GET$#Data%) Y% = 0 X% = 0 REPEAT Tile% = BGET#Data% CASE Tile% OF WHEN 10 Y% += 1: X% = 0 WHEN ASC" " X% += 1 WHEN ASC"P" PROCAmnesia_MakeObject(Table_Platforms%, 3, %1000000001010001, (X% << 16) + (1 << 15), (Y% << 16) + (1 << 15)) X% += 1 WHEN ASC"L" Object% = FNAmnesia_MakeObject(Table_Ladders%, 4, %1000000011010001, (X% << 16) + (1 << 15), (Y% << 16) + (1 << 15)) Object%!28 = &0008000F X% += 1 WHEN ASC"W" PROCAmnesia_MakeObject(Table_Walls%, 5, %1000000011010001, (X% << 16) + (1 << 15), (Y% << 16) + (1 << 15)) X% += 1 WHEN ASC"*" PROCAmnesia_MakeObject(Table_Items%, 11, %1000000011010001, (X% << 16) + (1 << 15), (Y% << 16) + (1 << 15)) X% += 1 WHEN ASC"S" PROCAmnesia_MakeObject(Table_Character%, 1, %1000000011010101, (X% << 16) + (1 << 15), (Y% << 16)) PROCAmnesia_SetPlotOffset((X% << 16) + (1 << 15) + (160 << 12), (Y% << 16) - (120 << 12)) WHEN ASC"F" PROCAmnesia_MakeObject(Table_Items%, 10, %1000000011010001, (X% << 16) + (1 << 15), (Y% << 16) + (1 << 15)) ENDCASE UNTIL Y% = High% CLOSE#Data% Enem% = OPENIN(".Levels."+Level$+".Enemies") WHILE NOT EOF#Enem% Object% = FNAmnesia_MakeObject(Table_Enemies%, 6, %1000000111010101, (VAL(GET$#Enem%) << 16), (VAL(GET$#Enem%) << 16) + (1 << 15)) Moves% = 0 Object%!36 = 0 Move$ = GET$#Enem% REPEAT Object%!(40 + 12 * Moves%) = FNCutVal(Move$) << 12 Object%!(44 + 12 * Moves%) = FNCutVal(Move$) << 12 Object%!(48 + 12 * Moves%) = ((FNCutVal(Move$) - 1) << 16) + 1 Moves% += 1 Move$ = GET$#Enem% UNTIL Move$ = "" Object%!32 = Moves% Object%!16 = Object%!40 Object%!20 = Object%!44 Object%!24 = Object%!48 ENDWHILE CLOSE#Enem% Droi% = OPENIN(".Levels."+Level$+".Droids") WHILE NOT EOF#Droi% Object% = FNAmnesia_MakeObject(Table_Droids%, 8, %1000000111010001, (VAL(GET$#Droi%) << 16) + (1 << 15), ((VAL(GET$#Droi%) - 1) << 16) + (1 << 15)) Object%!24 = &00100001 :REM blue (starts) Object%!32 = &00020001 :REM orange Object%!36 = &00100001 :REM blue Object%!40 = 2 :REM lives ENDWHILE CLOSE#Droi% !move_right_edge = ((Wide% - 1) << 16) + (1 << 15) !scroll_x = 0 !scroll_x_end = -((Wide% << 16) - (320 << 12)) !scroll_y = -((High% << 16) - (240 << 12)) !scroll_y_end = -((High% << 16) - (240 << 12)) !platforms_base = (High% << 16) ENDPROC DEF FNCutVal(RETURN Text$) LOCAL Result$ IF INSTR(Text$, ",") = 0 THEN Result$ = Text$: Text$ = "": =VAL(Result$) Result$ = LEFT$(Text$, INSTR(Text$, ",") - 1) Text$ = MID$(Text$, INSTR(Text$, ",") + 1) =VAL(Result$) DEF PROCMakeStars Star% = 0 Rand% = RND(500) Addr% = Rand% REPEAT Stars%!(Star% * 4) = Rand% Star% += 1 Rand% = RND(500) Addr% += Rand% UNTIL Addr% > (320*240) ENDPROC