Jump to content

Spriter Generic C++ API


Recommended Posts

Let me know what changes are needed. I don't know any other XML API (and I know streaming like Expat is so different), so I can't factor that out myself.

Yeah I'm afraid I'll be changing SCMLpp a bit to fit Shiva, which is unfortunate. I'm not sure how long I'll be able to stay in sync with your updates. I've already had to adding begin-load and checkLoadStatus functions as shiva needs frame cycles to do external stuff, but as that is Shiva specific, I didn't mention it before.

I'll continue to make suggestions where I think I find something generic though.

Link to comment
Share on other sites

  • Replies 63
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted Images


I finally got everything together, and the DOCS have been generated, although I'm not sure why Doxygen didn't go ahead and finish the *.CHM help file generation from the html files, I set all those options up inside the Doxyfile, and it said it was launching the hhc.exe file, and it generates the hhk, hhc, index files, and I have graphviz setup, and it did all those, and I now have a fully browsable copy of the help and sourcecode references, I changed the options to even include the non documented sourcecode, full classes and functions, etc.. Kind of nice setup once it is done.. maybe it generated the *.chm file I just don't know where it put it at.. hmmm... Anyways, I included the full tree options etc..

Now, when I get time to sift through things, I'll get to hammering down on the AGK revisions.. Just now though, I am hammering home some changes to my latest game, adding the spike objects, and scripts, and laying out the rest of the levels, objects needed..

Thanks for the patience, it's not that I'm an C++ newbie by any stretch of the words, it's just that it's been a while since I have gotten neck deep into a serious project.. Last project I wrote was the Unit Editor for Total Annihilation that I reverse engineered the *.3do file format, and made a DXF->3do file format convertor, then made it into a full blown editor, which cavedog informed me was better than what they used internally.. ;')

either that or snesKEY, not sure which was the last project...

Yes, I'm that StOrM3 ;')

Ciao' 4 now,


Link to comment
Share on other sites


I've made the following changes to correct the errors

1. Replaced my line 26

source.erase(std::find(source.rbegin(), source.rend(), '/').base(), source.end());


source.erase(source.rfind('/'), source.length());

Slight update on this one, because I am doing some stupid testing and hit a problem. For edge cases, where a directory is being passed in that isn't actually a directory, this line will fail without a dirname with a '/' in it. So a little extra validation gives us :-

