diff --git a/src/singe.c b/src/singe.c index 8dd4b1790..c441f6423 100644 --- a/src/singe.c +++ b/src/singe.c @@ -142,6 +142,10 @@ typedef struct VideoS { bool wasPlayingBeforePause; SDL_Texture *texture; SDL_Surface *surface; + double angle; + double scaleX; + double scaleY; + int smooth; UT_hash_handle hh; } VideoT; @@ -406,6 +410,10 @@ int32_t apiVideoIsPlaying(lua_State *L); int32_t apiVideoLoad(lua_State *L); int32_t apiVideoPause(lua_State *L); int32_t apiVideoPlay(lua_State *L); +int32_t apiVideoQuality(lua_State *L); +int32_t apiVideoRotate(lua_State *L); +int32_t apiVideoRotateAndScale(lua_State *L); +int32_t apiVideoScale(lua_State *L); int32_t apiVideoSeek(lua_State *L); int32_t apiVideoSetAudioTrack(lua_State *L); int32_t apiVideoSetVolume(lua_State *L); @@ -1935,8 +1943,8 @@ int32_t apiSpriteDraw(lua_State *L) { // spriteDraw(x, y, id) - Simple draw // spriteDraw(x, y, c, id) - Centered draw - // spriteDraw(x, y, x2, y2, id) - Scaled draw - // spriteDraw(x, y, x2, y2, c, id) - Centered scaled draw + // spriteDraw(x, y, x2, y2, id) - Stretched draw + // spriteDraw(x, y, x2, y2, c, id) - Centered Stretched draw if ((n >= 3) && (n <= 6)) { if (lua_isnumber(L, 1)) { @@ -1984,7 +1992,7 @@ int32_t apiSpriteDraw(lua_State *L) { if (center) { // Move sprite so the drawing coordinate is the center of the sprite dest.x -= dest.w * 0.5; - dest.y -= dest.w * 0.5; + dest.y -= dest.h * 0.5; } if ((n == 3) || (n == 4)) { // No scaling @@ -2286,43 +2294,72 @@ int32_t apiVideoDraw(lua_State *L) { int64_t frame = 0; double d = 0.0; VideoT *video = NULL; + bool center = false; SDL_Rect dest; + SDL_Surface *surface = NULL; - if (n == 5) { + // videoDraw(id, x1, y1, x2, y2) - Simple/Stretched draw + // videoDraw(id, x1, y1, c) - Scaled/Rotated draw + + if ((n == 4) || (n == 5)) { if (lua_isnumber(L, 1)) { if (lua_isnumber(L, 2)) { if (lua_isnumber(L, 3)) { if (lua_isnumber(L, 4)) { - if (lua_isnumber(L, 5)) { - d = lua_tonumber(L, 1); id = (int32_t)d; - d = lua_tonumber(L, 2); dest.x = (int32_t)d; - d = lua_tonumber(L, 3); dest.y = (int32_t)d; - d = lua_tonumber(L, 4); dest.w = (int32_t)d - dest.x + 1; - d = lua_tonumber(L, 5); dest.h = (int32_t)d - dest.y + 1; - // Get our video structure - HASH_FIND_INT(_global.videoList, &id, video); - if (!video) luaDie(L, "videoDraw", "No video at index %d in apiVideoDraw.", id); - frame = videoUpdate(video->handle, &video->texture); - // New Frame? - if (frame != video->lastFrame) { - // Get new frame into a surface - this is slow - if (video->surface) SDL_FreeSurface(video->surface); - SDL_QueryTexture(video->texture, NULL, NULL, &w, &h); - video->surface = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 255); - if (!video->surface) utilDie("%s", SDL_GetError()); - if (SDL_SetRenderTarget(_global.renderer, video->texture) < 0) luaDie(L, "videoDraw", "%s", SDL_GetError()); - if (SDL_RenderReadPixels(_global.renderer, NULL, video->surface->format->format, video->surface->pixels, video->surface->pitch) != 0) luaDie(L, "videoDraw", "%s", SDL_GetError()); - if (SDL_SetRenderTarget(_global.renderer, NULL) < 0) luaDie(L, "videoDraw", "%s", SDL_GetError()); + d = lua_tonumber(L, 1); id = (int32_t)d; + d = lua_tonumber(L, 2); dest.x = (int32_t)d; + d = lua_tonumber(L, 3); dest.y = (int32_t)d; + if (n == 5) { + if (lua_isnumber(L, 5)) { + d = lua_tonumber(L, 4); dest.w = (int32_t)d - dest.x + 1; + d = lua_tonumber(L, 5); dest.h = (int32_t)d - dest.y + 1; } - // Render frame into overlay - if (SDL_BlitScaled(video->surface, NULL, _global.overlay, &dest) != 0) luaDie(L, "videoDraw", "%s", SDL_GetError()); - result = true; + } else { + d = lua_tonumber(L, 4); center = (int32_t)d != 0; + dest.w = 0; + dest.h = 0; } - } - } - } - } - } + + // Get our video structure + HASH_FIND_INT(_global.videoList, &id, video); + if (!video) luaDie(L, "videoDraw", "No video at index %d in apiVideoDraw.", id); + frame = videoUpdate(video->handle, &video->texture); + + // New Frame? + if (frame != video->lastFrame) { + // Get new frame into a surface - this is slow + if (video->surface) SDL_FreeSurface(video->surface); + SDL_QueryTexture(video->texture, NULL, NULL, &w, &h); + video->surface = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 255); + if (!video->surface) utilDie("%s", SDL_GetError()); + if (SDL_SetRenderTarget(_global.renderer, video->texture) < 0) luaDie(L, "videoDraw", "%s", SDL_GetError()); + if (SDL_RenderReadPixels(_global.renderer, NULL, video->surface->format->format, video->surface->pixels, video->surface->pitch) != 0) luaDie(L, "videoDraw", "%s", SDL_GetError()); + if (SDL_SetRenderTarget(_global.renderer, NULL) < 0) luaDie(L, "videoDraw", "%s", SDL_GetError()); + } + + // Render frame into overlay + if ((dest.w == 0) && (dest.h == 0)) { + surface = rotozoomSurfaceXY(video->surface, 360 - video->angle, video->scaleX, video->scaleY, video->smooth); + dest.w = surface->w; + dest.h = surface->h; + // Scaled/Rotated draw + if (center) { + // Move video so the drawing coordinate is the center of the video + dest.x -= dest.w * 0.5; + dest.y -= dest.h * 0.5; + } + SDL_BlitSurface(surface, NULL, _global.overlay, &dest); + SDL_FreeSurface(surface); + } else { + // Simple/Stretched draw + if (SDL_BlitScaled(video->surface, NULL, _global.overlay, &dest) != 0) luaDie(L, "videoDraw", "%s", SDL_GetError()); + } + result = true; + } + } + } + } + } if (result) { luaTrace(L, "videoDraw", "%d %d %d %d %d %ld", id, dest.x, dest.y, dest.x + dest.w, dest.y + dest.h, frame); @@ -2683,6 +2720,145 @@ int32_t apiVideoPlay(lua_State *L) { } +int32_t apiVideoQuality(lua_State *L) { + int32_t n = lua_gettop(L); + int32_t id = -1; + int32_t s; + double d; + VideoT *video = NULL; + + if (n == 2) { + if (lua_isnumber(L, 1)) { + if (lua_isnumber(L, 2)) { + d = lua_tonumber(L, 1); id = (int32_t)d; + d = lua_tonumber(L, 2); s = (int32_t)d; + HASH_FIND_INT(_global.videoList, &id, video); + if (!video) luaDie(L, "videoQuality", "No video at index %d in apiVideoQuality.", id); + video->smooth = s; + } + } + } + + if (id >= 0) { + luaTrace(L, "videoQuality", "%d %d", id, video->smooth); + } else { + luaDie(L, "videoQuality", "Failed!"); + } + + return 0; +} + + +int32_t apiVideoRotate(lua_State *L) { + int32_t n = lua_gettop(L); + int32_t id = -1; + double d; + double a; + VideoT *video = NULL; + + if (n == 2) { + if (lua_isnumber(L, 1)) { + if (lua_isnumber(L, 2)) { + d = lua_tonumber(L, 1); id = (int32_t)d; + d = lua_tonumber(L, 2); a = fmod(d, 360.0); + HASH_FIND_INT(_global.videoList, &id, video); + if (!video) luaDie(L, "videoRotate", "No video at index %d in apiVideoRotate.", id); + video->angle = a; + } + } + } + + if (id >= 0) { + luaTrace(L, "videoRotate", "%d %f", id, video->angle); + } else { + luaDie(L, "videoRotate", "Failed!"); + } + + return 0; +} + + +int32_t apiVideoRotateAndScale(lua_State *L) { + int32_t n = lua_gettop(L); + int32_t id = -1; + double d; + double a; + double x; + double y; + VideoT *video = NULL; + + if ((n == 3) || (n == 4)) { + if (lua_isnumber(L, 1)) { + d = lua_tonumber(L, 1); id = (int32_t)d; + if (lua_isnumber(L, 2)) { + if (lua_isnumber(L, 3)) { + d = lua_tonumber(L, 2); a = fmod(d, 360.0); + d = lua_tonumber(L, 3); x = d; + if (n == 3) { + y = x; + } else { + if (lua_isnumber(L, 4)) { + d = lua_tonumber(L, 4); y = (int32_t)d; + } + } + HASH_FIND_INT(_global.videoList, &id, video); + if (!video) luaDie(L, "videoRotateAndScale", "No video at index %d in apiVideoRotateAndScale.", id); + video->angle = a; + video->scaleX = x; + video->scaleY = y; + } + } + } + } + + if (id >= 0) { + luaTrace(L, "videoRotateAndScale", "%d %f %f %f", id, video->angle, video->scaleX, video->scaleY); + } else { + luaDie(L, "videoRotateAndScale", "Failed!"); + } + + return 0; +} + + +int32_t apiVideoScale(lua_State *L) { + int32_t n = lua_gettop(L); + int32_t id = -1; + double d; + double x; + double y; + VideoT *video = NULL; + + if ((n == 2) || (n == 3)) { + if (lua_isnumber(L, 1)) { + d = lua_tonumber(L, 1); id = (int32_t)d; + if (lua_isnumber(L, 2)) { + d = lua_tonumber(L, 2); x = d; + if (n == 2) { + y = x; + } else { + if (lua_isnumber(L, 3)) { + d = lua_tonumber(L, 3); y = d; + } + } + HASH_FIND_INT(_global.videoList, &id, video); + if (!video) luaDie(L, "videoScale", "No video at index %d in apiVideoScale.", id); + video->scaleX = x; + video->scaleY = y; + } + } + } + + if (id >= 0) { + luaTrace(L, "videoScale", "%d %f %f", id, video->scaleX, video->scaleY); + } else { + luaDie(L, "videoScale", "Failed!"); + } + + return 0; +} + + int32_t apiVideoSeek(lua_State *L) { int32_t n = lua_gettop(L); bool result = false; @@ -4233,6 +4409,10 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) { lua_register(_global.luaContext, "videoLoad", apiVideoLoad); lua_register(_global.luaContext, "videoPause", apiVideoPause); lua_register(_global.luaContext, "videoPlay", apiVideoPlay); + lua_register(_global.luaContext, "videoQuality", apiVideoQuality); + lua_register(_global.luaContext, "videoRotate", apiVideoRotate); + lua_register(_global.luaContext, "videoRotateAndScale", apiVideoRotateAndScale); + lua_register(_global.luaContext, "videoScale", apiVideoScale); lua_register(_global.luaContext, "videoSeek", apiVideoSeek); lua_register(_global.luaContext, "videoSetAudioTrack", apiVideoSetAudioTrack); lua_register(_global.luaContext, "videoSetVolume", apiVideoSetVolume);