diff --git a/src/game/carrier.c b/src/game/carrier.c index 6efe2b594..2e20065a3 100644 --- a/src/game/carrier.c +++ b/src/game/carrier.c @@ -261,7 +261,7 @@ static void Carrier_AnimateDrop(CARRIED_ITEM *item) pickup->rot.y += in_water ? DROP_SLOW_TURN : DROP_FAST_TURN; if (sector->pit_room != NO_ROOM - && pickup->pos.y > (sector->floor << 8)) { + && pickup->pos.y > sector->floor.height) { room_num = sector->pit_room; } } diff --git a/src/game/inject.c b/src/game/inject.c index 4098912ac..e994d36a9 100644 --- a/src/game/inject.c +++ b/src/game/inject.c @@ -1346,6 +1346,10 @@ static void Inject_RoomShift(INJECTION *injection, int16_t room_num) File_Read(&z_shift, sizeof(uint32_t), 1, fp); File_Read(&y_shift, sizeof(int32_t), 1, fp); + x_shift = ROUND_TO_SECTOR(x_shift); + y_shift = ROUND_TO_CLICK(y_shift); + z_shift = ROUND_TO_SECTOR(z_shift); + ROOM_INFO *room = &g_RoomInfo[room_num]; room->x += x_shift; room->z += z_shift; @@ -1368,17 +1372,16 @@ static void Inject_RoomShift(INJECTION *injection, int16_t room_num) return; } - // Update the sector floor and ceiling clicks to match. - const int8_t click_shift = y_shift / STEP_L; - const int8_t wall_height = NO_HEIGHT / STEP_L; - for (int i = 0; i < room->z_size * room->x_size; i++) { - SECTOR_INFO *sector = &room->sectors[i]; - if (sector->floor == wall_height || sector->ceiling == wall_height) { + // Update the sector floor and ceiling heights to match. + for (int32_t i = 0; i < room->z_size * room->x_size; i++) { + SECTOR_INFO *const sector = &room->sectors[i]; + if (sector->floor.height == NO_HEIGHT + || sector->ceiling.height == NO_HEIGHT) { continue; } - sector->floor += click_shift; - sector->ceiling += click_shift; + sector->floor.height += y_shift; + sector->ceiling.height += y_shift; } // Update vertex Y values to match; x and z are room-relative. diff --git a/src/game/items.c b/src/game/items.c index 135c83b4d..e6bc895a7 100644 --- a/src/game/items.c +++ b/src/game/items.c @@ -173,7 +173,7 @@ void Item_Initialise(int16_t item_num) const int32_t x_sector = (item->pos.x - r->x) >> WALL_SHIFT; const SECTOR_INFO *const sector = &r->sectors[z_sector + x_sector * r->z_size]; - item->floor = sector->floor << 8; + item->floor = sector->floor.height; if (g_GameInfo.bonus_flag & GBF_NGPLUS) { item->hit_points *= 2; diff --git a/src/game/level.c b/src/game/level.c index 9936f4bfa..b6f7e1e57 100644 --- a/src/game/level.c +++ b/src/game/level.c @@ -214,12 +214,17 @@ static bool Level_LoadRooms(MYFILE *fp) GameBuf_Alloc(sizeof(SECTOR_INFO) * count4, GBUF_ROOM_SECTOR); for (int32_t j = 0; j < (signed)count4; j++) { SECTOR_INFO *const sector = ¤t_room_info->sectors[j]; + int8_t floor_clicks; + int8_t ceiling_clicks; File_Read(§or->index, sizeof(uint16_t), 1, fp); File_Read(§or->box, sizeof(int16_t), 1, fp); File_Read(§or->pit_room, sizeof(uint8_t), 1, fp); - File_Read(§or->floor, sizeof(int8_t), 1, fp); + File_Read(&floor_clicks, sizeof(int8_t), 1, fp); File_Read(§or->sky_room, sizeof(uint8_t), 1, fp); - File_Read(§or->ceiling, sizeof(int8_t), 1, fp); + File_Read(&ceiling_clicks, sizeof(int8_t), 1, fp); + + sector->floor.height = floor_clicks * STEP_L; + sector->ceiling.height = ceiling_clicks * STEP_L; } // Room lights diff --git a/src/game/objects/general/bridge.c b/src/game/objects/general/bridge.c index 1cdf050a3..fcf008a99 100644 --- a/src/game/objects/general/bridge.c +++ b/src/game/objects/general/bridge.c @@ -12,7 +12,7 @@ #include static bool Bridge_IsSameSector(int32_t x, int32_t z, const ITEM_INFO *item); -static bool Bridge_OnDrawBridge(ITEM_INFO *item, int32_t x, int32_t z); +static bool Bridge_OnDrawBridge(const ITEM_INFO *item, int32_t x, int32_t z); static int32_t Bridge_GetOffset( const ITEM_INFO *item, int32_t x, int32_t y, int32_t z); static void Bridge_FixEmbeddedPosition(int16_t item_num); @@ -27,7 +27,7 @@ static bool Bridge_IsSameSector(int32_t x, int32_t z, const ITEM_INFO *item) return sector_x == item_sector_x && sector_z == item_sector_z; } -static bool Bridge_OnDrawBridge(ITEM_INFO *item, int32_t x, int32_t z) +static bool Bridge_OnDrawBridge(const ITEM_INFO *item, int32_t x, int32_t z) { int32_t ix = item->pos.x >> WALL_SHIFT; int32_t iz = item->pos.z >> WALL_SHIFT; @@ -123,22 +123,22 @@ static void Bridge_FixEmbeddedPosition(int16_t item_num) void Bridge_SetupFlat(OBJECT_INFO *obj) { obj->initialise = Bridge_Initialise; - obj->floor = Bridge_FlatFloor; - obj->ceiling = Bridge_FlatCeiling; + obj->floor_height_func = Bridge_GetFlatFloorHeight; + obj->ceiling_height_func = Bridge_GetFlatCeilingHeight; } void Bridge_SetupTilt1(OBJECT_INFO *obj) { obj->initialise = Bridge_Initialise; - obj->floor = Bridge_Tilt1Floor; - obj->ceiling = Bridge_Tilt1Ceiling; + obj->floor_height_func = Bridge_GetTilt1FloorHeight; + obj->ceiling_height_func = Bridge_GetTilt1CeilingHeight; } void Bridge_SetupTilt2(OBJECT_INFO *obj) { obj->initialise = Bridge_Initialise; - obj->floor = Bridge_Tilt2Floor; - obj->ceiling = Bridge_Tilt2Ceiling; + obj->floor_height_func = Bridge_GetTilt2FloorHeight; + obj->ceiling_height_func = Bridge_GetTilt2CeilingHeight; } void Bridge_SetupDrawBridge(OBJECT_INFO *obj) @@ -146,12 +146,12 @@ void Bridge_SetupDrawBridge(OBJECT_INFO *obj) if (!obj->loaded) { return; } - obj->ceiling = Bridge_DrawBridgeCeiling; + obj->ceiling_height_func = Bridge_GetDrawBridgeCeilingHeight; obj->collision = Bridge_DrawBridgeCollision; obj->control = Cog_Control; obj->save_anim = 1; obj->save_flags = 1; - obj->floor = Bridge_DrawBridgeFloor; + obj->floor_height_func = Bridge_GetDrawBridgeFloorHeight; } void Bridge_Initialise(int16_t item_num) @@ -162,48 +162,50 @@ void Bridge_Initialise(int16_t item_num) Bridge_FixEmbeddedPosition(item_num); } -void Bridge_DrawBridgeFloor( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height) +int16_t Bridge_GetDrawBridgeFloorHeight( + const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z, + const int16_t height) { if (item->current_anim_state != DOOR_OPEN) { - return; + return height; } if (!Bridge_OnDrawBridge(item, x, z)) { - return; + return height; } if (y > item->pos.y) { - return; + return height; } - if (g_Config.fix_bridge_collision && item->pos.y >= *height) { - return; + if (g_Config.fix_bridge_collision && item->pos.y >= height) { + return height; } - *height = item->pos.y; + return item->pos.y; } -void Bridge_DrawBridgeCeiling( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height) +int16_t Bridge_GetDrawBridgeCeilingHeight( + const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z, + const int16_t height) { if (item->current_anim_state != DOOR_OPEN) { - return; + return height; } if (!Bridge_OnDrawBridge(item, x, z)) { - return; + return height; } if (y <= item->pos.y) { - return; + return height; } - if (g_Config.fix_bridge_collision && item->pos.y <= *height) { - return; + if (g_Config.fix_bridge_collision && item->pos.y <= height) { + return height; } - *height = item->pos.y + STEP_L; + return item->pos.y + STEP_L; } void Bridge_DrawBridgeCollision( @@ -215,118 +217,124 @@ void Bridge_DrawBridgeCollision( } } -void Bridge_FlatFloor( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height) +int16_t Bridge_GetFlatFloorHeight( + const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z, + const int16_t height) { if (g_Config.fix_bridge_collision && !Bridge_IsSameSector(x, z, item)) { - return; + return height; } if (y > item->pos.y) { - return; + return height; } - if (g_Config.fix_bridge_collision && item->pos.y >= *height) { - return; + if (g_Config.fix_bridge_collision && item->pos.y >= height) { + return height; } - *height = item->pos.y; + return item->pos.y; } -void Bridge_FlatCeiling( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height) +int16_t Bridge_GetFlatCeilingHeight( + const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z, + const int16_t height) { if (g_Config.fix_bridge_collision && !Bridge_IsSameSector(x, z, item)) { - return; + return height; } if (y <= item->pos.y) { - return; + return height; } - if (g_Config.fix_bridge_collision && item->pos.y <= *height) { - return; + if (g_Config.fix_bridge_collision && item->pos.y <= height) { + return height; } - *height = item->pos.y + STEP_L; + return item->pos.y + STEP_L; } -void Bridge_Tilt1Floor( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height) +int16_t Bridge_GetTilt1FloorHeight( + const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z, + const int16_t height) { if (g_Config.fix_bridge_collision && !Bridge_IsSameSector(x, z, item)) { - return; + return height; } const int32_t offset_height = item->pos.y + (Bridge_GetOffset(item, x, y, z) / 4); - if (y > offset_height || item->pos.y >= *height) { - return; + if (y > offset_height || item->pos.y >= height) { + return height; } - if (g_Config.fix_bridge_collision && item->pos.y >= *height) { - return; + if (g_Config.fix_bridge_collision && item->pos.y >= height) { + return height; } - *height = offset_height; + return offset_height; } -void Bridge_Tilt1Ceiling( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height) +int16_t Bridge_GetTilt1CeilingHeight( + const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z, + const int16_t height) { if (g_Config.fix_bridge_collision && !Bridge_IsSameSector(x, z, item)) { - return; + return height; } const int32_t offset_height = item->pos.y + (Bridge_GetOffset(item, x, y, z) / 4); if (y <= offset_height) { - return; + return height; } - if (g_Config.fix_bridge_collision && item->pos.y <= *height) { - return; + if (g_Config.fix_bridge_collision && item->pos.y <= height) { + return height; } - *height = offset_height + STEP_L; + return offset_height + STEP_L; } -void Bridge_Tilt2Floor( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height) +int16_t Bridge_GetTilt2FloorHeight( + const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z, + const int16_t height) { if (g_Config.fix_bridge_collision && !Bridge_IsSameSector(x, z, item)) { - return; + return height; } const int32_t offset_height = item->pos.y + (Bridge_GetOffset(item, x, y, z) / 2); if (y > offset_height) { - return; + return height; } - if (g_Config.fix_bridge_collision && item->pos.y >= *height) { - return; + if (g_Config.fix_bridge_collision && item->pos.y >= height) { + return height; } - *height = offset_height; + return offset_height; } -void Bridge_Tilt2Ceiling( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height) +int16_t Bridge_GetTilt2CeilingHeight( + const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z, + const int16_t height) { if (g_Config.fix_bridge_collision && !Bridge_IsSameSector(x, z, item)) { - return; + return height; } const int32_t offset_height = item->pos.y + (Bridge_GetOffset(item, x, y, z) / 2); if (y <= offset_height) { - return; + return height; } - if (g_Config.fix_bridge_collision && item->pos.y <= *height) { - return; + if (g_Config.fix_bridge_collision && item->pos.y <= height) { + return height; } - *height = offset_height + STEP_L; + return offset_height + STEP_L; } diff --git a/src/game/objects/general/bridge.h b/src/game/objects/general/bridge.h index 0b3fbd993..46df0e4bd 100644 --- a/src/game/objects/general/bridge.h +++ b/src/game/objects/general/bridge.h @@ -11,25 +11,25 @@ void Bridge_SetupDrawBridge(OBJECT_INFO *obj); void Bridge_Initialise(int16_t item_num); -void Bridge_DrawBridgeFloor( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height); -void Bridge_DrawBridgeCeiling( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height); +int16_t Bridge_GetDrawBridgeFloorHeight( + const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t height); +int16_t Bridge_GetDrawBridgeCeilingHeight( + const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t height); void Bridge_DrawBridgeCollision( int16_t item_num, ITEM_INFO *lara_item, COLL_INFO *coll); void Bridge_DrawBridgeControl(int16_t item_num); -void Bridge_FlatFloor( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height); -void Bridge_FlatCeiling( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height); +int16_t Bridge_GetFlatFloorHeight( + const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t height); +int16_t Bridge_GetFlatCeilingHeight( + const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t height); -void Bridge_Tilt1Floor( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height); -void Bridge_Tilt1Ceiling( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height); +int16_t Bridge_GetTilt1FloorHeight( + const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t height); +int16_t Bridge_GetTilt1CeilingHeight( + const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t height); -void Bridge_Tilt2Floor( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height); -void Bridge_Tilt2Ceiling( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height); +int16_t Bridge_GetTilt2FloorHeight( + const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t height); +int16_t Bridge_GetTilt2CeilingHeight( + const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t height); diff --git a/src/game/objects/general/door.c b/src/game/objects/general/door.c index 4ce3938cd..c4d41ff02 100644 --- a/src/game/objects/general/door.c +++ b/src/game/objects/general/door.c @@ -53,8 +53,8 @@ static void Door_Shut(DOORPOS_DATA *const d) sector->index = 0; sector->box = NO_BOX; - sector->floor = NO_HEIGHT / STEP_L; - sector->ceiling = NO_HEIGHT / STEP_L; + sector->floor.height = NO_HEIGHT; + sector->ceiling.height = NO_HEIGHT; sector->sky_room = NO_ROOM; sector->pit_room = NO_ROOM; diff --git a/src/game/objects/general/trapdoor.c b/src/game/objects/general/trapdoor.c index 8bbe8a6ec..46f6cc111 100644 --- a/src/game/objects/general/trapdoor.c +++ b/src/game/objects/general/trapdoor.c @@ -5,9 +5,9 @@ #include -static bool TrapDoor_StandingOn(ITEM_INFO *item, int32_t x, int32_t z); +static bool TrapDoor_StandingOn(const ITEM_INFO *item, int32_t x, int32_t z); -static bool TrapDoor_StandingOn(ITEM_INFO *item, int32_t x, int32_t z) +static bool TrapDoor_StandingOn(const ITEM_INFO *item, int32_t x, int32_t z) { int32_t tx = item->pos.x >> WALL_SHIFT; int32_t tz = item->pos.z >> WALL_SHIFT; @@ -29,8 +29,8 @@ static bool TrapDoor_StandingOn(ITEM_INFO *item, int32_t x, int32_t z) void TrapDoor_Setup(OBJECT_INFO *obj) { obj->control = TrapDoor_Control; - obj->floor = TrapDoor_Floor; - obj->ceiling = TrapDoor_Ceiling; + obj->floor_height_func = TrapDoor_GetFloorHeight; + obj->ceiling_height_func = TrapDoor_GetCeilingHeight; obj->save_anim = 1; obj->save_flags = 1; } @@ -48,32 +48,34 @@ void TrapDoor_Control(int16_t item_num) Item_Animate(item); } -void TrapDoor_Floor( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height) +int16_t TrapDoor_GetFloorHeight( + const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z, + const int16_t height) { if (!TrapDoor_StandingOn(item, x, z)) { - return; + return height; } if (item->current_anim_state == DOOR_OPEN || y > item->pos.y - || item->pos.y >= *height) { - return; + || item->pos.y >= height) { + return height; } - *height = item->pos.y; + return item->pos.y; } -void TrapDoor_Ceiling( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height) +int16_t TrapDoor_GetCeilingHeight( + const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z, + const int16_t height) { if (!TrapDoor_StandingOn(item, x, z)) { - return; + return height; } if (item->current_anim_state == DOOR_OPEN || y <= item->pos.y - || item->pos.y <= *height) { - return; + || item->pos.y <= height) { + return height; } - *height = item->pos.y + STEP_L; + return item->pos.y + STEP_L; } diff --git a/src/game/objects/general/trapdoor.h b/src/game/objects/general/trapdoor.h index ac38b3dc9..54e0ea09a 100644 --- a/src/game/objects/general/trapdoor.h +++ b/src/game/objects/general/trapdoor.h @@ -6,7 +6,7 @@ void TrapDoor_Setup(OBJECT_INFO *obj); void TrapDoor_Control(int16_t item_num); -void TrapDoor_Floor( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height); -void TrapDoor_Ceiling( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height); +int16_t TrapDoor_GetFloorHeight( + const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t height); +int16_t TrapDoor_GetCeilingHeight( + const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t height); diff --git a/src/game/objects/traps/falling_block.c b/src/game/objects/traps/falling_block.c index 9a6597e99..de52e24c7 100644 --- a/src/game/objects/traps/falling_block.c +++ b/src/game/objects/traps/falling_block.c @@ -8,8 +8,8 @@ void FallingBlock_Setup(OBJECT_INFO *obj) { obj->control = FallingBlock_Control; - obj->floor = FallingBlock_Floor; - obj->ceiling = FallingBlock_Ceiling; + obj->floor_height_func = FallingBlock_GetFloorHeight; + obj->ceiling_height_func = FallingBlock_GetCeilingHeight; obj->save_position = 1; obj->save_anim = 1; obj->save_flags = 1; @@ -65,22 +65,28 @@ void FallingBlock_Control(int16_t item_num) } } -void FallingBlock_Floor( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height) +int16_t FallingBlock_GetFloorHeight( + const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z, + const int16_t height) { if (y <= item->pos.y - STEP_L * 2 && (item->current_anim_state == TRAP_SET || item->current_anim_state == TRAP_ACTIVATE)) { - *height = item->pos.y - STEP_L * 2; + return item->pos.y - STEP_L * 2; } + + return height; } -void FallingBlock_Ceiling( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height) +int16_t FallingBlock_GetCeilingHeight( + const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z, + const int16_t height) { if (y > item->pos.y - STEP_L * 2 && (item->current_anim_state == TRAP_SET || item->current_anim_state == TRAP_ACTIVATE)) { - *height = item->pos.y - STEP_L; + return item->pos.y - STEP_L; } + + return height; } diff --git a/src/game/objects/traps/falling_block.h b/src/game/objects/traps/falling_block.h index 8fadf6352..f7241015a 100644 --- a/src/game/objects/traps/falling_block.h +++ b/src/game/objects/traps/falling_block.h @@ -6,7 +6,7 @@ void FallingBlock_Setup(OBJECT_INFO *obj); void FallingBlock_Control(int16_t item_num); -void FallingBlock_Floor( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height); -void FallingBlock_Ceiling( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height); +int16_t FallingBlock_GetFloorHeight( + const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t height); +int16_t FallingBlock_GetCeilingHeight( + const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t height); diff --git a/src/game/room.c b/src/game/room.c index 6e96db492..e6d33ff62 100644 --- a/src/game/room.c +++ b/src/game/room.c @@ -171,7 +171,7 @@ int16_t Room_GetTiltType( + ((x - r->x) >> WALL_SHIFT) * r->z_size]; } - if (y + 512 < ((int32_t)sector->floor << 8)) { + if ((y + 512) < sector->floor.height) { return 0; } @@ -275,7 +275,7 @@ SECTOR_INFO *Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num) } } while (data != NO_ROOM); - if (y >= ((int32_t)sector->floor << 8)) { + if (y >= sector->floor.height) { do { if (sector->pit_room == NO_ROOM) { break; @@ -287,8 +287,8 @@ SECTOR_INFO *Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num) const int32_t z_sector = (z - r->z) >> WALL_SHIFT; const int32_t x_sector = (x - r->x) >> WALL_SHIFT; sector = &r->sectors[z_sector + x_sector * r->z_size]; - } while (y >= ((int32_t)sector->floor << 8)); - } else if (y < ((int32_t)sector->ceiling << 8)) { + } while (y >= sector->floor.height); + } else if (y < sector->ceiling.height) { do { if (sector->sky_room == NO_ROOM) { break; @@ -300,7 +300,7 @@ SECTOR_INFO *Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num) const int32_t z_sector = (z - r->z) >> WALL_SHIFT; const int32_t x_sector = (x - r->x) >> WALL_SHIFT; sector = &r->sectors[z_sector + x_sector * r->z_size]; - } while (y < ((int32_t)sector->ceiling << 8)); + } while (y < sector->ceiling.height); } return sector; @@ -322,7 +322,7 @@ int16_t Room_GetCeiling( sky_sector = &r->sectors[z_sector + x_sector * r->z_size]; } - int16_t height = sky_sector->ceiling << 8; + int16_t height = sky_sector->ceiling.height; if (sky_sector->index) { data = &g_FloorData[sky_sector->index]; @@ -395,8 +395,9 @@ int16_t Room_GetCeiling( } else { ITEM_INFO *item = &g_Items[trigger & VALUE_BITS]; OBJECT_INFO *object = &g_Objects[item->object_number]; - if (object->ceiling) { - object->ceiling(item, x, y, z, &height); + if (object->ceiling_height_func) { + height = + object->ceiling_height_func(item, x, y, z, height); } } } while (!(trigger & END_BIT)); @@ -447,7 +448,7 @@ int16_t Room_GetHeight( sector = &r->sectors[z_sector + x_sector * r->z_size]; } - int16_t height = sector->floor << 8; + int16_t height = sector->floor.height; g_TriggerIndex = NULL; @@ -518,8 +519,9 @@ int16_t Room_GetHeight( } else { ITEM_INFO *item = &g_Items[trigger & VALUE_BITS]; OBJECT_INFO *object = &g_Objects[item->object_number]; - if (object->floor) { - object->floor(item, x, y, z, &height); + if (object->floor_height_func) { + height = + object->floor_height_func(item, x, y, z, height); } } } while (!(trigger & END_BIT)); @@ -583,12 +585,12 @@ int16_t Room_GetWaterHeight(int32_t x, int32_t y, int32_t z, int16_t room_num) x_sector = (x - r->x) >> WALL_SHIFT; sector = &r->sectors[z_sector + x_sector * r->z_size]; } - return sector->ceiling << 8; + return sector->ceiling.height; } else { while (sector->pit_room != NO_ROOM) { r = &g_RoomInfo[sector->pit_room]; if (r->flags & RF_UNDERWATER) { - return sector->floor << 8; + return sector->floor.height; } z_sector = (z - r->z) >> WALL_SHIFT; x_sector = (x - r->x) >> WALL_SHIFT; @@ -661,13 +663,14 @@ void Room_AlterFloorHeight(ITEM_INFO *item, int32_t height) sector = &r->sectors[z_sector + x_sector * r->z_size]; } - if (sector->floor != NO_HEIGHT / 256) { - sector->floor += height >> 8; - if (sector->floor == sky_sector->ceiling) { - sector->floor = NO_HEIGHT / 256; + if (sector->floor.height != NO_HEIGHT) { + sector->floor.height += ROUND_TO_CLICK(height); + if (sector->floor.height == sky_sector->ceiling.height) { + sector->floor.height = NO_HEIGHT; } } else { - sector->floor = sky_sector->ceiling + (height >> 8); + sector->floor.height = + sky_sector->ceiling.height + ROUND_TO_CLICK(height); } if (g_Boxes[sector->box].overlap_index & BLOCKABLE) { @@ -993,7 +996,7 @@ bool Room_IsOnWalkable( sector = &r->sectors[z_sector + x_sector * r->z_size]; } - int16_t height = sector->floor << 8; + int16_t height = sector->floor.height; bool object_found = false; int16_t *floor_data = &g_FloorData[sector->index]; @@ -1026,8 +1029,9 @@ bool Room_IsOnWalkable( const int16_t item_num = trigger & VALUE_BITS; ITEM_INFO *item = &g_Items[item_num]; OBJECT_INFO *object = &g_Objects[item->object_number]; - if (object->floor) { - object->floor(item, x, y, z, &height); + if (object->floor_height_func) { + height = + object->floor_height_func(item, x, y, z, height); object_found = true; } } else if (TRIG_BITS(trigger) == TO_CAMERA) { diff --git a/src/game/setup.c b/src/game/setup.c index c6180adaf..2022b2c93 100644 --- a/src/game/setup.c +++ b/src/game/setup.c @@ -249,8 +249,8 @@ void Setup_AllObjects(void) obj->collision = NULL; obj->control = NULL; obj->draw_routine = Object_DrawAnimatingItem; - obj->ceiling = NULL; - obj->floor = NULL; + obj->ceiling_height_func = NULL; + obj->floor_height_func = NULL; obj->pivot_length = 0; obj->radius = DEFAULT_RADIUS; obj->shadow_size = 0; @@ -268,15 +268,15 @@ void Setup_AllObjects(void) g_Objects[O_MEDI_ITEM].collision = NULL; g_Objects[O_MEDI_ITEM].control = NULL; g_Objects[O_MEDI_ITEM].draw_routine = Object_DrawDummyItem; - g_Objects[O_MEDI_ITEM].floor = NULL; - g_Objects[O_MEDI_ITEM].ceiling = NULL; + g_Objects[O_MEDI_ITEM].floor_height_func = NULL; + g_Objects[O_MEDI_ITEM].ceiling_height_func = NULL; g_Objects[O_BIGMEDI_ITEM].initialise = NULL; g_Objects[O_BIGMEDI_ITEM].collision = NULL; g_Objects[O_BIGMEDI_ITEM].control = NULL; g_Objects[O_BIGMEDI_ITEM].draw_routine = Object_DrawDummyItem; - g_Objects[O_BIGMEDI_ITEM].floor = NULL; - g_Objects[O_BIGMEDI_ITEM].ceiling = NULL; + g_Objects[O_BIGMEDI_ITEM].floor_height_func = NULL; + g_Objects[O_BIGMEDI_ITEM].ceiling_height_func = NULL; } if (g_Config.disable_magnums) { @@ -284,15 +284,15 @@ void Setup_AllObjects(void) g_Objects[O_MAGNUM_ITEM].collision = NULL; g_Objects[O_MAGNUM_ITEM].control = NULL; g_Objects[O_MAGNUM_ITEM].draw_routine = Object_DrawDummyItem; - g_Objects[O_MAGNUM_ITEM].floor = NULL; - g_Objects[O_MAGNUM_ITEM].ceiling = NULL; + g_Objects[O_MAGNUM_ITEM].floor_height_func = NULL; + g_Objects[O_MAGNUM_ITEM].ceiling_height_func = NULL; g_Objects[O_MAG_AMMO_ITEM].initialise = NULL; g_Objects[O_MAG_AMMO_ITEM].collision = NULL; g_Objects[O_MAG_AMMO_ITEM].control = NULL; g_Objects[O_MAG_AMMO_ITEM].draw_routine = Object_DrawDummyItem; - g_Objects[O_MAG_AMMO_ITEM].floor = NULL; - g_Objects[O_MAG_AMMO_ITEM].ceiling = NULL; + g_Objects[O_MAG_AMMO_ITEM].floor_height_func = NULL; + g_Objects[O_MAG_AMMO_ITEM].ceiling_height_func = NULL; } if (g_Config.disable_uzis) { @@ -300,15 +300,15 @@ void Setup_AllObjects(void) g_Objects[O_UZI_ITEM].collision = NULL; g_Objects[O_UZI_ITEM].control = NULL; g_Objects[O_UZI_ITEM].draw_routine = Object_DrawDummyItem; - g_Objects[O_UZI_ITEM].floor = NULL; - g_Objects[O_UZI_ITEM].ceiling = NULL; + g_Objects[O_UZI_ITEM].floor_height_func = NULL; + g_Objects[O_UZI_ITEM].ceiling_height_func = NULL; g_Objects[O_UZI_AMMO_ITEM].initialise = NULL; g_Objects[O_UZI_AMMO_ITEM].collision = NULL; g_Objects[O_UZI_AMMO_ITEM].control = NULL; g_Objects[O_UZI_AMMO_ITEM].draw_routine = Object_DrawDummyItem; - g_Objects[O_UZI_AMMO_ITEM].floor = NULL; - g_Objects[O_UZI_AMMO_ITEM].ceiling = NULL; + g_Objects[O_UZI_AMMO_ITEM].floor_height_func = NULL; + g_Objects[O_UZI_AMMO_ITEM].ceiling_height_func = NULL; } if (g_Config.disable_shotgun) { @@ -316,14 +316,14 @@ void Setup_AllObjects(void) g_Objects[O_SHOTGUN_ITEM].collision = NULL; g_Objects[O_SHOTGUN_ITEM].control = NULL; g_Objects[O_SHOTGUN_ITEM].draw_routine = Object_DrawDummyItem; - g_Objects[O_SHOTGUN_ITEM].floor = NULL; - g_Objects[O_SHOTGUN_ITEM].ceiling = NULL; + g_Objects[O_SHOTGUN_ITEM].floor_height_func = NULL; + g_Objects[O_SHOTGUN_ITEM].ceiling_height_func = NULL; g_Objects[O_SG_AMMO_ITEM].initialise = NULL; g_Objects[O_SG_AMMO_ITEM].collision = NULL; g_Objects[O_SG_AMMO_ITEM].control = NULL; g_Objects[O_SG_AMMO_ITEM].draw_routine = Object_DrawDummyItem; - g_Objects[O_SG_AMMO_ITEM].floor = NULL; - g_Objects[O_SG_AMMO_ITEM].ceiling = NULL; + g_Objects[O_SG_AMMO_ITEM].floor_height_func = NULL; + g_Objects[O_SG_AMMO_ITEM].ceiling_height_func = NULL; } } diff --git a/src/global/const.h b/src/global/const.h index 00d434967..63e4570f2 100644 --- a/src/global/const.h +++ b/src/global/const.h @@ -99,6 +99,8 @@ #define WALL_L 1024 #define WALL_SHIFT 10 #define STEP_L 256 +#define ROUND_TO_CLICK(V) ((V) & ~(STEP_L - 1)) +#define ROUND_TO_SECTOR(V) ((V) & ~(WALL_L - 1)) #define NO_ROOM 0xFF #define STEPUP_HEIGHT ((STEP_L * 3) / 2) // = 384 #define FRONT_ARC PHD_90 diff --git a/src/global/types.h b/src/global/types.h index 824b61fab..13e0cf2cb 100644 --- a/src/global/types.h +++ b/src/global/types.h @@ -1164,9 +1164,10 @@ typedef struct SECTOR_INFO { uint16_t index; int16_t box; uint8_t pit_room; - int8_t floor; uint8_t sky_room; - int8_t ceiling; + struct { + int16_t height; + } floor, ceiling; } SECTOR_INFO; typedef struct DOORPOS_DATA { @@ -1643,10 +1644,10 @@ typedef struct OBJECT_INFO { FRAME_INFO *frame_base; void (*initialise)(int16_t item_num); void (*control)(int16_t item_num); - void (*floor)( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height); - void (*ceiling)( - ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height); + int16_t (*floor_height_func)( + const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t height); + int16_t (*ceiling_height_func)( + const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t height); void (*draw_routine)(ITEM_INFO *item); void (*collision)(int16_t item_num, ITEM_INFO *lara_item, COLL_INFO *coll); const OBJECT_BOUNDS *(*bounds)(void);