Merge pull request #9 from duncanspumpkin/vehicle_update

Start implementing vehicle update.
This commit is contained in:
Duncan 2018-01-26 16:38:20 +00:00 committed by GitHub
commit 796a86962c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 376 additions and 8 deletions

View File

@ -5,7 +5,42 @@ using namespace openloco::interop;
namespace openloco::objectmgr
{
loco_global_array<object_repository_item, 64, 0x4FE0B8> object_repository;
loco_global_array<interface_skin_object*, 1, 0x0050C3D0> _interfaceObjects;
loco_global_array<sound_object*, 128, 0x0050C3D4> _soundObjects;
loco_global_array<currency_object*, 1, 0x0050C5D4> _currencyObjects;
loco_global_array<steam_object*, 32, 0x0050C5D8> _steamObjects;
loco_global_array<rock_object*, 8, 0x0050C658> _rockObjects;
loco_global_array<water_object*, 1, 0x0050C678> _waterObjects;
loco_global_array<land_object*, 32, 0x0050C67C> _landObjects;
loco_global_array<town_names_object*, 1, 0x0050C6FC> _townNamesObjects;
loco_global_array<cargo_object*, 32, 0x0050C700> _cargoObjects;
loco_global_array<wall_object*, 32, 0x0050C780> _wallObjects;
loco_global_array<train_signal_object*, 16, 0x0050C800> _trainSignalObjects;
loco_global_array<level_crossing_object*, 4, 0x0050C840> _levelCrossingObjects;
loco_global_array<street_light_object*, 1, 0x0050C850> _streetLightObjects;
loco_global_array<tunnel_object*, 16, 0x0050C854> _tunnelObjects;
loco_global_array<bridge_object*, 8, 0x0050C894> _bridgeObjects;
loco_global_array<train_station_object*, 16, 0x0050C8B4> _trainStationObjects;
loco_global_array<track_extra_object*, 8, 0x0050C8F4> _trackExtraObjects;
loco_global_array<track_object*, 8, 0x0050C914> _trackObjects;
loco_global_array<road_station_object*, 16, 0x0050C934> _roadStationObjects;
loco_global_array<road_extra_object*, 4, 0x0050C974> _roadExtraObjects;
loco_global_array<road_object*, 8, 0x0050C984> _roadObjects;
loco_global_array<airport_object*, 8, 0x0050C9A4> _airportObjects;
loco_global_array<dock_object*, 8, 0x0050C9C4> _dockObjects;
loco_global_array<vehicle_object*, 224, 0x0050C9E4> _vehicleObjects;
loco_global_array<tree_object*, 64, 0x0050CD64> _treeObjects;
loco_global_array<snow_object*, 1, 0x0050CE64> _snowObjects;
loco_global_array<climate_object*, 1, 0x0050CE68> _climateObjects;
loco_global_array<hill_shapes_object*, 1, 0x0050CE6C> _hillShapeObjects;
loco_global_array<building_object*, 128, 0x0050CE70> _buildingObjects;
loco_global_array<scaffolding_object*, 1, 0x0050D070> _scaffoldingObjects;
loco_global_array<industry_object*, 16, 0x0050D074> _industryObjects;
loco_global_array<region_object*, 1, 0x0050D0B4> _regionObjects;
loco_global_array<competitors_object*, 32, 0x0050D0B8> _competitorsObjects;
loco_global_array<scenario_text_object*, 1, 0x0050D138> _scenarioTextObjects;
// 0x00470F3C
void load_index()
@ -18,6 +53,11 @@ namespace openloco::objectmgr
return _cargoObjects[id];
}
vehicle_object* get_vehicle_object(size_t id)
{
return _vehicleObjects[id];
}
size_t get_max_objects(object_type type)
{
static size_t counts[] = {
@ -28,7 +68,7 @@ namespace openloco::objectmgr
8, // rock,
1, // water,
32, // surface,
1, // town_name,
1, // town_names,
32, // cargo,
32, // wall,
16, // train_signal,

View File

@ -1,5 +1,6 @@
#pragma once
#include <cstdint>
#include <cstdio>
namespace openloco
@ -42,7 +43,48 @@ namespace openloco
scenario_text,
};
struct object;
struct object_entry_extended;
struct cargo_object;
struct interface_skin_object;
struct sound_object;
struct currency_object;
struct steam_object;
struct rock_object;
struct water_object;
struct land_object;
struct town_names_object;
struct wall_object;
struct train_signal_object;
struct level_crossing_object;
struct street_light_object;
struct tunnel_object;
struct bridge_object;
struct train_station_object;
struct track_extra_object;
struct track_object;
struct road_station_object;
struct road_extra_object;
struct road_object;
struct airport_object;
struct dock_object;
struct vehicle_object;
struct tree_object;
struct snow_object;
struct climate_object;
struct hill_shapes_object;
struct building_object;
struct scaffolding_object;
struct industry_object;
struct region_object;
struct competitors_object;
struct scenario_text_object;
struct object_repository_item
{
object* objects;
uint32_t* object_entry_extendeds;
};
}
namespace openloco::objectmgr
@ -50,4 +92,5 @@ namespace openloco::objectmgr
void load_index();
cargo_object* get_cargo_object(size_t id);
size_t get_max_objects(object_type type);
vehicle_object* get_vehicle_object(size_t id);
}

