Jump to content

Code Discussion Thread


Celtic Minstrel

Recommended Posts

Originally Posted By: Celtic Minstrel
Close – it contains the terrain for all four currently loaded sections, combined into a single array.

Indeed wink

Originally Posted By: Celtic Minstrel
Yes we do. In the Mac version it's called "Blades of Exile Base" instead of "bladbase.exs". Note that I'm not actually using the one from Drakefyre's link at this time.

If you want to fix bladbase errors in the Mac version of it, go right ahead. Or you could just fix them on the Windows side and post them here so I can fix them in the Mac version.

Ok, i'll fix some errors i've spotted and report at http://www.ironycentral.com/forum/ubbthreads.php?ubb=showflat&Number=164683#Post164683

Originally Posted By: Celtic Minstrel
I don't think I'll implement that right now. I'm more interested in getting saving and loading of new-format parties, getting the game to run from the Finder, and then moving on to improve terrain and tool palettes in the scenario editor... and animating the terrain in the editor seems trivial in comparison.

Yup, i agree on that (to be honest, I was just toying with the scenario editor code and get a little carried away smile ). I've made a comment as suggested.

Originally Posted By: Celtic Minstrel
Or did you write the code for displaying custom graphics yourself?

I have written my own (temporary ?) version of the custom drawing code.

Originally Posted By: Celtic Minstrel
Actually, no. At least, I don't think so. The terrain of the current town is stored in the save file.

We're not speaking of the same thing smile I was thinking of the fact that leaving a town erase all changes in this town ...
Besides, changes in the current town (if any) only will be saved (because of town reset when leaving) ...

Chokboyz
Link to comment
Share on other sites

  • Replies 990
  • Created
  • Last Reply

Top Posters In This Topic

Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
Actually, no. At least, I don't think so. The terrain of the current town is stored in the save file.

We're not speaking of the same thing smile I was thinking of the fact that leaving a town erase all changes in this town ...
Besides, changes in the current town (if any) only will be saved (because of town reset when leaving) ...
Terrain changes, yes; creature changes and field changes are stored in the savegame though. However, the point was that terrain changes are saved for the current town, but not for the current outdoors. Hence, maybe they should be saved for the current outdoors; it would require skipping build_outdoors() after loading the party, I think.
Link to comment
Share on other sites

In BoA I solved the terrain change problem for towns with use of Init state and a SDF. Party enters town, Init state is run, if a SDF has been set then a state is called that alters the terrain. If SDF has not been set the terrain is loaded from the scenario as normal. See town 7, Hetware in River and Leaf. Sounds like BoE outdoors could do with a special on entry.

Link to comment
Share on other sites

Indeed, terrain changes in towns are lost when you leave the town and return, but this has been known since before the release of Blades of Exile in the first place, and in fact dates all the way back to Exile 1. In addition to implementing it in his scenarios, I believe Jeff warns us of this phenomenon in the editor instruction manual and advises designers to make sure they include nodes to rechange unchanged changed terrain, such as including special nodes to open gates on both sides of the gate.

 

I believe this is in fact a feature, not a bug. If you want to make such major permanent changes to a town's terrain that you can't easily change it every time the party reenters the town, you're better off using Variable Town Entry. On the other hand, cities like forts that need to guard their gates and keep them closed unless someone trusted wants to enter need to be reset, and for those players that don't close doors behind them, it's hard to believe an entire city would leave their doors wide open and unlocked forever just because an adventurer passed through.

Link to comment
Share on other sites

