Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement load_g1() #20

Merged
merged 15 commits into from Jan 25, 2018
Merged

Implement load_g1() #20

merged 15 commits into from Jan 25, 2018

Conversation

rwjuk
Copy link
Contributor

@rwjuk rwjuk commented Jan 21, 2018

Initial decompilation of the G1.DAT load function - doesn't work because various offset fixes are TBD. Please feel free to fix up. load_g1() implemented.

if (fread(&header, 8, 1, file) == 1) {

// Read element headers
g1Elements = (loco_g1_element *)malloc(header.num_entries * sizeof(loco_g1_header));
Copy link
Collaborator

@IntelOrca IntelOrca Jan 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You won't be able to do this until all references to g1Elements are implemented or replaced.
You will need to set it or copy it to 0x9E2424

Copy link
Contributor Author

@rwjuk rwjuk Jan 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah, of course. Guessing we should have a define for that, akin to RCT2_ADDRESS_G1_ELEMENTS?

Copy link
Collaborator

@IntelOrca IntelOrca Jan 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, loco_global_array<loco_g1_element, 15000, 0x9E2424> _g1Elements etc.

@rwjuk rwjuk changed the title Initial work on g1.dat load Implement load_g1() Jan 21, 2018

file = fopen(g1Path.make_preferred().u8string().c_str(), "rb");

if (file != NULL) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to add some early escapes, to prevent nesting too much.

uint32_t total_size;
};

struct loco_g1_element
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

g1_element_t seems to be more consistent with the rest of the codebase

Copy link
Contributor Author

@rwjuk rwjuk Jan 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change it - I just followed OpenRCT2's rct_g1_element.

Copy link
Collaborator

@IntelOrca IntelOrca Jan 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far I have used _t for any time that has no default initialisation. E.g. it won't be zeroed if you define a local instance of one. And it won't have any methods etc.

g1Buffer = malloc(header.total_size);
fread(g1Buffer, header.total_size, 1, file);

fclose(file);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you close it twice


// Read element data
g1Buffer = malloc(header.total_size);
fread(g1Buffer, header.total_size, 1, file);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs return value checked. Since you already throw in case there is no g1.DAT, you could maybe add a try { … } catch block here (encompassing both freads), upon exception close the file and re-throw?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... good point - I'll do just that I think.

@IntelOrca
Copy link
Collaborator

We should probably use iostream as that is the C++ way.

@@ -4,6 +4,8 @@
#include "../localisation/stringmgr.h"
#include "../openloco.h"

#define LOCO_G1_ELEMENT_COUNT 0x1A10
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this hold for the other variants (Steam/GOG/…) as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GOG, yes. Steam... no, it's 0x380F. I'll need to investigate that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure it's not 0x101A and 0xF38? Anyhow, I'd say log a warning in case g1 count doesn't match expected count. Probably best to still use the other one for array size, in case something depends on it.

call(0x0044733C);
auto g1Path = environment::get_path(environment::path_id::g1);

std::ifstream stream(g1Path.make_preferred().u8string().c_str(), std::ios::in | std::ios::binary);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ifstream takes a std::path, so you should just be able to do:
std::ifstream stream(g1Path, std::ios::in | std::ios::binary);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, victim of copy-paste from fopen - will fix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@rwjuk
Copy link
Contributor Author

rwjuk commented Jan 23, 2018

Exception thrown at 0x7709FD1A (ntdll.dll) in openloco.exe: 0xC0000005: Access violation reading location 0x00000004.. Line 117 when copying the elements vector into _g1Elements.

@@ -98,6 +98,8 @@ namespace openloco::gfx
// This code copies the closest variants into their place, and moves other elements accordingly
if (header.num_entries == g1_expected_count::steam)
{
elements.reserve(g1_expected_count::disc);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resize(). reserve() will only change capacity so you can pre-emptively allocate the space, but vector's size stays the same and the objects you copy in will not survive any calls that modify (e.g. copying to another vector) or will be replaced with values pushed in future.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sorry I didn't realise it needed to grow.


// Extra two tutorial images
std::copy_n(&elements[3549], header.num_entries - 3549, &elements[3551]);
std::copy_n(&elements[3551], 1, &elements[3549]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be 3550?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and I don't think we need L106 after all.

@@ -18,11 +18,55 @@ namespace openloco::gfx
int16_t pitch; // 0x0C note: this is actually (pitch - width)
uint16_t zoom_level; // 0x0E
};

#pragma pack(pop)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs removing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, must've accidentally reintroduced it during rebase.

@IntelOrca IntelOrca merged commit d768909 into OpenLoco:master Jan 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants