Match failure.

Match failure.

Stretched Sprite Origin Fix

Reporter: RobertBColton  |  Status: open  |  Last Modified: November 21, 2018, 08:25:37 AM

This is just a small fix to address #1099 which I have confirmed is in fact a bug. Mark Overmars is very explicit in the manual that draw_sprite_stretched "fills" the area as opposed to draw_sprite which places the origin at the position specified.

This simple fix just removes the offset of the primitive drawn by the sprite's origin. I've additionally added a test to the drawing test so we know if somebody tries to change it again. Although I do not actually change draw_sprite_stretched_ext here, it is still affected because it's just a wrapper that calls draw_sprite_stretched with its color and alpha.

In my opinion, GameMaker is correct about this behavior as the sprite origin is basically useless when drawing the sprite stretched over an area. I feel this is especially true considering the sprite origin is not scaled with the rest of the sprite, so it's better to just not use it both for compatibility and because it's saner.


The GameMaker 6 through 8 manuals state the following:

draw_sprite(sprite,subimg,x,y) Draws subimage subimg (-1 = current) of the sprite with its origin at position (x,y). (Without color blending and no alpha transparency.)
draw_sprite_stretched(sprite,subimg,x,y,w,h) Draws the sprite stretched so that it fills the region with top-left corner (x,y) and width w and height h.

The new GameMaker: Studio manual is even more explicit:

NOTE: When drawing with this function, the sprite x offset and y offset are ignored and the sprite will be drawn with the top left corner at the specified x / y position in the room.

This function ignores the sprite's origin.


master Stretched Sprite Origin

This pull request

pr Stretched Sprite Origin

GameMaker 8

GM8 Stretched Sprite Origin

GameMaker: Studio

GMS Stretched Sprite Origin

UNMATCHED: Regression tests have indicated that graphical changes have been introduced. Carefully review the following image comparison for anomalies and adjust the changeset accordingly.

d341e4a Master Diff
Image Diff Image Diff Screen Save


The bot is correct that changes have been introduced to the drawing test, but this time, they are intentional.

Codecov Report

Merging #1447 into master will increase coverage by 0.15%.
The diff coverage is 57.14%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1447      +/-   ##
+ Coverage   17.18%   17.34%   +0.15%     
  Files         164      164              
  Lines       17099    17103       +4     
+ Hits         2939     2967      +28     
+ Misses      14160    14136      -24
Impacted Files Coverage Δ
ENIGMAsystem/SHELL/Platforms/General/PFwindow.h 100% <ø> (ø) ⬆️
ENIGMAsystem/SHELL/Platforms/xlib/XLIBwindow.cpp 48.38% <ø> (ø) ⬆️
...system/SHELL/Widget_Systems/None/nowidget_impl.cpp 3.63% <0%> (ø) ⬆️
ENIGMAsystem/SHELL/SHELLmain.cpp 80% <0%> (-20%) ⬇️
...system/SHELL/Graphics_Systems/General/GSsprite.cpp 6.87% <100%> (+6.87%) ⬆️
...Asystem/SHELL/Graphics_Systems/General/GSmodel.cpp 48.21% <0%> (+0.77%) ⬆️
...em/SHELL/Graphics_Systems/General/GSprimitives.cpp 65.04% <0%> (+4.85%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6ce7aac...65ce560. Read the comment docs.


Alright, so I performed some additional testing on GameMaker 5 because of what I noticed in my comment on #1099. It seems Mark Overmars scaled the sprite origin in GM5 as you can see in the following screen. I will add a compatibility fix for that.
GM5 Stretched Sprite Origin


Alright, I've added a compliance setting for the behavior now for GameMaker 5 projects. I had to make several adjustments to the way GM_COMPATIBILITY_VERSION is implemented though.

  • Had to include "Preprocessor_Environment_Editable/GAME_SETTINGS.h" for GM_COMPATIBILITY_VERSION to be checked in GSsprite.cpp.
  • Had to change the macro void ABORT_ON_ALL_ERRORS() to stop multiple definition errors. I changed it to just define the value and then check it in the engine inside abort_on_errors.
  • I included GAME_SETTINGS.h in PFwindow.h so that I could check the GM_COMPATIBILITY_VERSION for window_handle(). Apparently SHELLmain.cpp is including PFwindow.h at some time before it, although I noticed API_Switchboard.h is in fact including PFwindow.h after GAME_SETTINGS.h in SHELLmain.cpp.

UNMATCHED: Regression tests have indicated that graphical changes have been introduced. Carefully review the following image comparison for anomalies and adjust the changeset accordingly.
65ce560 Master Diff
Image Diff Image Diff Screen Save


Including that header will cause files to be rebuilt each time that header changes. Depending on what's in that file, that is probably every time. This change, then, would vastly slow the build. Don't do less-than checks on the compatibility version without first checking that it is defined(), and otherwise, don't include that header.
Please sign in to post comments, or you can view this issue on GitHub.