5959** GetDrawLayer()
6060** SetViewport([x, y, width, height])
6161** SetDrawColor(red, green, blue[, alpha]) / SetDrawColor("<escapeStr>")
62- ** DrawImage({imgHandle|nil}, left, top, width, height[, tcLeft, tcTop, tcRight, tcBottom])
63- ** DrawImageQuad({imgHandle|nil}, x1, y1, x2, y2, x3, y3, x4, y4[, s1, t1, s2, t2, s3, t3, s4, t4])
62+ ** DrawImage({imgHandle|nil}, left, top, width, height[, tcLeft, tcTop, tcRight, tcBottom][, stackIdx[, mask]]) mask: nil|"arc"|"circle" // TODO(zao): define how mask works, none implemented yet
63+ ** DrawImageQuad({imgHandle|nil}, x1, y1, x2, y2, x3, y3, x4, y4[, s1, t1, s2, t2, s3, t3, s4, t4][, stackIdx[, mask]] )
6464** DrawString(left, top, align{"LEFT"|"CENTER"|"RIGHT"|"CENTER_X"|"RIGHT_X"}, height, font{"FIXED"|"VAR"|"VAR BOLD"}, "<text>")
6565** width = DrawStringWidth(height, font{"FIXED"|"VAR"|"VAR BOLD"}, "<text>")
6666** index = DrawStringCursorIndex(height, font{"FIXED"|"VAR"|"VAR BOLD"}, "<text>", cursorX, cursorY)
@@ -852,30 +852,77 @@ static int l_DrawImage(lua_State* L)
852852 ui->LAssert (L, ui->renderer != NULL , " Renderer is not initialised" );
853853 ui->LAssert (L, ui->renderEnable , " DrawImage() called outside of OnFrame" );
854854 int n = lua_gettop (L);
855- ui->LAssert (L, n >= 5 , " Usage: DrawImage({imgHandle|nil}, left, top, width, height[, tcLeft, tcTop, tcRight, tcBottom])" );
855+ const char * usage = " Usage: DrawImage({imgHandle|nil}, left, top, width, height[, tcLeft, tcTop, tcRight, tcBottom][, stackIdx[, mask]])" ;
856+ ui->LAssert (L, n >= 5 , usage);
856857 ui->LAssert (L, lua_isnil (L, 1 ) || ui->IsUserData (L, 1 , " uiimghandlemeta" ), " DrawImage() argument 1: expected image handle or nil, got %s" , luaL_typename (L, 1 ));
857858 r_shaderHnd_c* hnd = NULL ;
858- if (!lua_isnil (L, 1 )) {
859- imgHandle_s* imgHandle = (imgHandle_s*)lua_touserdata (L, 1 );
860- ui->LAssert (L, imgHandle->hnd != NULL , " DrawImage(): image handle has no image loaded" );
861- hnd = imgHandle->hnd ;
862- }
863- float arg[8 ];
864- if (n > 5 ) {
865- ui->LAssert (L, n >= 9 , " DrawImage(): incomplete set of texture coordinates provided" );
866- for (int i = 2 ; i <= 9 ; i++) {
859+ glm::vec2 xys[2 ]{}, uvs[2 ]{};
860+ int stackLayer = 0 ;
861+
862+ // | n |img| corners | uvs | stack | mask |
863+ // | 5 | X | X | | | |
864+ // | 6 | X | X | | X | |
865+ // | 7 | X | X | | X | X |
866+ // | 9 | X | X | X | | |
867+ // | 10 | X | X | X | X | |
868+ // | 11 | X | X | X | X | X |
869+
870+ enum ArgFlag : uint8_t { AF_IMG = 0x1 , AF_XY = 0x2 , AF_UV = 0x4 , AF_STACK = 0x8 , AF_MASK = 0x10 };
871+ ArgFlag af{};
872+ switch (n) {
873+ case 11 : af = (ArgFlag)(af | AF_MASK );
874+ case 10 : af = (ArgFlag)(af | AF_STACK );
875+ case 9 : af = (ArgFlag)(af | AF_IMG | AF_XY | AF_UV ); break ;
876+ case 7 : af = (ArgFlag)(af | AF_MASK );
877+ case 6 : af = (ArgFlag)(af | AF_STACK );
878+ case 5 : af = (ArgFlag)(af | AF_IMG | AF_XY ); break ;
879+ default : ui->LAssert (L, false , usage);
880+ }
881+
882+ int k = 1 ;
883+ if (af & AF_IMG ) {
884+ if (!lua_isnil (L, k)) {
885+ imgHandle_s* imgHandle = (imgHandle_s*)lua_touserdata (L, k);
886+ ui->LAssert (L, imgHandle->hnd != NULL , " DrawImage(): image handle has no image loaded" );
887+ hnd = imgHandle->hnd ;
888+ }
889+ k += 1 ;
890+ }
891+
892+ if (af & AF_XY ) {
893+ for (int i = k; i < k + 4 ; i++) {
867894 ui->LAssert (L, lua_isnumber (L, i), " DrawImage() argument %d: expected number, got %s" , i, luaL_typename (L, i));
868- arg[i - 2 ] = (float )lua_tonumber (L, i);
895+ const int idx = i - k;
896+ xys[idx/2 ][idx%2 ] = (float )lua_tonumber (L, i);
869897 }
870- ui-> renderer -> DrawImage (hnd, arg[ 0 ], arg[ 1 ], arg[ 2 ], arg[ 3 ], arg[ 4 ], arg[ 5 ], arg[ 6 ], arg[ 7 ]) ;
898+ k += 4 ;
871899 }
872- else {
873- for (int i = 2 ; i <= 5 ; i++) {
900+
901+ if (af & AF_UV ) {
902+ for (int i = k; i < k + 4 ; i++) {
874903 ui->LAssert (L, lua_isnumber (L, i), " DrawImage() argument %d: expected number, got %s" , i, luaL_typename (L, i));
875- arg[i - 2 ] = (float )lua_tonumber (L, i);
904+ int idx = i - k;
905+ uvs[idx/2 ][idx%2 ] = (float )lua_tonumber (L, i);
876906 }
877- ui->renderer ->DrawImage (hnd, arg[0 ], arg[1 ], arg[2 ], arg[3 ]);
907+ k += 4 ;
908+ }
909+ else {
910+ uvs[0 ] = { 0 , 0 };
911+ uvs[1 ] = { 1 , 1 };
878912 }
913+
914+ if (af & AF_STACK ) {
915+ ui->LAssert (L, lua_isinteger (L, k), " DrawImage() argument %d: expected integer, got %s" , k, luaL_typename (L, k));
916+ stackLayer = (int )lua_tointeger (L, k);
917+ k += 1 ;
918+ }
919+
920+ if (af & AF_MASK ) {
921+ ui->LAssert (L, lua_isnil (L, k) || lua_istable (L, k), " DrawImage() argument %d: expected integer or nil, got %s" , k, luaL_typename (L, k));
922+ }
923+
924+ ui->renderer ->DrawImage (hnd, xys[0 ], xys[1 ], uvs[0 ], uvs[1 ], stackLayer);
925+
879926 return 0 ;
880927}
881928
@@ -885,30 +932,81 @@ static int l_DrawImageQuad(lua_State* L)
885932 ui->LAssert (L, ui->renderer != NULL , " Renderer is not initialised" );
886933 ui->LAssert (L, ui->renderEnable , " DrawImageQuad() called outside of OnFrame" );
887934 int n = lua_gettop (L);
888- ui->LAssert (L, n >= 9 , " Usage: DrawImageQuad({imgHandle|nil}, x1, y1, x2, y2, x3, y3, x4, y4[, s1, t1, s2, t2, s3, t3, s4, t4])" );
935+ const char * usage = " Usage: DrawImageQuad({imgHandle|nil}, x1, y1, x2, y2, x3, y3, x4, y4[, s1, t1, s2, t2, s3, t3, s4, t4][, stackIdx[, mask]])" ;
936+ ui->LAssert (L, n >= 9 , usage);
889937 ui->LAssert (L, lua_isnil (L, 1 ) || ui->IsUserData (L, 1 , " uiimghandlemeta" ), " DrawImageQuad() argument 1: expected image handle or nil, got %s" , luaL_typename (L, 1 ));
938+
890939 r_shaderHnd_c* hnd = NULL ;
891- if (!lua_isnil (L, 1 )) {
892- imgHandle_s* imgHandle = (imgHandle_s*)lua_touserdata (L, 1 );
893- ui->LAssert (L, imgHandle->hnd != NULL , " DrawImageQuad(): image handle has no image loaded" );
894- hnd = imgHandle->hnd ;
895- }
896- float arg[16 ];
897- if (n > 9 ) {
898- ui->LAssert (L, n >= 17 , " DrawImageQuad(): incomplete set of texture coordinates provided" );
899- for (int i = 2 ; i <= 17 ; i++) {
940+ glm::vec2 xys[4 ]{}, uvs[4 ]{};
941+ int stackLayer{};
942+
943+ // | n |img| corners | uvs | stack | mask |
944+ // | 9 | X | X | | | |
945+ // | 10 | X | X | | X | |
946+ // | 11 | X | X | | X | X |
947+ // | 17 | X | X | X | | |
948+ // | 18 | X | X | X | X | |
949+ // | 19 | X | X | X | X | X |
950+
951+ enum ArgFlag : uint8_t { AF_IMG = 0x1 , AF_XY = 0x2 , AF_UV = 0x4 , AF_STACK = 0x8 , AF_MASK = 0x10 };
952+ ArgFlag af{};
953+ switch (n) {
954+ case 19 : af = (ArgFlag)(af | AF_MASK );
955+ case 18 : af = (ArgFlag)(af | AF_STACK );
956+ case 17 : af = (ArgFlag)(af | AF_IMG | AF_XY | AF_UV ); break ;
957+ case 11 : af = (ArgFlag)(af | AF_MASK );
958+ case 10 : af = (ArgFlag)(af | AF_STACK );
959+ case 9 : af = (ArgFlag)(af | AF_IMG | AF_XY ); break ;
960+ default : ui->LAssert (L, false , usage);
961+ }
962+
963+ int k = 1 ;
964+ if (af & AF_IMG ) {
965+ if (!lua_isnil (L, k)) {
966+ imgHandle_s* imgHandle = (imgHandle_s*)lua_touserdata (L, k);
967+ ui->LAssert (L, imgHandle->hnd != NULL , " DrawImageQuad(): image handle has no image loaded" );
968+ hnd = imgHandle->hnd ;
969+ }
970+ k += 1 ;
971+ }
972+
973+ if (af & AF_XY ) {
974+ for (int i = k; i < k + 8 ; i++) {
900975 ui->LAssert (L, lua_isnumber (L, i), " DrawImageQuad() argument %d: expected number, got %s" , i, luaL_typename (L, i));
901- arg[i - 2 ] = (float )lua_tonumber (L, i);
976+ const int idx = i - k;
977+ xys[idx / 2 ][idx % 2 ] = (float )lua_tonumber (L, i);
902978 }
903- ui-> renderer -> DrawImageQuad (hnd, arg[ 0 ], arg[ 1 ], arg[ 2 ], arg[ 3 ], arg[ 4 ], arg[ 5 ], arg[ 6 ], arg[ 7 ], arg[ 8 ], arg[ 9 ], arg[ 10 ], arg[ 11 ], arg[ 12 ], arg[ 13 ], arg[ 14 ], arg[ 15 ]) ;
979+ k += 8 ;
904980 }
905- else {
906- for (int i = 2 ; i <= 9 ; i++) {
981+
982+ if (af & AF_UV ) {
983+ for (int i = k; i < k + 8 ; i++) {
907984 ui->LAssert (L, lua_isnumber (L, i), " DrawImageQuad() argument %d: expected number, got %s" , i, luaL_typename (L, i));
908- arg[i - 2 ] = (float )lua_tonumber (L, i);
985+ int idx = i - k;
986+ uvs[idx / 2 ][idx % 2 ] = (float )lua_tonumber (L, i);
909987 }
910- ui->renderer ->DrawImageQuad (hnd, arg[0 ], arg[1 ], arg[2 ], arg[3 ], arg[4 ], arg[5 ], arg[6 ], arg[7 ]);
988+ k += 8 ;
989+ }
990+ else {
991+ uvs[0 ] = { 0 , 0 };
992+ uvs[1 ] = { 1 , 0 };
993+ uvs[2 ] = { 1 , 1 };
994+ uvs[3 ] = { 0 , 1 };
911995 }
996+
997+ if (af & AF_STACK ) {
998+ ui->LAssert (L, lua_isinteger (L, k), " DrawImageQuad() argument %d: expected integer, got %s" , k, luaL_typename (L, k));
999+ stackLayer = (int )lua_tointeger (L, k);
1000+ k += 1 ;
1001+ }
1002+
1003+ if (af & AF_MASK ) {
1004+ ui->LAssert (L, lua_isnil (L, k) || lua_istable (L, k), " DrawImageQuad() argument %d: expected integer or nil, got %s" , k, luaL_typename (L, k));
1005+ }
1006+
1007+
1008+ ui->renderer ->DrawImageQuad (hnd, xys[0 ], xys[1 ], xys[2 ], xys[3 ], uvs[0 ], uvs[1 ], uvs[2 ], uvs[3 ], stackLayer);
1009+
9121010 return 0 ;
9131011}
9141012
0 commit comments