diff --git a/libs/sf2dlib/libsf2d/.gitignore b/libs/sf2dlib/libsf2d/.gitignore new file mode 100644 index 0000000..e63ddd8 --- /dev/null +++ b/libs/sf2dlib/libsf2d/.gitignore @@ -0,0 +1 @@ +/Default/ diff --git a/libs/sf2dlib/libsf2d/include/sf2d.h b/libs/sf2dlib/libsf2d/include/sf2d.h index 9322ebb..b6f3277 100644 --- a/libs/sf2dlib/libsf2d/include/sf2d.h +++ b/libs/sf2dlib/libsf2d/include/sf2d.h @@ -67,6 +67,14 @@ typedef enum { TEXFMT_ETC1A4 = 13 } sf2d_texfmt; +/** + * @brief Represents a direction for drawing a gradient + */ + +typedef enum { + SF2D_TOP_TO_BOTTOM, + SF2D_LEFT_TO_RIGHT +} sf2d_gradient_dir; /** * @brief Data allocated on the RAM or VRAM @@ -264,6 +272,18 @@ void sf2d_set_clear_color(u32 color); */ void sf2d_draw_rectangle(int x, int y, int w, int h, u32 color); +/** + * @brief Draws a triangle + * @param x1 x coordinate of a vertex of the triangle + * @param y1 y coordinate of a vertex of the triangle + * @param x2 x coordinate of a vertex of the triangle + * @param y2 y coordinate of a vertex of the triangle + * @param x3 x coordinate of a vertex of the triangle + * @param y3 y coordinate of a vertex of the triangle + * @param color the color to draw the triangle + */ +void sf2d_draw_triangle(float x1, float y1, float x2, float y2, float x3, float y3, u32 color); + /** * @brief Draws a rotated rectangle * @param x x coordinate of the top left corner of the rectangle @@ -275,6 +295,31 @@ void sf2d_draw_rectangle(int x, int y, int w, int h, u32 color); */ void sf2d_draw_rectangle_rotate(int x, int y, int w, int h, u32 color, float rad); +/** + * @brief Draws a rectangle + * @param x x coordinate of the top left corner of the rectangle + * @param y y coordinate of the top left corner of the rectangle + * @param w rectangle width + * @param h rectangle height + * @param color1 the color at the start of the gradient + * @param color2 the color at the end of the gradient + * @param left_to_right determines which direction the gradient is in + */ +void sf2d_draw_rectangle_gradient(int x, int y, int w, int h, u32 color1, u32 color2, sf2d_gradient_dir direction); + +/** + * @brief Draws a rotated rectangle + * @param x x coordinate of the top left corner of the rectangle + * @param y y coordinate of the top left corner of the rectangle + * @param w rectangle width + * @param h rectangle height + * @param color1 the color at the start of the gradient + * @param color2 the color at the end of the gradient + * @param left_to_right determines which direction the gradient is in + * @param rad rotation (in radians) to draw the rectangle + */ +void sf2d_draw_rectangle_gradient_rotate(int x, int y, int w, int h, u32 color1, u32 color2, sf2d_gradient_dir direction, float rad); + /** * @brief Draws a filled circle * @param x x coordinate of the center of the circle diff --git a/libs/sf2dlib/libsf2d/include/sf2d_private.h b/libs/sf2dlib/libsf2d/include/sf2d_private.h index 76cf70d..07579ca 100644 --- a/libs/sf2dlib/libsf2d/include/sf2d_private.h +++ b/libs/sf2dlib/libsf2d/include/sf2d_private.h @@ -7,6 +7,8 @@ void GPU_SetDummyTexEnv(u8 num); +void sf2d_draw_rectangle_internal(const sf2d_vertex_pos_col *vertices); + // Vector operations void vector_mult_matrix4x4(const float *msrc, const sf2d_vector_3f *vsrc, sf2d_vector_3f *vdst); diff --git a/libs/sf2dlib/libsf2d/source/sf2d_draw.c b/libs/sf2dlib/libsf2d/source/sf2d_draw.c index 59a792e..a28e818 100644 --- a/libs/sf2dlib/libsf2d/source/sf2d_draw.c +++ b/libs/sf2dlib/libsf2d/source/sf2d_draw.c @@ -6,6 +6,30 @@ #define M_PI (3.14159265358979323846) #endif +void sf2d_setup_env_internal(const sf2d_vertex_pos_col* vertices) { + GPU_SetTexEnv( + 0, + GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), + GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), + GPU_TEVOPERANDS(0, 0, 0), + GPU_TEVOPERANDS(0, 0, 0), + GPU_REPLACE, GPU_REPLACE, + 0xFFFFFFFF + ); + + GPU_SetAttributeBuffers( + 2, // number of attributes + (u32*)osConvertVirtToPhys(vertices), + GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, GPU_UNSIGNED_BYTE), + 0xFFFC, //0b1100 + 0x10, + 1, //number of buffers + (u32[]){0x0}, // buffer offsets (placeholders) + (u64[]){0x10}, // attribute permutations for each buffer + (u8[]){2} // number of attributes for each buffer + ); +} + void sf2d_draw_line(float x0, float y0, float x1, float y1, float width, u32 color) { sf2d_vertex_pos_col *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_col), 8); @@ -38,31 +62,25 @@ void sf2d_draw_line(float x0, float y0, float x1, float y1, float width, u32 col vertices[2].color = vertices[0].color; vertices[3].color = vertices[0].color; - GPU_SetTexEnv( - 0, - GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), - GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), - GPU_TEVOPERANDS(0, 0, 0), - GPU_TEVOPERANDS(0, 0, 0), - GPU_REPLACE, GPU_REPLACE, - 0xFFFFFFFF - ); - - GPU_SetAttributeBuffers( - 2, // number of attributes - (u32*)osConvertVirtToPhys(vertices), - GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, GPU_UNSIGNED_BYTE), - 0xFFFC, //0b1100 - 0x10, - 1, //number of buffers - (u32[]){0x0}, // buffer offsets (placeholders) - (u64[]){0x10}, // attribute permutations for each buffer - (u8[]){2} // number of attributes for each buffer - ); + sf2d_setup_env_internal(vertices); GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4); } +void sf2d_draw_rectangle_internal(const sf2d_vertex_pos_col *vertices) +{ + sf2d_setup_env_internal(vertices); + + GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4); +} + +void sf2d_draw_triangle_internal(const sf2d_vertex_pos_col *vertices) +{ + sf2d_setup_env_internal(vertices); + + GPU_DrawArray(GPU_TRIANGLES, 0, 3); +} + void sf2d_draw_rectangle(int x, int y, int w, int h, u32 color) { sf2d_vertex_pos_col *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_col), 8); @@ -78,29 +96,23 @@ void sf2d_draw_rectangle(int x, int y, int w, int h, u32 color) vertices[2].color = vertices[0].color; vertices[3].color = vertices[0].color; - GPU_SetTexEnv( - 0, - GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), - GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), - GPU_TEVOPERANDS(0, 0, 0), - GPU_TEVOPERANDS(0, 0, 0), - GPU_REPLACE, GPU_REPLACE, - 0xFFFFFFFF - ); + sf2d_draw_rectangle_internal(vertices); +} - GPU_SetAttributeBuffers( - 2, // number of attributes - (u32*)osConvertVirtToPhys(vertices), - GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, GPU_UNSIGNED_BYTE), - 0xFFFC, //0b1100 - 0x10, - 1, //number of buffers - (u32[]){0x0}, // buffer offsets (placeholders) - (u64[]){0x10}, // attribute permutations for each buffer - (u8[]){2} // number of attributes for each buffer - ); +void sf2d_draw_triangle(float x1, float y1, float x2, float y2, float x3, float y3, u32 color) +{ + sf2d_vertex_pos_col *vertices = sf2d_pool_memalign(3 * sizeof(sf2d_vertex_pos_col), 8); + if (!vertices) return; - GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4); + vertices[0].position = (sf2d_vector_3f){(float)x1, (float)y1, SF2D_DEFAULT_DEPTH}; + vertices[1].position = (sf2d_vector_3f){(float)x2, (float)y2, SF2D_DEFAULT_DEPTH}; + vertices[2].position = (sf2d_vector_3f){(float)x3, (float)y3, SF2D_DEFAULT_DEPTH}; + + vertices[0].color = color; + vertices[1].color = vertices[0].color; + vertices[2].color = vertices[0].color; + + sf2d_draw_triangle_internal(vertices); } void sf2d_draw_rectangle_rotate(int x, int y, int w, int h, u32 color, float rad) @@ -131,29 +143,56 @@ void sf2d_draw_rectangle_rotate(int x, int y, int w, int h, u32 color, float rad vertices[i].position = (sf2d_vector_3f){rot[i].x + x + w2, rot[i].y + y + h2, rot[i].z}; } - GPU_SetTexEnv( - 0, - GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), - GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), - GPU_TEVOPERANDS(0, 0, 0), - GPU_TEVOPERANDS(0, 0, 0), - GPU_REPLACE, GPU_REPLACE, - 0xFFFFFFFF - ); + sf2d_draw_rectangle_internal(vertices); +} - GPU_SetAttributeBuffers( - 2, // number of attributes - (u32*)osConvertVirtToPhys(vertices), - GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, GPU_UNSIGNED_BYTE), - 0xFFFC, //0b1100 - 0x10, - 1, //number of buffers - (u32[]){0x0}, // buffer offsets (placeholders) - (u64[]){0x10}, // attribute permutations for each buffer - (u8[]){2} // number of attributes for each buffer - ); +void sf2d_draw_rectangle_gradient(int x, int y, int w, int h, u32 color1, u32 color2, sf2d_gradient_dir direction) +{ + sf2d_vertex_pos_col *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_col), 8); + if (!vertices) return; - GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4); + vertices[0].position = (sf2d_vector_3f){(float)x, (float)y, SF2D_DEFAULT_DEPTH}; + vertices[1].position = (sf2d_vector_3f){(float)x+w, (float)y, SF2D_DEFAULT_DEPTH}; + vertices[2].position = (sf2d_vector_3f){(float)x, (float)y+h, SF2D_DEFAULT_DEPTH}; + vertices[3].position = (sf2d_vector_3f){(float)x+w, (float)y+h, SF2D_DEFAULT_DEPTH}; + + vertices[0].color = color1; + vertices[1].color = (direction == SF2D_LEFT_TO_RIGHT) ? color2 : color1; + vertices[2].color = (direction == SF2D_LEFT_TO_RIGHT) ? color1 : color2; + vertices[3].color = color2; + + sf2d_draw_rectangle_internal(vertices); +} + +void sf2d_draw_rectangle_gradient_rotate(int x, int y, int w, int h, u32 color1, u32 color2, sf2d_gradient_dir direction, float rad) +{ + sf2d_vertex_pos_col *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_col), 8); + if (!vertices) return; + + int w2 = w/2.0f; + int h2 = h/2.0f; + + vertices[0].position = (sf2d_vector_3f){(float)-w2, (float)-h2, SF2D_DEFAULT_DEPTH}; + vertices[1].position = (sf2d_vector_3f){(float) w2, (float)-h2, SF2D_DEFAULT_DEPTH}; + vertices[2].position = (sf2d_vector_3f){(float)-w2, (float) h2, SF2D_DEFAULT_DEPTH}; + vertices[3].position = (sf2d_vector_3f){(float) w2, (float) h2, SF2D_DEFAULT_DEPTH}; + + vertices[0].color = color1; + vertices[1].color = (direction == SF2D_LEFT_TO_RIGHT) ? color2 : color1; + vertices[2].color = (direction == SF2D_LEFT_TO_RIGHT) ? color1 : color2; + vertices[3].color = color2; + + float m[4*4]; + matrix_set_z_rotation(m, rad); + sf2d_vector_3f rot[4]; + + int i; + for (i = 0; i < 4; i++) { + vector_mult_matrix4x4(m, &vertices[i].position, &rot[i]); + vertices[i].position = (sf2d_vector_3f){rot[i].x + x + w2, rot[i].y + y + h2, rot[i].z}; + } + + sf2d_draw_rectangle_internal(vertices); } void sf2d_draw_fill_circle(int x, int y, int radius, u32 color) @@ -186,27 +225,7 @@ void sf2d_draw_fill_circle(int x, int y, int radius, u32 color) vertices[num_segments + 1].position = vertices[1].position; vertices[num_segments + 1].color = vertices[1].color; - GPU_SetTexEnv( - 0, - GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), - GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), - GPU_TEVOPERANDS(0, 0, 0), - GPU_TEVOPERANDS(0, 0, 0), - GPU_REPLACE, GPU_REPLACE, - 0xFFFFFFFF - ); - - GPU_SetAttributeBuffers( - 2, // number of attributes - (u32*)osConvertVirtToPhys(vertices), - GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, GPU_UNSIGNED_BYTE), - 0xFFFC, //0b1100 - 0x10, - 1, //number of buffers - (u32[]){0x0}, // buffer offsets (placeholders) - (u64[]){0x10}, // attribute permutations for each buffer - (u8[]){2} // number of attributes for each buffer - ); + sf2d_setup_env_internal(vertices); GPU_DrawArray(GPU_TRIANGLE_FAN, 0, num_segments + 2); } diff --git a/libs/sf2dlib/libsf2d/source/sf2d_texture.c b/libs/sf2dlib/libsf2d/source/sf2d_texture.c index 12469ed..d0b7f09 100644 --- a/libs/sf2dlib/libsf2d/source/sf2d_texture.c +++ b/libs/sf2dlib/libsf2d/source/sf2d_texture.c @@ -8,7 +8,7 @@ #define M_PI (3.14159265358979323846) #endif -#define TEX_MIN_SIZE 8 +#define TEX_MIN_SIZE 32 static unsigned int nibbles_per_pixel(sf2d_texfmt format) { @@ -146,21 +146,40 @@ void sf2d_clear_target(sf2d_rendertarget *target, u32 color) { sf2d_texture_tile32(&(target->texture)); } +void sf2d_texture_tile32_hardware(sf2d_texture *texture, const void *data, int w, int h) +{ + if (texture->tiled) return; + const u32 flags = (GX_TRANSFER_FLIP_VERT(1) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_RAW_COPY(0) | + GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGBA8) | + GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)); + + GSPGPU_FlushDataCache(data, (w*h)<<2); + GX_DisplayTransfer( + (u32*)data, + GX_BUFFER_DIM(w, h), + (u32*)texture->data, + GX_BUFFER_DIM(texture->pow2_w, texture->pow2_h), + flags + ); + gspWaitForPPF(); + GSPGPU_InvalidateDataCache(texture->data, texture->data_size); + texture->tiled = 1; +} + void sf2d_fill_texture_from_RGBA8(sf2d_texture *dst, const void *rgba8, int source_w, int source_h) { // TODO: add support for non-RGBA8 textures - u8 *tmp = linearAlloc(dst->pow2_w * dst->pow2_h * 4); + u8 *tmp = linearAlloc((dst->pow2_w * dst->pow2_h)<<2); int i, j; for (i = 0; i < source_h; i++) { for (j = 0; j < source_w; j++) { - ((u32 *)tmp)[i*dst->pow2_w + j] = ((u32 *)rgba8)[i*source_w + j]; + ((u32 *)tmp)[i*dst->pow2_w + j] = __builtin_bswap32(((u32 *)rgba8)[i*source_w + j]); } } - memcpy(dst->data, tmp, dst->pow2_w*dst->pow2_h*4); + sf2d_texture_tile32_hardware(dst, tmp, dst->pow2_w, dst->pow2_h); linearFree(tmp); - sf2d_texture_tile32(dst); } sf2d_texture *sf2d_create_texture_mem_RGBA8(const void *src_buffer, int src_w, int src_h, sf2d_texfmt pixel_format, sf2d_place place) diff --git a/source/gfx.c b/source/gfx.c index 43a4fb5..3893380 100644 --- a/source/gfx.c +++ b/source/gfx.c @@ -192,6 +192,24 @@ static int gfx_vramSpaceFree(lua_State *L) { return 1; } +/*** +Draw a point, a single pixel, on the current screen. +@function point +@tparam integer x point horizontal coordinate, in pixels +@tparam integer y point vertical coordinate, in pixels +@tparam[opt=default color] integer color drawing color +*/ +static int gfx_point(lua_State *L) { + int x = luaL_checkinteger(L, 1); + int y = luaL_checkinteger(L, 2); + + u32 color = luaL_optinteger(L, 3, color_default); + + sf2d_draw_rectangle(x, y, 1, 1, color); // well, it looks like a point + + return 0; +} + /*** Draw a line on the current screen. @function line @@ -217,19 +235,57 @@ static int gfx_line(lua_State *L) { } /*** -Draw a point, a single pixel, on the current screen. -@function point -@tparam integer x point horizontal coordinate, in pixels -@tparam integer y point vertical coordinate, in pixels +Draw a triangle on the current screen. +@function triangle +@tparam integer x1 horizontal coordinate of a vertex of the triangle, in pixels +@tparam integer y1 vertical coordinate of a vertex of the triangle, in pixels +@tparam integer x2 horizontal coordinate of a vertex of the triangle, in pixels +@tparam integer y2 vertical coordinate of a vertex of the triangle, in pixels +@tparam integer x3 horizontal coordinate of a vertex of the triangle, in pixels +@tparam integer y3 vertical coordinate of a vertex of the triangle, in pixels @tparam[opt=default color] integer color drawing color */ -static int gfx_point(lua_State *L) { - int x = luaL_checkinteger(L, 1); - int y = luaL_checkinteger(L, 2); +static int gfx_triangle(lua_State *L) { + int x1 = luaL_checkinteger(L, 1); + int y1 = luaL_checkinteger(L, 2); + int x2 = luaL_checkinteger(L, 3); + int y2 = luaL_checkinteger(L, 4); + int x3 = luaL_checkinteger(L, 5); + int y3 = luaL_checkinteger(L, 6); - u32 color = luaL_optinteger(L, 3, color_default); + u32 color = luaL_optinteger(L, 7, color_default); - sf2d_draw_rectangle(x, y, 1, 1, color); // well, it looks like a point + sf2d_draw_triangle(x1, y1, x2, y2, x3, y3, color); + + return 0; +} + +/*** +Draw a triangle on the current screen. +@function triangle +@tparam integer x1 horizontal coordinate of a vertex of the triangle, in pixels +@tparam integer y1 vertical coordinate of a vertex of the triangle, in pixels +@tparam integer x2 horizontal coordinate of a vertex of the triangle, in pixels +@tparam integer y2 vertical coordinate of a vertex of the triangle, in pixels +@tparam integer x3 horizontal coordinate of a vertex of the triangle, in pixels +@tparam integer y3 vertical coordinate of a vertex of the triangle, in pixels +@tparam[opt=1] number lineWidth line's thickness, in pixels +@tparam[opt=default color] integer color drawing color +*/ +static int gfx_linedTriangle(lua_State *L) { + int x1 = luaL_checkinteger(L, 1); + int y1 = luaL_checkinteger(L, 2); + int x2 = luaL_checkinteger(L, 3); + int y2 = luaL_checkinteger(L, 4); + int x3 = luaL_checkinteger(L, 5); + int y3 = luaL_checkinteger(L, 6); + float lineWidth = luaL_optnumber(L, 7, 1.0f); + + u32 color = luaL_optinteger(L, 8, color_default); + + sf2d_draw_line(x1, y1, x2, y2, lineWidth, color); + sf2d_draw_line(x2, y2, x3, y3, lineWidth, color); + sf2d_draw_line(x3, y3, x1, y1, lineWidth, color); return 0; } @@ -243,6 +299,8 @@ Draw a filled rectangle on the current screen. @tparam integer height rectangle height, in pixels @tparam[opt=0] number angle rectangle rotation, in radians @tparam[opt=default color] integer color drawing color +@tparam[opt] integer color2 Second drawing color ; if the argument is not nil, the rectangle will be filled with a gradient from color to color2 +@tparam[opt] integer direction Gradient drawing direction (`gfx.TOP_TO_BOTTOM` or `gfx.LEFT_TO_RIGHT`). This argument is mandatory if a second color was specified. */ static int gfx_rectangle(lua_State *L) { int x = luaL_checkinteger(L, 1); @@ -252,11 +310,23 @@ static int gfx_rectangle(lua_State *L) { float angle = luaL_optnumber(L, 5, 0); u32 color = luaL_optinteger(L, 6, color_default); - - if (angle == 0) - sf2d_draw_rectangle(x, y, width, height, color); - else - sf2d_draw_rectangle_rotate(x, y, width, height, color, angle); + + // Not second color : fill with plain color. + if (lua_isnoneornil(L, 7)) { + if (angle == 0) + sf2d_draw_rectangle(x, y, width, height, color); + else + sf2d_draw_rectangle_rotate(x, y, width, height, color, angle); + // Two colors : fill with a gradient. + } else { + u32 color2 = luaL_checkinteger(L, 7); + u8 direction = luaL_checkinteger(L, 8); + + if (angle == 0) + sf2d_draw_rectangle_gradient(x, y, width, height, color, color2, direction); + else + sf2d_draw_rectangle_gradient_rotate(x, y, width, height, color, color2, direction, angle); + } return 0; } @@ -679,8 +749,10 @@ static const struct luaL_Reg gfx_lib[] = { { "setVBlankWait", gfx_setVBlankWait }, { "waitForVBlank", gfx_waitForVBlank }, { "vramSpaceFree", gfx_vramSpaceFree }, - { "line", gfx_line }, { "point", gfx_point }, + { "line", gfx_line }, + { "triangle", gfx_triangle }, + { "linedTriangle", gfx_linedTriangle }, { "rectangle", gfx_rectangle }, { "linedRectangle", gfx_linedRectangle }, { "circle", gfx_circle }, @@ -709,56 +781,65 @@ static const struct luaL_Reg target_methods[] = { Constants @section constants */ -// Constants struct { char *name; int value; } gfx_constants[] = { /*** Constant used to select the top screen. It is equal to `0`. @field TOP */ - { "TOP", GFX_TOP }, + { "TOP", GFX_TOP }, /*** Constant used to select the bottom screen. It is equal to `1`. @field BOTTOM */ - { "BOTTOM", GFX_BOTTOM }, + { "BOTTOM", GFX_BOTTOM }, /*** Constant used to select the left eye. It is equal to `0`. @field LEFT */ - { "LEFT", GFX_LEFT }, + { "LEFT", GFX_LEFT }, /*** Constant used to select the right eye. It is equal to `1`. @field RIGHT */ - { "RIGHT", GFX_RIGHT }, + { "RIGHT", GFX_RIGHT }, /*** The top screen height, in pixels. It is equal to `240`. @field TOP_HEIGHT */ - { "TOP_HEIGHT", 240 }, + { "TOP_HEIGHT", 240 }, /*** The top screen width, in pixels. It is equal to `400`. @field TOP_WIDTH */ - { "TOP_WIDTH", 400 }, + { "TOP_WIDTH", 400 }, /*** The bottom screen height, in pixels. It is equal to `240`. @field BOTTOM_HEIGHT */ - { "BOTTOM_HEIGHT", 240 }, + { "BOTTOM_HEIGHT", 240 }, /*** The bottom screen width, in pixels. It is equal to `320`. @field BOTTOM_WIDTH */ - { "BOTTOM_WIDTH", 320 }, + { "BOTTOM_WIDTH", 320 }, + /*** + Represents a vertical gradient drawn from the top (first color) to the bottom (second color). + @field TOP_TO_BOTTOM + */ + { "TOP_TO_BOTTOM", SF2D_TOP_TO_BOTTOM }, + /*** + Represents a horizontal gradient drawn from the left (first color) to the right (second color). + @field LEFT_TO_RIGHT + */ + { "LEFT_TO_RIGHT", SF2D_LEFT_TO_RIGHT }, { NULL, 0 } };