View File

@ -0,0 +1,66 @@
#pragma once
#include "../localisation/stringmgr.h"
namespace openloco
{
struct vehicle_object_unk
{
uint8_t length; // 0x00
uint8_t pad_01[0x04 - 0x01];
uint8_t sprite_ind; // 0x04
uint8_t var_05;
};
struct vehicle_object_sprite
{
uint8_t num_dir; // 0x00
uint8_t pad_01[0x03 - 0x01];
uint8_t vehicle_type; // 0x03
uint8_t num_units; // 0x04
uint8_t pad_05;
uint8_t bogey_position; // 0x06
uint8_t flags; // 0x07
uint8_t pad_08[0x0E - 0x08];
uint8_t sprite_num; // 0x0E
uint8_t pad_0F[0x1E - 0xF];
};
struct vehicle_object
{
string_id name; // 0x00 probably not confirmed
uint8_t vehicle_class; // 0x02
uint8_t type; // 0x03
uint8_t pad_04[0x6 - 0x4];
uint8_t num_mods; // 0x06
uint8_t cost_ind; // 0x07
int16_t cost_fact; // 0x08
uint8_t reliability; // 0x0A
uint8_t run_cost_ind; // 0x0B
int16_t run_cost_fact; // 0x0C
uint8_t colour_type; // 0x0E
uint8_t num_compat; // 0x0F
uint8_t pad_10[0x24 - 0x10];
vehicle_object_unk var_24[4];
vehicle_object_sprite sprites[4]; // 0x3C
uint8_t pad_B4[0xD8 - 0xB4];
uint16_t power; // 0xD8
uint16_t speed; // 0xDA
uint16_t rack_speed; // 0xDC
uint16_t weight; // 0xDE
uint16_t flags; // 0xE0
uint8_t pad_E1[0x10E - 0xE1];
uint8_t vis_fx_height; // 0x10E
uint8_t vis_fx_type; // 0x10F
uint8_t pad_110[0x112 - 0x110];
uint8_t wake_fx_type; // 0x112
uint8_t pad_113;
uint16_t designed; // 0x114
uint16_t obsolete; // 0x116
uint8_t pad_118;
uint8_t startsnd_type; // 0x119
uint8_t pad_11A[0x15A - 0x11A];
uint8_t numsnd; // 0x15A
uint8_t pad_15B[0x15E - 0x15B];
};
}

View File

@ -30,6 +30,7 @@
<ClCompile Include="things\thingmgr.cpp" />
<ClCompile Include="things\vehicle.cpp" />
<ClCompile Include="utility\string.cpp" />
<ClCompile Include="viewportmgr.cpp" />
<ClCompile Include="window.cpp" />
<ClCompile Include="intro.cpp" />
<ClCompile Include="objects\objectmgr.cpp" />
@ -63,6 +64,7 @@
<ClInclude Include="objects\cargo_object.h" />
<ClInclude Include="objects\objectmgr.h" />
<ClInclude Include="platform\platform.h" />
<ClInclude Include="objects\vehicle_object.h" />
<ClInclude Include="scenariomgr.h" />
<ClInclude Include="stationmgr.h" />
<ClInclude Include="things\thing.h" />
@ -73,6 +75,7 @@
<ClInclude Include="utility\numeric.hpp" />
<ClInclude Include="utility\string.hpp" />
<ClInclude Include="types.hpp" />
<ClInclude Include="viewportmgr.h" />
<ClInclude Include="window.h" />
<ClInclude Include="windowmgr.h" />
<ClInclude Include="graphics\gfx.h" />
@ -106,4 +109,4 @@
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
</Project>