Yes, this should not be changed. I never suggested this should be changed. The only change I suggested was that the current outdoors terrain should perhaps be stored in the save file, so that if an outdoor terrain change takes place and you then save, reloading has the change still in place. (But it'll still reset once you leave the area and the section is unloaded from memory.)

 

 

BoE already has the equivalent of an INIT_STATE for towns, so no problems there. It might be useful to add this for outdoor sections, too...

Link to comment
Share on other sites

I've added an option (switch for now) to use Mac (darker) graphics with the Win32 version. The only changes i could notice were in terrains sheets, field sheet and maps sheets (the pc, monsters and items graphics are the same)...

 

Some things were unclear though :

  • Does the Mac graphics have an equivalent of the rough graphic squares used in Win32 to draw on the map, or does it uses animmap/termap exclusively ? (for example, if you put a hill square with two boulders on it, will it appears like that on the map or rather like a plain hill square ?)
  • Are all the frills used in the Mac version ? (in Windows, only the cave frills are used; the others two (three) doesn't even exist !)
If i find the time, i'll try to add the Mac compatibility code ... (then i should need Mac saves to test it smile )

 

Chokboyz

Link to comment
Share on other sites

Originally Posted By: Chokboyz
Does the Mac graphics have an equivalent of the rough graphic squares used in Win32 to draw on the map, or does it uses animmap/termap exclusively ? (for example, if you put a hill square with two boulders on it, will it appears like that on the map or rather like a plain hill square ?)
I'm not quite sure what you mean. If you're referring to the fact that some of the terrains are drawn on the map using pattern fills, the Mac version does do that.

Originally Posted By: Chokboyz
Are all the frills used in the Mac version ? (in Windows, only the cave frills are used; the others two (three) doesn't even exist !)
The frills that exist in the Mac version are the top row (cave) and the third in the second row (grass corners). The others I just added for completeness; at the moment they are unused, but I intend to change that eventually.
Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
I'm not quite sure what you mean. If you're referring to the fact that some of the terrains are drawn on the map using pattern fills, the Mac version does do that.

Once again, i admit it was pretty confusing ...
I was indeed speaking of pattern filling (if you have access to the mixed.bmp file of the Windows version, these are the slightly larger squares on the top right of the bitmap).
Unfortunately, I couldn't find such patterns in the graphics you've provided (have i forgotten to get a file ?). So, the map is drawn with mixed graphics ...

Originally Posted By: Celtic Minstrel
The frills that exist in the Mac version are the top row (cave) and the third in the second row (grass corners). The others I just added for completeness; at the moment they are unused, but I intend to change that eventually.

Ok, so this is like Windows ... I'll see if we can use the remaining frills without much rewriting.

Thanks,
Chokboyz
Link to comment
Share on other sites

Originally Posted By: Chokboyz
Once again, i admit it was pretty confusing ...
I was indeed speaking of pattern filling (if you have access to the mixed.bmp file of the Windows version, these are the slightly larger squares on the top right of the bitmap).
Unfortunately, I couldn't find such patterns in the graphics you've provided (have i forgotten to get a file ?). So, the map is drawn with mixed graphics ...
The Mac version uses ppat resources for those files - I didn't upload the map ppats because I believe they are identical to the equivalent map graphic (termap.gif in the files I uploaded). If they aren't, though, I'll gladly add them (probably to pixpats.gif).

By the way, are you using the files I uploaded as they are (except maybe converted to BMP) or did you copy-paste their contents on top of the Windows graphics? And how many of the graphics are actually different? I had the impression that not all the graphics were brighter on Windows (mainly just the terrain graphics).

Another thing – if I recall correctly, the graphics are stored in the Scenario Editor folder, right? As opposed to a graphics subfolder? The latter would probably be preferable... though it doesn't matter that much.

EDIT: Oh, by the way, did you or Ishad Nha incorporate my beginnings of a rearrangement of the editor buttons?
Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
The Mac version uses ppat resources for those files - I didn't upload the map ppats because I believe they are identical to the equivalent map graphic (termap.gif in the files I uploaded). If they aren't, though, I'll gladly add them (probably to pixpats.gif).

They are, but scaled down ... I've extracted bitmaps from files and scaled them down, but the result was not really pretty (as soon as the terrain was not plain (bushes, ...) the square appears somewhat garbled).
So, if you find time, i'll be glad you upload them smile

Originally Posted By: Celtic Minstrel
By the way, are you using the files I uploaded as they are (except maybe converted to BMP) or did you copy-paste their contents on top of the Windows graphics?

I'm using your files (converted to BMP) except for MIXED.BMP which i've modified by copy/pasting from termaps.gif/animmap.gif.

Originally Posted By: Celtic Minstrel
And how many of the graphics are actually different? I had the impression that not all the graphics were brighter on Windows (mainly just the terrain graphics).

As far as i can tell, you're right. The only changes i've founded were terrains (animated/non-animated/map miniatures/frills) and some fields (poison, zap, ...), plus some minor differences (boats seeming higher qualities on Mac, ...).
I didn't find much (read any) difference between Windows and Mac PC/Monsters/Items/Text/Icons graphics. I may have missed some though ...

Originally Posted By: Celtic Minstrel
Another thing – if I recall correctly, the graphics are stored in the Scenario Editor folder, right? As opposed to a graphics subfolder? The latter would probably be preferable... though it doesn't matter that much.

Ormus has changed that a bit : the graphics are stored in an "Images" folder in the executable directory (hence outside of the Scenario Editor folder, which was the original way).

Originally Posted By: Celtic Minstrel
EDIT: Oh, by the way, did you or Ishad Nha incorporate my beginnings of a rearrangement of the editor buttons?

Apart from toying with the animations and custom graphics, i've not really worked on the Scenario Editor code.
Ishad Nha may have though ...

Chokboyz
Link to comment
Share on other sites

Originally Posted By: Chokboyz
They are, but scaled down ... I've extracted bitmaps from files and scaled them down, but the result was not really pretty (as soon as the terrain was not plain (bushes, ...) the square appears somewhat garbled).
So, if you find time, i'll be glad you upload them smile
Okay, I will. If I forget, you may remind me.

Originally Posted By: Chokboyz
I'm using your files (converted to BMP) except for MIXED.BMP which i've modified by copy/pasting from termaps.gif/animmap.gif.
My files didn't include a mixed.bmp... smirk are you saying you basically combined two files into one? My reason for separating them was that I intend to add about 9 additional rows of graphics on the bottom of termaps. There's no real reason to keep them separate though, if those extra rows are accounted for.

Originally Posted By: Chokboyz
Ormus has changed that a bit : the graphics are stored in an "Images" folder in the executable directory (hence outside of the Scenario Editor folder, which was the original way).
Good, that's much less cluttered. smile

Originally Posted By: Chokboyz
Apart from toying with the animations and custom graphics, i've not really worked on the Scenario Editor code.
Ishad Nha may have though ...
Well, I was wondering, because no-one responded to my post about it in the other thread (the "Scenario Editor Compiled" thread).

EDIT: I've uploaded three Mac save files (created by the other, older version of BoE on my computer) for testing compatibility if and when you decide to teach the Windows version to load Mac saves. They are in the character editor subfolder.
Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
EDIT: I've uploaded three Mac save files (created by the other, older version of BoE on my computer) for testing compatibility if and when you decide to teach the Windows version to load Mac saves. They are in the character editor subfolder.

Erf, your save files appeared corrupted on my computer (party data is ok, setup data is a little weird and pcs data is corrupted with lots of "kkkk" and the string "Blades of Exile doesn't" garbage in the end of the file) and i bet mine are too ... Maybe, zipping them would have been a good idea smile

I'll reupload zipped files, maybe that will solve the loading problem,
Chokboyz
Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
Huh, that's odd. Maybe they were downloaded as text instead of binary. That's the only reason I can think of that they may have been corrupted.

Quite likely ... Downloading them again, makes the name of the characters appears but the garbage was always there crazy

Anyway, I found a nice relic from Exile III in the place_spell_pattern() function :
Click to reveal..
void place_spell_pattern(effect_pat_type pat,location center,short type,Boolean,short who_hit)
//type; // 0 - take codes in pattern, OW make all nonzero this type
// Types 0 - Null 1 - web 2 - fire barrier 3 - force barrier 4 - force wall 5 - fire wall
// 6 - anti-magic field 7 - stink cloud 8 - ice wall 9 - blade wall 10 - quickfire
// 11 - dispel 12 - sleep field
// 50 + i - 80 : id6 fire damage 90 + i - 120 : id6 cold damage 130 + i - 160 : id6 magic dam.
// if prep for anim is TRUE, suppress look checks and go fast
{
short i,j,r1,k,store = 0;
unsigned char effect;
location spot_hit;
location s_loc;
RECT active;
creature_data_type *which_m;
Boolean monster_hit = FALSE;

location pool_locs[5] =
{ location(13,2), location(11,19), location(34,22), location(46,15), location(46,7) };//location of the slimes pool

if (type > 0)
modify_pattern(&pat,type);

// first clip out special results.
if (((is_town()) || ((is_combat()) && (which_combat_type == 1))) && (c_town.town_num == 46) && (center.x == 24) && (center.y == 41)//first slime pool outside of Slime Pit
&& (PSD[46][9] == 0) && (type >= 50) && (type < 90)) {
end_missile_anim();
run_a_missile(pc_pos[current_pc],center,2,1,11,0,0,200);
mondo_boom(center,0);
FCD(3464,0);
PSD[46][9] = 1;
for (i = 0; i < 4; i++)
elim_monst(138 + i,46,9);//erase all slimes
alter_space(24,41,0);
return;
}
for (i = 0; i < 5; i++)
store += PSD[20];//how many slime pools destroyed in Slime Pit ?
if (((is_town()) || ((is_combat()) && (which_combat_type == 1))) && (c_town.town_num == 23))//killing the five slime pools in Slime Pit
for (i = 0; i < 5; i++)
if ((center.x == pool_locs.x) && (center.y == pool_locs.y)
&& (PSD[20] == 0) && (type >= 50) && (type < 90)) {
end_missile_anim();
run_a_missile(pc_pos[current_pc],center,2,1,11,0,0,200);
mondo_boom(center,0);
if (store == 4) {
FCD(3239,0);
PSD[23][3] = 20;
erase_specials();
}
else FCD(3238,0);
PSD[20] = 1;
alter_space(pool_locs.x,pool_locs.y,0);
return;
}
[...]

I've deleted the code as it can lead to potential glitches (dialog 3464 and 3239 doesn't exist to begin with; i've locked up a game testing that wink ).
By the way, if anyone can confirm that town number 23 is Slime Pit (the level with the slime pool) and town number 46 is the town where you find the lone slime pool, don't hesitate ... I've found that it was indeed those town in Ishad Nha's Scenario Data sheet (Thanks smile )

Chokboyz

Edit 1 : the party.stuff_done[181][6] is checked in the Windows code and if different of 0, no target lines are drawn (doubling the option doing so, that works).
I've deleted it because it was redundant (and checking an unprotected SDF).

That's the last (obvious) PSD relic I could find ...
Link to comment
Share on other sites

Originally Posted By: Chokboyz
Anyway, I found a nice relic from Exile III in the place_spell_pattern() function :
[...]
I've deleted the code as it can lead to potential glitches (dialog 3464 and 3239 doesn't exist to begin with; i've locked up a game testing that wink ).
By the way, if anyone can confirm that town number 23 is Slime Pit (the level with the slime pool) and town number 46 is the town where you find the lone slime pool, don't hesitate ... I've found that it was indeed those town in Ishad Nha's Scenario Data sheet (Thanks smile )
I intend to eventually replace the "Ritual of Sanctification" special node with a "Target Space" special mode that can duplicate the behaviour of the slime pools, so that code will certainly not be necessary.

Originally Posted By: Chokboyz
Edit 1 : the party.stuff_done[181][6] is checked in the Windows code and if different of 0, no target lines are drawn (doubling the option doing so, that works).
I've deleted it because it was redundant (and checking an unprotected SDF).

That's the last (obvious) PSD relic I could find ...
Deleted it? Or replaced it with the correct SDF?




EDIT: I recently had another idea about reworking the dialog engine. When the current dialog code loads a dialog, all its contents are ignored except for the text edit fields, because the code handles drawing all the controls itself (with that one exception). So, I thought maybe we could create an XML format for the dialogs? Then if we had an appropriate stylesheet we could hopefully even preview the dialog in the browser! This would require two things in particular: the ability to create an empty dialog, and the ability to add text edit controls to it. I'd be surprised if that wasn't possible, though...
Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
I intend to eventually replace the "Ritual of Sanctification" special node with a "Target Space" special mode that can duplicate the behaviour of the slime pools

That is, in fact, on the ToDo List wink

Originally Posted By: Celtic Minstrel
Deleted it? Or replaced it with the correct SDF?

Deleted it, as it was redundant, hence useless (the preference option SDF check is done before ...).

Originally Posted By: Celtic Minstrel
I'd be surprised if that wasn't possible, though...

The two required things seem, indeed, to be doable smile

By the way, i've duplicated your graphics sheets in Windows (brightest) format (except for the last two pictures i couldn't find and the truncated large boulder which is a pit in Windows version. Note that in TER7 your second row is off by a pixel because of a brown mountain line right before the second cave mountain entry).

Chokboyz
Link to comment
Share on other sites

Originally Posted By: Chokboyz
By the way, i've duplicated your graphics sheets in Windows (brightest) format (except for the last two pictures i couldn't find and the truncated large boulder which is a pit in Windows version. Note that in TER7 your second row is off by a pixel because of a brown mountain line right before the second cave mountain entry).
Hmm, that's interesting. Perhaps I should repopulate that row.

Which graphics were you unable to find? The crystal on Vahnatai floor and the altar on cave floor? They are from Exile 2 and Exile 1 respectively, if that helps.

I'm going to change ter7, though – the walkways and special spots are going to be deleted at some point. (I'm going to delete them in the main sheets too, as well as the duplicate good altar on stone floor found in ter5.) I have an alternate mechanism in mind to replace both – the alternate for walk way I have already implemented (though not tested), and the alternate for special spots involves storing them as a field (in the outdoors they can be stored in the out_e variable, in, say, the most significant bits).

Also, the first of those cave entrances in ter7 is from Exile 3, but the others are bad transformations of it. If I recall correctly, they don't actually look right beside the basic cave wall. So it would be advisable to at some point replace them with better equivalents.
Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
I intend to eventually replace the "Ritual of Sanctification" special node with a "Target Space" special mode that can duplicate the behaviour of the slime pools

That is, in fact, on the ToDo List wink
And the nice thing is, it would allow you to create a special that is called when you shoot a space! smile
Link to comment
Share on other sites

I wrote up a quick dtd+css for an xml dialog format, but I ran into a problem – I can't seem to find a way to specify an element's position and size for an XML stylesheet. I have top, left, width, and height attributes on all elements, but there's no way that I can find to transmit that information to the browser. (There's the CSS3 attr() function that looks like it's exactly what I need; unfortunately there exists no browser that supports it.)

Link to comment
Share on other sites

Wha? What does CSS or a web-browser have to do with BoE dialogs? If you want to use XML to describe dialogs, go ahead and do that; you can put in any attributes or elements you want. Unless you intend to embed and (X)HTML/CSS rendering engine in the game to do the display, (X)HTML and CSS are utterly irrelevant, surely.

Link to comment
Share on other sites

One of the reasons for wanting to use XML is so that I can preview the dialog without running the game. The easiest way to do that is with a stylesheet. The stylesheet won't be used by the game; it's merely a convenience.

 

I think I'll try to make an XSL stylesheet instead. I suspect that will be more effective.

Link to comment
Share on other sites

XSL did indeed prove to be more effective. I actually ended up using a mixture of XSL and CSS.

 

So, now I can create and preview dialogs. Next I need to write the classes to support this. I have no idea how to read and parse XML from C++ code, but I'm sure it won't be too hard to find a library that does it, possibly even one included with the system.

Link to comment
Share on other sites

I'm still not convinced that this is really a good way to go given the amount of custom code you're having to write, but you're the one in the trenches, so it's up to your judgment.

 

I would recommend a cross platform XML library; I know Mac OS provides XML parsing, and I'm sure Windows does as well, but you might as well write the code only once, not twice. Have a look at TinyXML++. It really is tiny, easy to use, and gives you a proper C++ wrapper around C code of TinyXML. I'm using it for the BoA file format rewrite, and it's working pretty nicely.

Link to comment
Share on other sites

  • 2 weeks later...

A quick bug :

 

the create_wand_monst() function is bugged so that only the first monster type of the third and fourth row, and the second monster type of the fourth row may appear by pair (the editor tells us it should be the monster type of the last line for each row).

I choose to make a second monster of the last line type appears with a probability of 1/2 (inspired by the faulty code).

 

I'm still on the Empty bug ...

 

Chokboyz

Link to comment
Share on other sites

The start_outdoor_combat() function is also a little off from the Scenario Editor description :

the lines

short low[10] = {15,7,3,3,1,1,1,7,2,1};

short high[10] = {30,10,5,5,3,2,1,10,4,1};

should read

short low[10] = {15,7,4,3,2,1,1,7,2,1};

short high[10] = {30,10,6,5,3,2,1,10,4,1};

to be accurate ...

 

Chokboyz

Link to comment
Share on other sites

I finally got it: the linker warnings are banished. It turned out that for some reason it was set to link with the standard libraries statically rather than dynamically, which seems to be the default. Restoring the default removed the warnings.

 

I'm now down to 272 warnings, with the only ones I specifically turned off being those insipid ones about newlines at the end of files. Sometimes I can only take so much pedantry.

Link to comment
Share on other sites

I only deleted unused variables in functions that appeared to be complete and already doing their jobs. There were a couple of cases I saw of functions that were empty except for some variable declarations, which looked like they would be used if the functions were completed; those I just commented out for future use. I didn't mess with any function parameters yet, since for those I would want to check fairly carefully whether the parameters are really junk or should be being used somehow; it won't be a difficult job, I just didn't want to mess things up that I don't understand.

Link to comment
Share on other sites

After some nightmarish coding/hex-editing/testing i've finally implemented the compatibility with legacy Mac save files.

For some reasons, filling a structure field by field doesn't work when working on a Mac legacy save (then again, not even the party_record_type struct ended at the same byte in a Mac (46406) or a Windows (45xxx) save file, despite being the same size on both platform ...): i had to copy the struct as a whole ...

Even when doing this, the game would persist in skipping bytes (for example, it skipped 2 bytes between the short m_killed[200] array and the four long types, messing with the rest of the loading process) ...

The way I implemented this, is to manually adjust the file pointer when the loading function "skips" some bytes.

Upon testing, i found that the sfx, misc_i or maps data were also affected by this.

Finally, i've been able to open Mac files :

  • in mainscreen : i just had to fix the 2 bytes skipping when loading the party struct.
  • while outdoors : no problems besides the previous one
  • while in town : had to fix the loading of town_maps, sfx and misc_i. I also had to flip the shorts in the monsters and items structures contained in the current_town.
Monsters, items, dialogues, secrets, maps, ... works perfectly. The only thing i've been unable to test is stored items.

 

On another note, i've been able to finish a scenario without any Empty appearing, but that doesn't mean the problem is solved.

 

I also found (and fixed) a bug in Ormus' build that would prevent some scenario to be played when listing more than 25 scenarios (a maximum of 100 scenarios can now be listed and played).

 

I think I'll take some time this weekend to finish cleaning and test the code. Should nothing horrible arise, I will then post it in the repository and, why not, maybe release the first beta of (Win32) Classic Blades of Exile (the name means without major refactoring of the code). wink

 

Chokboyz

Link to comment
Share on other sites

Ah, so that was the problem. The structs were padded differently on the Mac than on Windows. And yes, multidimensional arrays are also subject to padding at the end of the rows.

 

So, if you had a problem with 2 bytes being skipped in the party struct, that probably means that I'll have to skip two bytes. Where exactly did that problem occur? And also can you tell me exactly how much space is taken up by each of the town_maps, sfx, and misc_i array, including any trailing padding?

 

Originally Posted By: Chokboyz
I also found (and fixed) a bug in Ormus' build that would prevent some scenario to be played when listing more than 25 scenarios (a maximum of 100 scenarios can now be listed and played).
Heh, I did that ages ago. Then I went even further, and now there's no limit on the number of scenarios that can be listed.

 

Originally Posted By: Chokboyz
I think I'll take some time this weekend to finish cleaning and test the code. Should nothing horrible arise, I will then post it in the repository and, why not, maybe release the first beta of (Win32) Classic Blades of Exile (the name means without major refactoring of the code). wink
Yes, please do. It's long overdue for entry into the repository.

 

And also, once it's in there, you should commit frequently.

 

And also, please add the scenario editor code at the same time.

Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
Ah, so that was the problem. The structs were padded differently on the Mac than on Windows. And yes, multidimensional arrays are also subject to padding at the end of the rows.
I suspected that ... Glad we found it smile

Originally Posted By: Celtic Minstrel
So, if you had a problem with 2 bytes being skipped in the party struct, that probably means that I'll have to skip two bytes. Where exactly did that problem occur? And also can you tell me exactly how much space is taken up by each of the town_maps, sfx, and misc_i array, including any trailing padding?

The 2 bytes skipping was between the end of the short m_killed[200] array and the beginning of the (unsigned) long total_m_killed.
Here is the map of a Mac legacy save file (while in town) : the three short flags, then the party struct with the previous 2 bytes skip.
Then there is (with no padding) setup_type and the 6 pc_record_type.
and :
  • out_e : first byte 74176, last byte 83391. (no padding with previous adven[5] struct as far as i can tell)
  • c_town : first byte 83392, last byte 99526
  • 1 byte padding (unused byte that is defined to 0. Is rightly skipped when reading the file, at least in Windows version ...)
  • t_d : first byte 99528, last byte 105583
  • t_i : first byte 105584, last byte 113173
  • stored_items[0] : first byte 113174, last byte 120763
  • stored_items[1] : first byte 120764, last byte 128353
  • stored_items[2] : first byte 128354 last byte 135943
  • town_maps : first byte 135944, last byte 238343
  • o_maps : first byte 238344, last byte 267143
  • sfx : first byte 267144, last byte 271239
  • misc_i : first byte 271240, last byte 275335
While doing this list, i found a bug (damn brackets !) during the loading process : the only thing that needs to be done is to correct the skipping of the 2 bytes when loading the party structure and the rest will load fine ... At least, that's what happen with the Windows build smile

Note that the structure of a Win32 savefile is quite different ...

Originally Posted By: Celtic Minstrel
Heh, I did that ages ago. Then I went even further, and now there's no limit on the number of scenarios that can be listed.

Ormus pushed the limit of scenarios up to 100 but forgot to adjust the (dynamically allocated) corresponding structure. I've only corrected that wink
No limit can easily be achieved by dynamic allocation but that's not on the todo list right now (or rather low priority, as more than 100 scenarios is quite hard to reach )...

Originally Posted By: Celtic Minstrel
And also, please add the scenario editor code at the same time.

If Ishad Nha allows me (read he isn't planning to upload a new version of his code), i would gladly do so ...

Hope it helps,
Chokboyz
Link to comment
Share on other sites

As for uploading more source code, I won't be doing it because I think I have done all that I can do, most of the stuff in the forum is now well over my head.

For a couple of months now, the fresh work has really come from Chokboyz, who knows what he is doing here, unlike me. As it is really his code he should be the one uploading it and taking credit for it.

Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
Oh? How so? Can you give me a map of that too?

Arf ... If i find some time tonight, i'll try to map the Windows savefile as well ...

Originally Posted By: Ishad Nha
As for uploading more source code, I won't be doing it because I think I have done all that I can do,[...]

Ok, i'll assume the last code you've uploaded here http://www.freewebs.com/ishadnha/2009BoESESource.zip is the most recent.
The only addition i could notice from the old version i had on my drive, was the code to display boats and horses in the view window when editing towns (i've adapted it and put it in the right function so that it now works smile ).

Originally Posted By: Ishad Nha
who knows what he is doing here, unlike me.
Let's say you're doing quite good for someone who doesn't know what he's doing grin

Originally Posted By: Ishad Nha
For what it is worth, yes. By now his own would be superior to mine anyway.

Originally Posted By: Ishad Nha
As it is really his code he should be the one uploading it and taking credit for it.
Don't be too modest, your work is all but negligible ... After all, there's more than a handful of bugs that you've found and fixed in the main game (let alone the implementation of the debug mode, that really makes my life easier when debugging in-game) and your additions to the scenario editor are simples, but neats.
Finally your work hexediting/exploring the Exile III data has helped us understand some older part of the code.
If you think you don't deserve credits after that ... wink

Originally Posted By: Celtic Minstrel
So, Chokboyz has your latest version of the scenario editor source and can upload it?

Yes, i've merged the last bit of Ishad Nha's code (boats and horses now displays on the view when editing towns) and will upload it, probably this weekend (maybe i'll also put the executable) ...

Chokboyz
Link to comment
Share on other sites

Originally Posted By: Chokboyz
The only addition i could notice from the old version i had on my drive, was the code to display boats and horses in the view window when editing towns (i've adapted it and put it in the right function so that it now works smile ).
Was this the one where a small icon is displayed, or the one where the full-size boat graphic is drawn?

Originally Posted By: Ishad Nha
who knows what he is doing here, unlike me.
Let's say you're doing quite good for someone who doesn't know what he's doing grin

Originally Posted By: Chokboyz
your additions to the scenario editor are simples, but neats.
What additions do you refer to?

Originally Posted By: Chokboyz
Yes, i've merged the last bit of Ishad Nha's code (boats and horses now displays on the view when editing towns) and will upload it, probably this weekend (maybe i'll also put the executable) ...
Finally.
Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
Was this the one where a small icon is displayed, or the one where the full-size boat graphic is drawn?
The full-size boat/horse graphic is actually displayed but a simple change to the destination rect would change it to a small icon.

Originally Posted By: Celtic Minstrel
What additions do you refer to?

Severals simple things, mainly in the new dropping menu "Additional Features" : fast access (via menu items) to town/outdoor/monsters/items editing, shortcuts (keyboard and menu items) to next town/outdoor when editing town/outdoor, fast jump to a given town/outdoor, fast zoom in/out, add access to the full 30 horses/boats, ...
Nothing groundbreaking, but it has proved very useful in several occasions ... smile

Chokboyz
Link to comment
Share on other sites

Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
Was this the one where a small icon is displayed, or the one where the full-size boat graphic is drawn?
The full-size boat/horse graphic is actually displayed but a simple change to the destination rect would change it to a small icon.
No, it should be the full-size boat, to match the behaviour of the Mac editor.

Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
What additions do you refer to?

Severals simple things, mainly in the new dropping menu "Additional Features" : fast access (via menu items) to town/outdoor/monsters/items editing, shortcuts (keyboard and menu items) to next town/outdoor when editing town/outdoor, fast jump to a given town/outdoor, fast zoom in/out, add access to the full 30 horses/boats, ...
Nothing groundbreaking, but it has proved very useful in several occasions ... smile
Ah. One or two of those I'm not going to implement as such. Actually, possibly the only one I won't do is the "next outdoor" one. I have a different plan in mind for that, which would be essentially the same as the behaviour of the most recent Mac Blades of Avernum Scenario Editor: basically, you will be able to simply scroll off the edge of the outdoor section and it will automatically load the next one in that direction (except that if there are unsaved changes it will confirm first).
Link to comment
Share on other sites

Okay, I'm having a problem with the legacy party record struct. It's around 250 bytes too small – the name of the scenario actually ends up occuring toward the end of the 256-character array in which it should be at the beginning. (For reference, "stealt" is all that is visible of the full "stealth.exs". Possibly the 'h' as well.)

 

It seems that all the padding should occur somewhere after the list of horse records, though I'm not quite certain of that. So, basically I need to determine what align attributes to give to which members in order to get the right padding. (The struct is currently packed, though this doesn't seem to have any effect on its layout – removing the attribute gives the same result.)

Link to comment
Share on other sites

I had read somewhere, and now can't find again, a claim that it was invalid to use __attribute__((packed)) in C++ code, which was why I used the align __attribue__. (Since I can't find this claim again or anywhere else, I'm inclined to think it was pure nonsense, now.)

 

At any rate the best method I can think of to check the paddings of structures is to use offsetof on every field and print the results, for both the old and new versions. That is, a lot of:

Code:
cout << offsetof(legacy::party_record_type,age) << endl;cout << offsetof(legacy::party_record_type,gold) << endl;
. . . and so on. Given we need to check every field of every structure, I'll see if I can hack together something to automatically generate the necessary printing code.
Link to comment
Share on other sites

As said, here is the Windows Savefile map (don't think there's padding in the party struct) :

  • 3 headers flags : first byte 0, last byte 5.
  • party : first byte 6, last byte 45913.
  • setup_save : first byte 45914, last byte 62297.
  • adven[0] : first byte 62298, last byte 64195.
  • adven[1] : first byte 64196, last byte 66093.
  • adven[2] : first byte 66094, last byte 67991.
  • adven[3] : first byte 67992, last byte 69889.
  • adven[4] : first byte 69890, last byte 71787.
  • adven[5] : first byte 71788, last byte 73685.
  • out_e : first byte 73686, last byte 82901.
  • c_town : first byte 82902, last byte 98915
  • t_d : first byte 98916, last byte 104971
  • t_i : first byte 104972, last byte 112561
  • stored_items[0] : first byte 112562, last byte 120151
  • stored_items[1] : first byte 120152, last byte 127741
  • stored_items[2] : first byte 127742, last byte 135331
  • town_maps : first byte 135332, last byte 237731
  • o_maps : first byte 237732, last byte 266531
  • sfx : first byte 266532, last byte 270627
  • misc_i : first byte 270628, last byte 274723

Originally Posted By: Celtic Minstrel
Okay, I'm having a problem with the legacy party record struct. It's around 250 bytes too small – the name of the scenario actually ends up occuring toward the end of the 256-character array in which it should be at the beginning. (For reference, "stealt" is all that is visible of the full "stealth.exs". Possibly the 'h' as well.)

If you're speaking about the Mac legacy savefile, i had a somewhat similar problem in that the first two letters of the scenario name were squished (because of the 2 bytes skipped between the array and the first long).

Just read the party struct and check what field is off (the joy of hexediting is yours now wink ).

 

Hope it helps,

Chokboyz

Link to comment
Share on other sites

Thanks Chokboyz. I'll put that to use soonish.

 

I was in fact reading the party struct and checking in the debugger which variables were off, but it was hard to tell because I wasn't sure what their values should be.

 

Originally Posted By: Niemand
I had read somewhere, and now can't find again, a claim that it was invalid to use __attribute__((packed)) in C++ code, which was why I used the align __attribue__. (Since I can't find this claim again or anywhere else, I'm inclined to think it was pure nonsense, now.)
Well, they theoretically have opposite effects: packed eliminates padding, whereas aligned suggests padding.

 

Originally Posted By: Niemand
for both the old and new versions.
So, with and without the -fpack-struct=2 flag? (That is what the flag was, right?)

 

Oh, it might be useful to do it like this instead: wink

Code:
cout << "offsetof(legacy::party_record_type,age) = " << offsetof(legacy::party_record_type,age) << endl;
. . . and so on. More readable... though I guess it doesn't matter that much.
Link to comment
Share on other sites

I was able to re-purpose a parser I had handy, so writing a generator program turned out to be pretty easy. Here's the code:

Click to reveal..
Code:
#include <iostream>#include <fstream>//really quick-and-dirty hard coded test for whether tok is a type namebool isType(const std::string& tok){	if(tok=="char")		return(true);	if(tok=="short")		return(true);	if(tok=="unsigned")		return(true);	if(tok=="talking_node_type")		return(true);	if(tok=="location")		return(true);	if(tok=="out_wandering_type")		return(true);	if(tok=="Rect")		return(true);	if(tok=="wandering_type")		return(true);	if(tok=="creature_start_type")		return(true);	if(tok=="sity_block_type")		return(true);	if(tok=="city_ter_rect_type")		return(true);	if(tok=="item_record_type")		return(true);	if(tok=="bool")		return(true);	if(tok=="monster_record_type")		return(true);	if(tok=="creature_data_type")		return(true);	if(tok=="boat_record_type")		return(true);	if(tok=="horse_record_type")		return(true);	if(tok=="outdoor_creature_type")		return(true);	if(tok=="talk_save_type")		return(true);	if(tok=="long")		return(true);	if(tok=="terrain_type_type")		return(true);	if(tok=="item_storage_shortcut_type")		return(true);	if(tok=="town_record_type")		return(true);	if(tok=="creature_list_type")		return(true);	if(tok=="char")		return(true);	if(tok=="preset_item_type")		return(true);	if(tok=="preset_field_type")		return(true);	if(tok=="special_node_type")		return(true);	if(tok=="city_block_type")		return(true);	return(false);}int main(int argc, char* argv[]){		std::string pathToOldStructs="Path to oldstructs.h";	std::ifstream ss(pathToOldStructs.c_str());		if(!ss.good()){		std::cerr << "Unable to open " << pathToOldStructs << std::endl;		exit(2);	}		std::string curStruct="";		int inComment=0;	bool inQuote=false;	unsigned int state=0; 	// 1 = read "struct", expect struct name	// 2 = read struct name, expect "{"	// 3 = inside struct, expect type name or '}'	// 4 = inside struct, read type name, expect type name or field name	// 5 = inside struct, read field name, expect ',', or ';'	while(!ss.eof() && !ss.fail()){		std::string token;		char nextChar,lastChar;		while(true){ //miniature scanner to read in a token			lastChar=nextChar;			nextChar=ss.peek();			if(ss.eof() || ss.fail())				break;			if(isspace(nextChar)){				if(!token.empty())					break;				if(inComment==1 && (nextChar=='\n' || nextChar=='\r'))					inComment=false;				ss.get(nextChar);				continue;			}			if(isalnum(nextChar) || nextChar=='_'){				if(!ispunct(lastChar) || lastChar=='_' || token.empty()){					ss.get(nextChar);					token=token+nextChar;					continue;				}				if(lastChar=='"' && !inQuote){					ss.get(nextChar);					token=token+nextChar;					inQuote=true;					continue;				}				else					break;			}			if((ispunct(nextChar) || nextChar!='_')){				if(ispunct(lastChar) && lastChar!='_'){					//separate quoted strings from adjacent operators:					if((lastChar=='"' || nextChar=='"' || nextChar==';') && !token.empty())						break;					ss.get(nextChar);					token=token+nextChar;					if(token=="//" || token=="/*" || token=="*/")						break;					continue;				}				if(nextChar=='"' && inQuote){					ss.get(nextChar);					token=token+nextChar;					inQuote=false;					continue;				}				else					break;			}		}		if(token.empty() || inComment==1)			continue;		if(inComment==2){			if(token=="*/")				inComment=0;			continue;		}		if(token=="/*"){			inComment=2;			continue;		}		if(token=="//" || token=="#"){ //treat preprocessor macros like comments			//note that multi line preprocessor stuff will still throw us off			inComment=1;			continue;		}				if(state==0 && token=="struct"){			state=1;			continue;		}		if(state==1){			curStruct=token;			std::cout << "std::cout << \"Struct: " << curStruct << "\" << '(' << sizeof(legacy::" 			  << curStruct << ") << ')' << std::endl;" << std::endl;			state=2;			continue;		}		if(state==2){			if(token!="{"){				std::cerr << "encountered unexpected token '" << token 				  << "' in state 2" << std::endl;				exit(1);			}			state=3;			continue;		}		if(state==3){			if(token=="}"){				state=0;				continue;			}			if(isType(token)){				state=4;				continue;			}			std::cerr << "encountered unexpected token '" << token 			  << "' in state 3" << std::endl;			exit(1);		}		if(state==4){			if(isType(token))				continue;			std::cout << "std::cout << \"\t" << token << ": \" << offsetof(legacy::" 			  << curStruct << ',' << token << ") << std::endl;" << std::endl;			state=5;			continue;		}		if(state==5){			if(token==",")				state=4;			else if(token==";")				state=3;			continue;		}	}	return(0);}

 

Just fill in the correct path to your copy of oldstructs.h and this program will read it and generate the code to print the offsets of all the field of all the structs, organized by the structs they belong to. The total size of each struct type is also included. Once this code is generated (about 400 lines) you can paste it into the main function or somewhere, run the program with different settings or versions of oldstructs.h, and then diff the output to find out which if any fields have moved or if struct sizes change.

 

I'll try to get time this weekend to do the analysis myself, but I wanted to make this available to everyone else in case I don't get to.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...