diff --git a/CMakeLists.txt b/CMakeLists.txt index 1000b22..0805316 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,6 +152,9 @@ add_object_library_macros(GS_PRIMITIVE_OBJS ee/gs/src/gsPrimitive.c gsKit_prim_line_strip gsKit_prim_line_strip_3d gsKit_prim_sprite + gsKit_prim_list_sprite_gouraud_3d + gsKit_prim_list_sprite_flat + gsKit_prim_list_sprite_flat_color gsKit_prim_triangle_3d gsKit_prim_triangle_strip gsKit_prim_triangle_strip_3d @@ -186,6 +189,8 @@ add_object_library_macros(GS_TEXTURE_OBJS ee/gs/src/gsTexture.c gsKit_prim_sprite_striped_texture_3d gsKit_prim_triangle_texture_3d gskit_prim_list_sprite_texture_uv_3d + gskit_prim_list_sprite_texture_uv_flat + gskit_prim_list_sprite_texture_uv_flat_color gsKit_prim_triangle_goraud_texture_3d gsKit_prim_list_triangle_goraud_texture_uv_3d gsKit_prim_list_triangle_goraud_texture_stq_3d diff --git a/ee/gs/include/gsInit.h b/ee/gs/include/gsInit.h index 7e819b6..8562067 100644 --- a/ee/gs/include/gsInit.h +++ b/ee/gs/include/gsInit.h @@ -970,18 +970,25 @@ typedef union { u16 y; u32 z; }; -} __attribute__((packed,aligned(8))) gs_xyz_t; +} __attribute__((packed)) gs_xyz_t; typedef union { - u64 rgbaq; + u32 rgba; struct { u8 r; u8 g; u8 b; u8 a; + }; +} __attribute__((packed)) gs_rgba_t; + +typedef union { + u64 rgbaq; + struct { + gs_rgba_t components; float q; }; -} __attribute__((packed,aligned(8))) gs_rgbaq_t; +} __attribute__((packed)) gs_rgbaq_t; typedef union { u64 st; @@ -989,7 +996,7 @@ typedef union { float s; float t; }; -} __attribute__((packed, aligned(8))) gs_stq_t; +} __attribute__((packed)) gs_stq_t; typedef union { u128 xyz2; @@ -997,7 +1004,7 @@ typedef union { gs_xyz_t xyz; u64 tag; }; -} __attribute__((packed,aligned(8))) gs_xyz2; +} __attribute__((packed)) gs_xyz2; typedef union { u128 rgbaq; @@ -1005,15 +1012,24 @@ typedef union { gs_rgbaq_t color; u64 tag; }; -} __attribute__((packed,aligned(8))) gs_rgbaq; +} __attribute__((packed)) gs_rgbaq; + +typedef union { + u64 uv; + struct { + u16 u; + u16 v; + u32 notused; + }; +} __attribute__((packed)) gs_uv_t; typedef union { u128 uv; struct { - u64 coord; + gs_uv_t coord; u64 tag; }; -} __attribute__((packed,aligned(8))) gs_uv; +} __attribute__((packed)) gs_uv; typedef union { u128 stq; @@ -1021,7 +1037,7 @@ typedef union { gs_stq_t st; u64 tag; }; -} __attribute__((packed, aligned(8))) gs_stq; +} __attribute__((packed)) gs_stq; /// gsKit Point Primitive Structure /// This structure holds all relevant data for any @@ -1041,6 +1057,13 @@ struct gsPrimUVPoint }; typedef struct gsPrimUVPoint GSPRIMUVPOINT; +struct gsPrimUVPointFlat +{ + gs_uv uv; + gs_xyz2 xyz2; +}; +typedef struct gsPrimUVPointFlat GSPRIMUVPOINTFLAT; + struct gsPrimSTQPoint { gs_rgbaq rgbaq; diff --git a/ee/gs/include/gsInline.h b/ee/gs/include/gsInline.h index cf12316..e065433 100644 --- a/ee/gs/include/gsInline.h +++ b/ee/gs/include/gsInline.h @@ -173,16 +173,38 @@ static inline gs_rgbaq color_to_RGBAQ(uint8_t r, uint8_t g, uint8_t b, uint8_t a { gs_rgbaq res; - res.color.r = r; - res.color.g = g; - res.color.b = b; - res.color.a = a; + res.color.components.r = r; + res.color.components.g = g; + res.color.components.b = b; + res.color.components.a = a; res.color.q = q; res.tag = GS_RGBAQ; return res; } +// If STQ coordinates are used set q to 1.0f otherwise keep it as 0.0f +static inline gs_rgbaq rgba_to_RGBAQ(uint32_t rgba, float q) +{ + gs_rgbaq res; + + res.color.components.rgba = rgba; + res.color.q = q; + res.tag = GS_RGBAQ; + + return res; +} + +static inline gs_rgbaq rgbaq_to_RGBAQ(uint64_t rgbaq) +{ + gs_rgbaq res; + + res.color.rgbaq = rgbaq; + res.tag = GS_RGBAQ; + + return res; +} + static inline gs_uv vertex_to_UV(const GSTEXTURE *Texture, float u, float v) { gs_uv res; @@ -190,7 +212,8 @@ static inline gs_uv vertex_to_UV(const GSTEXTURE *Texture, float u, float v) int iu = gsKit_float_to_int_u(Texture, u); int iv = gsKit_float_to_int_v(Texture, v); - res.coord = GS_SETREG_UV(iu, iv); + res.coord.u = iu; + res.coord.v = iv; res.tag = GS_UV; return res; diff --git a/ee/gs/include/gsPrimitive.h b/ee/gs/include/gsPrimitive.h index cc523e2..8d0b8ea 100644 --- a/ee/gs/include/gsPrimitive.h +++ b/ee/gs/include/gsPrimitive.h @@ -46,6 +46,9 @@ void gsKit_prim_line_strip(GSGLOBAL *gsGlobal, float *LineStrip, int segments, i void gsKit_prim_line_strip_3d(GSGLOBAL *gsGlobal, float *LineStrip, int segments, u64 color); void gsKit_prim_sprite(GSGLOBAL *gsGlobal, float x1, float y1, float x2, float y2, int iz, u64 color); +void gsKit_prim_list_sprite_gouraud_3d(GSGLOBAL *gsGlobal, int count, const GSPRIMPOINT *vertices); +void gsKit_prim_list_sprite_flat(GSGLOBAL *gsGlobal, int count, const u128 *flatContent); +void gsKit_prim_list_sprite_flat_color(GSGLOBAL *gsGlobal, gs_rgbaq color, int count, const gs_xyz2 *vertices); void gsKit_prim_triangle_3d(GSGLOBAL *gsGlobal, float x1, float y1, int iz1, float x2, float y2, int iz2, diff --git a/ee/gs/include/gsTexture.h b/ee/gs/include/gsTexture.h index faad80e..b5f236a 100644 --- a/ee/gs/include/gsTexture.h +++ b/ee/gs/include/gsTexture.h @@ -127,6 +127,8 @@ void gsKit_prim_sprite_striped_texture_3d(GSGLOBAL *gsGlobal, const GSTEXTURE *T u64 color); void gskit_prim_list_sprite_texture_uv_3d(GSGLOBAL *gsGlobal, const GSTEXTURE *Texture, int count, const GSPRIMUVPOINT *vertices); +void gskit_prim_list_sprite_texture_uv_flat(GSGLOBAL *gsGlobal, const GSTEXTURE *Texture, int count, const u128 *flatContent); +void gskit_prim_list_sprite_texture_uv_flat_color(GSGLOBAL *gsGlobal, const GSTEXTURE *Texture, gs_rgbaq color, int count, const GSPRIMUVPOINTFLAT *vertices); void gsKit_prim_triangle_texture_3d(GSGLOBAL *gsGlobal, GSTEXTURE *Texture, float x1, float y1, int iz1, float u1, float v1, diff --git a/ee/gs/src/gsCore.c b/ee/gs/src/gsCore.c index 43ab10d..cb43f5b 100644 --- a/ee/gs/src/gsCore.c +++ b/ee/gs/src/gsCore.c @@ -253,29 +253,28 @@ void gsKit_remove_hsync_handler(int callback_id) #endif #if F_gsKit_clear +#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) void gsKit_clear(GSGLOBAL *gsGlobal, u64 color) { u8 PrevZState; u8 strips; u8 remain; + u8 index; u32 pos; + u8 slices = (gsGlobal->Width + 63)/ 64; + u32 count = (slices * 2) + 1; + u128 flat_content[count]; PrevZState = gsGlobal->Test->ZTST; gsKit_set_test(gsGlobal, GS_ZTEST_OFF); - strips = gsGlobal->Width / 64; - remain = gsGlobal->Width % 64; - pos = 0; - strips++; - while(strips-- > 0) + flat_content[0] = (u128)rgbaq_to_RGBAQ(color).rgbaq; + for (index = 0; index < slices; index++) { - gsKit_prim_sprite(gsGlobal, pos, 0, pos + 64, gsGlobal->Height, 0, color); - pos += 64; - } - if(remain > 0) - { - gsKit_prim_sprite(gsGlobal, pos, 0, remain + pos, gsGlobal->Height, 0, color); + flat_content[index * 2 + 1] = vertex_to_XYZ2(gsGlobal, index * 64, 0, 0).xyz2; + flat_content[index * 2 + 2] = (u128)vertex_to_XYZ2(gsGlobal, MIN((index + 1) * 64, gsGlobal->Width) , gsGlobal->Height, 0).xyz2; } + gsKit_prim_list_sprite_flat(gsGlobal, count, flat_content); gsGlobal->Test->ZTST = PrevZState; gsKit_set_test(gsGlobal, 0); diff --git a/ee/gs/src/gsPrimitive.c b/ee/gs/src/gsPrimitive.c index 362ebb7..2bcc486 100644 --- a/ee/gs/src/gsPrimitive.c +++ b/ee/gs/src/gsPrimitive.c @@ -268,6 +268,89 @@ void gsKit_prim_sprite(GSGLOBAL *gsGlobal, float x1, float y1, float x2, float y } #endif +#if F_gsKit_prim_list_sprite_gouraud_3d +void gsKit_prim_list_sprite_gouraud_3d(GSGLOBAL *gsGlobal, int count, const GSPRIMPOINT *vertices) +{ + u64* p_store; + u64* p_data; + int qsize = (count*2) + 1; + int bytes = count * sizeof(GSPRIMPOINT); + + p_store = p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize*16), GIF_AD); + + if(p_store == gsGlobal->CurQueue->last_tag) + { + *p_data++ = GIF_TAG_AD(qsize); + *p_data++ = GIF_AD; + } + + *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_SPRITE, 1, 0, gsGlobal->PrimFogEnable, + gsGlobal->PrimAlphaEnable, gsGlobal->PrimAAEnable, + 0, gsGlobal->PrimContext, 0); + + *p_data++ = GS_PRIM; + + memcpy(p_data, vertices, bytes); +} +#endif + +#if F_gsKit_prim_list_sprite_flat_color +void gsKit_prim_list_sprite_flat_color(GSGLOBAL *gsGlobal, gs_rgbaq color, int count, const gs_xyz2 *vertices) +{ + u64* p_store; + u64* p_data; + int qsize = count + 2; + int bytes = count * sizeof(gs_xyz2); + + p_store = p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize*16), GIF_AD); + + if(p_store == gsGlobal->CurQueue->last_tag) + { + *p_data++ = GIF_TAG_AD(qsize); + *p_data++ = GIF_AD; + } + + *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_SPRITE, 0, 0, gsGlobal->PrimFogEnable, + gsGlobal->PrimAlphaEnable, gsGlobal->PrimAAEnable, + 0, gsGlobal->PrimContext, 0); + + *p_data++ = GS_PRIM; + + // Copy color + memcpy(p_data, &color, sizeof(gs_rgbaq)); + p_data += 2; // Advance 2 u64, which is 16 bytes the gs_rgbaq struct size + // Copy vertices + memcpy(p_data, vertices, bytes); +} +#endif + +#if F_gsKit_prim_list_sprite_flat +void gsKit_prim_list_sprite_flat(GSGLOBAL *gsGlobal, int count, const u128 *flatContent) +{ + u64* p_store; + u64* p_data; + int qsize = count + 1; + int bytes = count * sizeof(u128); + + p_store = p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize*16), GIF_AD); + + if(p_store == gsGlobal->CurQueue->last_tag) + { + *p_data++ = GIF_TAG_AD(qsize); + *p_data++ = GIF_AD; + } + + *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_SPRITE, 0, 0, gsGlobal->PrimFogEnable, + gsGlobal->PrimAlphaEnable, gsGlobal->PrimAAEnable, + 0, gsGlobal->PrimContext, 0); + + *p_data++ = GS_PRIM; + + memcpy(p_data, flatContent, bytes); +} +#endif + + #if F_gsKit_prim_triangle_3d void gsKit_prim_triangle_3d(GSGLOBAL *gsGlobal, float x1, float y1, int iz1, float x2, float y2, int iz2, diff --git a/ee/gs/src/gsTexture.c b/ee/gs/src/gsTexture.c index a997caa..70c06f1 100644 --- a/ee/gs/src/gsTexture.c +++ b/ee/gs/src/gsTexture.c @@ -734,6 +734,101 @@ void gskit_prim_list_sprite_texture_uv_3d(GSGLOBAL *gsGlobal, const GSTEXTURE *T } #endif +#if F_gskit_prim_list_sprite_texture_uv_flat +void gskit_prim_list_sprite_texture_uv_flat(GSGLOBAL *gsGlobal, const GSTEXTURE *Texture, int count, const u128 *flatContent) +{ + u64* p_data; + u64* p_store; + int tw, th; + + int qsize = (count) + 2; + int bytes = count * sizeof(u128); + + gsKit_set_texfilter(gsGlobal, Texture->Filter); + gsKit_set_tw_th(Texture, &tw, &th); + + p_store = p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize*16), GIF_AD); + + if(p_store == gsGlobal->CurQueue->last_tag) + { + *p_data++ = GIF_TAG_AD(qsize); + *p_data++ = GIF_AD; + } + + if(Texture->VramClut == 0) + { + *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM, + tw, th, gsGlobal->PrimAlphaEnable, 0, + 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD); + } + else + { + *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM, + tw, th, gsGlobal->PrimAlphaEnable, 0, + Texture->VramClut/256, Texture->ClutPSM, 0, 0, GS_CLUT_STOREMODE_LOAD); + } + *p_data++ = GS_TEX0_1 + gsGlobal->PrimContext; + + *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_SPRITE, 0, 1, gsGlobal->PrimFogEnable, + gsGlobal->PrimAlphaEnable, gsGlobal->PrimAAEnable, + 1, gsGlobal->PrimContext, 0); + + *p_data++ = GS_PRIM; + + memcpy(p_data, flatContent, bytes); +} +#endif + +#if F_gskit_prim_list_sprite_texture_uv_flat_color +void gskit_prim_list_sprite_texture_uv_flat_color(GSGLOBAL *gsGlobal, const GSTEXTURE *Texture, gs_rgbaq color, int count, const GSPRIMUVPOINTFLAT *vertices) +{ + u64* p_data; + u64* p_store; + int tw, th; + + int qsize = (count * 2) + 3; + int bytes = count * sizeof(GSPRIMUVPOINTFLAT); + + gsKit_set_texfilter(gsGlobal, Texture->Filter); + gsKit_set_tw_th(Texture, &tw, &th); + + p_store = p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize*16), GIF_AD); + + if(p_store == gsGlobal->CurQueue->last_tag) + { + *p_data++ = GIF_TAG_AD(qsize); + *p_data++ = GIF_AD; + } + + if(Texture->VramClut == 0) + { + *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM, + tw, th, gsGlobal->PrimAlphaEnable, 0, + 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD); + } + else + { + *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM, + tw, th, gsGlobal->PrimAlphaEnable, 0, + Texture->VramClut/256, Texture->ClutPSM, 0, 0, GS_CLUT_STOREMODE_LOAD); + } + *p_data++ = GS_TEX0_1 + gsGlobal->PrimContext; + + *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_SPRITE, 0, 1, gsGlobal->PrimFogEnable, + gsGlobal->PrimAlphaEnable, gsGlobal->PrimAAEnable, + 1, gsGlobal->PrimContext, 0); + + *p_data++ = GS_PRIM; + + // Copy color + memcpy(p_data, &color, sizeof(gs_rgbaq)); + p_data += 2; // Advance 2 u64, which is 16 bytes the gs_rgbaq struct size + // Copy vertices + memcpy(p_data, vertices, bytes); +} +#endif + + #if F_gsKit_prim_triangle_texture_3d void gsKit_prim_triangle_texture_3d(GSGLOBAL *gsGlobal, GSTEXTURE *Texture, float x1, float y1, int iz1, float u1, float v1, diff --git a/examples/atlas/atlas.c b/examples/atlas/atlas.c index 6ecd2ef..988d75c 100644 --- a/examples/atlas/atlas.c +++ b/examples/atlas/atlas.c @@ -81,7 +81,7 @@ int main(int argc, char *argv[]) gsKit_set_clamp(gsGlobal, GS_CMODE_CLAMP); - GSPRIMUVPOINT *verts = (GSPRIMUVPOINT*)malloc(sizeof(GSPRIMUVPOINT) * totalVertices); + GSPRIMUVPOINTFLAT *verts = (GSPRIMUVPOINTFLAT*)malloc(sizeof(GSPRIMUVPOINTFLAT) * totalVertices); for (int i = 0; i < TOTAL_RUNNERS_SCREEN; i++) { int line = i / RUNNER_PER_LINE_SCREEN; int col = i % RUNNER_PER_LINE_SCREEN; @@ -92,10 +92,7 @@ int main(int argc, char *argv[]) int y1 = y0 + RUNNER_HEIGHT; verts[i*2].xyz2 = vertex_to_XYZ2(gsGlobal, x0, y0, 0); - verts[i*2].rgbaq = color; - verts[i*2+1].xyz2 = vertex_to_XYZ2(gsGlobal, x1, y1, 0); - verts[i*2+1].rgbaq = color; } while(1) @@ -108,7 +105,7 @@ int main(int argc, char *argv[]) } gsKit_clear(gsGlobal, White); - gskit_prim_list_sprite_texture_uv_3d(gsGlobal, &atlas, totalVertices, verts); + gskit_prim_list_sprite_texture_uv_flat_color(gsGlobal, &atlas, color, totalVertices, verts); gsKit_queue_exec(gsGlobal); gsKit_sync_flip(gsGlobal);