View File

@ -1,9 +1,14 @@
#include "thing.h"
#include "../graphics/gfx.h"
#include "../interop/interop.hpp"
#include "../viewportmgr.h"
#include <algorithm>
using namespace openloco;
using namespace openloco::interop;
loco_global<uint8_t, 0x0050AF25> thing_zoom_max;
// 0x0046FC83
void thing::move_to(loc16 loc)
{
@ -14,3 +19,57 @@ void thing::move_to(loc16 loc)
regs.esi = (int32_t)this;
call(0x0046FC83, regs);
}
// 0x004CBB01
void openloco::thing::invalidate_sprite()
{
if (sprite_left == (int16_t)0x8000u)
{
return;
}
int16_t left = sprite_left;
int16_t top = sprite_top;
int16_t right = sprite_right;
int16_t bottom = sprite_bottom;
for (auto& viewport : openloco::ui::viewportmgr::viewports())
{
if (viewport->zoom > thing_zoom_max)
continue;
if (sprite_right <= viewport->view_x)
continue;
if (sprite_bottom <= viewport->view_y)
continue;
if (sprite_left >= viewport->view_x + viewport->view_width)
continue;
left = std::max(sprite_left, viewport->view_x);
right = std::min<int16_t>(sprite_right, viewport->view_x + viewport->view_width);
if (sprite_top >= viewport->view_y + viewport->view_height)
continue;
bottom = std::max(sprite_bottom, viewport->view_y);
top = std::min<int16_t>(sprite_top, viewport->view_y + viewport->view_height);
left -= viewport->view_x;
bottom -= viewport->view_y;
right -= viewport->view_x;
top -= viewport->view_y;
left >>= viewport->zoom;
bottom >>= viewport->zoom;
right >>= viewport->zoom;
top >>= viewport->zoom;
left += viewport->x;
bottom += viewport->y;
right += viewport->x;
top += viewport->y;
openloco::gfx::set_dirty_blocks(left, top, right, bottom);
}
}

View File

@ -34,19 +34,30 @@ namespace openloco
int16_t z; // 0x12
uint8_t var_14;
uint8_t var_15;
uint8_t pad_16[0x28 - 0x16];
int16_t sprite_left; // 0x16
int16_t sprite_top; // 0x18
int16_t sprite_right; // 0x1A
int16_t sprite_bottom; // 0x1C
uint8_t pad_1E[0x28 - 0x1E];
uint16_t var_28;
uint8_t pad_2A[0x3A - 0x2A];
uint8_t pad_2A[0x38 - 0x2A];
uint8_t var_38;
uint8_t pad_39;
thing_id_t next_car_id; // 0x3A
uint8_t pad_3C[0x4C - 0x3C];
uint8_t pad_3C[0x40 - 0x3C];
uint16_t object_type;
uint8_t var_42;
uint8_t pad_43[0x4C - 0x43];
uint8_t cargo_type; // 0x4C
uint8_t pad_4D;
uint16_t cargo_origin; // 0x4E
uint8_t pad_50;
uint8_t cargo_quantity; // 0x51
uint8_t pad_52[0x5D - 0x52];
uint8_t pad_52[0x54 - 0x52];
uint8_t var_54;
uint8_t pad_55[0x5D - 0x55];
uint8_t var_5D;
uint8_t pad_5E;
uint8_t var_5E;
uint8_t var_5F; // 0x5F (bit 1 = can break down)
uint8_t pad_60[0x6A - 0x60];
uint8_t var_6A;
@ -56,6 +67,7 @@ namespace openloco
};
void move_to(loc16 loc);
void invalidate_sprite();
};
#pragma pack(pop)
}

View File

