diff options
author | WlodekM <[email protected]> | 2024-06-16 10:35:45 +0300 |
---|---|---|
committer | WlodekM <[email protected]> | 2024-06-16 10:35:45 +0300 |
commit | abef6da56913f1c55528103e60a50451a39628b1 (patch) | |
tree | b3c8092471ecbb73e568cd0d336efa0e7871ee8d /src/Graphics_Xbox360.c |
initial commit
Diffstat (limited to 'src/Graphics_Xbox360.c')
-rw-r--r-- | src/Graphics_Xbox360.c | 407 |
1 files changed, 407 insertions, 0 deletions
diff --git a/src/Graphics_Xbox360.c b/src/Graphics_Xbox360.c new file mode 100644 index 0000000..71a4efb --- /dev/null +++ b/src/Graphics_Xbox360.c @@ -0,0 +1,407 @@ +#include "Core.h" +#ifdef CC_BUILD_XBOX360 +#include "_GraphicsBase.h" +#include "Errors.h" +#include "Window.h" +#include <xenos/xe.h> +#include <xenos/edram.h> + +#include "../misc/xbox360/ps_coloured.h" +#include "../misc/xbox360/vs_coloured.h" +#include "../misc/xbox360/ps_textured.h" +#include "../misc/xbox360/vs_textured.h" +static struct XenosShader* shdr_tex_vs; +static struct XenosShader* shdr_tex_ps; +static struct XenosShader* shdr_col_vs; +static struct XenosShader* shdr_col_ps; + +static struct XenosDevice device; +static struct XenosDevice* xe; + +static const struct XenosVBFFormat textured_vbf = { +3, { + { XE_USAGE_POSITION, 0, XE_TYPE_FLOAT4 }, + { XE_USAGE_COLOR, 0, XE_TYPE_UBYTE4 }, + { XE_USAGE_TEXCOORD, 0, XE_TYPE_FLOAT2 } +} }; + +static const struct XenosVBFFormat coloured_vbf = { +2, { + { XE_USAGE_POSITION, 0, XE_TYPE_FLOAT4 }, + { XE_USAGE_COLOR, 0, XE_TYPE_UBYTE4 } +} }; + +static void CreateState(void) { + xe = &device; + Xe_Init(xe); + edram_init(xe); + + struct XenosSurface* fb = Xe_GetFramebufferSurface(xe); + Xe_SetRenderTarget(xe, fb); +} + +static void CreateShaders(void) { + shdr_tex_vs = Xe_LoadShaderFromMemory(xe, (void*)vs_textured); + Xe_InstantiateShader(xe, shdr_tex_vs, 0); + Xe_ShaderApplyVFetchPatches(xe, shdr_tex_vs, 0, &textured_vbf); + shdr_tex_ps = Xe_LoadShaderFromMemory(xe, (void*)ps_textured); + Xe_InstantiateShader(xe, shdr_tex_ps, 0); + + shdr_col_vs = Xe_LoadShaderFromMemory(xe, (void*)vs_coloured); + Xe_InstantiateShader(xe, shdr_col_vs, 0); + Xe_ShaderApplyVFetchPatches(xe, shdr_col_vs, 0, &coloured_vbf); + shdr_col_ps = Xe_LoadShaderFromMemory(xe, (void*)ps_coloured); + Xe_InstantiateShader(xe, shdr_col_ps, 0); +} + +void Gfx_Create(void) { + if (!Gfx.Created) { + CreateState(); + CreateShaders(); + } + Gfx.Created = true; + Gfx_SetVertexFormat(VERTEX_FORMAT_COLOURED); + + Gfx.MaxTexWidth = 1024; + Gfx.MaxTexHeight = 1024; + Gfx.MaxTexSize = 512 * 512; +} + +cc_bool Gfx_TryRestoreContext(void) { + return true; +} + +void Gfx_Free(void) { + Gfx_FreeState(); +} + +static void Gfx_FreeState(void) { + FreeDefaultResources(); +} + +static void Gfx_RestoreState(void) { + InitDefaultResources(); + Gfx_SetFaceCulling(false); + SetAlphaBlend(false); + + Xe_SetAlphaFunc(xe, XE_CMP_GREATER); + Xe_SetAlphaRef(xe, 0.5f); + Xe_SetZFunc(xe, XE_CMP_LESSEQUAL); +} + + +/*########################################################################################################################* +*---------------------------------------------------------Textures--------------------------------------------------------* +*#########################################################################################################################*/ +static void SetTextureData(struct XenosSurface* xtex, int x, int y, const struct Bitmap* bmp, int rowWidth, int lvl) { + void* dst = Xe_Surface_LockRect(xe, xtex, x, y, bmp->width, bmp->height, XE_LOCK_WRITE); + + CopyTextureData(dst, bmp->width * 4, bmp, rowWidth << 2); + + Xe_Surface_Unlock(xe, xtex); +} + +static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) { + struct XenosSurface* xtex = Xe_CreateTexture(xe, bmp->width, bmp->height, 1, XE_FMT_8888, 0); + SetTextureData(xtex, 0, 0, bmp, rowWidth, 0); + return xtex; +} + +void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, int rowWidth, cc_bool mipmaps) { + struct XenosSurface* xtex = (struct XenosSurface*)texId; + SetTextureData(xtex, x, y, part, rowWidth, 0); +} + +void Gfx_BindTexture(GfxResourceID texId) { + struct XenosSurface* xtex = (struct XenosSurface*)texId; + Xe_SetTexture(xe, 0, xtex); +} + +void Gfx_DeleteTexture(GfxResourceID* texId) { + struct XenosSurface* xtex = (struct XenosSurface*)(*texId); + if (xtex) Xe_DestroyTexture(xe, xtex); + *texId = NULL; +} + +void Gfx_EnableMipmaps(void) { } // TODO + +void Gfx_DisableMipmaps(void) { } // TODO + + +/*########################################################################################################################* +*-----------------------------------------------------State management----------------------------------------------------* +*#########################################################################################################################*/ +void Gfx_SetFaceCulling(cc_bool enabled) { + Xe_SetCullMode(xe, enabled ? XE_CULL_CW : XE_CULL_NONE); +} + +void Gfx_SetFog(cc_bool enabled) { + // TODO +} + +void Gfx_SetFogCol(PackedCol color) { + // TODO +} + +void Gfx_SetFogDensity(float value) { + // TODO +} + +void Gfx_SetFogEnd(float value) { + // TODO +} + +void Gfx_SetFogMode(FogFunc func) { + // TODO +} + +static void SetAlphaTest(cc_bool enabled) { + Xe_SetAlphaTestEnable(xe, enabled); +} + +static void SetAlphaBlend(cc_bool enabled) { + if (enabled) { + Xe_SetBlendControl(xe, + XE_BLEND_SRCALPHA, XE_BLENDOP_ADD, XE_BLEND_INVSRCALPHA, + XE_BLEND_SRCALPHA, XE_BLENDOP_ADD, XE_BLEND_INVSRCALPHA); + } else { + Xe_SetBlendControl(xe, + XE_BLEND_ONE, XE_BLENDOP_ADD, XE_BLEND_ZERO, + XE_BLEND_ONE, XE_BLENDOP_ADD, XE_BLEND_ZERO); + } +} + +void Gfx_SetAlphaArgBlend(cc_bool enabled) { + // TODO +} + +void Gfx_ClearColor(PackedCol color) { + Xe_SetClearColor(xe, color); +} + +void Gfx_SetDepthTest(cc_bool enabled) { + Xe_SetZEnable(xe, enabled); +} + +void Gfx_SetDepthWrite(cc_bool enabled) { + Xe_SetZWrite(xe, enabled); +} + +static void SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a) { + // TODO +} + +void Gfx_DepthOnlyRendering(cc_bool depthOnly) { + cc_bool enabled = !depthOnly; + SetColorWrite(enabled & gfx_colorMask[0], enabled & gfx_colorMask[1], + enabled & gfx_colorMask[2], enabled & gfx_colorMask[3]); +} + + +/*########################################################################################################################* +*-------------------------------------------------------Index buffers-----------------------------------------------------* +*#########################################################################################################################*/ +GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { + int size = count * 2; + struct XenosIndexBuffer* xib = Xe_CreateIndexBuffer(xe, size, XE_FMT_INDEX16); + + void* dst = Xe_IB_Lock(xe, xib, 0, size, XE_LOCK_WRITE); + fillFunc((cc_uint16*)dst, count, obj); + Xe_IB_Unlock(xe, xib); + return xib; +} + +void Gfx_BindIb(GfxResourceID ib) { + struct XenosIndexBuffer* xib = (struct XenosIndexBuffer*)ib; + Xe_SetIndices(xe, xib); +} + +void Gfx_DeleteIb(GfxResourceID* ib) { + struct XenosIndexBuffer* xib = (struct XenosIndexBuffer*)(*ib); + if (xib) Xe_DestroyIndexBuffer(xe, xib); + *ib = NULL; +} + + +/*########################################################################################################################* +*------------------------------------------------------Vertex buffers-----------------------------------------------------* +*#########################################################################################################################*/ +static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) { + int size = count * strideSizes[fmt]; + return Xe_CreateVertexBuffer(xe, size); +} + +void Gfx_DeleteVb(GfxResourceID* vb) { + struct XenosVertexBuffer* xvb = (struct XenosVertexBuffer*)(*vb); + if (xvb) Xe_DestroyVertexBuffer(xe, xvb); + *vb = NULL; +} + +void Gfx_BindVb(GfxResourceID vb) { + struct XenosVertexBuffer* xvb = (struct XenosVertexBuffer*)vb; + Xe_SetStreamSource(xe, 0, xvb, 0, gfx_stride); +} + +void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) { + struct XenosVertexBuffer* xvb = (struct XenosVertexBuffer*)vb; + int size = count * strideSizes[fmt]; + return Xe_VB_Lock(xe, xvb, 0, size, XE_LOCK_WRITE); +} + +void Gfx_UnlockVb(GfxResourceID vb) { + struct XenosVertexBuffer* xvb = (struct XenosVertexBuffer*)vb; + Xe_VB_Unlock(xe, xvb); +} + + +/*########################################################################################################################* +*--------------------------------------------------Dynamic vertex buffers-------------------------------------------------* +*#########################################################################################################################*/ +static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) { + return Gfx_AllocStaticVb(fmt, maxVertices); +} + +void Gfx_DeleteDynamicVb(GfxResourceID* vb) { Gfx_DeleteVb(vb); } + +void Gfx_BindDynamicVb(GfxResourceID vb) { Gfx_BindVb(vb); } + +void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) { + return Gfx_LockVb(vb, fmt, count); +} + +void Gfx_UnlockDynamicVb(GfxResourceID vb) { Gfx_UnlockVb(vb); Gfx_BindVb(vb); } + + +/*########################################################################################################################* +*-----------------------------------------------------Vertex rendering----------------------------------------------------* +*#########################################################################################################################*/ +void Gfx_SetVertexFormat(VertexFormat fmt) { + if (fmt == gfx_format) return; + gfx_format = fmt; + gfx_stride = strideSizes[fmt]; + + if (fmt == VERTEX_FORMAT_COLOURED) { + Xe_SetTexture(xe, 0, NULL); + Xe_SetShader(xe, SHADER_TYPE_PIXEL, shdr_col_ps, 0); + Xe_SetShader(xe, SHADER_TYPE_VERTEX, shdr_col_vs, 0); + } else { + Xe_SetShader(xe, SHADER_TYPE_PIXEL, shdr_tex_ps, 0); + Xe_SetShader(xe, SHADER_TYPE_VERTEX, shdr_tex_vs, 0); + } +} + +void Gfx_DrawVb_Lines(int verticesCount) { + Xe_DrawPrimitive(xe, XE_PRIMTYPE_LINELIST, 0, verticesCount >> 1); +} + +void Gfx_DrawVb_IndexedTris(int verticesCount) { + Xe_DrawIndexedPrimitive(xe, XE_PRIMTYPE_TRIANGLELIST, // TODO QUADLIST instead? + 0, 0, verticesCount, 0, verticesCount >> 1); +} + +void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) { + Xe_DrawIndexedPrimitive(xe, XE_PRIMTYPE_TRIANGLELIST, + startVertex, 0, verticesCount, 0, verticesCount >> 1); +} + +void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { + Xe_DrawIndexedPrimitive(xe, XE_PRIMTYPE_TRIANGLELIST, + startVertex, 0, verticesCount, 0, verticesCount >> 1); +} + + +/*########################################################################################################################* +*---------------------------------------------------------Matrices--------------------------------------------------------* +*#########################################################################################################################*/ +static struct Matrix _view, _proj, _mvp; + +void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix) { + struct Matrix* dst = type == MATRIX_PROJECTION ? &_proj : &_view; + *dst = *matrix; + + Matrix_Mul(&_mvp, &_view, &_proj); + // TODO: Is this a global uniform, or does it need to be reloaded on shader change? + Xe_SetVertexShaderConstantF(xe, 0, (float*)&_mvp, 4); +} + +void Gfx_LoadIdentityMatrix(MatrixType type) { + Gfx_LoadMatrix(type, &Matrix_Identity); +} + +void Gfx_EnableTextureOffset(float x, float y) { + // TODO +} + +void Gfx_DisableTextureOffset(void) { + // TODO +} + +void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float zNear, float zFar) { + // TODO verify this + *matrix = Matrix_Identity; + + matrix->row1.x = 2.0f / width; + matrix->row2.y = -2.0f / height; + matrix->row3.z = 1.0f / (zNear - zFar); + + matrix->row4.x = -1.0f; + matrix->row4.y = 1.0f; + matrix->row4.z = zNear / (zNear - zFar); +} + +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } +void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { + // TODO verify this + float zNear = 0.1f; + float c = Cotangent(0.5f * fov); + *matrix = Matrix_Identity; + + matrix->row1.x = c / aspect; + matrix->row2.y = c; + matrix->row3.z = zFar / (zNear - zFar); + matrix->row3.w = -1.0f; + matrix->row4.z = (zNear * zFar) / (zNear - zFar); + matrix->row4.w = 0.0f; +} + + +/*########################################################################################################################* +*-----------------------------------------------------------Misc----------------------------------------------------------* +*#########################################################################################################################*/ +cc_result Gfx_TakeScreenshot(struct Stream* output) { + return ERR_NOT_SUPPORTED; +} + +void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMs) { + gfx_minFrameMs = minFrameMs; + gfx_vsync = vsync; +} + +void Gfx_BeginFrame(void) { +} + +void Gfx_ClearBuffers(GfxBuffers buffers) { + // TODO clear only some buffers + // Xe_Clear is just a Resolve anyways +} + +void Gfx_EndFrame(void) { + Xe_Resolve(xe); + Xe_Sync(xe); + + if (gfx_minFrameMs) LimitFPS(); +} + +cc_bool Gfx_WarnIfNecessary(void) { return false; } + +void Gfx_GetApiInfo(cc_string* info) { + String_AppendConst(info, "-- Using XBox 360 --\n"); + PrintMaxTextureInfo(info); +} + +void Gfx_OnWindowResize(void) { + +} + +void Gfx_SetViewport(int x, int y, int w, int h) { } +#endif |