Draw_surface_part_ext() Scaling and Boundary Problem

So I'm having some trouble with some maths here. I have a sprite that I have made through code saved to a variable (global.star_bg_sprite[0]). I want to draw a few variations of that sprite to a few surfaces, then draw those surfaces at different scales, but I also need it to draw only a section of the surface, with that section scrolling along the sprite but staying in the same place within the room and within the bounds of the area it should be drawn in. I also want it to loop back over to the start when it reaches the end. For context, the sprite is a star field, with "rotation" being applied to it by moving the drawn section of the sprite. Here's a gif of it working sans some of the stuff I need:

The section on the right is what I'm talking about. I've got it working with the surface having an origin of 0,0 and no scaling applied with this code:
GML:
if (!surface_exists(star_surf)) {
    star_surf = surface_create(surfw,surfh);
    surface_set_target(star_surf);
        draw_clear_alpha(c_white,0);
        draw_sprite(global.star_bg_sprite[0],0,0,0);
    surface_reset_target();
}
if (scroll+cw > surfw) { // Draws two surfaces to account for when the scroll starts going off the edge of the sprite but hasn't fully looped back yet
    var size = (scroll+cw)-(surfw);
    draw_surface_part_ext(star_surf,0,0,size,surfh,gx+cw-size,gy,1,1,c_white,1);
    draw_surface_part_ext(star_surf,scroll,0,cw-size,surfh,gx,gy,1,1,c_white,1);
    scroll = scroll mod (surfw);
}
else { // Draws a single surface whenever scroll+cw is firmly within the bounds of the sprite
    draw_surface_part_ext(star_surf,scroll,0,cw,surfh,gx,gy,1,1,c_white,1);
}
scroll tracks how much the player has scrolled to the left or right (looping around if it goes negative or exceeds the surface width), cw is the width of the "section", ch (although it doesn't appear in this code) contains the height of the "section" and gx and gy are the coordinates on the screen where the surface should start being drawn from, here's an image to make that all a little clearer:

So, what I want to have happen is for the surface to be drawn with an origin at the middle of cw and ch. Its bounds need to not go outside of the coordinates of gx, gx+cw, gy and gy+ch (the last two are less important, as it wouldn't show anyway since it's offscreen, but still). I need to be able to scroll it in either direction horizontally with the double surface drawing thing happening once it reaches the edge so it loops seamlessly and I need to be able to scale it at will without it breaking through its boundaries because of the scaling. Whenever I try to apply scaling, it either breaks the scrolling or it breaks the boundaries of the area it needs to be contained in because I cannot figure out how draw_surface_part_ext() deals with all these things. Once I can figure that out, drawing the multiple surfaces should be relatively easy.

I would really appreciate some help with the maths of the situation going on here.
 
Last edited:

Nocturne

Friendly Tyrant
Forum Staff
Admin
Would it not be simpler to keep the surface a fixed size (whatever is required) and then draw the SPRITE offset onto the surface? That way you can use the draw_sprite_tiled() function and not have to worry about the edges as the sprite is offset onto the surface, since it'll automatically repeat, and the surface itself can be drawn at a fixed size and position...
 
Top