@ -1,13 +1,26 @@
#include "vehicle.h"
#include "../audio/audio.h"
#include "../config.h"
#include "../graphics/gfx.h"
#include "../interop/interop.hpp"
#include "../objects/objectmgr.h"
#include "../objects/vehicle_object.h"
#include "../openloco.h"
#include "../utility/numeric.hpp"
#include "../viewportmgr.h"
#include "thingmgr.h"
#include <algorithm>
using namespace openloco;
using namespace openloco::interop;
using namespace openloco::objectmgr;
loco_global<vehicle*, 0x01136118> vehicle_1136118;
loco_global<vehicle*, 0x01136124> vehicle_1136124;
loco_global<vehicle*, 0x01136128> vehicle_1136128;
loco_global<uint32_t, 0x01136130> vehicle_var_1136130;
loco_global<uint8_t, 0x01136237> vehicle_var_1136237; // var_28 related?
loco_global<uint8_t, 0x01136238> vehicle_var_1136238; // var_28 related?
vehicle* vehicle::next_vehicle()
{
@ -53,7 +66,7 @@ bool vehicle::update()
break;
case 4:
case 5:
result = call(0x004AA1D0, regs);
result = sub_4AA1D0();
break;
case 6:
result = call(0x004AA24A, regs);
@ -146,3 +159,90 @@ void vehicle::sub_4BAA76()
regs.esi = (int32_t)this;
call(0x004BAA76, regs);
}
// 0x004AA1D0
int32_t openloco::vehicle::sub_4AA1D0()
{
registers regs;
regs.esi = (int32_t)this;
if (var_42 == 2 || var_42 == 3)
{
sub_4AAC4E();
return 0;
}
if (vehicle_var_1136237 | vehicle_var_1136238)
{
invalidate_sprite();
vehicle* veh = vehicle_1136124;
regs.ebx = (int32_t)veh;
veh = vehicle_1136128;
regs.edi = (int32_t)veh;
call(0x004AC255, regs);
invalidate_sprite();
}
uint32_t backup1136130 = vehicle_var_1136130;
if (var_5E != 0)
{
uint32_t var_1136130 = var_5E;
if (var_5E > 32)
{
var_1136130 = 64 - var_1136130;
}
vehicle_var_1136130 += var_1136130 * 320 + 500;
}
sub_4AAC4E();
call(0x004AAB0B, regs);
vehicle_var_1136130 = backup1136130;
return 0;
}
void openloco::vehicle::sub_4AAC4E()
{
if (var_38 & (1 << 4))
return;
vehicle* veh = vehicle_1136118;
if ((veh->var_5D == 8) || (veh->var_5D == 9))
return;
vehicle_object* vehicleObject = get_vehicle_object(object_type);
registers regs;
regs.esi = (int32_t)this;
regs.bl = vehicleObject->var_24[var_54].var_05;
if (vehicleObject->var_24[var_54].var_05 == 0)
{
call(0x004AB655, regs);
return;
}
regs.ebx -= 0x80;
switch (vehicleObject->vis_fx_type)
{
case 0:
call(0x004AB655, regs);
break;
case 1:
case 2:
case 3:
call(0x004AACA5, regs);
break;
case 4:
call(0x004AAFFA, regs);
break;
case 5:
call(0x004AB3CA, regs);
break;
case 6:
call(0x004AB4E0, regs);
break;
case 7:
call(0x004AB177, regs);
break;
case 8:
call(0x004AB2A7, regs);
break;
}
}

View File

@ -22,6 +22,8 @@ namespace openloco
private:
bool update();
void sub_4BAA76();
int32_t sub_4AA1D0();
void sub_4AAC4E();
};
#pragma pack(pop)
}

View File

@ -0,0 +1,19 @@
#include "viewportmgr.h"
#include "interop/interop.hpp"
#include "ui.h"
#include "window.h"
#include <algorithm>
using namespace openloco::ui;
using namespace openloco::interop;
namespace openloco::ui::viewportmgr
{
loco_global_array<viewport*, max_viewports, 0x0113D820> _viewports;
std::array<viewport*, max_viewports> viewports()
{
auto arr = (std::array<viewport*, max_viewports>*)_viewports.get();
return *arr;
}
}

View File

@ -0,0 +1,10 @@
#pragma once
#include "window.h"
#include <array>
namespace openloco::ui::viewportmgr
{
constexpr size_t max_viewports = 10;
std::array<viewport*, max_viewports> viewports();
}

View File

@ -42,5 +42,19 @@ namespace openloco::ui
void sub_4CA17F();
};
struct viewport
{
int16_t width; // 0x00
int16_t height; // 0x02
int16_t x; // 0x04
int16_t y; // 0x06
int16_t view_x; // 0x08
int16_t view_y; // 0x0A
int16_t view_width; // 0x0C
int16_t view_height; // 0x0E
uint8_t zoom; // 0x10
uint8_t pad_11;
uint16_t var_12; // 0x12, maybe flags
};
#pragma pack(pop)
}