unsigned found = source.rfind('/');
if (found!=std::string::npos) {
source.erase(found, source.length());
return source;
} else {
return "";

I think that's what it should be doing, you might want to double check. There will still probably be errors further along if you do something silly like I am, but that's an internal issue. This fix fill just stop the erase failing.


Link to comment
Share on other sites

Now I've got the basics of loading a single SCML file and texture atlas done, I'm expanding my APi to multiples of everything - files/entities/animations.

I notice in your SDL main, you push all 3 SCML files onto the data file stack, but only render them one at a time, clearing everything between selection. Have you considered what is necessary for loading multiple SCML files at once, or even jus if/when Spriter gets multiple entities in the one file? It looks to me like there would be a couple of things needed :-

1. The Data object is only needed at load time, isn't it, and the actual data SCML ends up stored in the "list entities" list? So to load multiple SCML files at once, we would need to clear out the Data object and keep appending to the entities list? I'm still trying to see how the FIlesystem fs object links in, but I think we need a separate instance for each set of entity images, don't we?

*EDIT* after looking closer, I see the stand-alone Entity class constructor is referencing a Data object, so we need to keep a reference to all Data objects until we are no longer using them? In which case, I guess there needs to be a vector list of data objects created, and indexes used to reference where appropriate?

2. If loading multiple SCML files, the Entity ID's are going to duplicate, so we would need to be able to add some form of uniqueness to the ID's. Not sure if the SCML data itself will provide enough uniqueness, via the name/ID combo, or maybe SCML filename, or whether it would be better to just add a run-time unique value.

3. I'm currently identifying my in-game assets using the folderID/fileID for uniqueness. This is not sufficient for even more than one entity, let alone multiple files, so some unique identifier needs to be added here as well.

Any other thoughts on things I should look out for in trying to implement multiple files/entities?

Thanks. Russell.

Link to comment
Share on other sites

  • 2 weeks later...

Just an update on my own questions since I've progressed a little bit.

1. I have added a vector list of data_object pointers to keep the data object as an external reference. Not sure, but I might be able to remove this a a later date.

2. I've updated the entity::load functions to split the "entity" index value, into entityID, and data_entityID. This allows me to keep the original ID in the SCML file, pointing to the direct SCML info, but use an incrementing index into the "entities" vector as the actual entityID field in the "Entity" stand-alone class. This was fairly easy, and I think should give me a unique index for multiple file loads, across the whole application.

3. This one I'm currently struggling with, as it is used widely across the code, and during updates. From what I can see at the moment, the folderID/fileID is assumed to be unique across the app, which is obviously not true once you load more than one SCML file at the same time. Given the folder/file is associated more with the SCML data file than the Entities themselves, it's a bit trickier deciding how to uniquely identify these across data files.

I am assigning an SCML ID for each file loaded, so I'm thinking the best bet at the moment is to add the SCML ID as an extra field in the FIlesystem class, and use that in combination with the folder/file ID's to create uniqueness, but this will be more work. I'm not 100% committed to that yet, so I'm going to give it some more thought. If anyone else has any other ideas, I'd love to hear them.

Link to comment
Share on other sites

Oh sorry, I thought I had hit send on my reply to that last one. Oops. :(

The Data objects are not needed after the Entities are created. Consider Data to be a definition and Entity to be the instance. You can create multiple instances from one definition and delete the definition any time. The definition is simply the interface to the actual SCML file. The Entity is the interface with the display/user.

Entities do need a unique ID for many applications, but that is specific to the use-case. Entities are technically uniquely identified by the pointer value, so it is up to the game developer (i.e. user of this library) to decide how to store and identify them for the purposes of the particular game. However, if you think this is much easier to do already for the user, we could do it.

Yes, the FileSystem storage class does not work as intended. It directly stores the SCML file/folder IDs, which are not common across multiple SCML files. What it needs to do is to provide a translation from the SCML IDs to the unique FileSystem IDs, which would be used by the Entity class.

Link to comment
Share on other sites

  • 5 months later...

Hey, thanks a ton for writing this library and releasing it under such a permissive license, I really appreciate it.

I'm just starting to use it, and I've noticed that there are a few bugs in the SFML renderer.

In SCML_SFML.cpp, in FileSystem::loadImageFile on lines 18-21: you do a null check after dereferencing the pointer. This obviously make no sense, as new throws on failure, not returns NULL anyway. If the check succeeded, then you would leak img. As it is, you never check if the filename is valid.

I think what you meant to do is check if the loadFromFile call succeeded. The right way to do that would be something like:

if (!img->loadFromFile(filename)) {
delete img;
return false;

... Not to mention that img can be leaked several other ways. If images throws when inserting the img (e.g. because the map failed to allocate a new node), or if img->loadFromFile freakishly throws (It shouldn't but could if it allocates memory)... But I digress. (There's no way I could convince you to use smart pointers, is there? c++11's std::unique_ptr is exception safe and has no overhead, after all... probably not, as you won't even commit to using the standard library of all things!).

Anyway, thought you might want to know. This is the only issue I see in the renderer. Eventually I'm sure I'll end up needing to peek in SFMLpp.{h,cpp}, and if I see anything in there I'll post about it here too.

Thanks again for taking the time to write SFMLpp.

Link to comment
Share on other sites

I'm not personally against using C++11 or STL (I would prefer that, in fact), but I did get a request to make the backend more generic so that the STL would not be required. There are some cases where one would be justified in avoiding the STL... though most of those may be considered premature optimization.

I haven't been maintaining SCMLpp lately, so if you want write access to the repo, just send me an email.

Link to comment
Share on other sites

Maybe passing nothrow to new would be better than adding exception handling?

Probably just providing (weak) exception safety without throwing exceptions would be best, IMO.

There are some cases where one would be justified in avoiding the STL, though most of those may be considered premature optimization

It's usually someone who blames the STL because they chose the wrong datastructure or algorithm at one point. Also the std associative (set, map, ordered and unordered) containers tend to be slow, and require mallocs on every insertion, which is very unfortunate.

Still, these people will almost always be more happy with their own implementations anyway, so I'm not sure those people are worth catering to.

I haven't been maintaining SCMLpp lately, so if you want write access to the repo, just send me an email.

Regardless, I'm not sure how much of your code I'd be able to reuse if I took over your implementation. Well thats not really true, to be honest I have a fairly hard time understanding (huge single file, lots of nested classes many with same name) and am very uncomfortable when I make changes to it. But there's a lot I would change (you use heap the much more than I would, you use a map where I would use a vector, I rarely, if ever, use nested classes, etc).

I've made some changes to make it work better with the most recent version of SCML files (nothing major, just fall back to the pivot_x and pivot_y values in a file when missing in an object), but after struggling with the code for a while (unable to get x-flipping to work, unable to understand what your code does to handle it (should rotate_point() be doing something about the flip parameter?)) I've more or less given up and started working on a separate implementation, which I'll try to release in the near future.

Link to comment
Share on other sites


First of all, thank you for all the effort of putting together scml-pp.

I'm trying to use the library in my game and I found some bugs along the way.


As far as I can tell void Entity::update(int dt_ms) does not handle

updates that skips two or more keys. So if keys are very close in time

or the application is not calling update very often the wrong key will

be used for drawing.


In both void Entity::draw_tweened_object and void Entity::Bone_Transform_State::rebuild

sprites and bones are tweened between their Mainline references. This is however incorrect as the

references might be pointing to the same key in which case the tweening will be halted.

In Bone_Transform_State::rebuild the line

Animation::Mainline::Key::Bone_Ref* ref2 = nextitem.bone_ref;

should be removed and the line

Animation::Timeline::Key* b_key2 = entity_ptr->getTimelineKey(animation, ref2->timeline, ref2->key);

should be replaced with code that fetches the next Timeline key after b_key1.

I modified getTimelineKey to handle out of index keys and changed the line to

Animation::Timeline::Key* b_key2 = entity_ptr->getTimelineKey(animation, ref1->timeline, ref1->key+1);

My animation renders correctly after this dirty hack.

The logic in Entity::draw_tweened_object needs to be updated in the same way.

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.
Note: Your post will require moderator approval before it will be visible.

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.


  • Recently Browsing   0 members

    • No registered users viewing this page.

  • Create New...