Function "sprite_add" Not Successfully Loading Sprites.

Reporter: Kayomn  |  Status: open  |  Last Modified: June 19, 2017, 08:06:37 AM

So I often load sprites externally in Game Maker like so...

ds_map_add(Game.sprite,varName,sprite_add(varPath,varImgs,false,false,varX,varY,false));

Creating a sprite dictionary, and running a check to see if the sprite name already exists, if so, reusing the resource already allocated. Enigma, however doesn't seem to like this.

Here's the full code snippet, in case further elaboration is needed.

/// sprite_get(path,img);

var varPath = argument[0];
var varImgs = argument[1];

var varX = 0;
var varY = 0;
var varSprite, varName, varBreak;

if (Game.sprite > -1) {
// Grab the position of the last slash in the path.
for (var i = string_length(varPath); i > 0; i--) {
if (string_char_at(varPath,i) == '/' || string_char_at(varPath,i) == '') { //'
varBreak = i;
break;
}
}
// Set the map index name to file name.
varName = string_copy(varPath,varBreak,string_length(varPath));

if (!ds_map_exists(Game.sprite,varName)) {
	varSprite = sprite_add(varPath,varImgs,false,false,0,0,false);
	
	if (sprite_get_width(varSprite) > 0 && sprite_get_height(varSprite) > 0) {
		varX = sprite_get_width(varSprite)/2;	
		varY = sprite_get_height(varSprite)/2;
	}
	ds_map_add(Game.sprite,varName,sprite_add(varPath,varImgs,false,false,varX,varY,false));
	sprite_delete(varSprite);
}

if (sprite_exists(ds_map_find_value(Game.sprite,varName))) {
	return ds_map_find_value(Game.sprite,varName);
}

}
return no_sprite;

Kayomn  
Update:

The issue appears to be with accessing sprites via their numeric indexes and not with assigning sprite index values to map.

This issue is also present whole trying to assign sprites in the asset tree via their integer index.

JoshDreamland  

What is ENIGMA actually doing that you don't expect? The code you are running appears correct, ignoring the roundabout way you are changing your sprite's x and y offset. In fact, you might be tickling a bug, there. Does the issue go away if you remove that sprite_delete line?
Kayomn  

Yeah, after I posted it I realized there was an easier way to change the x and y offset. Removed it and issue still persists.

Essentially if you do...
return spr_sprite;

It works find, but try and return a number representative of the sprite index for use in a draw function, such as the kind assigned based on the resource position in the list, and it immediately crashes at runtime.

JoshDreamland  

Well, spr_sprite is just a number. There's nothing special about it. If using that number directly does what you expect, but using another number does not, then the problem is in how that number is persisted. How did you verify that the number you're retrieving later is identical?
Kayomn  

I printed the value in the program using draw text.
JoshDreamland  

There may be some sort of corruption happening in the internal sprite storage. How many sprites are you adding after the one that crashes the game when you go to use it? Does just adding that many sprites and drawing the first of those cause the crash?
Kayomn  

That was my thought just now. I'll test the script when at my computer later further. As far as I know the issue happens when the value is returned from the script and used in the draw function. I imagine it is an issue with loading but will collect more info later.
Kayomn  

Right now I'm only loading 1 sprite and then attempting to draw it.
Kayomn  

So yeah, I've done further testing (drunk testing so take with a grain of salt) and the issue appears to be with the sprite_add function.

If you were to try to assign an invalid / non-existing sprite asset index to the draw_sprite function the same issue would occur as what I am having.

So it appears the issue lies within the sprite_add function itself.

JoshDreamland  

If it's only one sprite, then there's no reason at all that accessing it by that return value would behave differently than accessing it from the map. If the value returned by sprite_add is positive, then it should be safe to call sprite functions on that result. So just to clarify: you have some integer, sprite_exists(integer) returns true, but drawing that integer fails?
JoshDreamland  

Also, what graphics system are you using? GL3?
Kayomn  

https://pastebin.com/WNKz39Bk

I've uploaded the /revisied/ script to Pastebin for easier reading, since Github appears to be mis-formatting it. I got rid of unnecessary stuff like humanizing the map string to only include the file name, since it would have caused unexpected conflicts with items in other folders using the same filenames. I also ditched the re-loading of the sprite and no longer delete anything while loading. The issue still persists loading like this, regardless.

In the attached screenshot I am printing the sprite index to the screen as well as conditional check that only shows based on whether or not the runtime thinks the sprite exists.

screenshot at 2017-06-19 08-57-09

In my project I only have 1 sprite held within the IDE, that being the no_sprite sprite. All other sprite assets are to be loaded externally. As I started this project a day ago I'm currently only trying to load 1 sprite, ergo why I found this error. With the script returning 1 we can assume it at least thinks its loaded it, as the sprite_exists has been tested at multiple stages of loading the image. Even after the initially load it still thinks it's there. Nevertheless, the game would freak out if I were to use that asset ID in a draw_sprite function, like it would if the asset index didn't exist.

I'm using GL1.1 right now. I'll try with another one and report my findings.

Kayomn  

The issue persists with OpenGL 3.3, instantly crashing at runtime like 1.1.

OpenGLES fails to compile, due to it not being able to find any of its headers in "Graphics_Systems/OpenGLES/". I suspect this particular one may just be me missing the dependencies to compiler with it, however.

JoshDreamland  

Okay. At least there's consistency. I have no idea what's wrong, but looking at the code, I see a lot of failure surface. For starters, the sprite system is doing its own memory management. There's just no need for that. I'll see about getting that patched over in a pull request later this week.
Please sign in to post comments, or you can view this issue on GitHub.