diff --git a/src/machines/emitter.asm b/src/machines/emitter.asm index 795fa7d1..543575cb 100644 --- a/src/machines/emitter.asm +++ b/src/machines/emitter.asm @@ -19,10 +19,12 @@ .INCLUDE "../macros.inc" .INCLUDE "../oam.inc" +.INCLUDE "../platform.inc" .INCLUDE "../ppu.inc" .INCLUDE "emitter.inc" .INCLUDE "shared.inc" +.IMPORT FuncA_Machine_StartWaiting .IMPORT FuncA_Objects_Draw1x1Shape .IMPORT FuncA_Objects_GetMachineLightTileId .IMPORT FuncA_Objects_MoveShapeDownByA @@ -32,14 +34,30 @@ .IMPORT FuncA_Objects_SetShapePosToMachineTopLeft .IMPORT Func_DivMod .IMPORT Func_GetRandomByte +.IMPORT Func_MovePointDownByA +.IMPORT Func_MovePointRightByA +.IMPORT Func_SetPlatformTopLeftToPoint +.IMPORT Func_SetPointToPlatformTopLeft .IMPORT Ram_MachineGoalHorz_u8_arr .IMPORT Ram_MachineGoalVert_u8_arr .IMPORT Ram_MachineSlowdown_u8_arr +.IMPORT Ram_MachineState1_byte_arr +.IMPORT Ram_PlatformBottom_i16_0_arr +.IMPORT Ram_PlatformTop_i16_0_arr +.IMPORT Ram_PlatformType_ePlatform_arr .IMPORTZP Zp_FrameCounter_u8 .IMPORTZP Zp_MachineIndex_u8 ;;;=========================================================================;;; +;;; How long an emitter machine's beam fires for after an ACT operation, in +;;; frames. +kEmitterBeamDuration = 10 + +;;; How long an emitter machine must wait after an ACT operation before it can +;;; continue executing, in frames. +kEmitterActCooldown = 30 + ;;; OBJ tiles IDs used for drawing emitter machines. kTileIdObjEmitterBeamHorz = kTileIdObjEmitterFirst + 0 kTileIdObjEmitterBeamVert = kTileIdObjEmitterFirst + 1 @@ -52,15 +70,138 @@ kPaletteObjEmitterGlow = 1 ;;;=========================================================================;;; +.SEGMENT "PRG8" + +;;; ReadReg implementation for emitter machines. +;;; @prereq Zp_MachineIndex_u8 and Zp_Current_sMachine_ptr are initialized. +;;; @return A The value of the emitter's position register (0-9). +.EXPORT Func_MachineEmitterReadReg +.PROC Func_MachineEmitterReadReg + ldy Zp_MachineIndex_u8 + lda Ram_MachineState1_byte_arr, y ; X/Y register value + rts +.ENDPROC + +;;;=========================================================================;;; + +.SEGMENT "PRGA_Room" + +;;; Init/Reset implementation for emitter-Y machines. +;;; @param A The initial value of the Y register (0-9). +.EXPORT FuncA_Room_MachineEmitterYInitReset +.PROC FuncA_Room_MachineEmitterYInitReset + sta Ram_MachineState1_byte_arr + kEmitterYMachineIndex ; Y register value + pha ; register value + lda Ram_PlatformBottom_i16_0_arr + kEmitterRegionPlatformIndex + sub Ram_PlatformTop_i16_0_arr + kEmitterRegionPlatformIndex + div #kBlockHeightPx + sta T2 ; num rows + tay ; num rows (param: divisor) + pla ; register value (param: dividend) + jsr Func_DivMod ; preserves T2+, returns remainder in A + clc + rsbc T2 + sta Ram_MachineGoalVert_u8_arr + kEmitterYMachineIndex ; beam row + bpl FuncA_Room_RemoveEmitterForcefield ; unconditional +.ENDPROC + +;;; Init/Reset implementation for emitter-X machines. +;;; @param A The initial value of the X register (0-9). +.EXPORT FuncA_Room_MachineEmitterXInitReset +.PROC FuncA_Room_MachineEmitterXInitReset + sta Ram_MachineState1_byte_arr + kEmitterXMachineIndex ; X register value + sta Ram_MachineGoalHorz_u8_arr + kEmitterXMachineIndex ; beam col + fall FuncA_Room_RemoveEmitterForcefield +.ENDPROC + +;;; Removes the forcefield (if any) created by the emitter machines. +.PROC FuncA_Room_RemoveEmitterForcefield + lda #ePlatform::Zone + sta Ram_PlatformType_ePlatform_arr + kEmitterForcefieldPlatformIndex + rts +.ENDPROC + +;;;=========================================================================;;; + +.SEGMENT "PRGA_Machine" + +;;; WriteReg implementation for emitter-X machines. +;;; @param A The value to write (0-9). +.EXPORT FuncA_Machine_EmitterXWriteReg +.PROC FuncA_Machine_EmitterXWriteReg + sta Ram_MachineState1_byte_arr + kEmitterXMachineIndex ; X register value + sta Ram_MachineGoalHorz_u8_arr + kEmitterXMachineIndex ; beam column + rts +.ENDPROC + +;;; WriteReg implementation for emitter-Y machines. +;;; @prereq Zp_MachineIndex_u8 and Zp_Current_sMachine_ptr are initialized. +;;; @param A The value to write (0-9). +.EXPORT FuncA_Machine_EmitterYWriteReg +.PROC FuncA_Machine_EmitterYWriteReg + sta Ram_MachineState1_byte_arr + kEmitterYMachineIndex ; Y register value + pha ; register value + lda Ram_PlatformBottom_i16_0_arr + kEmitterRegionPlatformIndex + sub Ram_PlatformTop_i16_0_arr + kEmitterRegionPlatformIndex + div #kBlockHeightPx + sta T2 ; num rows + tay ; num rows (param: divisor) + pla ; register value (param: dividend) + jsr Func_DivMod ; preserves T2+, returns remainder in A + clc + rsbc T2 + sta Ram_MachineGoalVert_u8_arr + kEmitterYMachineIndex ; beam row + rts +.ENDPROC + +;;; TryAct implementation for emitter machines. +.EXPORT FuncA_Machine_EmitterTryAct +.PROC FuncA_Machine_EmitterTryAct + ldy #kEmitterRegionPlatformIndex ; param: platform index + jsr Func_SetPointToPlatformTopLeft + ;; Start this emitter machine's beam firing. + ldy Zp_MachineIndex_u8 + lda #kEmitterBeamDuration + sta Ram_MachineSlowdown_u8_arr, y + ;; Remove any existing forcefield. + lda #ePlatform::Zone + sta Ram_PlatformType_ePlatform_arr + kEmitterForcefieldPlatformIndex + ;; Only make a new forcefield if both emitters are firing at once. + lda Ram_MachineSlowdown_u8_arr + kEmitterXMachineIndex + beq _Finish + lda Ram_MachineSlowdown_u8_arr + kEmitterYMachineIndex + beq _Finish + ;; Reposition the forcefield platform. + lda Ram_MachineGoalHorz_u8_arr + kEmitterXMachineIndex ; beam col + mul #kBlockWidthPx + jsr Func_MovePointRightByA + lda Ram_MachineGoalVert_u8_arr + kEmitterYMachineIndex ; beam row + mul #kBlockHeightPx + jsr Func_MovePointDownByA + ldy #kEmitterForcefieldPlatformIndex ; param: platform index + jsr Func_SetPlatformTopLeftToPoint + ;; Make the forcefield platform solid. + lda #ePlatform::Solid + sta Ram_PlatformType_ePlatform_arr + kEmitterForcefieldPlatformIndex + ;; TODO: if avatar is deep in platform, harm (kill?) it + ;; TODO: push avatar out of platform +_Finish: + ;; Make the emitter machine wait to cool down. + lda #kEmitterActCooldown ; param: num frames to wait + jmp FuncA_Machine_StartWaiting +.ENDPROC + +;;;=========================================================================;;; + .SEGMENT "PRGA_Objects" ;;; Draws a forcefield emitter machine that fires a vertical beam at various ;;; X-positions. ;;; @prereq Zp_MachineIndex_u8 and Zp_Current_sMachine_ptr are initialized. -;;; @param A The length of the beam, in tiles. +;;; @param Y The length of the beam, in tiles. .EXPORT FuncA_Objects_DrawEmitterXMachine .PROC FuncA_Objects_DrawEmitterXMachine - sta T0 ; beam length in tiles + sty T0 ; beam length in tiles jsr FuncA_Objects_SetShapePosToMachineTopLeft ; preserves T0+ lda #kBlockHeightPx ; param: offset jsr FuncA_Objects_MoveShapeDownByA ; preserves T0+ @@ -95,15 +236,14 @@ _DrawGlow: ;;; Draws a forcefield emitter machine that fires a horizontal beam at various ;;; Y-positions. ;;; @prereq Zp_MachineIndex_u8 and Zp_Current_sMachine_ptr are initialized. -;;; @param A The length of the beam, in tiles. +;;; @param Y The length of the beam, in tiles. .EXPORT FuncA_Objects_DrawEmitterYMachine .PROC FuncA_Objects_DrawEmitterYMachine - sta T0 ; beam length in tiles + sty T0 ; beam length in tiles jsr FuncA_Objects_SetShapePosToMachineTopLeft ; preserves T0+ jsr FuncA_Objects_MoveShapeRightOneTile ; preserves T0+ ldx Zp_MachineIndex_u8 - lda #9 - sub Ram_MachineGoalVert_u8_arr, x + lda Ram_MachineGoalVert_u8_arr, x mul #kBlockHeightPx adc #kTileHeightPx / 2 ; param: offset jsr FuncA_Objects_MoveShapeDownByA ; preserves X and T0+ diff --git a/src/machines/emitter.inc b/src/machines/emitter.inc index 3be33c3d..a1c092aa 100644 --- a/src/machines/emitter.inc +++ b/src/machines/emitter.inc @@ -19,12 +19,22 @@ ;;; State bytes for emitter machines: ;;; * Slowdown: Nonzero if the emitter beam is currently firing. -;;; * State1: Unused. +;;; * GoalHorz: For EmitterX machines, this is the column (starting from the +;;; left) that the beam will emit from. +;;; * GoalVert: For EmitterY machines, this is the row (starting from the +;;; top) that the beam will emit from. +;;; * State1: The actual value (0-9) stored in the machine's X/Y register. ;;; * State2: Unused. ;;; * State3: Unused. -;;; How many frames an emitter machine spends per ACT operation. -kEmitterActCountdown = 10 +;;; The machine indices that must be used for emitter machines. +kEmitterXMachineIndex = 0 +kEmitterYMachineIndex = 1 + +;;; The platform index for the forcefield created by emitter machines. +kEmitterForcefieldPlatformIndex = 0 +;;; The platform index for the region that the forcefield can appear in. +kEmitterRegionPlatformIndex = 1 ;;; OBJ tile IDs used for drawing emitter machines. kTileIdObjEmitterFirst = $90 diff --git a/src/platform.asm b/src/platform.asm index 30e5bda7..55fa43a9 100644 --- a/src/platform.asm +++ b/src/platform.asm @@ -85,6 +85,23 @@ Ram_PlatformRight_i16_1_arr: .res kMaxPlatforms .SEGMENT "PRG8" +;;; Stores the room pixel position of the top-left corner of the platform in +;;; Zp_Point*_i16. +;;; @param Y The platform index. +;;; @preserve X, Y, T0+ +.EXPORT Func_SetPointToPlatformTopLeft +.PROC Func_SetPointToPlatformTopLeft + lda Ram_PlatformLeft_i16_0_arr, y + sta Zp_PointX_i16 + 0 + lda Ram_PlatformLeft_i16_1_arr, y + sta Zp_PointX_i16 + 1 + lda Ram_PlatformTop_i16_0_arr, y + sta Zp_PointY_i16 + 0 + lda Ram_PlatformTop_i16_1_arr, y + sta Zp_PointY_i16 + 1 + rts +.ENDPROC + ;;; Stores the room pixel position of the center of the platform in ;;; Zp_Point*_i16. The platform's width and height must fit in one byte. ;;; @param Y The platform index. @@ -218,8 +235,75 @@ _Inside: rts .ENDPROC +;;; Repositions the platform so that its top-left corner is at the point stored +;;; in Zp_PointX_i16 and Zp_PointY_i16. This does not affect the player +;;; avatar. +;;; @param Y The platform index. +;;; @preserve X, Y, T2+ +.EXPORT Func_SetPlatformTopLeftToPoint +.PROC Func_SetPlatformTopLeftToPoint + jsr Func_SetPlatformTopToPointY ; preserves X, Y, and T2+ + fall Func_SetPlatformLeftToPointX ; preserves X, Y, and T2+ +.ENDPROC + +;;; Repositions the platform so that its left edge is at Zp_PointX_i16. This +;;; does not affect the player avatar. +;;; @param Y The platform index. +;;; @preserve X, Y, T2+ +.PROC Func_SetPlatformLeftToPointX + ;; Calculate the delta from Left to PointX, storing the result in T1T0. + lda Zp_PointX_i16 + 0 + sub Ram_PlatformLeft_i16_0_arr, y + sta T0 ; delta (lo) + lda Zp_PointX_i16 + 1 + sbc Ram_PlatformLeft_i16_1_arr, y + sta T1 ; delta (hi) + ;; Add the delta in T1T0 to Right. + lda Ram_PlatformRight_i16_0_arr, y + add T0 ; delta (lo) + sta Ram_PlatformRight_i16_0_arr, y + lda Ram_PlatformRight_i16_1_arr, y + adc T1 ; delta (hi) + sta Ram_PlatformRight_i16_1_arr, y + ;; Copy PointX into Left. + lda Zp_PointX_i16 + 0 + sta Ram_PlatformLeft_i16_0_arr, y + lda Zp_PointX_i16 + 1 + sta Ram_PlatformLeft_i16_1_arr, y + rts +.ENDPROC + +;;; Repositions the platform so that its top edge is at Zp_PointY_i16. This +;;; does not affect the player avatar. +;;; @param Y The platform index. +;;; @preserve X, Y, T2+ +.EXPORT Func_SetPlatformTopToPointY +.PROC Func_SetPlatformTopToPointY + ;; Calculate the delta from Top to PointY, storing the result in T1T0. + lda Zp_PointY_i16 + 0 + sub Ram_PlatformTop_i16_0_arr, y + sta T0 ; delta (lo) + lda Zp_PointY_i16 + 1 + sbc Ram_PlatformTop_i16_1_arr, y + sta T1 ; delta (hi) + ;; Add the delta in T1T0 to Bottom. + lda Ram_PlatformBottom_i16_0_arr, y + add T0 ; delta (lo) + sta Ram_PlatformBottom_i16_0_arr, y + lda Ram_PlatformBottom_i16_1_arr, y + adc T1 ; delta (hi) + sta Ram_PlatformBottom_i16_1_arr, y + ;; Copy PointY into Top. + lda Zp_PointY_i16 + 0 + sta Ram_PlatformTop_i16_0_arr, y + lda Zp_PointY_i16 + 1 + sta Ram_PlatformTop_i16_1_arr, y + rts +.ENDPROC + ;;; Move the specified platform horizontally such that its left edge moves -;;; toward the goal position without overshooting it. +;;; toward the goal position without overshooting it. This may push or carry +;;; the player avatar. ;;; @prereq Zp_PointX_i16 is set to the goal room-space pixel X-position. ;;; @param A The max distance to move by, in pixels (0-127). ;;; @param X The platform index. @@ -262,8 +346,8 @@ _MoveByA: rts .ENDPROC -;;; Moves the specified platform right or left by the specified delta. If the -;;; player avatar is standing on the platform, it will be moved along with it. +;;; Moves the specified platform right or left by the specified delta. This +;;; may push or carry the player avatar. ;;; @param A How many pixels to move the platform by (signed). ;;; @param X The platform index. ;;; @preserve X @@ -347,7 +431,8 @@ _Return: .ENDPROC ;;; Move the specified platform vertically such that its top edge moves toward -;;; the goal position without overshooting it. +;;; the goal position without overshooting it. This may push or carry the +;;; player avatar. ;;; @prereq Zp_PointY_i16 is set to the goal room-space pixel Y-position. ;;; @param A The max distance to move by, in pixels (0-127). ;;; @param X The platform index. @@ -390,8 +475,8 @@ _MoveByA: rts .ENDPROC -;;; Moves the specified platform up or down by the specified delta. If the -;;; player avatar is standing on the platform, it will be moved along with it. +;;; Moves the specified platform up or down by the specified delta. This may +;;; push or carry the player avatar. ;;; @param A How many pixels to move the platform by (signed). ;;; @param X The platform index. ;;; @preserve X diff --git a/src/program.inc b/src/program.inc index 71252570..b4c14701 100644 --- a/src/program.inc +++ b/src/program.inc @@ -197,6 +197,8 @@ LavaVentLift LavaCavernBoiler ShadowFlowerLaser + ShadowHeartEmitterX + ShadowHeartEmitterY NUM_VALUES .ENDENUM diff --git a/src/rooms/boss_mine.asm b/src/rooms/boss_mine.asm index 09c2adb7..f5542036 100644 --- a/src/rooms/boss_mine.asm +++ b/src/rooms/boss_mine.asm @@ -73,6 +73,7 @@ .IMPORT Func_PlaySfxShootFire .IMPORT Func_SetActorCenterToPoint .IMPORT Func_SetMachineIndex +.IMPORT Func_SetPlatformTopLeftToPoint .IMPORT Func_SetPointToAvatarCenter .IMPORT Func_SetPointToPlatformCenter .IMPORT Func_ShakeRoom @@ -83,13 +84,9 @@ .IMPORT Ram_MachineGoalVert_u8_arr .IMPORT Ram_MachineStatus_eMachine_arr .IMPORT Ram_PlatformBottom_i16_0_arr -.IMPORT Ram_PlatformBottom_i16_1_arr .IMPORT Ram_PlatformLeft_i16_0_arr -.IMPORT Ram_PlatformLeft_i16_1_arr .IMPORT Ram_PlatformRight_i16_0_arr -.IMPORT Ram_PlatformRight_i16_1_arr .IMPORT Ram_PlatformTop_i16_0_arr -.IMPORT Ram_PlatformTop_i16_1_arr .IMPORT Ram_PlatformType_ePlatform_arr .IMPORT Ram_PpuTransfer_arr .IMPORTZP Zp_Chr04Bank_u8 @@ -148,10 +145,8 @@ kBoulderHeightPx = kBlockHeightPx ;;; The room pixel positions for each side of the boulder platform when a new ;;; boulder is spawned. -kBoulderSpawnTop = $0060 -kBoulderSpawnBottom = kBoulderSpawnTop + kBoulderHeightPx -kBoulderSpawnLeft = $ffff & -$18 -kBoulderSpawnRight = kBoulderSpawnLeft + kBoulderWidthPx +kBoulderSpawnTop = $0060 +kBoulderSpawnLeft = $ffff & -$18 ;;; States that the boulder in this room can be in. .ENUM eBoulder @@ -1049,35 +1044,24 @@ _BossIsDead: .ENDREPEAT .ENDPROC -;;; Performs per-frame upates for the boulder when it's on the conveyor. +;;; Performs per-frame upates for the boulder when it's absent. ;;; @prereq BoulderState_eBoulder is eBoulder::Absent. .PROC FuncA_Room_BossMine_TickBoulderAbsent ;; Spawn a new boulder. - lda #kBoulderSpawnLeft - sta Ram_PlatformLeft_i16_1_arr + kBoulderPlatformIndex - .assert >kBoulderSpawnRight = >kBoulderSpawnLeft, error - sta Ram_PlatformRight_i16_1_arr + kBoulderPlatformIndex - lda #kBoulderSpawnTop - sta Ram_PlatformTop_i16_1_arr + kBoulderPlatformIndex - .assert >kBoulderSpawnBottom = >kBoulderSpawnTop, error - sta Ram_PlatformBottom_i16_1_arr + kBoulderPlatformIndex - .assert >kBoulderSpawnBottom = 0, error + .assert eBoulder::OnConveyor = eBoulder::Absent + 1, error + inc Zp_RoomState + sState::BoulderState_eBoulder + lda #ePlatform::Solid + sta Ram_PlatformType_ePlatform_arr + kBoulderPlatformIndex + ldax #kBoulderSpawnLeft + stax Zp_PointX_i16 + ldax #kBoulderSpawnTop + stax Zp_PointY_i16 + .assert >kBoulderSpawnTop = 0, error sta Zp_RoomState + sState::BoulderSubY_u8 sta Zp_RoomState + sState::BoulderVelY_i16 + 0 sta Zp_RoomState + sState::BoulderVelY_i16 + 1 - lda #eBoulder::OnConveyor - sta Zp_RoomState + sState::BoulderState_eBoulder - lda #ePlatform::Solid - sta Ram_PlatformType_ePlatform_arr + kBoulderPlatformIndex - rts + ldy #kBoulderPlatformIndex ; param: platform index + jmp Func_SetPlatformTopLeftToPoint .ENDPROC ;;; Performs per-frame upates for the boulder when it's on the conveyor. diff --git a/src/rooms/boss_shadow.asm b/src/rooms/boss_shadow.asm index 7457c51f..fe864b68 100644 --- a/src/rooms/boss_shadow.asm +++ b/src/rooms/boss_shadow.asm @@ -37,18 +37,23 @@ .IMPORT DataA_Room_Shadow_sTileset .IMPORT Data_Empty_sActor_arr +.IMPORT FuncA_Machine_EmitterTryAct +.IMPORT FuncA_Machine_EmitterXWriteReg +.IMPORT FuncA_Machine_EmitterYWriteReg .IMPORT FuncA_Machine_Error .IMPORT FuncA_Machine_ReachedGoal -.IMPORT FuncA_Machine_StartWaiting .IMPORT FuncA_Objects_AnimateLavaTerrain .IMPORT FuncA_Objects_DrawBoss .IMPORT FuncA_Objects_DrawEmitterXMachine .IMPORT FuncA_Objects_DrawEmitterYMachine .IMPORT FuncA_Objects_DrawForcefieldPlatform .IMPORT FuncA_Room_InitBoss +.IMPORT FuncA_Room_MachineEmitterXInitReset +.IMPORT FuncA_Room_MachineEmitterYInitReset .IMPORT FuncA_Room_TickBoss .IMPORT FuncA_Terrain_FadeInShortRoomWithLava .IMPORT Func_AckIrqAndLatchWindowFromParam4 +.IMPORT Func_MachineEmitterReadReg .IMPORT Func_MovePlatformVert .IMPORT Func_Noop .IMPORT Func_ShakeRoom @@ -56,44 +61,30 @@ .IMPORT Ppu_ChrObjBoss1 .IMPORT Ram_MachineGoalHorz_u8_arr .IMPORT Ram_MachineGoalVert_u8_arr -.IMPORT Ram_MachineSlowdown_u8_arr -.IMPORT Ram_PlatformBottom_i16_0_arr -.IMPORT Ram_PlatformLeft_i16_0_arr -.IMPORT Ram_PlatformRight_i16_0_arr -.IMPORT Ram_PlatformTop_i16_0_arr -.IMPORT Ram_PlatformType_ePlatform_arr .IMPORTZP Zp_Buffered_sIrq .IMPORTZP Zp_RoomScrollY_u8 .IMPORTZP Zp_RoomState ;;;=========================================================================;;; -;;; The machine index for the BossShadowEmitterX machine. -kEmitterXMachineIndex = 0 -;;; The machine index for the BossShadowEmitterY machine. -kEmitterYMachineIndex = 1 - ;;; The platform index for the BossShadowEmitterX machine. -kEmitterXPlatformIndex = 1 +kEmitterXPlatformIndex = 3 ;;; The platform index for the BossShadowEmitterY machine. -kEmitterYPlatformIndex = 2 +kEmitterYPlatformIndex = 4 ;;; The initial positions of the emitter beams. -kEmitterXInitGoalX = 3 -kEmitterYInitGoalY = 7 - -;;; The platform index for the emitted forcefield. -kForcefieldPlatformIndex = 3 +kEmitterXInitRegX = 3 +kEmitterYInitRegY = 7 ;;; The minimum/maximum room pixel X/Y-positions for the top-left of the ;;; forcefield platform. kForcefieldMinPlatformLeft = $0030 -kForcefieldMaxPlatformTop = $00b0 +kForcefieldMinPlatformTop = $0020 ;;;=========================================================================;;; ;;; The platform index for the lava in this room. -kLavaPlatformIndex = 4 +kLavaPlatformIndex = 5 ;;; The maximum value for sState::LavaOffset_u8, for when the lava is fully ;;; raised. @@ -126,7 +117,7 @@ kBossInitHealth = 8 kBossInitCooldown = 120 ;;; The platform index for the boss's body. -kBossBodyPlatformIndex = 0 +kBossBodyPlatformIndex = 2 ;;;=========================================================================;;; @@ -188,37 +179,56 @@ _Machines_sMachine_arr: d_byte ScrollGoalY_u8, $0 d_byte RegNames_u8_arr4, 0, 0, "X", 0 d_byte MainPlatform_u8, kEmitterXPlatformIndex - d_addr Init_func_ptr, FuncC_Boss_ShadowEmitterX_InitReset - d_addr ReadReg_func_ptr, FuncC_Boss_ShadowEmitterX_ReadReg - d_addr WriteReg_func_ptr, FuncA_Machine_BossShadowEmitterX_WriteReg + d_addr Init_func_ptr, FuncA_Room_BossShadowEmitterX_InitReset + d_addr ReadReg_func_ptr, Func_MachineEmitterReadReg + d_addr WriteReg_func_ptr, FuncA_Machine_EmitterXWriteReg d_addr TryMove_func_ptr, FuncA_Machine_Error - d_addr TryAct_func_ptr, FuncC_Boss_ShadowEmitterX_TryAct + d_addr TryAct_func_ptr, FuncA_Machine_EmitterTryAct d_addr Tick_func_ptr, FuncA_Machine_ReachedGoal d_addr Draw_func_ptr, FuncA_Objects_BossShadowEmitterX_Draw - d_addr Reset_func_ptr, FuncC_Boss_ShadowEmitterX_InitReset + d_addr Reset_func_ptr, FuncA_Room_BossShadowEmitterX_InitReset D_END .assert * - :- = kEmitterYMachineIndex * .sizeof(sMachine), error D_STRUCT sMachine d_byte Code_eProgram, eProgram::BossShadowEmitterY d_byte Breaker_eFlag, 0 d_byte Flags_bMachine, bMachine::Act | bMachine::WriteF - d_byte Status_eDiagram, eDiagram::MinigunLeft ; TODO + d_byte Status_eDiagram, eDiagram::MinigunRight ; TODO d_word ScrollGoalX_u16, $0 d_byte ScrollGoalY_u8, $0 d_byte RegNames_u8_arr4, 0, 0, 0, "Y" d_byte MainPlatform_u8, kEmitterYPlatformIndex - d_addr Init_func_ptr, FuncC_Boss_ShadowEmitterY_InitReset - d_addr ReadReg_func_ptr, FuncC_Boss_ShadowEmitterY_ReadReg - d_addr WriteReg_func_ptr, FuncA_Machine_BossShadowEmitterY_WriteReg + d_addr Init_func_ptr, FuncA_Room_BossShadowEmitterY_InitReset + d_addr ReadReg_func_ptr, Func_MachineEmitterReadReg + d_addr WriteReg_func_ptr, FuncA_Machine_EmitterYWriteReg d_addr TryMove_func_ptr, FuncA_Machine_Error - d_addr TryAct_func_ptr, FuncC_Boss_ShadowEmitterY_TryAct + d_addr TryAct_func_ptr, FuncA_Machine_EmitterTryAct d_addr Tick_func_ptr, FuncA_Machine_ReachedGoal d_addr Draw_func_ptr, FuncA_Objects_BossShadowEmitterY_Draw - d_addr Reset_func_ptr, FuncC_Boss_ShadowEmitterY_InitReset + d_addr Reset_func_ptr, FuncA_Room_BossShadowEmitterY_InitReset D_END .assert * - :- <= kMaxMachines * .sizeof(sMachine), error _Platforms_sPlatform_arr: -: .assert * - :- = kBossBodyPlatformIndex * .sizeof(sPlatform), error +: .linecont + + .assert * - :- = kEmitterForcefieldPlatformIndex * .sizeof(sPlatform), \ + error + .linecont - + D_STRUCT sPlatform + d_byte Type_ePlatform, ePlatform::Zone + d_word WidthPx_u16, kForcefieldPlatformWidth + d_byte HeightPx_u8, kForcefieldPlatformHeight + d_word Left_i16, kForcefieldMinPlatformLeft + d_word Top_i16, kForcefieldMinPlatformTop + D_END + .assert * - :- = kEmitterRegionPlatformIndex * .sizeof(sPlatform), error + D_STRUCT sPlatform + d_byte Type_ePlatform, ePlatform::Zone + d_word WidthPx_u16, $a0 + d_byte HeightPx_u8, $a0 + d_word Left_i16, kForcefieldMinPlatformLeft + d_word Top_i16, kForcefieldMinPlatformTop + D_END + .assert * - :- = kBossBodyPlatformIndex * .sizeof(sPlatform), error D_STRUCT sPlatform d_byte Type_ePlatform, ePlatform::Zone d_word WidthPx_u16, $40 ; TODO @@ -242,14 +252,6 @@ _Platforms_sPlatform_arr: d_word Left_i16, $0018 d_word Top_i16, $0020 D_END - .assert * - :- = kForcefieldPlatformIndex * .sizeof(sPlatform), error - D_STRUCT sPlatform - d_byte Type_ePlatform, ePlatform::Zone - d_word WidthPx_u16, kForcefieldPlatformWidth - d_byte HeightPx_u8, kForcefieldPlatformHeight - d_word Left_i16, kForcefieldMinPlatformLeft - d_word Top_i16, kForcefieldMaxPlatformTop - D_END .assert * - :- = kLavaPlatformIndex * .sizeof(sPlatform), error D_STRUCT sPlatform d_byte Type_ePlatform, ePlatform::Kill @@ -327,6 +329,7 @@ _BossIsDead: ;;; Performs per-frame upates for the boss in this room. ;;; @prereq PRGA_Room is loaded. .PROC FuncC_Boss_Shadow_TickBoss + ;; TODO: if boss is in platform, damage it _CoolDown: lda Zp_RoomState + sState::BossCooldown_u8 beq @done @@ -422,7 +425,7 @@ _SetUpIrq: stax <(Zp_Buffered_sIrq + sIrq::FirstIrq_int_ptr) @done: _Forcefield: - ldx #kForcefieldPlatformIndex ; param: platform index + ldx #kEmitterForcefieldPlatformIndex ; param: platform index jsr FuncA_Objects_DrawForcefieldPlatform _DrawBoss: jmp FuncA_Objects_DrawBoss @@ -435,83 +438,6 @@ _DrawBoss: rts .ENDPROC -.PROC FuncC_Boss_ShadowEmitterX_InitReset - lda #kEmitterXInitGoalX - sta Ram_MachineGoalHorz_u8_arr + kEmitterXMachineIndex - .assert kEmitterXInitGoalX < $80, error - bpl FuncC_Boss_Shadow_RemoveForcefield ; unconditional -.ENDPROC - -.PROC FuncC_Boss_ShadowEmitterY_InitReset - lda #kEmitterYInitGoalY - sta Ram_MachineGoalVert_u8_arr + kEmitterYMachineIndex - .assert * = FuncC_Boss_Shadow_RemoveForcefield, error, "fallthrough" -.ENDPROC - -.PROC FuncC_Boss_Shadow_RemoveForcefield - lda #ePlatform::None - sta Ram_PlatformType_ePlatform_arr + kForcefieldPlatformIndex - rts -.ENDPROC - -.PROC FuncC_Boss_ShadowEmitterX_ReadReg - lda Ram_MachineGoalHorz_u8_arr + kEmitterXMachineIndex - rts -.ENDPROC - -.PROC FuncC_Boss_ShadowEmitterY_ReadReg - lda Ram_MachineGoalVert_u8_arr + kEmitterYMachineIndex - rts -.ENDPROC - -.PROC FuncC_Boss_ShadowEmitterX_TryAct - lda #kEmitterActCountdown ; param: num frames to wait - sta Ram_MachineSlowdown_u8_arr + kEmitterXMachineIndex - jsr FuncA_Machine_StartWaiting - jmp FuncC_Boss_Shadow_TryCreateForcefield -.ENDPROC - -.PROC FuncC_Boss_ShadowEmitterY_TryAct - lda #kEmitterActCountdown ; param: num frames to wait - sta Ram_MachineSlowdown_u8_arr + kEmitterYMachineIndex - jsr FuncA_Machine_StartWaiting - .assert * = FuncC_Boss_Shadow_TryCreateForcefield, error, "fallthrough" -.ENDPROC - -.PROC FuncC_Boss_Shadow_TryCreateForcefield - ;; Remove any existing forcefield. - jsr FuncC_Boss_Shadow_RemoveForcefield - ;; Only make a new forcefield if both emitters are firing at once. - lda Ram_MachineSlowdown_u8_arr + kEmitterXMachineIndex - beq @done - lda Ram_MachineSlowdown_u8_arr + kEmitterYMachineIndex - beq @done - ;; TODO: prevent forming forcefield on top of a console or wall - ;; Set horizontal position of forcefield platform. - lda Ram_MachineGoalHorz_u8_arr + kEmitterXMachineIndex - mul #kBlockWidthPx - adc #kForcefieldMinPlatformLeft ; carry is already clear from mul - sta Ram_PlatformLeft_i16_0_arr + kForcefieldPlatformIndex - adc #kBlockWidthPx ; carry is still clear - sta Ram_PlatformRight_i16_0_arr + kForcefieldPlatformIndex - ;; Set vertical position of forcefield platform. - lda Ram_MachineGoalVert_u8_arr + kEmitterYMachineIndex - mul #kBlockHeightPx - sta T0 ; Y-offset - lda #kForcefieldMaxPlatformTop - sub T0 ; Y-offset - sta Ram_PlatformTop_i16_0_arr + kForcefieldPlatformIndex - add #kBlockHeightPx - sta Ram_PlatformBottom_i16_0_arr + kForcefieldPlatformIndex - ;; Make the forcefield platform solid. - lda #ePlatform::Solid - sta Ram_PlatformType_ePlatform_arr + kForcefieldPlatformIndex - ;; TODO: if avatar is deep in platform, harm (kill?) it - ;; TODO: if boss is in platform, damage it - @done: - rts -.ENDPROC - ;;;=========================================================================;;; .SEGMENT "PRGA_Room" @@ -523,18 +449,14 @@ _DrawBoss: jmp FuncA_Room_TickBoss .ENDPROC -;;;=========================================================================;;; - -.SEGMENT "PRGA_Machine" - -.PROC FuncA_Machine_BossShadowEmitterX_WriteReg - sta Ram_MachineGoalHorz_u8_arr + kEmitterXMachineIndex - rts +.PROC FuncA_Room_BossShadowEmitterX_InitReset + lda #kEmitterXInitRegX ; param: X register value + jmp FuncA_Room_MachineEmitterXInitReset .ENDPROC -.PROC FuncA_Machine_BossShadowEmitterY_WriteReg - sta Ram_MachineGoalVert_u8_arr + kEmitterYMachineIndex - rts +.PROC FuncA_Room_BossShadowEmitterY_InitReset + lda #kEmitterYInitRegY ; param: X register value + jmp FuncA_Room_MachineEmitterYInitReset .ENDPROC ;;;=========================================================================;;; @@ -582,17 +504,17 @@ _WriteLavaTileRow: .PROC FuncA_Objects_BossShadowEmitterX_Draw ldx Ram_MachineGoalHorz_u8_arr + kEmitterXMachineIndex - lda _BeamLength_u8_arr, x ; param: beam length in tiles + ldy _BeamLength_u8_arr, x ; param: beam length in tiles jmp FuncA_Objects_DrawEmitterXMachine _BeamLength_u8_arr: .byte 18, 20, 20, 20, 20, 20, 20, 20, 20, 18 .ENDPROC .PROC FuncA_Objects_BossShadowEmitterY_Draw - lda #2 ; param: beam length in tiles + ldy #2 ; param: beam length in tiles ldx Ram_MachineGoalVert_u8_arr + kEmitterYMachineIndex beq @draw - lda #24 ; param: beam length in tiles + ldy #24 ; param: beam length in tiles @draw: jmp FuncA_Objects_DrawEmitterYMachine .ENDPROC diff --git a/src/rooms/core_south.asm b/src/rooms/core_south.asm index 9cc21b88..f0a46328 100644 --- a/src/rooms/core_south.asm +++ b/src/rooms/core_south.asm @@ -45,6 +45,7 @@ .IMPORT Func_Noop .IMPORT Func_SetActorCenterToPoint .IMPORT Func_SetFlag +.IMPORT Func_SetPlatformTopToPointY .IMPORT Func_SetPointToPlatformCenter .IMPORT Ppu_ChrObjGarden .IMPORT Ram_ActorPosX_i16_0_arr @@ -287,9 +288,8 @@ _ReleaseCrates: jsr Func_SetFlag ldax #kCrate3FloatingPositionY stax Zp_PointY_i16 - ldx #kCrate3PlatformIndex ; param: platform index - lda #127 ; param: max move by - jmp Func_MovePlatformTopTowardPointY + ldy #kCrate3PlatformIndex ; param: platform index + jmp Func_SetPlatformTopToPointY .ENDPROC .PROC FuncC_Core_South_TickRoom diff --git a/src/rooms/shadow_heart.asm b/src/rooms/shadow_heart.asm index 619cf629..5ebd9bb4 100644 --- a/src/rooms/shadow_heart.asm +++ b/src/rooms/shadow_heart.asm @@ -18,15 +18,49 @@ ;;;=========================================================================;;; .INCLUDE "../actor.inc" +.INCLUDE "../actors/townsfolk.inc" +.INCLUDE "../charmap.inc" .INCLUDE "../device.inc" +.INCLUDE "../machine.inc" +.INCLUDE "../machines/emitter.inc" .INCLUDE "../macros.inc" .INCLUDE "../platform.inc" +.INCLUDE "../platforms/force.inc" +.INCLUDE "../ppu.inc" +.INCLUDE "../program.inc" .INCLUDE "../room.inc" .IMPORT DataA_Room_Shadow_sTileset -.IMPORT Data_Empty_sActor_arr -.IMPORT Func_Noop +.IMPORT FuncA_Machine_EmitterTryAct +.IMPORT FuncA_Machine_EmitterXWriteReg +.IMPORT FuncA_Machine_EmitterYWriteReg +.IMPORT FuncA_Machine_Error +.IMPORT FuncA_Machine_ReachedGoal +.IMPORT FuncA_Objects_DrawEmitterXMachine +.IMPORT FuncA_Objects_DrawEmitterYMachine +.IMPORT FuncA_Objects_DrawForcefieldPlatform +.IMPORT FuncA_Room_MachineEmitterXInitReset +.IMPORT FuncA_Room_MachineEmitterYInitReset +.IMPORT Func_MachineEmitterReadReg +.IMPORT Func_WriteToUpperAttributeTable .IMPORT Ppu_ChrObjShadow +.IMPORT Ram_MachineGoalHorz_u8_arr + +;;;=========================================================================;;; + +;;; The platform index for the ShadowHeartEmitterX machine. +kEmitterXPlatformIndex = 2 +;;; The platform index for the ShadowHeartEmitterY machine. +kEmitterYPlatformIndex = 3 + +;;; The initial positions of the emitter beams. +kEmitterXInitRegX = 4 +kEmitterYInitRegY = 2 + +;;; The minimum room pixel X/Y-positions for the top-left of the forcefield +;;; platform. +kForcefieldMinPlatformLeft = $0040 +kForcefieldMinPlatformTop = $0030 ;;;=========================================================================;;; @@ -41,8 +75,8 @@ d_byte MinimapStartRow_u8, 13 d_byte MinimapStartCol_u8, 7 d_addr TerrainData_ptr, _TerrainData - d_byte NumMachines_u8, 0 - d_addr Machines_sMachine_arr_ptr, 0 + d_byte NumMachines_u8, 2 + d_addr Machines_sMachine_arr_ptr, _Machines_sMachine_arr d_byte Chr18Bank_u8, <.bank(Ppu_ChrObjShadow) d_addr Ext_sRoomExt_ptr, _Ext_sRoomExt D_END @@ -50,23 +84,126 @@ _Ext_sRoomExt: D_STRUCT sRoomExt d_addr Terrain_sTileset_ptr, DataA_Room_Shadow_sTileset d_addr Platforms_sPlatform_arr_ptr, _Platforms_sPlatform_arr - d_addr Actors_sActor_arr_ptr, Data_Empty_sActor_arr + d_addr Actors_sActor_arr_ptr, _Actors_sActor_arr d_addr Devices_sDevice_arr_ptr, _Devices_sDevice_arr d_addr Passages_sPassage_arr_ptr, _Passages_sPassage_arr - d_addr Enter_func_ptr, Func_Noop - d_addr FadeIn_func_ptr, Func_Noop - d_addr Tick_func_ptr, Func_Noop - d_addr Draw_func_ptr, Func_Noop + d_addr Enter_func_ptr, FuncA_Room_ShadowHeart_EnterRoom + d_addr FadeIn_func_ptr, FuncA_Terrain_ShadowHeart_FadeInRoom + d_addr Tick_func_ptr, FuncA_Room_ShadowHeart_TickRoom + d_addr Draw_func_ptr, FuncA_Objects_ShadowHeart_DrawRoom D_END _TerrainData: : .incbin "out/rooms/shadow_heart.room" .assert * - :- = 33 * 15, error +_Machines_sMachine_arr: +: .assert * - :- = kEmitterXMachineIndex * .sizeof(sMachine), error + D_STRUCT sMachine + d_byte Code_eProgram, eProgram::ShadowHeartEmitterX + d_byte Breaker_eFlag, 0 + d_byte Flags_bMachine, bMachine::Act | bMachine::WriteE + d_byte Status_eDiagram, eDiagram::MinigunDown ; TODO + d_word ScrollGoalX_u16, $0 + d_byte ScrollGoalY_u8, $0 + d_byte RegNames_u8_arr4, 0, 0, "X", 0 + d_byte MainPlatform_u8, kEmitterXPlatformIndex + d_addr Init_func_ptr, FuncA_Room_ShadowHeartEmitterX_InitReset + d_addr ReadReg_func_ptr, Func_MachineEmitterReadReg + d_addr WriteReg_func_ptr, FuncA_Machine_EmitterXWriteReg + d_addr TryMove_func_ptr, FuncA_Machine_Error + d_addr TryAct_func_ptr, FuncA_Machine_EmitterTryAct + d_addr Tick_func_ptr, FuncA_Machine_ReachedGoal + d_addr Draw_func_ptr, FuncA_Objects_ShadowHeartEmitterX_Draw + d_addr Reset_func_ptr, FuncA_Room_ShadowHeartEmitterX_InitReset + D_END + .assert * - :- = kEmitterYMachineIndex * .sizeof(sMachine), error + D_STRUCT sMachine + d_byte Code_eProgram, eProgram::ShadowHeartEmitterY + d_byte Breaker_eFlag, 0 + d_byte Flags_bMachine, bMachine::Act | bMachine::WriteF + d_byte Status_eDiagram, eDiagram::MinigunRight ; TODO + d_word ScrollGoalX_u16, $0 + d_byte ScrollGoalY_u8, $0 + d_byte RegNames_u8_arr4, 0, 0, 0, "Y" + d_byte MainPlatform_u8, kEmitterYPlatformIndex + d_addr Init_func_ptr, FuncA_Room_ShadowHeartEmitterY_InitReset + d_addr ReadReg_func_ptr, Func_MachineEmitterReadReg + d_addr WriteReg_func_ptr, FuncA_Machine_EmitterYWriteReg + d_addr TryMove_func_ptr, FuncA_Machine_Error + d_addr TryAct_func_ptr, FuncA_Machine_EmitterTryAct + d_addr Tick_func_ptr, FuncA_Machine_ReachedGoal + d_addr Draw_func_ptr, FuncA_Objects_ShadowHeartEmitterY_Draw + d_addr Reset_func_ptr, FuncA_Room_ShadowHeartEmitterY_InitReset + D_END + .assert * - :- <= kMaxMachines * .sizeof(sMachine), error _Platforms_sPlatform_arr: -: ;; TODO +: .linecont + + .assert * - :- = kEmitterForcefieldPlatformIndex * .sizeof(sPlatform), \ + error + .linecont - + D_STRUCT sPlatform + d_byte Type_ePlatform, ePlatform::Zone + d_word WidthPx_u16, kForcefieldPlatformWidth + d_byte HeightPx_u8, kForcefieldPlatformHeight + d_word Left_i16, kForcefieldMinPlatformLeft + d_word Top_i16, kForcefieldMinPlatformTop + D_END + .assert * - :- = kEmitterRegionPlatformIndex * .sizeof(sPlatform), error + D_STRUCT sPlatform + d_byte Type_ePlatform, ePlatform::Zone + d_word WidthPx_u16, $a0 + d_byte HeightPx_u8, $60 + d_word Left_i16, kForcefieldMinPlatformLeft + d_word Top_i16, kForcefieldMinPlatformTop + D_END + .assert * - :- = kEmitterXPlatformIndex * .sizeof(sPlatform), error + D_STRUCT sPlatform + d_byte Type_ePlatform, ePlatform::Solid + d_word WidthPx_u16, $08 + d_byte HeightPx_u8, $08 + d_word Left_i16, $00d8 + d_word Top_i16, $0010 + D_END + .assert * - :- = kEmitterYPlatformIndex * .sizeof(sPlatform), error + D_STRUCT sPlatform + d_byte Type_ePlatform, ePlatform::Solid + d_word WidthPx_u16, $08 + d_byte HeightPx_u8, $08 + d_word Left_i16, $0028 + d_word Top_i16, $0030 + D_END + ;; Acid: + D_STRUCT sPlatform + d_byte Type_ePlatform, ePlatform::Kill + d_word WidthPx_u16, $1c0 + d_byte HeightPx_u8, $20 + d_word Left_i16, $0040 + d_word Top_i16, $00ca + D_END .assert * - :- <= kMaxPlatforms * .sizeof(sPlatform), error .byte ePlatform::None +_Actors_sActor_arr: +: ;; TODO: add some goo baddies + D_STRUCT sActor + d_byte Type_eActor, eActor::NpcMermaid + d_word PosX_i16, $01e4 + d_word PosY_i16, $0071 + d_byte Param_byte, kTileIdMermaidGhostFirst + D_END + .assert * - :- <= kMaxActors * .sizeof(sActor), error + .byte eActor::None _Devices_sDevice_arr: -: ;; TODO +: D_STRUCT sDevice + d_byte Type_eDevice, eDevice::Console + d_byte BlockRow_u8, 10 + d_byte BlockCol_u8, 4 + d_byte Target_byte, kEmitterYMachineIndex + D_END + D_STRUCT sDevice + d_byte Type_eDevice, eDevice::Console + d_byte BlockRow_u8, 10 + d_byte BlockCol_u8, 13 + d_byte Target_byte, kEmitterXMachineIndex + D_END .assert * - :- <= kMaxDevices * .sizeof(sDevice), error .byte eDevice::None _Passages_sPassage_arr: @@ -80,3 +217,64 @@ _Passages_sPassage_arr: .ENDPROC ;;;=========================================================================;;; + +.SEGMENT "PRGA_Room" + +.PROC FuncA_Room_ShadowHeart_EnterRoom + ;; TODO: if flag set, remove mermaid ghost + rts +.ENDPROC + +.PROC FuncA_Room_ShadowHeart_TickRoom + ;; TODO: set room darkness based on avatar position + ;; TODO: if a baddie is in a solid forcefield platform, kill it + ;; TODO: if avatar approaches the mermaid ghost, set flag and disappear it + rts +.ENDPROC + +.PROC FuncA_Room_ShadowHeartEmitterX_InitReset + lda #kEmitterXInitRegX ; param: X register value + jmp FuncA_Room_MachineEmitterXInitReset +.ENDPROC + +.PROC FuncA_Room_ShadowHeartEmitterY_InitReset + lda #kEmitterYInitRegY ; param: X register value + jmp FuncA_Room_MachineEmitterYInitReset +.ENDPROC + +;;;=========================================================================;;; + +.SEGMENT "PRGA_Terrain" + +;;; @prereq Rendering is disabled. +.PROC FuncA_Terrain_ShadowHeart_FadeInRoom + ldx #8 ; param: num bytes to write + ldy #$aa ; param: attribute value + lda #$30 ; param: initial byte offset + jmp Func_WriteToUpperAttributeTable +.ENDPROC + +;;;=========================================================================;;; + +.SEGMENT "PRGA_Objects" + +;;; Draw function for the ShadowHeart room. +.PROC FuncA_Objects_ShadowHeart_DrawRoom + ldx #kEmitterForcefieldPlatformIndex ; param: platform index + jmp FuncA_Objects_DrawForcefieldPlatform +.ENDPROC + +.PROC FuncA_Objects_ShadowHeartEmitterX_Draw + ldx Ram_MachineGoalHorz_u8_arr + kEmitterXMachineIndex + ldy _BeamLength_u8_arr, x ; param: beam length in tiles + jmp FuncA_Objects_DrawEmitterXMachine +_BeamLength_u8_arr: + .byte 18, 20, 20, 20, 16, 20, 20, 20, 20, 18 +.ENDPROC + +.PROC FuncA_Objects_ShadowHeartEmitterY_Draw + ldy #24 ; param: beam length in tiles + jmp FuncA_Objects_DrawEmitterYMachine +.ENDPROC + +;;;=========================================================================;;; diff --git a/src/rooms/shadow_heart.bg b/src/rooms/shadow_heart.bg index b5da564c..67a0e435 100644 --- a/src/rooms/shadow_heart.bg +++ b/src/rooms/shadow_heart.bg @@ -6,18 +6,18 @@ >shadow_4 >shadow_5 -EFEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEO -EGEO EO -ECEO EO -EMEO EO -EJEO EO -EMEO EO -EHEO EO -EBEOEO EO -ENEOEO EO - EO - EO -EEEOEO EO -EMEOEO EOEO EO -EGEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEO -ENEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOEO +EFEAENENENEBECEGENENEHEAENENENELEBEGENENENENEBEAENENENEHEMEDEAENEF +EGEFDACDEAENELENENENENENENEBAK BC EAENELEB EG +ECEMDBCBAIAIAIAIAIAIAIAIAIAI DA BC BD EE +EMEMECAHBBCF AK CABAECDBBMBABACH DA AK CGBACN EM +EJEDEMAJ BC CEBBBBCP EIENEBBBBBCFCADBCB CEBBBBCF BC EM +EMEAEJAJ CCBBBBBBCFBD EM BCBKEAEBBIBL BCDCDJ ED +EHECEMAJ CCBFBBBBBBCFEM AK BCBC COBBCFBCDEDFBBEC +EBEMEMAJ AK BD BCEMBBBBBBBBBHCP BCCKDIDH EM +ENEHEDAJCIBBBBBBDABBCD AK CKEDCB BC AK BKEEENENENEH + CMBACH CMDBCN CODA CCBBDADABBBBBBCPEDEAEBEAEF + BD AB CGEOCH AB CMDBCN CADBDBCB AK EM +EEENENENEBBBBBBBBNBBBBBBBBEOBABAEEEFCP CKEAEBCL EM +EMEAENEFAOAOAOAOAOAOAOAOAOAOAOAOEMEMAOAOAOAOAOAOAOAOAOAOAOAOAOAOEG +EGENEBEMAPAPAPAPAPAPAPAPAPAPAPAPEMFFAPAPAPAPAPAPAPAPAPAPAPAPAPAPEC +ENENEFEDEAENEFEEENENENENENENEBEEEHEGENENENENEBEEENENENENENEFEAENEJ diff --git a/src/tilesets/shadow.bg b/src/tilesets/shadow.bg index 291b24d6..69a1d07f 100644 --- a/src/tilesets/shadow.bg +++ b/src/tilesets/shadow.bg @@ -9,8 +9,8 @@ >terrain_shared_0 >terrain_shared_1 - HMHN HCHDDODPICID EAEBEC FAFBCACBBB BAAAAAABAB - HOHPDMDN DODP ED FCFDCBCABD BCABABABAB + HMHN HCHDDODPICID ECEJEAEBEC FAFBCACBBB BAAAAAABAB + HOHPDMDN DODP EDEG ED FCFDCBCABD BCABABABAB EIEI EJ EJEJEI EJEIEIEJ EIEIEJEJEGEIEIEHEFEEEJEJ EIEIEJ EJEJ EIEJ EJEIEIEIEIEJEJEEEIEIEFEJEJEHEG EEEIEIEFEJ EJ EGEH EGEIEIEH EEEF EJEJ