1
0
Fork 0
mirror of https://github.com/ctruLua/ctruLua.git synced 2025-10-28 08:49:30 +00:00

Updated all the libs, added citro3d, added ctr.swkbd (WIP, untested)

This commit is contained in:
Firew0lf 2016-08-05 17:30:24 +02:00
parent 68a44645f7
commit 49c87e5526
97 changed files with 7341 additions and 944 deletions

View file

@ -2,7 +2,6 @@
#include <string.h>
#include <math.h>
#include "sf2d.h"
#include "sf2d_private.h"
#ifndef M_PI
#define M_PI (3.14159265358979323846)
@ -10,159 +9,98 @@
#define TEX_MIN_SIZE 32
static unsigned int nibbles_per_pixel(sf2d_texfmt format)
//Grabbed from: http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
unsigned int next_pow2(unsigned int v)
{
switch (format) {
case TEXFMT_RGBA8:
return 8;
case TEXFMT_RGB8:
return 6;
case TEXFMT_RGB5A1:
case TEXFMT_RGB565:
case TEXFMT_RGBA4:
case TEXFMT_IA8:
return 4;
case TEXFMT_A4:
return 1;
case TEXFMT_I8:
case TEXFMT_A8:
case TEXFMT_IA4:
default:
return 2;
}
}
static int calc_buffer_size(sf2d_texfmt pixel_format, int width, int height)
{
return width * height * (nibbles_per_pixel(pixel_format)>>1);
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return v >= TEX_MIN_SIZE ? v : TEX_MIN_SIZE;
}
sf2d_texture *sf2d_create_texture(int width, int height, sf2d_texfmt pixel_format, sf2d_place place)
{
int pow2_w = next_pow2(width);
int pow2_h = next_pow2(height);
if (pow2_w < TEX_MIN_SIZE) pow2_w = TEX_MIN_SIZE;
if (pow2_h < TEX_MIN_SIZE) pow2_h = TEX_MIN_SIZE;
int data_size = calc_buffer_size(pixel_format, pow2_w, pow2_h);
void *data;
sf2d_texture *texture = calloc(1, sizeof(*texture));
if (!texture) return NULL;
bool success = false;
texture->width = width;
texture->height = height;
if (place == SF2D_PLACE_RAM) {
// If there's not enough linear heap space, return
if (linearSpaceFree() < data_size) {
return NULL;
}
data = linearMemAlign(data_size, 0x80);
success = C3D_TexInit(&texture->tex, next_pow2(width), next_pow2(height), pixel_format);
} else if (place == SF2D_PLACE_VRAM) {
// If there's not enough VRAM heap space, return
if (vramSpaceFree() < data_size) {
return NULL;
}
data = vramMemAlign(data_size, 0x80);
} else if (place == SF2D_PLACE_TEMP) {
if (sf2d_pool_space_free() < data_size) {
return NULL;
}
data = sf2d_pool_memalign(data_size, 0x80);
} else {
//wot?
success = C3D_TexInitVRAM(&texture->tex, next_pow2(width), next_pow2(height), pixel_format);
}
if (!success) {
free(texture);
return NULL;
}
sf2d_texture *texture = malloc(sizeof(*texture));
texture->tiled = 0;
texture->place = place;
texture->pixel_format = pixel_format;
texture->params = GPU_TEXTURE_MAG_FILTER(GPU_NEAREST)
| GPU_TEXTURE_MIN_FILTER(GPU_NEAREST)
| GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_BORDER)
| GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_BORDER);
texture->width = width;
texture->height = height;
texture->pow2_w = pow2_w;
texture->pow2_h = pow2_h;
texture->data_size = data_size;
texture->data = data;
if (place == SF2D_PLACE_VRAM) {
GX_MemoryFill(texture->data, 0x00000000, (u32*)&((u8*)texture->data)[texture->data_size], GX_FILL_TRIGGER | GX_FILL_32BIT_DEPTH,
NULL, 0x00000000, NULL, 0);
gspWaitForPSC0();
} else {
memset(texture->data, 0, texture->data_size);
}
C3D_TexSetWrap(&texture->tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER);
return texture;
}
sf2d_rendertarget *sf2d_create_rendertarget(int width, int height)
{
sf2d_texture *tx = sf2d_create_texture(width, height, TEXFMT_RGBA8, SF2D_PLACE_RAM);
sf2d_rendertarget *rt = malloc(sizeof(*rt));
//memcpy(rt, tx, sizeof(*tx));
rt->texture = *tx;
free(tx);
//tx = * rt->texture;
//rt->projection
sf2d_rendertarget *rt = calloc(1, sizeof(*rt));
if (!rt) return NULL;
matrix_init_orthographic(rt->projection, 0.0f, width, height, 0.0f, 0.0f, 1.0f);
matrix_rotate_z(rt->projection, M_PI / 2.0f);
rt->target = C3D_RenderTargetCreate(height, width, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
if (!rt->target)
{
free(rt);
return NULL;
}
Mtx_OrthoTilt(&rt->projection, 0.0f, width, height, 0.0f, 0.0f, 1.0f, true);
return rt;
}
void sf2d_free_texture(sf2d_texture *texture)
{
if (texture) {
if (texture->place == SF2D_PLACE_RAM) {
linearFree(texture->data);
} else if (texture->place == SF2D_PLACE_VRAM) {
vramFree(texture->data);
}
C3D_TexDelete(&texture->tex);
free(texture);
}
}
void sf2d_free_target(sf2d_rendertarget *target)
{
sf2d_free_texture(&(target->texture));
//free(target); // unnecessary since the texture is the start of the target struct
C3D_RenderTargetDelete(target->target);
free(target);
}
void sf2d_clear_target(sf2d_rendertarget *target, u32 color) {
if (color == 0) { // if fully transparent, take a shortcut
memset(target->texture.data, 0, target->texture.width * target->texture.height * 4);
sf2d_texture_tile32(&(target->texture));
return;
}
void sf2d_clear_target(sf2d_rendertarget *target, u32 color)
{
color = ((color>>24)&0x000000FF) | ((color>>8)&0x0000FF00) | ((color<<8)&0x00FF0000) | ((color<<24)&0xFF000000); // reverse byte order
int itarget = target->texture.width * target->texture.height;
for (int i = 0; i < itarget; i++) { memcpy(target->texture.data + i*4, &color, 4); }
sf2d_texture_tile32(&(target->texture));
C3D_RenderTargetSetClear(target->target, C3D_CLEAR_ALL, color, 0);
}
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));
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);
GSPGPU_FlushDataCache(texture->tex.data, texture->tex.size);
C3D_SafeDisplayTransfer(
(u32*)data,
GX_BUFFER_DIM(w, h),
(u32*)texture->tex.data,
GX_BUFFER_DIM(texture->tex.width, texture->tex.height),
flags
);
gspWaitForPPF();
texture->tiled = 1;
}
@ -170,14 +108,14 @@ void sf2d_fill_texture_from_RGBA8(sf2d_texture *dst, const void *rgba8, int sour
{
// TODO: add support for non-RGBA8 textures
u8 *tmp = linearAlloc((dst->pow2_w * dst->pow2_h)<<2);
u8 *tmp = linearAlloc((dst->tex.width * dst->tex.height)<<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] = __builtin_bswap32(((u32 *)rgba8)[i*source_w + j]);
((u32 *)tmp)[i*dst->tex.width + j] = __builtin_bswap32(((u32 *)rgba8)[i*source_w + j]);
}
}
sf2d_texture_tile32_hardware(dst, tmp, dst->pow2_w, dst->pow2_h);
sf2d_texture_tile32_hardware(dst, tmp, dst->tex.width, dst->tex.height);
linearFree(tmp);
}
@ -190,86 +128,45 @@ sf2d_texture *sf2d_create_texture_mem_RGBA8(const void *src_buffer, int src_w, i
return tex;
}
static inline int sf2d_get_texunit(GPU_TEXUNIT unit)
{
switch (unit) {
case GPU_TEXUNIT0: return 0;
case GPU_TEXUNIT1: return 1;
case GPU_TEXUNIT2: return 2;
default: return -1;
}
}
void sf2d_bind_texture(const sf2d_texture *texture, GPU_TEXUNIT unit)
{
GPU_SetTextureEnable(unit);
C3D_TexBind(sf2d_get_texunit(unit), (C3D_Tex*)&texture->tex);
GPU_SetTexEnv(
0,
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_TEXTURE0, GPU_TEXTURE0),
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_TEXTURE0, GPU_TEXTURE0),
GPU_TEVOPERANDS(0, 0, 0),
GPU_TEVOPERANDS(0, 0, 0),
GPU_REPLACE, GPU_REPLACE,
0xFFFFFFFF
);
GPU_SetTexture(
unit,
(u32 *)osConvertVirtToPhys(texture->data),
texture->pow2_w,
texture->pow2_h,
texture->params,
texture->pixel_format
);
C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, 0, 0);
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0);
C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE);
}
void sf2d_bind_texture_color(const sf2d_texture *texture, GPU_TEXUNIT unit, u32 color)
{
GPU_SetTextureEnable(unit);
C3D_TexBind(sf2d_get_texunit(unit), (C3D_Tex*)&texture->tex);
GPU_SetTexEnv(
0,
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, GPU_CONSTANT),
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, GPU_CONSTANT),
GPU_TEVOPERANDS(0, 0, 0),
GPU_TEVOPERANDS(0, 0, 0),
GPU_MODULATE, GPU_MODULATE,
color
);
GPU_SetTexture(
unit,
(u32 *)osConvertVirtToPhys(texture->data),
texture->pow2_w,
texture->pow2_h,
texture->params,
texture->pixel_format
);
}
void sf2d_bind_texture_parameters(const sf2d_texture *texture, GPU_TEXUNIT unit, unsigned int params)
{
GPU_SetTextureEnable(unit);
GPU_SetTexEnv(
0,
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_TEXTURE0, GPU_TEXTURE0),
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_TEXTURE0, GPU_TEXTURE0),
GPU_TEVOPERANDS(0, 0, 0),
GPU_TEVOPERANDS(0, 0, 0),
GPU_REPLACE, GPU_REPLACE,
0xFFFFFFFF
);
GPU_SetTexture(
unit,
(u32 *)osConvertVirtToPhys(texture->data),
texture->pow2_w,
texture->pow2_h,
params,
texture->pixel_format
);
C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_CONSTANT, 0);
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0);
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
C3D_TexEnvColor(env, color);
}
void sf2d_texture_set_params(sf2d_texture *texture, u32 params)
{
texture->params = params;
texture->tex.param = params;
}
int sf2d_texture_get_params(const sf2d_texture *texture)
{
return texture->params;
return texture->tex.param;
}
static inline void sf2d_draw_texture_generic(const sf2d_texture *texture, int x, int y)
@ -285,27 +182,24 @@ static inline void sf2d_draw_texture_generic(const sf2d_texture *texture, int x,
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};
float u = texture->width/(float)texture->pow2_w;
float v = texture->height/(float)texture->pow2_h;
float u = texture->width/(float)texture->tex.width;
float v = texture->height/(float)texture->tex.height;
vertices[0].texcoord = (sf2d_vector_2f){0.0f, 0.0f};
vertices[1].texcoord = (sf2d_vector_2f){u, 0.0f};
vertices[2].texcoord = (sf2d_vector_2f){0.0f, v};
vertices[3].texcoord = (sf2d_vector_2f){u, v};
GPU_SetAttributeBuffers(
2, // number of attributes
(u32*)osConvertVirtToPhys(vertices),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
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
);
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
AttrInfo_Init(attrInfo);
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
}
void sf2d_draw_texture(const sf2d_texture *texture, int x, int y)
@ -344,8 +238,8 @@ static inline void sf2d_draw_texture_rotate_hotspot_generic(const sf2d_texture *
vertices[3].position.y = h - center_y;
vertices[3].position.z = SF2D_DEFAULT_DEPTH;
float u = w/(float)texture->pow2_w;
float v = h/(float)texture->pow2_h;
float u = w/(float)texture->tex.width;
float v = h/(float)texture->tex.height;
vertices[0].texcoord = (sf2d_vector_2f){0.0f, 0.0f};
vertices[1].texcoord = (sf2d_vector_2f){u, 0.0f};
@ -362,19 +256,16 @@ static inline void sf2d_draw_texture_rotate_hotspot_generic(const sf2d_texture *
vertices[i].position.y = _x*s + _y*c + y;
}
GPU_SetAttributeBuffers(
2, // number of attributes
(u32*)osConvertVirtToPhys(vertices),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
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
);
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
AttrInfo_Init(attrInfo);
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
}
void sf2d_draw_texture_rotate_hotspot(const sf2d_texture *texture, int x, int y, float rad, float center_x, float center_y)
@ -428,8 +319,8 @@ static inline void sf2d_draw_texture_rotate_scale_hotspot_generic(const sf2d_tex
vertices[3].position.y = h - center_y * scale_y;
vertices[3].position.z = SF2D_DEFAULT_DEPTH;
float u = w/(float)texture->pow2_w;
float v = h/(float)texture->pow2_h;
float u = w/(float)texture->tex.width;
float v = h/(float)texture->tex.height;
vertices[0].texcoord = (sf2d_vector_2f){0.0f, 0.0f};
vertices[1].texcoord = (sf2d_vector_2f){u, 0.0f};
@ -446,19 +337,16 @@ static inline void sf2d_draw_texture_rotate_scale_hotspot_generic(const sf2d_tex
vertices[i].position.y = _x*s + _y*c + y;
}
GPU_SetAttributeBuffers(
2, // number of attributes
(u32*)osConvertVirtToPhys(vertices),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
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
);
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
AttrInfo_Init(attrInfo);
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
}
void sf2d_draw_texture_rotate_scale_hotspot(const sf2d_texture *texture, int x, int y, float rad, float scale_x, float scale_y, float center_x, float center_y)
@ -483,29 +371,26 @@ static inline void sf2d_draw_texture_part_generic(const sf2d_texture *texture, i
vertices[2].position = (sf2d_vector_3f){(float)x, (float)y+tex_h, SF2D_DEFAULT_DEPTH};
vertices[3].position = (sf2d_vector_3f){(float)x+tex_w, (float)y+tex_h, SF2D_DEFAULT_DEPTH};
float u0 = tex_x/(float)texture->pow2_w;
float v0 = tex_y/(float)texture->pow2_h;
float u1 = (tex_x+tex_w)/(float)texture->pow2_w;
float v1 = (tex_y+tex_h)/(float)texture->pow2_h;
float u0 = tex_x/(float)texture->tex.width;
float v0 = tex_y/(float)texture->tex.height;
float u1 = (tex_x+tex_w)/(float)texture->tex.width;
float v1 = (tex_y+tex_h)/(float)texture->tex.height;
vertices[0].texcoord = (sf2d_vector_2f){u0, v0};
vertices[1].texcoord = (sf2d_vector_2f){u1, v0};
vertices[2].texcoord = (sf2d_vector_2f){u0, v1};
vertices[3].texcoord = (sf2d_vector_2f){u1, v1};
GPU_SetAttributeBuffers(
2, // number of attributes
(u32*)osConvertVirtToPhys(vertices),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
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
);
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
AttrInfo_Init(attrInfo);
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
}
void sf2d_draw_texture_part(const sf2d_texture *texture, int x, int y, int tex_x, int tex_y, int tex_w, int tex_h)
@ -533,27 +418,24 @@ static inline void sf2d_draw_texture_scale_generic(const sf2d_texture *texture,
vertices[2].position = (sf2d_vector_3f){(float)x, (float)y+hs, SF2D_DEFAULT_DEPTH};
vertices[3].position = (sf2d_vector_3f){(float)x+ws, (float)y+hs, SF2D_DEFAULT_DEPTH};
float u = texture->width/(float)texture->pow2_w;
float v = texture->height/(float)texture->pow2_h;
float u = texture->width/(float)texture->tex.width;
float v = texture->height/(float)texture->tex.height;
vertices[0].texcoord = (sf2d_vector_2f){0.0f, 0.0f};
vertices[1].texcoord = (sf2d_vector_2f){u, 0.0f};
vertices[2].texcoord = (sf2d_vector_2f){0.0f, v};
vertices[3].texcoord = (sf2d_vector_2f){u, v};
GPU_SetAttributeBuffers(
2, // number of attributes
(u32*)osConvertVirtToPhys(vertices),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
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
);
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
AttrInfo_Init(attrInfo);
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
}
void sf2d_draw_texture_scale(const sf2d_texture *texture, int x, int y, float x_scale, float y_scale)
@ -573,10 +455,10 @@ static inline void sf2d_draw_texture_part_scale_generic(const sf2d_texture *text
sf2d_vertex_pos_tex *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_tex), 8);
if (!vertices) return;
float u0 = tex_x/(float)texture->pow2_w;
float v0 = tex_y/(float)texture->pow2_h;
float u1 = (tex_x+tex_w)/(float)texture->pow2_w;
float v1 = (tex_y+tex_h)/(float)texture->pow2_h;
float u0 = tex_x/(float)texture->tex.width;
float v0 = tex_y/(float)texture->tex.height;
float u1 = (tex_x+tex_w)/(float)texture->tex.width;
float v1 = (tex_y+tex_h)/(float)texture->tex.height;
vertices[0].texcoord = (sf2d_vector_2f){u0, v0};
vertices[1].texcoord = (sf2d_vector_2f){u1, v0};
@ -591,19 +473,16 @@ static inline void sf2d_draw_texture_part_scale_generic(const sf2d_texture *text
vertices[2].position = (sf2d_vector_3f){(float)x, (float)y+tex_h, SF2D_DEFAULT_DEPTH};
vertices[3].position = (sf2d_vector_3f){(float)x+tex_w, (float)y+tex_h, SF2D_DEFAULT_DEPTH};
GPU_SetAttributeBuffers(
2, // number of attributes
(u32*)osConvertVirtToPhys(vertices),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
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
);
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
AttrInfo_Init(attrInfo);
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
}
void sf2d_draw_texture_part_scale(const sf2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale)
@ -618,23 +497,23 @@ 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);
}
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)
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)
{
sf2d_vertex_pos_tex *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_tex), 8);
if (!vertices) return;
int w = tex_w;
int h = tex_h;
int w2 = (tex_w * x_scale)/2.0f;
int h2 = (tex_h * y_scale)/2.0f;
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) (w - center_x) * x_scale, (float)-center_y * y_scale, 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) (w - center_x) * x_scale, (float) h - center_y * y_scale, SF2D_DEFAULT_DEPTH};
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};
float u0 = tex_x/(float)texture->pow2_w;
float v0 = tex_y/(float)texture->pow2_h;
float u1 = (tex_x+tex_w)/(float)texture->pow2_w;
float v1 = (tex_y+tex_h)/(float)texture->pow2_h;
float u0 = tex_x/(float)texture->tex.width;
float v0 = tex_y/(float)texture->tex.height;
float u1 = (tex_x+tex_w)/(float)texture->tex.width;
float v1 = (tex_y+tex_h)/(float)texture->tex.height;
vertices[0].texcoord = (sf2d_vector_2f){u0, v0};
vertices[1].texcoord = (sf2d_vector_2f){u1, v0};
@ -651,37 +530,28 @@ static inline void sf2d_draw_texture_part_rotate_scale_hotspot_generic(const sf2
vertices[i].position.y = _x*s + _y*c + y;
}
GPU_SetAttributeBuffers(
2, // number of attributes
(u32*)osConvertVirtToPhys(vertices),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
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
);
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
AttrInfo_Init(attrInfo);
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
}
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_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);
sf2d_draw_texture_part_rotate_scale_generic(texture, x, y, rad, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale);
}
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_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);
sf2d_draw_texture_part_rotate_scale_generic(texture, x, y, rad, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale);
}
static inline void sf2d_draw_texture_depth_generic(const sf2d_texture *texture, int x, int y, signed short z)
@ -698,27 +568,24 @@ static inline void sf2d_draw_texture_depth_generic(const sf2d_texture *texture,
vertices[2].position = (sf2d_vector_3f){(float)x, (float)y+h, depth};
vertices[3].position = (sf2d_vector_3f){(float)x+w, (float)y+h, depth};
float u = texture->width/(float)texture->pow2_w;
float v = texture->height/(float)texture->pow2_h;
float u = texture->width/(float)texture->tex.width;
float v = texture->height/(float)texture->tex.height;
vertices[0].texcoord = (sf2d_vector_2f){0.0f, 0.0f};
vertices[1].texcoord = (sf2d_vector_2f){u, 0.0f};
vertices[2].texcoord = (sf2d_vector_2f){0.0f, v};
vertices[3].texcoord = (sf2d_vector_2f){u, v};
GPU_SetAttributeBuffers(
2, // number of attributes
(u32*)osConvertVirtToPhys(vertices),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
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
);
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
AttrInfo_Init(attrInfo);
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
}
void sf2d_draw_texture_depth(const sf2d_texture *texture, int x, int y, signed short z)
@ -733,8 +600,7 @@ void sf2d_draw_texture_depth_blend(const sf2d_texture *texture, int x, int y, si
sf2d_draw_texture_depth_generic(texture, x, y, z);
}
void sf2d_draw_quad_uv(const sf2d_texture *texture, float left, float top, float right, float bottom, float u0, float v0, float u1, float v1, unsigned int params)
void sf2d_draw_quad_uv_current(float left, float top, float right, float bottom, float u0, float v0, float u1, float v1)
{
sf2d_vertex_pos_tex *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_tex), 8);
if (!vertices) return;
@ -749,21 +615,28 @@ void sf2d_draw_quad_uv(const sf2d_texture *texture, float left, float top, float
vertices[2].texcoord = (sf2d_vector_2f){u0, v1};
vertices[3].texcoord = (sf2d_vector_2f){u1, v1};
sf2d_bind_texture_parameters(texture, GPU_TEXUNIT0, params);
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
AttrInfo_Init(attrInfo);
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
GPU_SetAttributeBuffers(
2, // number of attributes
(u32*)osConvertVirtToPhys(vertices),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
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
);
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
}
void sf2d_draw_quad_uv(const sf2d_texture *texture, float left, float top, float right, float bottom, float u0, float v0, float u1, float v1)
{
sf2d_bind_texture(texture, GPU_TEXUNIT0);
sf2d_draw_quad_uv_current(left, top, right, bottom, u0, v0, u1, v1);
}
void sf2d_draw_quad_uv_blend(const sf2d_texture *texture, float left, float top, float right, float bottom, float u0, float v0, float u1, float v1, u32 color)
{
sf2d_bind_texture_color(texture, GPU_TEXUNIT0, color);
sf2d_draw_quad_uv_current(left, top, right, bottom, u0, v0, u1, v1);
}
// Grabbed from Citra Emulator (citra/src/video_core/utils.h)
@ -786,25 +659,25 @@ static inline u32 get_morton_offset(u32 x, u32 y, u32 bytes_per_pixel)
void sf2d_set_pixel(sf2d_texture *texture, int x, int y, u32 new_color)
{
y = (texture->pow2_h - 1 - y);
y = (texture->tex.height - 1 - y);
if (texture->tiled) {
u32 coarse_y = y & ~7;
u32 offset = get_morton_offset(x, y, 4) + coarse_y * texture->pow2_w * 4;
*(u32 *)(texture->data + offset) = new_color;
u32 offset = get_morton_offset(x, y, 4) + coarse_y * texture->tex.width * 4;
*(u32 *)(texture->tex.data + offset) = new_color;
} else {
((u32 *)texture->data)[x + y * texture->pow2_w] = new_color;
((u32 *)texture->tex.data)[x + y * texture->tex.width] = new_color;
}
}
u32 sf2d_get_pixel(sf2d_texture *texture, int x, int y)
{
y = (texture->pow2_h - 1 - y);
y = (texture->tex.height - 1 - y);
if (texture->tiled) {
u32 coarse_y = y & ~7;
u32 offset = get_morton_offset(x, y, 4) + coarse_y * texture->pow2_w * 4;
return *(u32 *)(texture->data + offset);
u32 offset = get_morton_offset(x, y, 4) + coarse_y * texture->tex.width * 4;
return *(u32 *)(texture->tex.data + offset);
} else {
return ((u32 *)texture->data)[x + y * texture->pow2_w];
return ((u32 *)texture->tex.data)[x + y * texture->tex.width];
}
}
@ -814,21 +687,21 @@ void sf2d_texture_tile32(sf2d_texture *texture)
if (texture->tiled) return;
// TODO: add support for non-RGBA8 textures
u8 *tmp = linearAlloc(texture->pow2_w * texture->pow2_h * 4);
u8 *tmp = linearAlloc(texture->tex.width * texture->tex.height * 4);
int i, j;
for (j = 0; j < texture->pow2_h; j++) {
for (i = 0; i < texture->pow2_w; i++) {
for (j = 0; j < texture->tex.height; j++) {
for (i = 0; i < texture->tex.width; i++) {
u32 coarse_y = j & ~7;
u32 dst_offset = get_morton_offset(i, j, 4) + coarse_y * texture->pow2_w * 4;
u32 dst_offset = get_morton_offset(i, j, 4) + coarse_y * texture->tex.width * 4;
u32 v = ((u32 *)texture->data)[i + (texture->pow2_h - 1 - j)*texture->pow2_w];
u32 v = ((u32 *)texture->tex.data)[i + (texture->tex.height - 1 - j)*texture->tex.width];
*(u32 *)(tmp + dst_offset) = __builtin_bswap32(v); /* RGBA8 -> ABGR8 */
}
}
memcpy(texture->data, tmp, texture->pow2_w*texture->pow2_h*4);
memcpy(texture->tex.data, tmp, texture->tex.width*texture->tex.height*4);
linearFree(tmp);
texture->tiled = 1;