1
0
Fork 0
mirror of https://github.com/ctruLua/ctruLua.git synced 2025-10-27 16:39:29 +00:00

Added hotspot arguments when drawing rotated textures

Did related changes to sprite.lua and cleaned stuff.

I had to add a function to sf2dlib to make this work, so a make build-sf2dlib is required. Also, we should probably send this change to the original sf2dlib repository...
This commit is contained in:
Reuh 2016-04-25 19:43:09 +02:00
parent 4d1e3ec455
commit d0fb704205
4 changed files with 103 additions and 49 deletions

View file

@ -588,6 +588,24 @@ void sf2d_draw_texture_part_rotate_scale(const sf2d_texture *texture, int x, int
*/ */
void sf2d_draw_texture_part_rotate_scale_blend(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale, u32 color); void sf2d_draw_texture_part_rotate_scale_blend(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale, u32 color);
/**
* @brief Draws a part of a texture, with rotation, scaling, color and hotspot
* @param texture the texture to draw
* @param x the x coordinate to draw the texture to
* @param y the y coordinate to draw the texture to
* @param rad rotation (in radians) to draw the texture
* @param tex_x the starting point (x coordinate) where to start drawing
* @param tex_y the starting point (y coordinate) where to start drawing
* @param tex_w the width to draw from the starting point
* @param tex_h the height to draw from the starting point
* @param x_scale the x scale
* @param y_scale the y scale
* @param center_x the x position of the hotspot
* @param center_y the y position of the hotspot
* @param color the color to blend with the texture
*/
void sf2d_draw_texture_part_rotate_scale_hotspot_blend(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale, float center_x, float center_y, u32 color);
/** /**
* @brief Draws a texture blended in a certain depth * @brief Draws a texture blended in a certain depth
* @param texture the texture to draw * @param texture the texture to draw

View file

@ -599,18 +599,18 @@ void sf2d_draw_texture_part_scale_blend(const sf2d_texture *texture, float x, fl
sf2d_draw_texture_part_scale_generic(texture, x, y, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale); sf2d_draw_texture_part_scale_generic(texture, x, y, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale);
} }
static inline void sf2d_draw_texture_part_rotate_scale_generic(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale) static inline void sf2d_draw_texture_part_rotate_scale_hotspot_generic(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale, float center_x, float center_y)
{ {
sf2d_vertex_pos_tex *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_tex), 8); sf2d_vertex_pos_tex *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_tex), 8);
if (!vertices) return; if (!vertices) return;
int w2 = (tex_w * x_scale)/2.0f; int w = tex_w;
int h2 = (tex_h * y_scale)/2.0f; int h = tex_h;
vertices[0].position = (sf2d_vector_3f){(float)-w2, (float)-h2, SF2D_DEFAULT_DEPTH}; vertices[0].position = (sf2d_vector_3f){(float)-center_x * x_scale, (float)-center_y * y_scale, SF2D_DEFAULT_DEPTH};
vertices[1].position = (sf2d_vector_3f){(float) w2, (float)-h2, SF2D_DEFAULT_DEPTH}; vertices[1].position = (sf2d_vector_3f){(float) (w - center_x) * x_scale, (float)-center_y * y_scale, SF2D_DEFAULT_DEPTH};
vertices[2].position = (sf2d_vector_3f){(float)-w2, (float) h2, SF2D_DEFAULT_DEPTH}; vertices[2].position = (sf2d_vector_3f){(float)-center_x * x_scale, (float) (h - center_y) * y_scale, SF2D_DEFAULT_DEPTH};
vertices[3].position = (sf2d_vector_3f){(float) w2, (float) h2, SF2D_DEFAULT_DEPTH}; vertices[3].position = (sf2d_vector_3f){(float) (w - center_x) * x_scale, (float) h - center_y * y_scale, SF2D_DEFAULT_DEPTH};
float u0 = tex_x/(float)texture->pow2_w; float u0 = tex_x/(float)texture->pow2_w;
float v0 = tex_y/(float)texture->pow2_h; float v0 = tex_y/(float)texture->pow2_h;
@ -650,13 +650,19 @@ static inline void sf2d_draw_texture_part_rotate_scale_generic(const sf2d_textur
void sf2d_draw_texture_part_rotate_scale(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale) void sf2d_draw_texture_part_rotate_scale(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale)
{ {
sf2d_bind_texture(texture, GPU_TEXUNIT0); sf2d_bind_texture(texture, GPU_TEXUNIT0);
sf2d_draw_texture_part_rotate_scale_generic(texture, x, y, rad, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale); sf2d_draw_texture_part_rotate_scale_hotspot_generic(texture, x, y, rad, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale, tex_w/2.0f, tex_h/2.0f);
} }
void sf2d_draw_texture_part_rotate_scale_blend(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale, u32 color) void sf2d_draw_texture_part_rotate_scale_blend(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale, u32 color)
{ {
sf2d_bind_texture_color(texture, GPU_TEXUNIT0, color); sf2d_bind_texture_color(texture, GPU_TEXUNIT0, color);
sf2d_draw_texture_part_rotate_scale_generic(texture, x, y, rad, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale); sf2d_draw_texture_part_rotate_scale_hotspot_generic(texture, x, y, rad, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale, tex_w/2.0f, tex_h/2.0f);
}
void sf2d_draw_texture_part_rotate_scale_hotspot_blend(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale, float center_x, float center_y, u32 color)
{
sf2d_bind_texture_color(texture, GPU_TEXUNIT0, color);
sf2d_draw_texture_part_rotate_scale_hotspot_generic(texture, x, y, rad, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale, center_x, center_y);
} }
static inline void sf2d_draw_texture_depth_generic(const sf2d_texture *texture, int x, int y, signed short z) static inline void sf2d_draw_texture_depth_generic(const sf2d_texture *texture, int x, int y, signed short z)

View file

@ -26,7 +26,7 @@ local function draw(self, x, y, rad)
local tsx, tsy = self.texture:getSize() local tsx, tsy = self.texture:getSize()
local sx, sy = getBox(tsx, tsy, frame, self.frameSizeX, self.frameSizeY) local sx, sy = getBox(tsx, tsy, frame, self.frameSizeX, self.frameSizeY)
self.texture:drawPart(x, y, sx, sy, self.frameSizeX, self.frameSizeY, rad) self.texture:drawPart(x, y, sx, sy, self.frameSizeX, self.frameSizeY, rad, self.offsetX, self.offsetY)
return frame return frame
end end
@ -52,12 +52,19 @@ local function resetTimer(self)
self.frameTimer = ctr.time() self.frameTimer = ctr.time()
end end
local function setOffset(self, x, y)
self.offsetX = x or 0
self.offsetY = y or self.offsetX
end
-- Sprite object constructor -- Sprite object constructor
function mod.new(texture, fsx, fsy) function mod.new(texture, fsx, fsy)
return { return {
texture = texture, texture = texture,
frameSizeX = fsx, frameSizeX = fsx,
frameSizeY = fsy, frameSizeY = fsy,
offsetX = 0,
offsetY = 0,
animations = {}, animations = {},
currentAnimation = 0, currentAnimation = 0,
currentFrame = 1, currentFrame = 1,
@ -66,6 +73,7 @@ function mod.new(texture, fsx, fsy)
draw = draw, draw = draw,
addAnimation = addAnimation, addAnimation = addAnimation,
setAnimation = setAnimation, setAnimation = setAnimation,
setOffset = setOffset,
resetTimer = resetTimer, resetTimer = resetTimer,
} }
end end

View file

@ -127,20 +127,24 @@ Texture object
/*** /***
Draw a texture. Draw a texture.
@function :draw @function :draw
@tparam number x X position @tparam integer x X position
@tparam number y Y position @tparam integer y Y position
@tparam[opt=0.0] number rad rotation of the texture (in radians) @tparam[opt=0.0] number rad rotation of the texture around the hotspot (in radians)
@tparam[opt=0.0] number hotspotX the hostpot X coordinate
@tparam[opt=0.0] number hotspotY the hostpot Y coordinate
*/ */
static int texture_draw(lua_State *L) { static int texture_draw(lua_State *L) {
texture_userdata *texture = luaL_checkudata(L, 1, "LTexture"); texture_userdata *texture = luaL_checkudata(L, 1, "LTexture");
int x = luaL_checkinteger(L, 2); int x = luaL_checkinteger(L, 2);
int y = luaL_checkinteger(L, 3); int y = luaL_checkinteger(L, 3);
float rad = luaL_optnumber(L, 4, 0.0f); float rad = luaL_optnumber(L, 4, 0.0f);
float hotspotX = luaL_optnumber(L, 5, 0.0f);
float hotspotY = luaL_optnumber(L, 6, 0.0f);
if (rad == 0.0f && texture->scaleX == 1.0f && texture->scaleY == 1.0f && texture->blendColor == 0xffffffff) { if (rad == 0.0f && texture->scaleX == 1.0f && texture->scaleY == 1.0f && texture->blendColor == 0xffffffff) {
sf2d_draw_texture(texture->texture, x, y); sf2d_draw_texture(texture->texture, x - hotspotX, y - hotspotY);
} else { } else {
sf2d_draw_texture_part_rotate_scale_blend(texture->texture, x, y, rad, 0, 0, texture->texture->width, texture->texture->height, texture->scaleX, texture->scaleY, texture->blendColor); sf2d_draw_texture_rotate_scale_hotspot_blend(texture->texture, x, y, rad, texture->scaleX, texture->scaleY, hotspotX, hotspotY, texture->blendColor);
} }
return 0; return 0;
@ -149,13 +153,15 @@ static int texture_draw(lua_State *L) {
/*** /***
Draw a part of the texture Draw a part of the texture
@function :drawPart @function :drawPart
@tparam number x X position @tparam integer x X position
@tparam number y Y position @tparam integer y Y position
@tparam number sx X position of the beginning of the part @tparam integer sx X position of the beginning of the part
@tparam number sy Y position of the beginning of the part @tparam integer sy Y position of the beginning of the part
@tparam number w width of the part @tparam integer w width of the part
@tparam number h height of the part @tparam integer h height of the part
@tparam[opt=0.0] number rad rotation of the part (in radians) @tparam[opt=0.0] number rad rotation of the part around the hotspot (in radians)
@tparam[opt=0.0] number hotspotX the hostpot X coordinate
@tparam[opt=0.0] number hotspotY the hostpot Y coordinate
*/ */
static int texture_drawPart(lua_State *L) { static int texture_drawPart(lua_State *L) {
texture_userdata *texture = luaL_checkudata(L, 1, "LTexture"); texture_userdata *texture = luaL_checkudata(L, 1, "LTexture");
@ -166,8 +172,10 @@ static int texture_drawPart(lua_State *L) {
int w = luaL_checkinteger(L, 6); int w = luaL_checkinteger(L, 6);
int h = luaL_checkinteger(L, 7); int h = luaL_checkinteger(L, 7);
int rad = luaL_optnumber(L, 8, 0.0f); int rad = luaL_optnumber(L, 8, 0.0f);
float hotspotX = luaL_optnumber(L, 9, 0.0f);
float hotspotY = luaL_optnumber(L, 10, 0.0f);
sf2d_draw_texture_part_rotate_scale_blend(texture->texture, x, y, rad, sx, sy, w, h, texture->scaleX, texture->scaleY, texture->blendColor); sf2d_draw_texture_part_rotate_scale_hotspot_blend(texture->texture, x, y, rad, sx, sy, w, h, texture->scaleX, texture->scaleY, hotspotX, hotspotY, texture->blendColor);
return 0; return 0;
} }
@ -206,12 +214,12 @@ static int texture_unload(lua_State *L) {
Rescale the texture. The default scale is `1.0`. Rescale the texture. The default scale is `1.0`.
@function :scale @function :scale
@tparam number scaleX new scale of the width @tparam number scaleX new scale of the width
@tparam number scaleY new scale of the height @tparam[opt=scaleX] number scaleY new scale of the height
*/ */
static int texture_scale(lua_State *L) { static int texture_scale(lua_State *L) {
texture_userdata *texture = luaL_checkudata(L, 1, "LTexture"); texture_userdata *texture = luaL_checkudata(L, 1, "LTexture");
float sx = luaL_checknumber(L, 2); float sx = luaL_checknumber(L, 2);
float sy = luaL_checknumber(L, 3); float sy = luaL_optnumber(L, 3, sx);
texture->scaleX = sx; texture->scaleX = sx;
texture->scaleY = sy; texture->scaleY = sy;
@ -268,6 +276,19 @@ static int texture_setBlendColor(lua_State *L) {
return 0; return 0;
} }
/***
Get the blend color of the texture.
@function :getBlendColor
@treturn number the blend color
*/
static int texture_getBlendColor(lua_State *L) {
texture_userdata *texture = luaL_checkudata(L, 1, "LTexture");
lua_pushinteger(L, texture->blendColor);
return 1;
}
/*** /***
Save a texture to a file. Save a texture to a file.
@function :save @function :save
@ -357,6 +378,7 @@ static const struct luaL_Reg texture_methods[] = {
{ "getPixel", texture_getPixel }, { "getPixel", texture_getPixel },
{ "setPixel", texture_setPixel }, { "setPixel", texture_setPixel },
{ "setBlendColor", texture_setBlendColor }, { "setBlendColor", texture_setBlendColor },
{ "getBlendColor", texture_getBlendColor },
{ "save", texture_save }, { "save", texture_save },
{ "__gc", texture_unload }, { "__gc", texture_unload },
{NULL, NULL} {NULL, NULL}