**************************************************************************** **************************************************************************** ** ** Platinum (Level Setup Routines) ** ** This software is in the public domain. There is no warranty. ** ** by Patrick Davidson (pad@calc.org, http://pad.calc.org/) ** ** Last updated August 2, 2001. ** **************************************************************************** **************************************************************************** ******************************************** PREPATE FIGURE ENEMY * * Prepares a sequence of enemies that will move through a figure. This * assumes the basic enemy structures have already been set up correctly. * Arguments to this function are: * * D0 = number of enemies - 1 * D1 = figure relative pointer * D2 = initial Y coordinate * D3 = initial X coordinate * D4 = initial timer value * D5 = timer value step * ******** Prepare_Figure_Enemies: lea enemies_data(a5),a4 pfe_loop: move.w d2,e_y(a4) move.w d3,e_x(a4) move.w d1,e_path(a4) move.w d4,e_timer(a4) add.w d5,d4 lea e_size(a4),a4 dbra d0,pfe_loop rts ******************************************** PREPARE FOR PLAIN, FIRING ENTRY * * This routine prepares the first D0 enemies in the enemy data for entry in * the U pattern, setting X and Y coordinates appropriately. This assumes * the array already has all other data items for these enemies, as well as * the coordinate map, are already initialized correctly. This routine also * adjusts the Y coordinates in the map by the value in D3. * ******** Prepare_Plain_Entry: lea enemies_data(a5),a4 lea xy_pointers(a5),a3 ppe_loop: move.w (a3)+,e_x(a4) add.w d3,(a3) move.w (a3)+,d1 sub.w #72,d1 move.w d1,e_y(a4) lea e_size(a4),a4 ; next enemy structure dbra d0,ppe_loop move.w #DONTMOVE,pattern_type(a5) rts ******************************************** PREPARE SPINNER ENTRY Prepare_Spin_Entry: lea enemies_data(a5),a4 lea xy_pointers(a5),a3 moveq #122,d1 ; D1 = left Y coordinate moveq #122,d2 ; D2 = right Y coordinate \loop: cmp.w #110,(a3) bge.s \right \left: move.w d2,e_y(a4) add.w #12,d2 move.w #48,e_x(a4) bra.s \done \right: move.w d1,e_y(a4) add.w #12,d1 move.w #196,e_x(a4) \done: lea 4(a3),a3 lea e_size(a4),a4 dbra d0,\loop rts ******************************************** PREPARE FOR SIMPLE ENTRY * * This routine prepares the first D0 enemies in the enemy data for entry in * the U pattern, setting X and Y coordinates appropriately. This assumes * the array already has all other data items for these enemies, as well as * the coordinate map, are already initialized correctly. * ******** Prepare_Simple_Entry: lea enemies_data(a5),a4 lea xy_pointers(a5),a3 moveq #64,d2 pse_loop: move.w (a3)+,d1 add.w #32,d1 cmp.w #142,d1 bge.s pse_right pse_left: sub.w d2,d1 bra.s pse_done pse_right: add.w d2,d1 pse_done: move.w d1,e_x(a4) move.w (a3)+,d1 sub.w d2,d1 move.w d1,e_y(a4) lea e_size(a4),a4 ; next enemy structure dbra d0,pse_loop move.w #DONTMOVE,pattern_type(a5) move.w #1,pattern_stage(a5) move.w #32,pattern_x(a5) rts ******************************************** PREPARE FOR U ENTRY * * This routine prepares the first D0 enemies in the enemy data for entry in * the U pattern, setting X and Y coordinates appropriately. This assumes * the array already has all other data items for these enemies, as well as * the coordinate map, are already initialized correctly. D4 holds the * spacing (in pixels) between entering enemies). * ******** Prepare_U_Entry: lea enemies_data(a5),a4 lea xy_pointers(a5),a3 moveq #13,d1 ; D1 = left Y coordinate moveq #13,d2 ; D2 = right Y coordinate peu_loop: cmp.w #110,(a3) bge.s peu_right peu_left: move.w d2,e_y(a4) sub.w d4,d2 move.w #49,e_x(a4) bra.s peu_done peu_right: move.w d1,e_y(a4) sub.w d4,d1 move.w #196,e_x(a4) peu_done: lea e_size(a4),a4 ; next enemy structure addq.w #4,a3 ; next coordinate dbra d0,peu_loop rts ******************************************** LEVEL LOADER SUBROUTINES * * This routine is used to install enemies in the enemy array. It is called * with the following arguments: * * A4 -> Table of coordinates (if any) * D0 = Number of enemies to install * D6 = Enemy destruction routine (see EDESTROY.ASM) * A0 -> Enemy data block * A1 -> Position in enemy array (should be enemies_data on first call) * * This routine will increase the number of enemies remaining by the given * amount, and install the specified number of enemies at the specified type. * The main level code will call the level loader with A1 set to enemies_data * initially so it is usually unnecessary for the level loader to set that. * Also, D6 is the "normal" destruction routine (for non-bosses) on entry to * the loader, so it can often be ignored also. * * The X and Y coordinates are both set to -300, so enemies must move * themselves into the screen at an appropriate time. * * This routine changes only D0, A1, and A2. * ******** Load_Enemy_Info: add.w d0,enemies_remaining(a5) subq.w #1,d0 _Load_Enemy_Info: lea (a0),a2 move.l (a2)+,(a1)+ move.w #-300,(a1)+ move.w (a2)+,(a1)+ move.w #-300,(a1)+ move.l (a2)+,(a1)+ move.w (a2)+,(a1)+ move.w d6,(A1)+ move.l (a2)+,(a1)+ move.w (a2)+,(a1)+ dbra d0,_Load_Enemy_Info rts ******************************************** COORDINATE DATA BANK LOADER * * Takes a pointer to a coordinate data bank in A4. Modifies D0, A0, A4. * ******** Install_Data_Bank: moveq #24,d0 lea xy_pointers(a5),a0 lidb: move.l (a4)+,(a0)+ dbra d0,lidb rts ******************************************** LOAD NEXT LEVEL * * This routine initializes the next level. It is called from the game's main * loop whenever no enemies remain. It is responsible for counting level * numbers and calling the level setup routines, which allows maximum * flexibility in nitializing data structures. It also allows special levels, * such as the shop, which do not contain any gameplay at all. * * The code levels themselves will be called with A1 pointing to enemies_data, * and D6 containg the default enemy destuction routine (these values are * useful as defaults for the enemy installation code). * ******** Next_Level: clr.w oskey clr.w special_weapon_delay(a5) lea pattern_type(a5),a1 ;restore pattern to default move.w #RECTANGLE,(a1)+ clr.l (a1)+ clr.l (a1) lea enemies_data(a5),a1 move.w #EDestruct_Normal-Destroy_Base,d6 addq.w #1,level_number(a5) move.w level_number(a5),d0 add.w d0,d0 ;D0 = index into Level_Table move.w Level_Table-2(pc,d0.w),d0 ;D0 = offset of level's code jmp Level_Table(pc,d0.w) ;Jump to level's code ******************************************** LEVEL DEFINITION MACROS numlev set 0 LEVEL MACRO dc.w \1-Level_Table ;\2 set numlev ;numlev set numlev+1 ENDM