mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2025-04-18 05:38:36 +01:00
Start of SSE vector math library. Fixed compiler warnings. Removed rasterizer and Doom map loader from CosmicGL.
This commit is contained in:
parent
e5596ee2bf
commit
e912217325
30 changed files with 1050 additions and 2077 deletions
Zenith-latest-2021-07-01-06_22_17.iso
src
Home
Zenith/CosmicGL
BIN
Zenith-latest-2021-06-30-02_54_42.iso → Zenith-latest-2021-07-01-06_22_17.iso
Executable file → Normal file
BIN
Zenith-latest-2021-06-30-02_54_42.iso → Zenith-latest-2021-07-01-06_22_17.iso
Executable file → Normal file
Binary file not shown.
Binary file not shown.
|
@ -1,83 +0,0 @@
|
|||
/* This demo renders a BSP. Put DOOM1.WAD in the directory to try this. */
|
||||
|
||||
Cd(__DIR__);;
|
||||
|
||||
"\n\n\n\n"; // Seperate from annoying warnings
|
||||
|
||||
I64 wWC = 90; // Window width in columns
|
||||
I64 wHC = 90; // Window height in rows
|
||||
I64 wW = wWC * 8;
|
||||
I64 wH = wHC * 8;
|
||||
I64 wXC = 1; // Window x in columns
|
||||
I64 wYC = 2; // Window y in rows
|
||||
I64 wX = wXC * 8;
|
||||
I64 wY = wYC * 8;
|
||||
|
||||
SettingsPush;
|
||||
WinHorz(wXC, wXC + wWC - 1);
|
||||
WinVert(wYC, wYC + wHC - 1);
|
||||
DocClear;
|
||||
|
||||
// Prepare framebuffer
|
||||
CTex2D frameBuf;
|
||||
Tex2DInit(&frameBuf, TEX2D_RAW, wW, wH);
|
||||
Tex2DColorFill(&frameBuf, gr_palette[WHITE]);
|
||||
|
||||
// Load BSP and render
|
||||
CWAD doom1;
|
||||
WADLoad(&doom1, "DOOM1.WAD");
|
||||
|
||||
CDoomMap map;
|
||||
DoomMapLoad(&map, &doom1, "E1M1");
|
||||
|
||||
// Sprite loading
|
||||
CTex2D sprite;
|
||||
Tex2DLoadWADSprite(&sprite, &doom1, "POSSF2F8");
|
||||
|
||||
WADFree(&doom1);
|
||||
|
||||
CBGR24 cRed;
|
||||
cRed.r = 255; cRed.b = cRed.g = 0;
|
||||
|
||||
I64 i, a, b, c, d;
|
||||
for (i = 0; i < map.nLines; i++)
|
||||
{
|
||||
a = map.lines[i].v1->x >> 32;
|
||||
b = map.lines[i].v1->y >> 32;
|
||||
c = map.lines[i].v2->x >> 32;
|
||||
d = map.lines[i].v2->y >> 32;
|
||||
|
||||
a /= 8;
|
||||
b /= 8;
|
||||
c /= 8;
|
||||
d /= 8;
|
||||
|
||||
a += 200;
|
||||
b += 650;
|
||||
c += 200;
|
||||
d += 650;
|
||||
|
||||
if (a < 0 || b < 0 || c < 0 || d < 0 ||
|
||||
a >= wW || b >= wH || c >= wW || d >= wH)
|
||||
{
|
||||
// One coordinate outside window
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawLine(&frameBuf, a, b, c, d, cRed);
|
||||
}
|
||||
}
|
||||
|
||||
DrawTexture(&frameBuf, &sprite, 200, 200, TRUE);
|
||||
|
||||
while (CharScan() == 0)
|
||||
{
|
||||
Tex2DDebugDisp(&frameBuf, wX, wY);
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
DoomMapFree(&doom1);
|
||||
Tex2DFree(&sprite);
|
||||
Tex2DFree(&framebuf);
|
||||
SettingsPop;
|
||||
Exit;
|
|
@ -17,37 +17,37 @@ WinVert(wYC, wYC + wHC - 1);
|
|||
DocClear;
|
||||
|
||||
// Prepare framebuffer
|
||||
CTex2D frameBuf;
|
||||
Tex2DInit(&frameBuf, TEX2D_RAW, wW, wH);
|
||||
Tex2DColorFill(&frameBuf, gr_palette[WHITE]);
|
||||
CGLTex2D frameBuf;
|
||||
GLTex2DInit(&frameBuf, TEX2D_RAW, wW, wH);
|
||||
GLTex2DColorFill(&frameBuf, gr_palette[WHITE]);
|
||||
|
||||
// Draw Rectangles
|
||||
DrawRectFill(&frameBuf, 32, 32, 128, 96, gr_palette[CYAN]);
|
||||
GLDrawRectFill(&frameBuf, 32, 32, 128, 96, gr_palette[CYAN]);
|
||||
|
||||
DrawRectVertGradient(&frameBuf, 64, 128, 96, 256, gr_palette[CYAN],
|
||||
GLDrawRectVertGradient(&frameBuf, 64, 128, 96, 256, gr_palette[CYAN],
|
||||
gr_palette[BLUE]);
|
||||
|
||||
// Gradient's starting transition points can also be modified:
|
||||
DrawRectVertGradient(&frameBuf, 160, 32, 224, 96, gr_palette[BLACK],
|
||||
GLDrawRectVertGradient(&frameBuf, 160, 32, 224, 96, gr_palette[BLACK],
|
||||
gr_palette[WHITE], 0.65, 0.7);
|
||||
|
||||
DrawRectOutline(&frameBuf, 55, 300, 75, 310, gr_palette[LTGRAY]);
|
||||
GLDrawRectOutline(&frameBuf, 55, 300, 75, 310, gr_palette[LTGRAY]);
|
||||
|
||||
// You can also define a second color for adding button-like shading
|
||||
DrawRectSoftOutline(&frameBuf, 100, 200, 130, 210, gr_palette[LTGRAY],
|
||||
GLDrawRectSoftOutline(&frameBuf, 100, 200, 130, 210, gr_palette[LTGRAY],
|
||||
gr_palette[DKGRAY]);
|
||||
|
||||
// Drawing text
|
||||
DrawChar(&frameBuf, 48, 48, '!', gr_palette[WHITE]);
|
||||
DrawString(&frameBuf, 16, 104, "When I wrote this, God said:
|
||||
GLDrawChar(&frameBuf, 48, 48, '!', gr_palette[WHITE]);
|
||||
GLDrawString(&frameBuf, 16, 104, "When I wrote this, God said:
|
||||
calls singing moist days excellence.", gr_palette[GREEN]);
|
||||
|
||||
while (CharScan() == 0)
|
||||
{
|
||||
Tex2DDebugDisp(&frameBuf, wX, wY);
|
||||
GLTex2DDebugDisp(&frameBuf, wX, wY);
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
Tex2DFree(&frameBuf);
|
||||
GLTex2DFree(&frameBuf);
|
||||
SettingsPop;
|
||||
Exit;
|
||||
|
|
Binary file not shown.
|
@ -1,247 +0,0 @@
|
|||
/* This demo shows how to load a custom model (created based on the .obj format
|
||||
using a converstion script). It uses WAD textures rather than BMP textures
|
||||
unlike most of the other demos. The model is not transformed in any way and
|
||||
is rendered directly, so scaling the window will also scale the resulting
|
||||
render. */
|
||||
|
||||
Cd(__DIR__);;
|
||||
|
||||
I64 wWC = 80; // Window width in columns (Drop to under 80 for 640x480 displays)
|
||||
I64 wHC = 45; // Window height in rows (Drop to under 60 for 640x480 displays)
|
||||
I64 wW = wWC * 8;
|
||||
I64 wH = wHC * 8;
|
||||
I64 wXC = 1; // Window x in columns
|
||||
I64 wYC = 2; // Window y in rows
|
||||
I64 wX = wXC * 8;
|
||||
I64 wY = (wYC + 0) * 8;
|
||||
|
||||
SettingsPush;
|
||||
WinHorz(wXC, wXC + wWC - 1);
|
||||
WinVert(wYC, wYC + wHC - 1);
|
||||
DocClear;
|
||||
|
||||
// Framebuffer Initialization
|
||||
CTex2D frameBuf;
|
||||
CTex2D depthBuf;
|
||||
|
||||
Tex2DInit(&frameBuf, TEX2D_RAW, wW, wH);
|
||||
Tex2DInit(&depthBuf, TEX2D_DEPTH, wW, wH);
|
||||
|
||||
// Colors
|
||||
CBGR24 cBlack;
|
||||
cBlack.r = 0; cBlack.g = 0; cBlack.b = 0;
|
||||
CBGR24 cRed;
|
||||
cRed.r = 255; cRed.g = 20; cRed.b = 20;
|
||||
CBGR24 cWhite;
|
||||
cWhite.r = 255; cWhite.g = 255; cWhite.b = 255;
|
||||
|
||||
Tex2DColorFill(&frameBuf, cBlack);
|
||||
|
||||
// Texture Intitalization
|
||||
CWAD wad;
|
||||
WADLoad(&wad, "KingTerry.wad");
|
||||
|
||||
CTex2D TexRevelation;
|
||||
Tex2DLoadWAD(&TexRevelation, &wad, "Revelation");
|
||||
|
||||
CTex2D TexKingTerrySkin;
|
||||
Tex2DLoadWAD(&TexKingTerrySkin, &wad, "KingTerry_Skin");
|
||||
|
||||
CTex2D TexKingTerryBody;
|
||||
Tex2DLoadWAD(&TexKingTerryBody, &wad, "KingTerry_Body");
|
||||
|
||||
CTex2D TexNebula;
|
||||
Tex2DLoadWAD(&TexNebula, &wad, "Nebula");
|
||||
|
||||
WADFree(&wad);
|
||||
|
||||
// Generate our own page texture
|
||||
CTex2D TexPages;
|
||||
Tex2DInit(&TexPages, TEX2D_RAW, 256, 256);
|
||||
Tex2DColorFill(&TexPages, cWhite);
|
||||
DrawString(&TexPages, 16, 20, "I should fix", cBlack);
|
||||
DrawString(&TexPages, 16, 35, "the UVs on this", cBlack);
|
||||
DrawString(&TexPages, 16, 50, "book model.", cBlack);
|
||||
|
||||
class CMat
|
||||
{
|
||||
U8 name[32];
|
||||
U32 nOffset; // Offset to first triangle
|
||||
U32 nTris; // Number of triangles
|
||||
};
|
||||
|
||||
class CZMHeader
|
||||
{
|
||||
I32 nMats; // Number of materials
|
||||
U32 nTriOffset; // Triangle array offset
|
||||
U32 nVertOffset; // Vertex array offset
|
||||
U32 nUVOffset; // UV array offset
|
||||
U32 nNormOffset; // Normal array offset
|
||||
};
|
||||
|
||||
class CZMTri
|
||||
{
|
||||
U32 iV1; // Vertices
|
||||
U32 iV2;
|
||||
U32 iV3;
|
||||
U32 iN1; // Normals
|
||||
U32 iN2;
|
||||
U32 iN3;
|
||||
U32 iT1; // UVs
|
||||
U32 iT2;
|
||||
U32 iT3;
|
||||
};
|
||||
|
||||
class CZModel
|
||||
{
|
||||
CMat *mat;
|
||||
CZMTri *tri;
|
||||
CVec3 *vert;
|
||||
CVec2 *uv;
|
||||
CVec3 *norm;
|
||||
};
|
||||
|
||||
class UniformTex
|
||||
{
|
||||
I64 mat; // Material index of model to render
|
||||
CTex2D *tex;
|
||||
};
|
||||
|
||||
class UniformCol
|
||||
{
|
||||
I64 mat;
|
||||
CBGR24 col;
|
||||
};
|
||||
|
||||
// Load model
|
||||
U8 *MdlHandle = FileRead("TerryTruth.ZM");
|
||||
CZMHeader *header = MdlHandle;
|
||||
CZModel MdlTerry;
|
||||
|
||||
MdlTerry.mat = MdlHandle + 20;
|
||||
MdlTerry.tri = MdlHandle + header->nTriOffset;
|
||||
MdlTerry.vert = MdlHandle + header->nVertOffset;
|
||||
MdlTerry.uv = MdlHandle + header->nUVOffset;
|
||||
MdlTerry.norm = MdlHandle + header->nNormOffset;
|
||||
|
||||
// Prepare uniforms (unchanging parameters) to feed into shader
|
||||
|
||||
// Book cover is red
|
||||
UniformCol UniCover;
|
||||
UniCover.col.r = 150;
|
||||
UniCover.col.g = 0;
|
||||
UniCover.col.b = 0;
|
||||
UniCover.mat = 0;
|
||||
|
||||
// Skin uses skin texture
|
||||
UniformTex UniKingTerry_Skin;
|
||||
UniKingTerry_Skin.tex = &TexKingTerrySkin;
|
||||
UniKingTerry_Skin.mat = 1;
|
||||
|
||||
// Body uses body texture
|
||||
UniformTex UniKingTerry_Body;
|
||||
UniKingTerry_Body.tex = &TexKingTerryBody;
|
||||
UniKingTerry_Body.mat = 2;
|
||||
|
||||
// Hat is black (dark gray)
|
||||
UniformCol UniHat;
|
||||
UniHat.col.r = 20;
|
||||
UniHat.col.g = 20;
|
||||
UniHat.col.b = 20;
|
||||
UniHat.mat = 3;
|
||||
|
||||
// Pages uses WAD texture
|
||||
UniformTex UniPages;
|
||||
UniPages.tex = &TexPages; // Set this to &TexRevelation for original.
|
||||
UniPages.mat = 4;
|
||||
|
||||
// Nebula uses WAD texture
|
||||
UniformTex UniNebula;
|
||||
UniNebula.tex = &TexNebula;
|
||||
UniNebula.mat = 5;
|
||||
|
||||
// Generate a texure and color shader
|
||||
CShader ShdTex, ShdCol;
|
||||
ShdTex.vertValues = MAlloc(2 * sizeof(I64));
|
||||
ShdTex.vertValues[0] = SHD_CVEC2; // UV
|
||||
ShdTex.vertValues[1] = SHD_CVEC3; // Normal
|
||||
|
||||
ShdCol.vertValues = MAlloc(2 * sizeof(I64));
|
||||
ShdCol.vertValues[0] = SHD_CVEC2; // UV
|
||||
ShdCol.vertValues[1] = SHD_CVEC3; // Normal
|
||||
|
||||
ShdTex.nVertValues = 2;
|
||||
ShdCol.nVertValues = 2;
|
||||
|
||||
U0 vShaderTex(CTri *tri, F64 *vertOutBuf, U8 *mdlPtr, U8 *uniforms, I64 iTri, I64 nTris)
|
||||
{
|
||||
CZModel *mdl = mdlPtr;
|
||||
UniformTex *uni = uniforms;
|
||||
|
||||
nTris++; // So I don't have to see the unused warning.
|
||||
|
||||
I64 t = mdl->mat[uni->mat].nOffset + iTri; // Triangle index in triangle array
|
||||
|
||||
// Copy model directly into the triangle, I won't even transform for this demo.
|
||||
MemCopy(&tri->p[0], &mdl->vert[mdl->tri[t].iV1 - 1], sizeof(CVec3));
|
||||
MemCopy(&tri->p[1], &mdl->vert[mdl->tri[t].iV2 - 1], sizeof(CVec3));
|
||||
MemCopy(&tri->p[2], &mdl->vert[mdl->tri[t].iV3 - 1], sizeof(CVec3));
|
||||
|
||||
tri->p[0].z = -1 * tri->p[0].z;
|
||||
tri->p[1].z = -1 * tri->p[1].z;
|
||||
tri->p[2].z = -1 * tri->p[2].z;
|
||||
|
||||
// Copy uv and normals into vertOutBuf to be interpolated for the vertex shader.
|
||||
MemCopy(&vertOutBuf[0], &mdl->uv[mdl->tri[t].iT1 - 1], sizeof(CVec2));
|
||||
MemCopy(&vertOutBuf[2], &mdl->norm[mdl->tri[t].iN1 - 1], sizeof(CVec3));
|
||||
MemCopy(&vertOutBuf[5], &mdl->uv[mdl->tri[t].iT2 - 1], sizeof(CVec2));
|
||||
MemCopy(&vertOutBuf[7], &mdl->norm[mdl->tri[t].iN2 - 1], sizeof(CVec3));
|
||||
MemCopy(&vertOutBuf[10], &mdl->uv[mdl->tri[t].iT3 - 1], sizeof(CVec2));
|
||||
MemCopy(&vertOutBuf[12], &mdl->norm[mdl->tri[t].iN3 - 1], sizeof(CVec3));
|
||||
}
|
||||
|
||||
U0 fShaderTex(CBGR24 *color, F64 *fragInBuf, U8 *uniforms)
|
||||
{
|
||||
UniformTex *uni = uniforms;
|
||||
Tex2DSampleNorm(color, uni->tex, fragInBuf[0], 1.0-fragInBuf[1]);
|
||||
// Debug, display normals
|
||||
// color->r=fragInBuf[2]*255.0; color->g=fragInBuf[3]*255.0; color->b=fragInBuf[4]*255.0;
|
||||
}
|
||||
|
||||
U0 fShaderCol(CBGR24 *color, F64 *fragInBuf, U8 *uniforms)
|
||||
{
|
||||
UniformCol *uni = uniforms;
|
||||
color->r = uni->col.r;
|
||||
color->g = uni->col.g;
|
||||
color->b = uni->col.b;
|
||||
}
|
||||
|
||||
ShdTex.FragShd = &fShaderTex;
|
||||
ShdTex.VertShd = &vShaderTex;
|
||||
ShdCol.FragShd = &fShaderCol;
|
||||
ShdCol.VertShd = &vShaderTex;
|
||||
|
||||
Tex2DDepthReset(&depthBuf);
|
||||
RenderTris(&ShdCol, &frameBuf, &depthBuf, &MdlTerry, &UniCover, MdlTerry.mat[0].nTris);
|
||||
RenderTris(&ShdTex, &frameBuf, &depthBuf, &MdlTerry, &UniKingTerry_Skin, MdlTerry.mat[1].nTris);
|
||||
RenderTris(&ShdTex, &frameBuf, &depthBuf, &MdlTerry, &UniKingTerry_Body, MdlTerry.mat[2].nTris);
|
||||
RenderTris(&ShdCol, &frameBuf, &depthBuf, &MdlTerry, &UniHat, MdlTerry.mat[3].nTris);
|
||||
RenderTris(&ShdTex, &frameBuf, &depthBuf, &MdlTerry, &UniPages, MdlTerry.mat[4].nTris);
|
||||
RenderTris(&ShdTex, &frameBuf, $ER$&depthBuf, &MdlTerry, &UniNebula, MdlTerry.mat[5].nTris);
|
||||
|
||||
while (CharScan() == 0)
|
||||
{
|
||||
Tex2DDebugDisp(&frameBuf, wX, wY);
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
Tex2DFree(&frameBuf);
|
||||
Tex2DFree(&depthBuf);
|
||||
Tex2DFree(&TexPages);
|
||||
Tex2DFree(&TexRevelation);
|
||||
Tex2DFree(&TexKingTerrySkin);
|
||||
Tex2DFree(&TexKingTerryBody);
|
||||
Tex2DFree(&TexNebula);
|
||||
|
||||
SettingsPop;
|
||||
Exit;
|
Binary file not shown.
|
@ -16,15 +16,15 @@ WinHorz(wXC, wXC + wWC - 1);
|
|||
WinVert(wYC, wYC + wHC - 1);
|
||||
DocClear;
|
||||
|
||||
CTex2D texture;
|
||||
Tex2DLoadBMP(&texture, "SaintTerry.bmp");
|
||||
CGLTex2D texture;
|
||||
GLTex2DLoadBMP(&texture, "SaintTerry.bmp");
|
||||
|
||||
while (CharScan() == 0)
|
||||
{
|
||||
Tex2DDebugDisp(&texture, wX, wY);
|
||||
GLTex2DDebugDisp(&texture, wX, wY);
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
Tex2DFree(&texture);
|
||||
GLTex2DFree(&texture);
|
||||
SettingsPop;
|
||||
Exit;
|
||||
|
|
Binary file not shown.
Before ![]() (image error) Size: 192 KiB |
|
@ -1,119 +0,0 @@
|
|||
/* This demo shows how to create a custom model format, import a texture, and
|
||||
program a shader to render a triangle. */
|
||||
|
||||
Cd(__DIR__);;
|
||||
|
||||
I64 wWC = 32; // Window width in columns (512px)
|
||||
I64 wHC = 32; // Window height in rows (512px)
|
||||
I64 wW = wWC * 8;
|
||||
I64 wH = wHC * 8;
|
||||
I64 wXC = 1; // Window x in columns
|
||||
I64 wYC = 2; // Window y in rows
|
||||
I64 wX = wXC * 8;
|
||||
I64 wY = (wYC + 4) * 8;
|
||||
|
||||
SettingsPush;
|
||||
WinHorz(wXC, wXC + wWC - 1);
|
||||
WinVert(wYC, wYC + wHC + 3);
|
||||
DocClear;
|
||||
|
||||
// Framebuffer Initialization
|
||||
CTex2D frameBuf;
|
||||
CTex2D depthBuf;
|
||||
|
||||
Tex2DInit(&frameBuf, TEX2D_RAW, wW, wH);
|
||||
Tex2DInit(&depthBuf, TEX2D_DEPTH, wW, wH);
|
||||
|
||||
// Clear framebuffer texture with black background
|
||||
CBGR24 cBlack;
|
||||
cBlack.r = 0; cBlack.g = 0; cBlack.b = 0;
|
||||
Tex2DColorFill(&frameBuf, cBlack);
|
||||
|
||||
// Importing BMP texture
|
||||
CTex2D texture;
|
||||
Tex2DLoadBMP(&texture, "MrGod.bmp");
|
||||
|
||||
// Create custom model format that is quite straightforward
|
||||
class MDL
|
||||
{
|
||||
I64 nTris;
|
||||
CTri *tri;
|
||||
CVec2 *uv;
|
||||
};
|
||||
|
||||
// Load it with a texture mapped triangle.
|
||||
MDL model;
|
||||
model.nTris = 1;
|
||||
model.tri = MAlloc(sizeof(CTri));
|
||||
model.tri[0].p[0].x = 0.0;
|
||||
model.tri[0].p[0].y = 0.8;
|
||||
model.tri[0].p[0].z = 0.0;
|
||||
model.tri[0].p[1].x = -0.8;
|
||||
model.tri[0].p[1].y = -0.4;
|
||||
model.tri[0].p[1].z = 0.0;
|
||||
model.tri[0].p[2].x = 0.8;
|
||||
model.tri[0].p[2].y = -0.4;
|
||||
model.tri[0].p[2].z = 0.0;
|
||||
model.uv = MAlloc(sizeof(CVec2)*3);
|
||||
// UVs commonly use coordinates of 0.0-1.0, although you can use direct pixel
|
||||
// coordinates if you use the pixel coordinate sampler in the shader.
|
||||
model.uv[0].x = 0.5;
|
||||
model.uv[0].y = 0.0898;
|
||||
model.uv[1].x = 0.07421875;
|
||||
model.uv[1].y = 0.73046875;
|
||||
model.uv[2].x = 0.9375;
|
||||
model.uv[2].y = 0.7305;
|
||||
|
||||
// In this example a class is not needed for the uniforms (unchanging
|
||||
// parameters), we only feed the pointer for the texture we want to sample.
|
||||
// to the shader.
|
||||
|
||||
// Generate a shader. Each vertex has a UV coordinate (coordinate that
|
||||
// maps to the texture), so we only need to pass one CVEC2 attribute
|
||||
// from the vertex shader to the fragment shader.
|
||||
CShader shd, shdB;
|
||||
shd.vertValues = MAlloc(sizeof(I64));
|
||||
shd.vertValues[0] = SHD_CVEC2; // UV coordinate
|
||||
shd.nVertValues = 1;
|
||||
|
||||
// The vertex shader gives the normalized device coordinates (screen coordinates
|
||||
// from -1.0 to 1.0) of each vertex of a specified triangle. Normally you would
|
||||
// do translations and perspective transforms, but here our model is already in
|
||||
// NDC. It also passes the UV coordinates of each vertex to the vertOutBuf to
|
||||
// be interpolated for the fragment shader.
|
||||
U0 vShader(CTri *tri, F64 *vertOutBuf, U8 *mdlPtr, U8 *uniforms, I64 iTri, I64 nTris)
|
||||
{
|
||||
MDL *mdl = mdlPtr;
|
||||
MemCopy(tri, &mdl->tri[iTri], sizeof(CTri));
|
||||
MemCopy(vertOutBuf, &mdl->uv[iTri*3], sizeof(CVec2)*3);
|
||||
}
|
||||
|
||||
// The fragment shader calculates what color an individual fragment (pixel)
|
||||
// should be. Here we use the interpolated UV coordinate from the fragInBuf to
|
||||
// sample the color from the texture.
|
||||
U0 fShader(CBGR24 *color, F64 *fragInBuf, U8 *uniforms)
|
||||
{
|
||||
// We will pass in the texture pointer through the uniform later
|
||||
// when we render.
|
||||
Tex2DSampleNorm(color, uniforms, fragInBuf[0], fragInBuf[1]);
|
||||
}
|
||||
|
||||
// Attach vertex and fragment shader
|
||||
shd.FragShd = &fShader;
|
||||
shd.VertShd = &vShader;
|
||||
|
||||
while (CharScan() == 0)
|
||||
{
|
||||
// Where &texture is you would usually feed in a pointer to uniforms,
|
||||
// however since the texture is the only value the shader needs,
|
||||
// we simply pass in that pointer.
|
||||
RenderTris(&shd, &frameBuf, &depthBuf, &model, &texture, 1);
|
||||
Tex2DDebugDisp(&frameBuf, wX, wY);
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
Tex2DFree(&frameBuf);
|
||||
Tex2DFree(&depthBuf);
|
||||
Tex2DFree(&texture);
|
||||
SettingsPop;
|
||||
Exit;
|
13
src/Home/MakeHome.CC
Normal file
13
src/Home/MakeHome.CC
Normal file
|
@ -0,0 +1,13 @@
|
|||
Cd(__DIR__);;
|
||||
|
||||
//If these are not present in /Home, it uses the version in the root dir. You
|
||||
//can make your own, modified, version of these files in your /Home directory.
|
||||
#include "~/HomeLocalize"
|
||||
#include "/Zenith/Boot/MakeBoot"
|
||||
#include "/Zenith/Utils/MakeUtils"
|
||||
#include "~/HomeWrappers"
|
||||
MapFileLoad("::/Kernel/Kernel");
|
||||
MapFileLoad("::/Compiler/Compiler");
|
||||
#include "~/HomeKeyPlugIns"
|
||||
#include "~/HomeSys"
|
||||
Cd("..");;
|
|
@ -1,10 +1,10 @@
|
|||
/**
|
||||
@defgroup Draw Draw
|
||||
@defgroup GLDraw Draw
|
||||
@brief Functions for drawing to textures.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ingroup Draw
|
||||
@ingroup GLDraw
|
||||
@brief Draw pixel on color texture. Does not check boundaries, point
|
||||
must be fully inside texture.
|
||||
|
||||
|
@ -13,14 +13,14 @@
|
|||
@param[in] y Y position.
|
||||
@param[in] color Color of point.
|
||||
*/
|
||||
U0 DrawPixel(CTex2D *tex, I64 x, I64 y, CBGR24 color)
|
||||
U0 GLDrawPixel(CGLTex2D *tex, I64 x, I64 y, CBGR24 color)
|
||||
{
|
||||
tex->rawBuf[x + y * tex->w] = color;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ingroup Draw
|
||||
@ingroup GLDraw
|
||||
@brief Draw line on color texture. Does not check boundaries, line must
|
||||
be fully inside texture.
|
||||
|
||||
|
@ -31,11 +31,14 @@ U0 DrawPixel(CTex2D *tex, I64 x, I64 y, CBGR24 color)
|
|||
@param[in] y1 End y.
|
||||
@param[in] color Color of line.
|
||||
*/
|
||||
U0 DrawLine(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, CBGR24 color)
|
||||
U0 GLDrawLine(CGLTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, CBGR24 color)
|
||||
{
|
||||
Bool steep = (Abs(y1 - y0) > Abs(x1 - x0));
|
||||
Bool steep;
|
||||
I64 temp,
|
||||
delta_x, delta_y, error,
|
||||
step_y, x, y;
|
||||
|
||||
I64 temp;
|
||||
steep = Abs(y1 - y0) > Abs(x1 - x0);
|
||||
|
||||
if (steep == TRUE)
|
||||
{
|
||||
|
@ -57,11 +60,11 @@ U0 DrawLine(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, CBGR24 color)
|
|||
y1 = temp;
|
||||
}
|
||||
|
||||
I64 delta_x = x1 - x0;
|
||||
I64 delta_y = Abs(y1 - y0);
|
||||
I64 error = delta_x / 2;
|
||||
delta_x = x1 - x0;
|
||||
delta_y = Abs(y1 - y0);
|
||||
error = delta_x / 2;
|
||||
|
||||
I64 step_y;
|
||||
step_y;
|
||||
|
||||
if (y0 < y1)
|
||||
{
|
||||
|
@ -72,11 +75,9 @@ U0 DrawLine(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, CBGR24 color)
|
|||
step_y = -1;
|
||||
}
|
||||
|
||||
I64 y = y0;
|
||||
y = y0;
|
||||
|
||||
|
||||
I64 x;
|
||||
for (x = x0; x < (x1 + 1); x++)
|
||||
for (x = x0; x < x1 + 1; x++)
|
||||
{
|
||||
if (steep == TRUE)
|
||||
{
|
||||
|
@ -98,7 +99,7 @@ U0 DrawLine(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, CBGR24 color)
|
|||
}
|
||||
|
||||
/**
|
||||
@ingroup Draw
|
||||
@ingroup GLDraw
|
||||
@brief Draw single color triangle to color texture. Does not check
|
||||
boundaries, triangle must be fully inside texture.
|
||||
|
||||
|
@ -111,11 +112,18 @@ U0 DrawLine(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, CBGR24 color)
|
|||
@param[in] y2 Third vertex y.
|
||||
@param[in] color Color of triangle.
|
||||
*/
|
||||
U0 DrawTriangle(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, I64 x2, I64 y2,
|
||||
U0 GLDrawTriangle(CGLTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, I64 x2, I64 y2,
|
||||
CBGR24 color)
|
||||
{
|
||||
Bool middle_line_drawn;
|
||||
I64 temp;
|
||||
F64 ftemp;
|
||||
F64 ftemp,
|
||||
x_delta, y_delta,
|
||||
left_delta, right_delta,
|
||||
left_x, right_x,
|
||||
y, lX, rX,
|
||||
left_index, right_index,
|
||||
width;
|
||||
|
||||
if (y0 > y1)
|
||||
{
|
||||
|
@ -147,25 +155,16 @@ U0 DrawTriangle(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, I64 x2, I64 y2,
|
|||
y2 = temp;
|
||||
}
|
||||
|
||||
Bool middle_line_drawn = FALSE;
|
||||
F64 x_delta;
|
||||
F64 y_delta;
|
||||
F64 left_delta;
|
||||
F64 right_delta;
|
||||
F64 left_x;
|
||||
F64 right_x;
|
||||
I64 y, lX, rX;
|
||||
I64 left_index, right_index;
|
||||
I64 width;
|
||||
middle_line_drawn = FALSE;
|
||||
|
||||
// Bottom Half
|
||||
if (y0 != y1)
|
||||
{
|
||||
x_delta = (x1 - x0);
|
||||
y_delta = (y1 - y0);
|
||||
x_delta = x1 - x0;
|
||||
y_delta = y1 - y0;
|
||||
left_delta = x_delta / y_delta;
|
||||
x_delta = (x2 - x0);
|
||||
y_delta = (y2 - y0);
|
||||
x_delta = x2 - x0;
|
||||
y_delta = y2 - y0;
|
||||
right_delta = x_delta / y_delta;
|
||||
|
||||
if (left_delta > right_delta)
|
||||
|
@ -180,7 +179,7 @@ U0 DrawTriangle(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, I64 x2, I64 y2,
|
|||
|
||||
middle_line_drawn = TRUE;
|
||||
|
||||
for (y = y0; y < (y1 + 1); y++)
|
||||
for (y = y0; y < y1 + 1; y++)
|
||||
{
|
||||
lX = left_x + 0.5;
|
||||
rX = right_x + 0.5;
|
||||
|
@ -196,11 +195,11 @@ U0 DrawTriangle(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, I64 x2, I64 y2,
|
|||
// Top Half
|
||||
if (y1 != y2)
|
||||
{
|
||||
x_delta = -(x1 - x2);
|
||||
y_delta = (y1 - y2);
|
||||
x_delta = -x1 - x2;
|
||||
y_delta = y1 - y2;
|
||||
left_delta = x_delta / y_delta;
|
||||
x_delta = -(x0 - x2);
|
||||
y_delta = (y0 - y2);
|
||||
x_delta = -x0 - x2;
|
||||
y_delta = y0 - y2;
|
||||
right_delta = x_delta / y_delta;
|
||||
|
||||
if (left_delta > right_delta)
|
||||
|
@ -218,7 +217,7 @@ U0 DrawTriangle(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, I64 x2, I64 y2,
|
|||
y1 += 1;
|
||||
}
|
||||
|
||||
for (y = y2; y > (y1 - 1); y--)
|
||||
for (y = y2; y > y1 - 1; y--)
|
||||
{
|
||||
lX = left_x + 0.5;
|
||||
rX = right_x + 0.5;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
/**
|
||||
@ingroup Draw
|
||||
@ingroup GLDraw
|
||||
@brief Draw single color rectangle.
|
||||
|
||||
@param[in,out] tex Texture to draw to.
|
||||
|
@ -10,17 +10,21 @@
|
|||
@param[in] y1 End corner y.
|
||||
@param[in] color Color of rectangle.
|
||||
*/
|
||||
U0 DrawRectFill(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, CBGR24 color)
|
||||
U0 GLDrawRectFill(CGLTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, CBGR24 color)
|
||||
{
|
||||
I64 xMaxIndex = tex->w - 1;
|
||||
I64 yMaxIndex = tex->h - 1;
|
||||
I64 xMin = Clamp(Min(x0, x1), 0, xMaxIndex);
|
||||
I64 xMax = Clamp(Max(x0, x1), 0, xMaxIndex);
|
||||
I64 yMin = Clamp(Min(y0, y1), 0, yMaxIndex);
|
||||
I64 yMax = Clamp(Max(y0, y1), 0, yMaxIndex);
|
||||
I64 xLen = xMax - xMin;
|
||||
I64 xMaxIndex, yMaxIndex,
|
||||
xMin, xMax,
|
||||
yMin, yMax,
|
||||
xLen, y;
|
||||
|
||||
xMaxIndex = tex->w - 1;
|
||||
yMaxIndex = tex->h - 1;
|
||||
xMin = Clamp(Min(x0, x1), 0, xMaxIndex);
|
||||
xMax = Clamp(Max(x0, x1), 0, xMaxIndex);
|
||||
yMin = Clamp(Min(y0, y1), 0, yMaxIndex);
|
||||
yMax = Clamp(Max(y0, y1), 0, yMaxIndex);
|
||||
xLen = xMax - xMin;
|
||||
|
||||
I64 y;
|
||||
for (y = yMin; y < yMax; y++)
|
||||
{
|
||||
MemSetU32(&tex->rawBuf[xMin + y * tex->w], color, xLen);
|
||||
|
@ -28,8 +32,8 @@ U0 DrawRectFill(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, CBGR24 color)
|
|||
}
|
||||
|
||||
/**
|
||||
@ingroup Draw
|
||||
@brief Draw 1px soft rectangle outline (corners not filled).
|
||||
@ingroup GLDraw
|
||||
@brief Draw 1px soft rectangle outline (corners not filled).
|
||||
|
||||
@param[in,out] tex Texture to draw to.
|
||||
@param[in] x0 Start corner x.
|
||||
|
@ -40,19 +44,24 @@ U0 DrawRectFill(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1, CBGR24 color)
|
|||
@param[in] shadeColor (Optional) color of bottom right corner
|
||||
for shading effect.
|
||||
*/
|
||||
U0 DrawRectSoftOutline(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1,
|
||||
U0 GLDrawRectSoftOutline(CGLTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1,
|
||||
CBGR24 color, CBGR24 shadeColor = 0x7FFFFFFF)
|
||||
{
|
||||
I64 xMaxIndex, yMaxIndex,
|
||||
xMin, xMax,
|
||||
yMin, yMax,
|
||||
xLen, y;
|
||||
|
||||
if (shadeColor == 0x7FFFFFFF)
|
||||
shadeColor = color;
|
||||
|
||||
I64 xMaxIndex = tex->w - 1;
|
||||
I64 yMaxIndex = tex->w - 1;
|
||||
I64 xMin = Clamp(Min(x0, x1), 0, xMaxIndex);
|
||||
I64 xMax = Clamp(Max(x0, x1), 0, xMaxIndex);
|
||||
I64 yMin = Clamp(Min(y0, y1), 0, yMaxIndex);
|
||||
I64 yMax = Clamp(Max(y0, y1), 0, yMaxIndex);
|
||||
I64 xLen = xMax - xMin - 1;
|
||||
xMaxIndex = tex->w - 1;
|
||||
yMaxIndex = tex->w - 1;
|
||||
xMin = Clamp(Min(x0, x1), 0, xMaxIndex);
|
||||
xMax = Clamp(Max(x0, x1), 0, xMaxIndex);
|
||||
yMin = Clamp(Min(y0, y1), 0, yMaxIndex);
|
||||
yMax = Clamp(Max(y0, y1), 0, yMaxIndex);
|
||||
xLen = xMax - xMin - 1;
|
||||
|
||||
// Top border
|
||||
MemSetU32(&tex->rawBuf[xMin + 1 + yMin * tex->w], color, xLen);
|
||||
|
@ -61,7 +70,6 @@ U0 DrawRectSoftOutline(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1,
|
|||
MemSetU32(&tex->rawBuf[xMin + 1 + yMax * tex->w], shadeColor, xLen);
|
||||
|
||||
// Left/Right border
|
||||
I64 y;
|
||||
for (y = yMin + 1; y < yMax; y++)
|
||||
{
|
||||
tex->rawBuf[xMin + y * tex->w] = color;
|
||||
|
@ -70,7 +78,7 @@ U0 DrawRectSoftOutline(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1,
|
|||
}
|
||||
|
||||
/**
|
||||
@ingroup Draw
|
||||
@ingroup GLDraw
|
||||
@brief Draw 1px rectangle outline.
|
||||
|
||||
@param[in,out] tex Texture to draw to.
|
||||
|
@ -82,19 +90,24 @@ U0 DrawRectSoftOutline(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1,
|
|||
@param[in] shadeColor (Optional) color of bottom right corner
|
||||
for shading effect.
|
||||
*/
|
||||
U0 DrawRectOutline(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1,
|
||||
U0 GLDrawRectOutline(CGLTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1,
|
||||
CBGR24 color, CBGR24 shadeColor = 0x7FFFFFFF)
|
||||
{
|
||||
I64 xMaxIndex, yMaxIndex,
|
||||
xMin, xMax,
|
||||
yMin, yMax,
|
||||
xLen, y;
|
||||
|
||||
if (shadeColor == 0x7FFFFFFF)
|
||||
shadeColor = color;
|
||||
|
||||
I64 xMaxIndex = tex->w - 1;
|
||||
I64 yMaxIndex = tex->w - 1;
|
||||
I64 xMin = Clamp(Min(x0, x1), 0, xMaxIndex);
|
||||
I64 xMax = Clamp(Max(x0, x1), 0, xMaxIndex);
|
||||
I64 yMin = Clamp(Min(y0, y1), 0, yMaxIndex);
|
||||
I64 yMax = Clamp(Max(y0, y1), 0, yMaxIndex);
|
||||
I64 xLen = xMax - xMin + 1;
|
||||
xMaxIndex = tex->w - 1;
|
||||
yMaxIndex = tex->w - 1;
|
||||
xMin = Clamp(Min(x0, x1), 0, xMaxIndex);
|
||||
xMax = Clamp(Max(x0, x1), 0, xMaxIndex);
|
||||
yMin = Clamp(Min(y0, y1), 0, yMaxIndex);
|
||||
yMax = Clamp(Max(y0, y1), 0, yMaxIndex);
|
||||
xLen = xMax - xMin + 1;
|
||||
|
||||
// Top border
|
||||
MemSetU32(&tex->rawBuf[xMin + yMin * tex->w], color, xLen);
|
||||
|
@ -103,7 +116,6 @@ U0 DrawRectOutline(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1,
|
|||
MemSetU32(&tex->rawBuf[xMin + yMax * tex->w], shadeColor, xLen);
|
||||
|
||||
// Left/Right border
|
||||
I64 y;
|
||||
for (y = yMin + 1; y < yMax; y++)
|
||||
{
|
||||
tex->rawBuf[xMin + y * tex->w] = color;
|
||||
|
@ -112,9 +124,11 @@ U0 DrawRectOutline(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1,
|
|||
}
|
||||
|
||||
/**
|
||||
@ingroup Draw
|
||||
@ingroup GLDraw
|
||||
@brief Draw two color vertical gradient rectangle.
|
||||
|
||||
Should be optimized to avoid such heavy use of F64's.
|
||||
|
||||
@param[in,out] tex Texture to draw to.
|
||||
@param[in] x0 Start corner x.
|
||||
@param[in] y0 Start corner y.
|
||||
|
@ -127,30 +141,35 @@ U0 DrawRectOutline(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1,
|
|||
@param[in] tStart (Optional) start of gradient.
|
||||
@param[in] tEnd (Optional) end of gradient.
|
||||
*/
|
||||
U0 DrawRectVertGradient(CTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1,
|
||||
U0 GLDrawRectVertGradient(CGLTex2D *tex, I64 x0, I64 y0, I64 x1, I64 y1,
|
||||
CBGR24 colorTop, CBGR24 colorBottom, F64 tStart = 0.0, F64 tEnd = 1.0)
|
||||
{
|
||||
I64 xMaxIndex = tex->w - 1;
|
||||
I64 yMaxIndex = tex->h - 1;
|
||||
I64 xMin = Clamp(Min(x0, x1), 0, xMaxIndex);
|
||||
I64 xMax = Clamp(Max(x0, x1), 0, xMaxIndex);
|
||||
I64 yMinReal = Min(y0, y1);
|
||||
I64 yMin = Clamp(yMinReal, 0, yMaxIndex);
|
||||
I64 yMaxReal = Max(y0, y1);
|
||||
I64 yMax = Clamp(yMaxReal, 0, yMaxIndex);
|
||||
I64 xLen = xMax - xMin;
|
||||
|
||||
F64 yHeight = yMaxReal - yMinReal + 1;
|
||||
F64 t;
|
||||
|
||||
F64 rDiff = colorBottom.r - colorTop.r;
|
||||
F64 gDiff = colorBottom.g - colorTop.g;
|
||||
F64 bDiff = colorBottom.b - colorTop.b;
|
||||
|
||||
F64 r, g, b;
|
||||
|
||||
I64 y;
|
||||
CBGR24 color;
|
||||
I64 xMaxIndex, yMaxIndex,
|
||||
xMin, xMax,
|
||||
yMin, yMax,
|
||||
yMinReal, yMaxReal,
|
||||
xLen, y;
|
||||
F64 yHeight, t,
|
||||
rDiff, gDiff, bDiff,
|
||||
r, g, b;
|
||||
|
||||
xMaxIndex = tex->w - 1;
|
||||
yMaxIndex = tex->h - 1;
|
||||
xMin = Clamp(Min(x0, x1), 0, xMaxIndex);
|
||||
xMax = Clamp(Max(x0, x1), 0, xMaxIndex);
|
||||
yMinReal = Min(y0, y1);
|
||||
yMin = Clamp(yMinReal, 0, yMaxIndex);
|
||||
yMaxReal = Max(y0, y1);
|
||||
yMax = Clamp(yMaxReal, 0, yMaxIndex);
|
||||
xLen = xMax - xMin;
|
||||
|
||||
yHeight = yMaxReal - yMinReal + 1;
|
||||
|
||||
rDiff = colorBottom.r - colorTop.r;
|
||||
gDiff = colorBottom.g - colorTop.g;
|
||||
bDiff = colorBottom.b - colorTop.b;
|
||||
|
||||
for (y = yMin; y < yMax; y++)
|
||||
{
|
||||
t = Clamp((y - yMinReal) / yHeight, tStart, tEnd);
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
/**
|
||||
@ingroup Draw
|
||||
@ingroup GLDraw
|
||||
@brief Draw a single color character to color texture.
|
||||
|
||||
Will not draw character if partially off-screen.
|
||||
|
||||
@param[in,out] tex Texture to draw to.
|
||||
@param[in] x X position to draw character at.
|
||||
@param[in] y Y position to draw character at.
|
||||
*/
|
||||
U0 DrawChar(CTex2D *tex, I64 x, I64 y, U8 char, CBGR24 color,
|
||||
U0 GLDrawChar(CGLTex2D *tex, I64 x, I64 y, U8 char, CBGR24 color,
|
||||
U64 *font = text.font)
|
||||
{
|
||||
// Check if off-screen
|
||||
|
@ -18,28 +20,32 @@ U0 DrawChar(CTex2D *tex, I64 x, I64 y, U8 char, CBGR24 color,
|
|||
{
|
||||
for (i = 0; i < FONT_WIDTH; i++)
|
||||
{
|
||||
if (font[char].u8[j] & (1 << i))
|
||||
if (font[char].u8[j] & 1 << i)
|
||||
tex->rawBuf[x + i + (y + j) * tex->w] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ingroup Draw
|
||||
@ingroup GLDraw
|
||||
@brief Draw a single color string to color texture.
|
||||
|
||||
Escape sequences are not working correctly.
|
||||
|
||||
@param[in,out] tex Texture to draw to.
|
||||
@param[in] x X position to draw text at.
|
||||
@param[in] y Y position to draw text at.
|
||||
@param[in] color Color of text.
|
||||
@param[in] font Pointer to font buffer. System font by default.
|
||||
*/
|
||||
U0 DrawString(CTex2D *tex, I64 x, I64 y, U8 *str, CBGR24 color,
|
||||
U0 GLDrawString(CGLTex2D *tex, I64 x, I64 y, U8 *str, CBGR24 color,
|
||||
U64 *font = text.font)
|
||||
{
|
||||
I64 cur = 0; // String cursor
|
||||
I64 xCur = x; // Screen cursors
|
||||
I64 yCur = y;
|
||||
I64 cur = 0, // String cursor
|
||||
xCur, yCur; // Screen cursors
|
||||
|
||||
xCur = x;
|
||||
yCur = y;
|
||||
|
||||
while (str[cur] != NULL)
|
||||
{
|
||||
|
@ -47,7 +53,6 @@ U0 DrawString(CTex2D *tex, I64 x, I64 y, U8 *str, CBGR24 color,
|
|||
{
|
||||
// Escape sequence
|
||||
case '\\':
|
||||
"ESCAPE SEQ\n";
|
||||
switch (str[cur + 1])
|
||||
{
|
||||
case 'n':
|
||||
|
@ -62,7 +67,7 @@ U0 DrawString(CTex2D *tex, I64 x, I64 y, U8 *str, CBGR24 color,
|
|||
break;
|
||||
|
||||
case '\\':
|
||||
DrawChar(tex, xCur, yCur, '\\', color, font);
|
||||
GLDrawChar(tex, xCur, yCur, '\\', color, font);
|
||||
xCur += FONT_WIDTH;
|
||||
break;
|
||||
|
||||
|
@ -76,7 +81,7 @@ U0 DrawString(CTex2D *tex, I64 x, I64 y, U8 *str, CBGR24 color,
|
|||
break;
|
||||
|
||||
default:
|
||||
DrawChar(tex, xCur, yCur, str[cur], color, font);
|
||||
GLDrawChar(tex, xCur, yCur, str[cur], color, font);
|
||||
cur++;
|
||||
xCur += FONT_WIDTH;
|
||||
break;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
/**
|
||||
@ingroup Draw
|
||||
@ingroup GLDraw
|
||||
@brief Draw non-transformed color texture with blit operation.
|
||||
|
||||
Does not yet check if texture being drawn is entirely inside the texture
|
||||
|
@ -12,14 +12,15 @@
|
|||
@param[in] y Y location to draw texture.
|
||||
@param[in] transparent (optional) use alpha as mask. False by default.
|
||||
*/
|
||||
U0 DrawTexture(CTex2D *dst, CTex2D *src, I64 x, I64 y,
|
||||
U0 GLDrawTexture(CGLTex2D *dst, CGLTex2D *src, I64 x, I64 y,
|
||||
Bool transparent = FALSE)
|
||||
{
|
||||
I64 xC, yC; // Current width/height position being copied from
|
||||
I64 xC, yC, // Current width/height position being copied from
|
||||
srcW, srcH, dstW;
|
||||
|
||||
I64 srcW = src->w; // Don't think the compiler is optimizing this so I am
|
||||
I64 srcH = src->h;
|
||||
I64 dstW = dst->w;
|
||||
srcW = src->w;
|
||||
srcH = src->h;
|
||||
dstW = dst->w;
|
||||
|
||||
if (transparent)
|
||||
{
|
||||
|
@ -30,7 +31,7 @@ U0 DrawTexture(CTex2D *dst, CTex2D *src, I64 x, I64 y,
|
|||
if (src->rawBuf[xC + yC * srcW].pad == 255)
|
||||
{
|
||||
// Assume target doesn't care about alpha byte being copied
|
||||
dst->rawBuf[(x + xC) + (y + yC) * dstW] =
|
||||
dst->rawBuf[x + xC + (y + yC) * dstW] =
|
||||
src->rawBuf[xC + yC * srcW];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
/* Include this file to rebuild the CosmicGL library. */
|
||||
|
||||
Option(OPTf_WARN_PAREN, ON);
|
||||
Option(OPTf_WARN_DUP_TYPES, ON);
|
||||
|
||||
Cd(__DIR__);;
|
||||
#include "Math/Math"
|
||||
#include "Math/Types"
|
||||
#include "Math/Vec4"
|
||||
#include "Math/Vec3"
|
||||
#include "Math/Conversion"
|
||||
#include "Texture/Texture"
|
||||
#include "Draw/Primitive"
|
||||
#include "Draw/Texture"
|
||||
#include "Draw/Rectangle"
|
||||
#include "Draw/Text"
|
||||
#include "Render/Shader"
|
||||
#include "Render/Rasterize"
|
||||
#include "WAD/WADTypes"
|
||||
#include "WAD/WAD"
|
||||
#include "Texture/TextureImport"
|
||||
#include "WAD/DoomTypes"
|
||||
#include "WAD/DoomMap"
|
||||
#include "Texture/TextureImport"
|
19
src/Zenith/CosmicGL/Math/Conversion.CC
Normal file
19
src/Zenith/CosmicGL/Math/Conversion.CC
Normal file
|
@ -0,0 +1,19 @@
|
|||
asm
|
||||
{
|
||||
_DOUBLE_TO_SINGLE::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
//
|
||||
|
||||
POP RBP
|
||||
RET1 8
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Convert double-precision scalar to single-precision.
|
||||
|
||||
@param[in] d Double-precision scalar.
|
||||
@return Single-precision scalar.
|
||||
*/
|
||||
_extern _DOUBLE_TO_SINGLE I32 DoubleToSingle(F64 d);
|
|
@ -1,141 +0,0 @@
|
|||
/* Legacy math library. Is being replaced, however the few functions
|
||||
still used will remain until SIMD math library is finished. */
|
||||
|
||||
/**
|
||||
@defgroup math Math
|
||||
@brief Legacy math stuff that is still being used.
|
||||
*/
|
||||
|
||||
class CVec4
|
||||
{
|
||||
F64 x;
|
||||
F64 y;
|
||||
F64 z;
|
||||
F64 w;
|
||||
};
|
||||
|
||||
class CVec3
|
||||
{
|
||||
F64 x;
|
||||
F64 y;
|
||||
F64 z;
|
||||
};
|
||||
|
||||
class CVec2
|
||||
{
|
||||
F64 x;
|
||||
F64 y;
|
||||
};
|
||||
|
||||
class CIVec2
|
||||
{
|
||||
I64 x;
|
||||
I64 y;
|
||||
};
|
||||
|
||||
class CTri
|
||||
{
|
||||
CVec3 p[3];
|
||||
};
|
||||
|
||||
/**
|
||||
@ingroup math
|
||||
@brief Subtract vector b from a.
|
||||
|
||||
@param[in] a Vector 1
|
||||
@param[in] b Vector 2
|
||||
@param[in,out] dest Destination vector.
|
||||
*/
|
||||
U0 Vec2Sub(CVec2 *a, CVec2 *b, CVec2 *dest)
|
||||
{
|
||||
dest->x = a->x - b->x;
|
||||
dest->y = a->y - b->y;
|
||||
}
|
||||
|
||||
/**
|
||||
@ingroup math
|
||||
@brief Dot product of two vectors.
|
||||
|
||||
@param[in] a Vector 1
|
||||
@param[in] b Vector 2
|
||||
@return Dot product.
|
||||
*/
|
||||
F64 Vec2Dot(CVec2 *a, CVec2 *b)
|
||||
{
|
||||
return a->x * b->x + a->y * b->y;
|
||||
}
|
||||
|
||||
/**
|
||||
@ingroup math
|
||||
@brief Calculates barycentric coordinates for point p from triangle
|
||||
vertices a, b, and c.
|
||||
|
||||
@param[in] p Point
|
||||
@param[in] a Vertex 1
|
||||
@param[in] b Vertex 2
|
||||
@param[in] c Vertex 3
|
||||
@param[in,out] u U coordinate.
|
||||
@param[in,out] b V coordinate.
|
||||
@param[in,out] w W coordinate.
|
||||
*/
|
||||
U0 Vec2Barycentric(CVec2 *p, CVec2 *a, CVec2 *b, CVec2 *c, F64 *u, F64 *v, F64 *w)
|
||||
{
|
||||
CVec2 v0, v1, v2;
|
||||
Vec2Sub(b, a, &v0);
|
||||
Vec2Sub(c, a, &v1);
|
||||
Vec2Sub(p, a, &v2);
|
||||
|
||||
F64 d00 = Vec2Dot(&v0, &v0);
|
||||
F64 d01 = Vec2Dot(&v0, &v1);
|
||||
F64 d11 = Vec2Dot(&v1, &v1);
|
||||
F64 d20 = Vec2Dot(&v2, &v0);
|
||||
F64 d21 = Vec2Dot(&v2, &v1);
|
||||
F64 denom = d00 * d11 - d01 * d01;
|
||||
|
||||
F64 tempV, tempW;
|
||||
tempV = (d11 * d20 - d01 * d21)/denom;
|
||||
tempW = (d00 * d21 - d01 * d20)/denom;
|
||||
*u = 1.0 - tempV - tempW;
|
||||
*v = tempV;
|
||||
*w = tempW;
|
||||
}
|
||||
|
||||
/**
|
||||
@ingroup math
|
||||
@brief Converts float at address to double and writes to given address.
|
||||
|
||||
Useful for parsing standard model formats.
|
||||
|
||||
@param[in] float Float
|
||||
@param[in,out] double Double
|
||||
*/
|
||||
U0 Float2Double(U32 *float, U64 *double)
|
||||
{
|
||||
double->u32[1] = *float;
|
||||
|
||||
// Isolate parts of F32
|
||||
U64 MASK_SIGN = 0b1000000000000000000000000000000000000000000000000000000000000000;
|
||||
U64 MASK_EXP = 0b0111111110000000000000000000000000000000000000000000000000000000;
|
||||
U64 MASK_MANT = 0b0000000001111111111111111111111100000000000000000000000000000000;
|
||||
|
||||
U64 EXP = *double & MASK_EXP;
|
||||
U64 MANT = *double & MASK_MANT;
|
||||
|
||||
// Clear original F64 so that the masked values can be OR'd in
|
||||
*double = *double & MASK_SIGN;
|
||||
|
||||
// Exponent of F64 is 11 bits instead of 8, shift mantissa by 3 and OR it back in
|
||||
MANT = MANT >> 3;
|
||||
*double = *double | MANT;
|
||||
|
||||
// Shift exponent to regular int format
|
||||
// F32: [1 bit sign][8 bit exponent][23 bit mantissa]
|
||||
EXP = EXP >> 55; // 23 + 32 to get it in regular int format
|
||||
|
||||
if (EXP != 0)
|
||||
{
|
||||
EXP += 896; // -127, +1023
|
||||
EXP = EXP << 52;
|
||||
}
|
||||
*double = *double | EXP;
|
||||
}
|
49
src/Zenith/CosmicGL/Math/Types.CC
Normal file
49
src/Zenith/CosmicGL/Math/Types.CC
Normal file
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
@defgroup gfxmath Graphics Math
|
||||
@brief SSE accelerated graphics math.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Single-precision floating point 2D vector.
|
||||
|
||||
Must be kept on 16-byte alignment in memory.
|
||||
*/
|
||||
class CVec2
|
||||
{
|
||||
I32 x, y, z, w;
|
||||
};
|
||||
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Single-precision floating point 3D vector.
|
||||
|
||||
Must be kept on 16-byte alignment in memory.
|
||||
*/
|
||||
class CVec3
|
||||
{
|
||||
I32 x, y, z, w;
|
||||
};
|
||||
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Single-precision floating point 4D vector.
|
||||
|
||||
Must be kept on 16-byte alignment in memory.
|
||||
*/
|
||||
class CVec4
|
||||
{
|
||||
I32 x, y, z, w;
|
||||
};
|
||||
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Single-precision floating point 4x4 matrix.
|
||||
|
||||
Must be kept on 16 byte alignment in memory.
|
||||
*/
|
||||
class CMat4
|
||||
{
|
||||
U32 e[16];
|
||||
};
|
216
src/Zenith/CosmicGL/Math/Vec3.CC
Normal file
216
src/Zenith/CosmicGL/Math/Vec3.CC
Normal file
|
@ -0,0 +1,216 @@
|
|||
|
||||
asm
|
||||
{
|
||||
_VEC3::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG4[RBP] // = *dest
|
||||
|
||||
// CVTSD2SS XMM0, SF_ARG1[RBP]
|
||||
DU8 0xF2, 0x0F, 0x5A, 0x45, 0x10;
|
||||
// MOVSS [RAX], XMM0
|
||||
DU8 0xF3, 0x0F, 0x11, 0x00;
|
||||
|
||||
// CVTSD2SS XMM0, SF_ARG1[RBP]
|
||||
DU8 0xF2, 0x0F, 0x5A, 0x45, 0x18;
|
||||
// MOVSS 4[RAX], XMM0
|
||||
DU8 0xF3, 0x0F, 0x11, 0x40, 0x04;
|
||||
|
||||
// CVTSD2SS XMM0, SF_ARG1[RBP]
|
||||
DU8 0xF2, 0x0F, 0x5A, 0x45, 0x20;
|
||||
// MOVSS 8[RAX], XMM0
|
||||
DU8 0xF3, 0x0F, 0x11, 0x40, 0x08;
|
||||
|
||||
POP RBP
|
||||
RET1 32
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Initialize members of a vector with double-precision floats.
|
||||
|
||||
@param[in] x X component.
|
||||
@param[in] y Y component.
|
||||
@param[in] z Z component.
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC3 U0 Vec3(F64 x, F64 y, F64 z, CVec3 *dest);
|
||||
|
||||
asm
|
||||
{
|
||||
_VEC3_PRINT::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG1[RBP] // = *v
|
||||
SUB RSP, 24
|
||||
|
||||
// CVTSS2SD XMM0, 8[RAX] // (F64) v->z
|
||||
DU8 0xF3, 0x0F, 0x5A, 0x40, 0x08;
|
||||
// MOVSD 16[RSP], XMM0 // Push v->z
|
||||
DU8 0xF2, 0x0F, 0x11, 0x44, 0x24, 0x10;
|
||||
|
||||
// CVTSS2SD XMM0, 4[RAX] // (F64) v->y
|
||||
DU8 0xF3, 0x0F, 0x5A, 0x40, 0x04;
|
||||
// MOVSD 8[RSP], XMM0 // Push v->y
|
||||
DU8 0xF2, 0x0F, 0x11, 0x44, 0x24, 0x08;
|
||||
|
||||
// CVTSS2SD XMM0, [RAX] // (F64) v->x
|
||||
DU8 0xF3, 0x0f, 0x5A, 0x00;
|
||||
// MOVSD [RSP], XMM0 // Push v->x
|
||||
DU8 0xF2, 0x0F, 0x11, 0x04, 0x24;
|
||||
|
||||
PUSH 3 // # of varargs
|
||||
PUSH "X: %n | Y: %n | Z: %n\n"
|
||||
CALL &Print
|
||||
ADD RSP, 40
|
||||
|
||||
POP RBP
|
||||
RET1 8
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Print members of a vector.
|
||||
|
||||
@param[in] v Vector
|
||||
*/
|
||||
_extern _VEC3_PRINT U0 Vec3Print(CVec3 *v);
|
||||
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Copy all members of a vector to destination.
|
||||
|
||||
@param[in] src Source
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_COPY U0 Vec3Copy(CVec3 *src, CVec3 *dest);
|
||||
|
||||
asm
|
||||
{
|
||||
_VEC3_IS_EQUAL::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG1[RBP] // = *a
|
||||
// MOVAPS XMM0, [RAX]
|
||||
DU8 0x0F, 0x28, 0x00;
|
||||
MOV RAX, SF_ARG2[RBP] // = *b
|
||||
// MOVAPS XMM1, [RAX]
|
||||
DU8 0x0F, 0x28, 0x08;
|
||||
// CMPPS XMM0, XMM1, 0 // CMPEQPS
|
||||
DU8 0x0F, 0xC2, 0xC1, 0x00;
|
||||
|
||||
// PMOVMSKB RAX, XMM0
|
||||
DU8 0x66, 0x0F, 0xD7, 0xC0;
|
||||
AND RAX, 0xFFF
|
||||
CMP RAX, 0xFFF
|
||||
JNZ _is_not_equal
|
||||
MOV RAX, 1
|
||||
JMP _return
|
||||
_is_not_equal:
|
||||
MOV RAX, 0
|
||||
|
||||
_return:
|
||||
POP RBP
|
||||
RET1 16
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Checks if two vectors are equal.
|
||||
|
||||
@param[in] a Vector 1
|
||||
@param[in] b Vector 2
|
||||
*/
|
||||
_extern _VEC3_IS_EQUAL Bool Vec3IsEqual(CVec3 *a, CVec3 *b);
|
||||
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Sum of two vectors.
|
||||
|
||||
@param[in] a Vector 1
|
||||
@param[in] b Vector 2
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_ADD U0 Vec3Add(CVec3 *a, CVec3 *b, CVec3 *dest);
|
||||
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Add a scalar to a vector.
|
||||
|
||||
@param[in] v Vector
|
||||
@param[in] s Scalar
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_ADDS U0 Vec3AddS(CVec3 *v, I32 *s, CVec3 *dest);
|
||||
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Difference of two vectors.
|
||||
|
||||
@param[in] a Vector 1
|
||||
@param[in] b Vector 2
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_SUB U0 Vec3Sub(CVec3 *a, CVec3 *b, CVec3 *dest);
|
||||
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Subtract a scalar from a vector.
|
||||
|
||||
@param[in] v Vector
|
||||
@param[in] s Scalar
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_SUBS U0 Vec3SubS(CVec3 *v, I32 *s, CVec3 *dest);
|
||||
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Product of two vectors (element multiplication).
|
||||
|
||||
@param[in] a Vector 1
|
||||
@param[in] b Vector 2
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_MUL U0 Vec3Mul(CVec3 *a, CVec3 *b, CVec3 *dest);
|
||||
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Scale a vector by a scalar.
|
||||
|
||||
@param[in] v Vector
|
||||
@param[in] s Scalar
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_MULS U0 Vec3MulS(CVec3 *v, I32 *s, CVec3 *dest);
|
||||
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Quotient of two vectors.
|
||||
|
||||
@param[in] a Vector 1
|
||||
@param[in] b Vector 2
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_DIV U0 Vec3Div(CVec3 *a, CVec3 *b, CVec3 *dest);
|
||||
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Divide a vector by a scalar.
|
||||
|
||||
@param[in] v Vector
|
||||
@param[in] s Scalar
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_DIVS U0 Vec3DivS(CVec3 *v, I32 *s, CVec3 *dest);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
436
src/Zenith/CosmicGL/Math/Vec4.CC
Normal file
436
src/Zenith/CosmicGL/Math/Vec4.CC
Normal file
|
@ -0,0 +1,436 @@
|
|||
|
||||
asm
|
||||
{
|
||||
_VEC4::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG5[RBP] // = *dest
|
||||
|
||||
// CVTSD2SS XMM0, SF_ARG1[RBP]
|
||||
DU8 0xF2, 0x0F, 0x5A, 0x45, 0x10;
|
||||
// MOVSS [RAX], XMM0
|
||||
DU8 0xF3, 0x0F, 0x11, 0x00;
|
||||
|
||||
// CVTSD2SS XMM0, SF_ARG2[RBP]
|
||||
DU8 0xF2, 0x0F, 0x5A, 0x45, 0x18;
|
||||
// MOVSS 4[RAX], XMM0
|
||||
DU8 0xF3, 0x0F, 0x11, 0x40, 0x04;
|
||||
|
||||
// CVTSD2SS XMM0, SF_ARG3[RBP]
|
||||
DU8 0xF2, 0x0F, 0x5A, 0x45, 0x20;
|
||||
// MOVSS 8[RAX], XMM0
|
||||
DU8 0xF3, 0x0F, 0x11, 0x40, 0x08;
|
||||
|
||||
// CVTSD2SS XMM0, SF_ARG4[RBP]
|
||||
DU8 0xF2, 0x0F, 0x5A, 0x45, 0x28;
|
||||
// MOVSS 16[RAX], XMM0
|
||||
DU8 0xF3, 0x0F, 0x11, 0x40, 0x10;
|
||||
|
||||
POP RBP
|
||||
RET1 40
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Initialize members of a vector with double-precision floats.
|
||||
|
||||
@param[in] x X component.
|
||||
@param[in] y Y component.
|
||||
@param[in] z Z component.
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4 U0 Vec4(F64 x, F64 y, F64 z, F64 w, CVec4 *dest);
|
||||
|
||||
asm
|
||||
{
|
||||
_VEC4_PRINT::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG1[RBP] // = *v
|
||||
SUB RSP, 32
|
||||
|
||||
|
||||
// CVTSS2SD XMM0, 12[RAX] // (F64) v->w
|
||||
DU8 0xF3, 0x0F, 0x5A, 0x40, 0x0C;
|
||||
// MOVSD 24[RSP], XMM0 // Push v->w
|
||||
DU8 0xF2, 0x0F, 0x11, 0x44, 0x24, 0x18;
|
||||
|
||||
// CVTSS2SD XMM0, 8[RAX] // (F64) v->z
|
||||
DU8 0xF3, 0x0F, 0x5A, 0x40, 0x08;
|
||||
// MOVSD 16[RSP], XMM0 // Push v->z
|
||||
DU8 0xF2, 0x0F, 0x11, 0x44, 0x24, 0x10;
|
||||
|
||||
// CVTSS2SD XMM0, 4[RAX] // (F64) v->y
|
||||
DU8 0xF3, 0x0F, 0x5A, 0x40, 0x04;
|
||||
// MOVSD 8[RSP], XMM0 // Push v->y
|
||||
DU8 0xF2, 0x0F, 0x11, 0x44, 0x24, 0x08;
|
||||
|
||||
// CVTSS2SD XMM0, [RAX] // (F64) v->x
|
||||
DU8 0xF3, 0x0f, 0x5A, 0x00;
|
||||
// MOVSD [RSP], XMM0 // Push v->x
|
||||
DU8 0xF2, 0x0F, 0x11, 0x04, 0x24;
|
||||
|
||||
PUSH 4 // # of varargs
|
||||
PUSH "X: %n | Y: %n | Z: %n | W: %n\n"
|
||||
CALL &Print
|
||||
ADD RSP, 48
|
||||
|
||||
POP RBP
|
||||
RET1 8
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Print members of a vector.
|
||||
|
||||
@param[in] v Vector
|
||||
*/
|
||||
_extern _VEC4_PRINT U0 Vec4Print(CVec4 *v);
|
||||
|
||||
asm
|
||||
{
|
||||
_VEC4_COPY::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG1[RBP] // = *src
|
||||
// MOVAPS XMM0, [RAX]
|
||||
DU8 0x0F, 0x28, 0x00;
|
||||
MOV RAX, SF_ARG2[RBP] // = *dest
|
||||
// MOVAPS [RAX], XMM0
|
||||
DU8 0x0F, 0x29, 0x00;
|
||||
|
||||
POP RBP
|
||||
RET1 16
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Copy all members of a vector to destination.
|
||||
|
||||
@param[in] src Source
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_COPY U0 Vec4Copy(CVec4 *src, CVec4 *dest);
|
||||
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Checks if two vectors are equal.
|
||||
|
||||
@param[in] a Vector 1
|
||||
@param[in] b Vector 2
|
||||
@return TRUE if equal.
|
||||
*/
|
||||
Bool Vec4IsEqual(CVec4 *a, CVec4 *b)
|
||||
{
|
||||
U64 *c, *d;
|
||||
|
||||
c = a;
|
||||
d = b;
|
||||
if (c[0] == d[0] && c[1] == d[1])
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
asm
|
||||
{
|
||||
_VEC4_ADD::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG1[RBP]
|
||||
// MOVAPS XMM0, [RAX]
|
||||
DU8 0x0F, 0x28, 0x00;
|
||||
MOV RAX, SF_ARG2[RBP]
|
||||
// MOVAPS XMM1, [RAX]
|
||||
DU8 0x0F, 0x28, 0x08;
|
||||
// ADDPS XMM0, XMM1
|
||||
DU8 0x0F, 0x58, 0xC1;
|
||||
MOV RAX, SF_ARG3[RBP]
|
||||
// MOVAPS [RAX], XMM0
|
||||
DU8 0x0F, 0x29, 0x00;
|
||||
|
||||
POP RBP
|
||||
RET1 24
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Sum of two vectors.
|
||||
|
||||
@param[in] a Vector 1
|
||||
@param[in] b Vector 2
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_ADD U0 Vec4Add(CVec4 *a, CVec4 *b, CVec4 *dest);
|
||||
|
||||
asm
|
||||
{
|
||||
_VEC4_ADDS::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG1[RBP]
|
||||
// MOVAPS XMM0, [RAX]
|
||||
DU8 0x0F, 0x28, 0x00;
|
||||
// MOVSS XMM1, SF_ARG2[RBP]
|
||||
DU8 0xF3, 0x0F, 0x10, 0x4D, 0x18;
|
||||
// SHUFPS XMM1, XMM1, 0
|
||||
DU8 0x0F, 0xC6, 0xC9, 0x00;
|
||||
// ADDPS XMM0, XMM1
|
||||
DU8 0x0F, 0x58, 0xC1;
|
||||
MOV RAX, SF_ARG3[RBP]
|
||||
// MOVAPS [RAX], XMM0
|
||||
DU8 0x0F, 0x29, 0x00;
|
||||
|
||||
POP RBP
|
||||
RET1 24
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Add a scalar to a vector.
|
||||
|
||||
@param[in] v Vector
|
||||
@param[in] s Scalar
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_ADDS U0 Vec4AddS(CVec4 *v, I32 *s, CVec4 *dest);
|
||||
|
||||
asm
|
||||
{
|
||||
_VEC4_SUB::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG1[RBP]
|
||||
// MOVAPS XMM0, [RAX]
|
||||
DU8 0x0F, 0x28, 0x00;
|
||||
MOV RAX, SF_ARG2[RBP]
|
||||
// MOVAPS XMM1, [RAX]
|
||||
DU8 0x0F, 0x28, 0x08;
|
||||
// SUBPS XMM0, XMM1
|
||||
DU8 0x0F, 0x5C, 0xC1;
|
||||
MOV RAX, SF_ARG3[RBP]
|
||||
// MOVAPS [RAX], XMM0
|
||||
DU8 0x0F, 0x29, 0x00;
|
||||
|
||||
POP RBP
|
||||
RET1 24
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Difference of two vectors.
|
||||
|
||||
@param[in] a Vector 1
|
||||
@param[in] b Vector 2
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_SUB U0 Vec4Sub(CVec4 *a, CVec4 *b, CVec4 *dest);
|
||||
|
||||
asm
|
||||
{
|
||||
_VEC4_SUBS::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG1[RBP]
|
||||
// MOVAPS XMM0, [RAX]
|
||||
DU8 0x0F, 0x28, 0x00;
|
||||
// MOVSS XMM1, SF_ARG2[RBP]
|
||||
DU8 0xF3, 0x0F, 0x10, 0x4D, 0x18;
|
||||
// SHUFPS XMM1, XMM1, 0
|
||||
DU8 0x0F, 0xC6, 0xC9, 0x00;
|
||||
// SUBPS XMM0, XMM1
|
||||
DU8 0x0F, 0x5C, 0xC1;
|
||||
MOV RAX, SF_ARG3[RBP]
|
||||
// MOVAPS [RAX], XMM0
|
||||
DU8 0x0F, 0x29, 0x00;
|
||||
|
||||
POP RBP
|
||||
RET1 24
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Subtract a scalar from a vector.
|
||||
|
||||
@param[in] v Vector
|
||||
@param[in] s Scalar
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_SUBS U0 Vec4SubS(CVec4 *v, I32 *s, CVec4 *dest);
|
||||
|
||||
asm
|
||||
{
|
||||
_VEC4_MUL::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG1[RBP]
|
||||
// MOVAPS XMM0, [RAX]
|
||||
DU8 0x0F, 0x28, 0x00;
|
||||
MOV RAX, SF_ARG2[RBP]
|
||||
// MOVAPS XMM1, [RAX]
|
||||
DU8 0x0F, 0x28, 0x08;
|
||||
// MULPS XMM0, XMM1
|
||||
DU8 0x0F, 0x59, 0xC1;
|
||||
MOV RAX, SF_ARG3[RBP]
|
||||
// MOVAPS [RAX], XMM0
|
||||
DU8 0x0F, 0x29, 0x00;
|
||||
|
||||
POP RBP
|
||||
RET1 24
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Product of two vectors (element multiplication).
|
||||
|
||||
@param[in] a Vector 1
|
||||
@param[in] b Vector 2
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_MUL U0 Vec4Mul(CVec4 *a, CVec4 *b, CVec4 *dest);
|
||||
|
||||
asm
|
||||
{
|
||||
_VEC4_MULS::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG1[RBP]
|
||||
// MOVAPS XMM0, [RAX]
|
||||
DU8 0x0F, 0x28, 0x00;
|
||||
// MOVSS XMM1, SF_ARG2[RBP]
|
||||
DU8 0xF3, 0x0F, 0x10, 0x4D, 0x18;
|
||||
// SHUFPS XMM1, XMM1, 0
|
||||
DU8 0x0F, 0xC6, 0xC9, 0x00;
|
||||
// MULPS XMM0, XMM1
|
||||
DU8 0x0F, 0x59, 0xC1;
|
||||
MOV RAX, SF_ARG3[RBP]
|
||||
// MOVAPS [RAX], XMM0
|
||||
DU8 0x0F, 0x29, 0x00;
|
||||
|
||||
POP RBP
|
||||
RET1 24
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Scale a vector by a scalar.
|
||||
|
||||
@param[in] v Vector
|
||||
@param[in] s Scalar
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_MULS U0 Vec4MulS(CVec4 *v, I32 *s, CVec4 *dest);
|
||||
|
||||
|
||||
asm
|
||||
{
|
||||
_VEC4_DIV::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG1[RBP]
|
||||
// MOVAPS XMM0, [RAX]
|
||||
DU8 0x0F, 0x28, 0x00;
|
||||
MOV RAX, SF_ARG2[RBP]
|
||||
// MOVAPS XMM1, [RAX]
|
||||
DU8 0x0F, 0x28, 0x08;
|
||||
// DIVPS XMM0, XMM1
|
||||
DU8 0x0F, 0x5E, 0xC1;
|
||||
MOV RAX, SF_ARG3[RBP]
|
||||
// MOVAPS [RAX], XMM0
|
||||
DU8 0x0F, 0x29, 0x00;
|
||||
|
||||
POP RBP
|
||||
RET1 24
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Quotient of two vectors.
|
||||
|
||||
@param[in] a Vector 1
|
||||
@param[in] b Vector 2
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_DIV U0 Vec4Div(CVec4 *a, CVec4 *b, CVec4 *dest);
|
||||
|
||||
asm
|
||||
{
|
||||
_VEC4_DIVS::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG1[RBP]
|
||||
// MOVAPS XMM0, [RAX]
|
||||
DU8 0x0F, 0x28, 0x00;
|
||||
// MOVSS XMM1, SF_ARG2[RBP]
|
||||
DU8 0xF3, 0x0F, 0x10, 0x4D, 0x18;
|
||||
// SHUFPS XMM1, XMM1, 0
|
||||
DU8 0x0F, 0xC6, 0xC9, 0x00;
|
||||
// DIVPS XMM0, XMM1
|
||||
DU8 0x0F, 0x5E, 0xC1;
|
||||
MOV RAX, SF_ARG3[RBP]
|
||||
// MOVAPS [RAX], XMM0
|
||||
DU8 0x0F, 0x29, 0x00;
|
||||
|
||||
POP RBP
|
||||
RET1 24
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Scale a vector by a scalar.
|
||||
|
||||
@param[in] v Vector
|
||||
@param[in] s Scalar
|
||||
@param[in,out] dest Destination
|
||||
*/
|
||||
_extern _VEC4_DIVS U0 Vec4DivS(CVec4 *v, I32 *s, CVec4 *dest);
|
||||
|
||||
asm
|
||||
{
|
||||
_VEC4_DOT::
|
||||
PUSH RBP
|
||||
MOV RBP, RSP
|
||||
|
||||
MOV RAX, SF_ARG1[RBP]
|
||||
// MOVAPS XMM0, [RAX]
|
||||
DU8 0x0F, 0x28, 0x00;
|
||||
MOV RAX, SF_ARG2[RBP]
|
||||
// MOVAPS XMM1, [RAX]
|
||||
DU8 0x0F, 0x29, 0x08;
|
||||
// MULPS XMM0, XMM1
|
||||
DU8 0x0F, 0x59, 0xC1;
|
||||
|
||||
// MOVHLPS XMM1, XMM0
|
||||
DU8 0x0F, 0x12, 0xC8;
|
||||
// ADDPS XMM0, XMM1
|
||||
DU8 0x0F, 0x58, 0xC1;
|
||||
// MOVSS XMM1, XMM0
|
||||
DU8 0xF3, 0x0F, 0x10, 0xC8;
|
||||
// SHUFPS XMM1, XMM1, 0
|
||||
DU8 0x0F, 0xC6, 0xC9, 0x00;
|
||||
// ADDSS XMM0, XMM1
|
||||
DU8 0xF3, 0x0F, 0x58, 0xC1;
|
||||
|
||||
// MOVQ RAX, XMM0
|
||||
DU8 0x66, 0x48, 0x0F, 0x7E, 0xC0;
|
||||
|
||||
POP RBP
|
||||
RET1 16
|
||||
}
|
||||
/**
|
||||
@ingroup gfxmath
|
||||
@brief Dot product of two vectors.
|
||||
|
||||
@param[in] a Vector 1
|
||||
@param[in] b Vector 2
|
||||
@return Dot product.
|
||||
*/
|
||||
_extern _VEC4_DOT I32 Vec4Dot(CVec4 *a, CVec4 *b);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,323 +0,0 @@
|
|||
/**
|
||||
@ingroup Render
|
||||
@brief Renders triangles to texture.
|
||||
|
||||
Limitations: Triangles must be clipped to NDC.
|
||||
|
||||
@param[in] shd Shader.
|
||||
@param[in,out] frameBuf Color texture to render to.
|
||||
@param[in,out] depthBuf Depth texture to render to and check against.
|
||||
@param[in] mdl Model buffer, shader defines how to read this.
|
||||
@param[in] uniforms Buffer of unchanging values for shader.
|
||||
@param[in] nTris Number of triangles to render.
|
||||
*/
|
||||
U0 RenderTris(CShader *shd, CTex2D *frameBuf, CTex2D *depthBuf, U8 *mdl,
|
||||
U8 *uniforms, I64 nTris)
|
||||
{
|
||||
Bool middle_line_drawn = FALSE;
|
||||
F64 x_delta;
|
||||
F64 y_delta;
|
||||
F64 left_delta;
|
||||
F64 right_delta;
|
||||
F64 left_x;
|
||||
F64 right_x;
|
||||
I64 y, lX, rX;
|
||||
I64 left_index, right_index;
|
||||
|
||||
I64 i, j, temp;
|
||||
F64 ftemp;
|
||||
F64 z; // Interpolated value to depth check
|
||||
|
||||
// Stores baryocentric coordinates for current fragment
|
||||
F64 bc[3];
|
||||
|
||||
// Vertex coordinates. P is the point to get baryocentric coordinate for
|
||||
CVec2 p, a, b, c;
|
||||
|
||||
CBGR24 fragColor; // Final color to write to fragment
|
||||
|
||||
// Calculate dimensions and allocate vertex attributes buffer
|
||||
// to pass interpolated per-frag values to the fragment
|
||||
// shader from the vertex shader:
|
||||
|
||||
F64 *vOut; // This would be like Out from GLSL, it is 3x the size of fIn (3 vertices)
|
||||
F64 *fIn; // This would be like In from GLSL
|
||||
|
||||
I64 attrBufSize = 0;
|
||||
for (i = 0; i < shd->nVertValues; i++)
|
||||
{
|
||||
switch (shd->vertValues[i])
|
||||
{
|
||||
case SHD_F64:
|
||||
attrBufSize += 1;
|
||||
break;
|
||||
|
||||
case SHD_CVEC2:
|
||||
attrBufSize += 2;
|
||||
break;
|
||||
|
||||
case SHD_CVEC3:
|
||||
attrBufSize += 3;
|
||||
break;
|
||||
|
||||
case SHD_CMat4:
|
||||
attrBufSize += 16;
|
||||
break;
|
||||
}
|
||||
}
|
||||
vOut = MAlloc(attrBufSize * sizeof(F64) * 3); // 3x for 3 vertexes
|
||||
fIn = MAlloc(attrBufSize * sizeof(F64)); // Single set of interpolated values
|
||||
|
||||
CTri cTri; // Current Triangle in NDC
|
||||
CIVec2 cTriPx[3]; // Current Triangle in pixels
|
||||
I64 tri; // Current Triangle Index
|
||||
I64 VI[3]; // Vertex Indices
|
||||
|
||||
for (tri = 0; tri < nTris; tri++)
|
||||
{
|
||||
// Get current triangle in NDC from vertex shader
|
||||
shd->VertShd(&cTri, vOut, mdl, uniforms, tri, nTris);
|
||||
|
||||
ftemp = 0;
|
||||
ftemp += Abs(cTri.p[0].x);
|
||||
ftemp += Abs(cTri.p[0].y);
|
||||
ftemp += Abs(cTri.p[1].x);
|
||||
ftemp += Abs(cTri.p[1].y);
|
||||
ftemp += Abs(cTri.p[2].x);
|
||||
ftemp += Abs(cTri.p[2].y);
|
||||
|
||||
// Triangle is not outside NDC range, it is on screen
|
||||
//if (ftemp =< 6)
|
||||
if (1 == 1)
|
||||
{
|
||||
|
||||
// This triangle may not be in the correct order.
|
||||
// y0 should be lowest in texture coordinates, then y1 and y2.
|
||||
// This means y0 should be the highest in NDC coordinates.
|
||||
|
||||
// In VI (Vertex Indices), the array index is the index of the final point,
|
||||
// and it's value is the point from the original tri it get's it's
|
||||
// coordinates from.
|
||||
VI[0] = 0;
|
||||
VI[1] = 1;
|
||||
VI[2] = 2;
|
||||
|
||||
if (cTri.p[VI[0]].y < cTri.p[VI[1]].y)
|
||||
{
|
||||
temp = VI[0];
|
||||
VI[0] = VI[1];
|
||||
VI[1] = temp;
|
||||
}
|
||||
|
||||
if (cTri.p[VI[0]].y < cTri.p[VI[2]].y)
|
||||
{
|
||||
temp = VI[0];
|
||||
VI[0] = VI[2];
|
||||
VI[2] = temp;
|
||||
}
|
||||
|
||||
if (cTri.p[VI[1]].y < cTri.p[VI[2]].y)
|
||||
{
|
||||
temp = VI[1];
|
||||
VI[1] = VI[2];
|
||||
VI[2] = temp;
|
||||
}
|
||||
|
||||
// By now, VI[0] points to the point with the lowest
|
||||
// y in texture coordinates, and VI[2] points to the highest
|
||||
|
||||
// Convert NDC coordinates into tex coordinates for rasterization process
|
||||
cTriPx[0].x = ToI64(((cTri.p[VI[0]].x * 0.5) + 0.5) * ToF64(frameBuf->w));
|
||||
cTriPx[0].y = ToI64(((-cTri.p[VI[0]].y * 0.5) + 0.5) * ToF64(frameBuf->h));
|
||||
cTriPx[1].x = ToI64(((cTri.p[VI[1]].x * 0.5) + 0.5) * ToF64(frameBuf->w));
|
||||
cTriPx[1].y = ToI64(((-cTri.p[VI[1]].y * 0.5) + 0.5) * ToF64(frameBuf->h));
|
||||
cTriPx[2].x = ToI64(((cTri.p[VI[2]].x * 0.5) + 0.5) * ToF64(frameBuf->w));
|
||||
cTriPx[2].y = ToI64(((-cTri.p[VI[2]].y * 0.5) + 0.5) * ToF64(frameBuf->h));
|
||||
|
||||
|
||||
// Prepare F64 triangle point vectors for calculating barycentric coords later
|
||||
//Userd to use VI[0]
|
||||
a.x = cTriPx[0].x;
|
||||
a.y = cTriPx[0].y;
|
||||
b.x = cTriPx[1].x;
|
||||
b.y = cTriPx[1].y;
|
||||
c.x = cTriPx[2].x;
|
||||
c.y = cTriPx[2].y;
|
||||
|
||||
// Rasterize Bottom Half (Tex coordinates, not NDC)
|
||||
if (cTriPx[0].y != cTriPx[1].y)
|
||||
{
|
||||
x_delta = (cTriPx[1].x - cTriPx[0].x);
|
||||
y_delta = (cTriPx[1].y - cTriPx[0].y);
|
||||
left_delta = x_delta / y_delta;
|
||||
x_delta = (cTriPx[2].x - cTriPx[0].x);
|
||||
y_delta = (cTriPx[2].y - cTriPx[0].y);
|
||||
right_delta = x_delta / y_delta;
|
||||
|
||||
if (left_delta > right_delta)
|
||||
{
|
||||
ftemp = left_delta;
|
||||
left_delta = right_delta;
|
||||
right_delta = ftemp;
|
||||
}
|
||||
|
||||
left_x = cTriPx[0].x;
|
||||
right_x = cTriPx[0].x;
|
||||
|
||||
middle_line_drawn = TRUE;
|
||||
|
||||
for (y = cTriPx[0].y; y < (cTriPx[1].y + 1); y++)
|
||||
{
|
||||
lX = left_x + 0.5;
|
||||
rX = right_x + 0.5;
|
||||
left_index = y * frameBuf->w + lX;
|
||||
right_index = y * frameBuf->w + rX;
|
||||
|
||||
// Temporary fix, the y should just be clipped and left_x/right_x adjusted accordingly
|
||||
if (TRUE)
|
||||
|
||||
{
|
||||
// Check if x coordinate is off screen and clip it.
|
||||
if (lX < 0)
|
||||
{
|
||||
lX = 0;
|
||||
}
|
||||
if (lX > frameBuf->w)
|
||||
{
|
||||
lX = frameBuf->w;
|
||||
}
|
||||
if (rX > frameBuf->w)
|
||||
{
|
||||
rX = frameBuf->w;
|
||||
}
|
||||
if (rX < 0)
|
||||
{
|
||||
rX = 0;
|
||||
}
|
||||
|
||||
// For every pixel along the line, set it's color
|
||||
for (i = lX; i < rX; i++)
|
||||
{
|
||||
// Get barycentric coordinates (u, v, w)
|
||||
p.x = i;
|
||||
p.y = y;
|
||||
Vec2Barycentric(&p, &a, &b, &c, &bc[VI[0]], &bc[VI[1]], &bc[VI[2]]);
|
||||
|
||||
z = (bc[VI[0]] * cTri.p[VI[0]].z) + (bc[VI[1]] * cTri.p[VI[1]].z) + (bc[VI[2]] * cTri.p[VI[2]].z);
|
||||
|
||||
if (z <= depthBuf->depthBuf[y * frameBuf->w + i])
|
||||
{
|
||||
// Interpolate all vOut values to fIn values for the fragment shader
|
||||
for (j = 0; j < attrBufSize; j++)
|
||||
{
|
||||
fIn[j] = (vOut[j] * bc[0]) + (vOut[j+attrBufSize] * bc[1]) + (vOut[j+(2*attrBufSize)] * bc[2]);
|
||||
}
|
||||
|
||||
left_index = y * frameBuf->w + i;
|
||||
depthBuf->depthBuf[left_index] = z;
|
||||
shd->FragShd(&fragColor, fIn, uniforms);
|
||||
frameBuf->rawBuf[left_index] = fragColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
left_x += left_delta;
|
||||
right_x += right_delta;
|
||||
}
|
||||
}
|
||||
|
||||
// Rasterize Top Half (Tex coordinates, not NDC)
|
||||
if (cTriPx[1].y != cTriPx[2].y)
|
||||
{
|
||||
x_delta = -(cTriPx[1].x - cTriPx[2].x);
|
||||
y_delta = (cTriPx[1].y - cTriPx[2].y);
|
||||
left_delta = x_delta / y_delta;
|
||||
x_delta = -(cTriPx[0].x - cTriPx[2].x);
|
||||
y_delta = (cTriPx[0].y - cTriPx[2].y);
|
||||
right_delta = x_delta / y_delta;
|
||||
|
||||
if (left_delta > right_delta)
|
||||
{
|
||||
ftemp = left_delta;
|
||||
left_delta = right_delta;
|
||||
right_delta = ftemp;
|
||||
}
|
||||
|
||||
left_x = cTriPx[2].x;
|
||||
right_x = cTriPx[2].x;
|
||||
|
||||
if (middle_line_drawn == TRUE)
|
||||
{
|
||||
cTriPx[1].y += 1;
|
||||
}
|
||||
|
||||
a.x = cTriPx[0].x;
|
||||
a.y = cTriPx[0].y;
|
||||
b.x = cTriPx[1].x;
|
||||
b.y = cTriPx[1].y;
|
||||
c.x = cTriPx[2].x;
|
||||
c.y = cTriPx[2].y;
|
||||
|
||||
|
||||
for (y = cTriPx[2].y; y > (cTriPx[1].y - 1); y--)
|
||||
{
|
||||
lX = left_x + 0.5;
|
||||
rX = right_x + 0.5;
|
||||
left_index = y * frameBuf->w + lX;
|
||||
right_index = y * frameBuf->w + rX;
|
||||
|
||||
// Temporary fix, the y should just be clipped and left_x/right_x adjusted accordingly
|
||||
if (TRUE)
|
||||
{
|
||||
if (lX < 0)
|
||||
{
|
||||
lX = 0;
|
||||
}
|
||||
if (lX > frameBuf->w)
|
||||
{
|
||||
lX = frameBuf->w;
|
||||
}
|
||||
if (rX > frameBuf->w)
|
||||
{
|
||||
rX = frameBuf->w;
|
||||
}
|
||||
if (rX < 0)
|
||||
{
|
||||
rX = 0;
|
||||
}
|
||||
|
||||
// For every pixel along the line, set it's color
|
||||
for (i = lX; i < rX; i++)
|
||||
{
|
||||
// Get barycentric coordinates (u, v, w)
|
||||
p.x = i;
|
||||
p.y = y;
|
||||
Vec2Barycentric(&p, &a, &b, &c, &bc[VI[0]], &bc[VI[1]], &bc[VI[2]]);
|
||||
|
||||
z = (bc[VI[0]] * cTri.p[VI[0]].z) + (bc[VI[1]] * cTri.p[VI[1]].z) + (bc[VI[2]] * cTri.p[VI[2]].z);
|
||||
|
||||
if (z <= depthBuf->depthBuf[y * frameBuf->w + i])
|
||||
{
|
||||
// Interpolate all vOut values to fIn values for the fragment shader
|
||||
for (j = 0; j < attrBufSize; j++)
|
||||
{
|
||||
fIn[j] = (vOut[j] * bc[0]) + (vOut[j+attrBufSize] * bc[1]) + (vOut[j+(2*attrBufSize)] * bc[2]);
|
||||
}
|
||||
|
||||
left_index = y * frameBuf->w + i;
|
||||
depthBuf->depthBuf[left_index] = z;
|
||||
shd->FragShd(&fragColor, fIn, uniforms);
|
||||
frameBuf->rawBuf[left_index] = fragColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
left_x += left_delta;
|
||||
right_x += right_delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Free(vOut);
|
||||
Free(fIn);
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
/**
|
||||
@defgroup Render Render
|
||||
@brief For rendering triangle arrays using vertex/fragment shaders.
|
||||
*/
|
||||
|
||||
#define SHD_F64 1 /// @ingroup Render
|
||||
#define SHD_CVEC2 2 /// @ingroup Render
|
||||
#define SHD_CVEC3 3 /// @ingroup Render
|
||||
#define SHD_CVEC4 4 /// @ingroup Render
|
||||
#define SHD_CMat4 5 /// @ingroup Render
|
||||
|
||||
/**
|
||||
@ingroup Render
|
||||
@brief User-programmed and passed to renderer. Calculates on-screen
|
||||
coordinates of every triangle vertex, as well as the color for any given
|
||||
pixel being rasterized.
|
||||
|
||||
|
||||
Render Pipeline:
|
||||
|
||||
1) Vertex shader feeds in triangle coordinates in NDC format
|
||||
(Normalized Device Coordinates), as well as other
|
||||
per-vertex values it would like to interpolate and later
|
||||
feed to the frag shader.
|
||||
|
||||
2) Using these NDC triangle coordinates, the rasterizer
|
||||
calculates pixel positions of the triangles on the texture,
|
||||
and interpolates the per-vertex values given by the vertex
|
||||
shader into values for the particular fragment (pixel).
|
||||
|
||||
3) The fragment shader is called, with the interpolated
|
||||
fragment values fed in, and it calculates the color to
|
||||
be drawn at that particular fragment.
|
||||
*/
|
||||
class CShader
|
||||
{
|
||||
/**
|
||||
@brief The number of vertex attributes to interpolate and pass between
|
||||
the vertex and fragment shader.
|
||||
|
||||
For example if you wanted to pass an interpolated position and UV
|
||||
coordinate to the fragment shader, this value would be 2.
|
||||
*/
|
||||
I64 nVertValues;
|
||||
|
||||
/**
|
||||
@brief Array of vertex attribute types that describes the format of
|
||||
the vertex attributes. See SHD_ macros for types.
|
||||
|
||||
For example if you wanted to pass an interpolated position and UV
|
||||
coordinate to the fragment shader, this array would be
|
||||
{SHD_CVEC2, SHD_CVEC3}.
|
||||
*/
|
||||
I64 *vertValues;
|
||||
|
||||
/**
|
||||
@brief The vertex shader serves the purpose of returning
|
||||
a triangle in NDC (normalized device coordinates), as well as
|
||||
returning a buffer containing other vertex attributes such as
|
||||
position/normals/UVs.
|
||||
|
||||
@param[in,out] tri Returned triangle (in NDC).
|
||||
@param[in,out] vertOutBuf Vertex attributes to be interpolated
|
||||
for the frag shader. These are in format:
|
||||
Vertex 0 values, Vertex 1 values, Vertex
|
||||
2 values, where values has the format
|
||||
defined by vertValues in CShader.
|
||||
@param[in] mdlPtr The pointer to the model to calculate
|
||||
the output triangle from. There is no
|
||||
predefined model format, the user can
|
||||
give the renderer any model they want
|
||||
and interpret it in this function.
|
||||
@param[in] uniforms Unchanging variables throughout the render
|
||||
(ie: perspective/lighting/textures).
|
||||
@param[in] iTri Index of triangle to calculate.
|
||||
@param[in] nTris Total triangles being rendered. This
|
||||
function only calculates one triangle
|
||||
but this is given if accessing a triangle
|
||||
in your model depends on this value.
|
||||
*/
|
||||
U0 (*VertShd)(CTri *tri, F64 *vertOutBuf, U8 *mdlPtr, U8 *uniforms,
|
||||
I64 iTri, I64 nTris);
|
||||
|
||||
/**
|
||||
@brief The fragment shader serves the purpose of calculating
|
||||
the color for the current fragment (pixel) using the passed-in
|
||||
interpolated vertex attributes, as well as anything else given in
|
||||
the uniform buffer.
|
||||
|
||||
@param[in] vertBuf Interpolated vertex attributes at that frag
|
||||
(ie: position, uv, normal).
|
||||
@param[in] uniforms Unchanging variables throughout the render
|
||||
(ie: perspective/lighting/textures).
|
||||
@param[in,out] color Color calculated for this fragment.
|
||||
*/
|
||||
U0 (*FragShd)(CBGR24 *color, F64 *fragInBuf, U8 *uniforms);
|
||||
};
|
44
src/Zenith/CosmicGL/Test/TestMath.CC
Normal file
44
src/Zenith/CosmicGL/Test/TestMath.CC
Normal file
|
@ -0,0 +1,44 @@
|
|||
Cd(__DIR__);;
|
||||
#include "../Math/Types"
|
||||
#include "../Math/Vec4"
|
||||
#include "../Math/Vec3"
|
||||
|
||||
CVec4 *a = MAllocAligned(sizeof(CVec4), 16);
|
||||
CVec4 *b = MAllocAligned(sizeof(CVec4), 16);
|
||||
CVec4 *dest = MAllocAligned(sizeof(CVec4), 16);
|
||||
CVec4 *trueRes = MAllocAligned(sizeof(CVec4), 16);
|
||||
|
||||
// Note that some smaller vector functions are identical to larger vector
|
||||
// functions so they do not get tested.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Vec4Copy
|
||||
|
||||
Vec4(1.25, 2.5, 3.75, 5.0, a);
|
||||
Vec4(0.0, 0.0, 0.0, 0.0, dest);
|
||||
Vec4Copy(a, dest);
|
||||
if (!Vec4IsEqual(a, dest))
|
||||
{
|
||||
"[WARNING] Vec4Copy NOT WORKING CORRECTLY! RESULT VECTOR:\n";
|
||||
Vec4Print(dest);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Vec4Add
|
||||
|
||||
Vec4(1.25, -2.5, 3.75, -5.0, a);
|
||||
Vec4(-1.0, 2.0, -3.0, 4.0, b);
|
||||
Vec4(0.25, -0.5, 0.75, -1.0, trueRes);
|
||||
Vec4Add(a, b, dest);
|
||||
// Looks like I have to use actual float compare and not direct
|
||||
// equal compare. I'll fix Vec4IsEqual to do this.
|
||||
if (!Vec3IsEqual(dest, trueRes))
|
||||
{
|
||||
"[WARNING] Vec4Add NOT WORKING CORRECTLY! RESULT VECTOR:\n";
|
||||
Vec3Print(dest);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Free(a);
|
||||
Free(b);
|
||||
Free(dest);
|
||||
|
|
@ -1,29 +1,28 @@
|
|||
/**
|
||||
@defgroup Tex2D Texture
|
||||
@defgroup GLTex2D Texture
|
||||
@brief The core of the library, almost all functions either read from
|
||||
or write to textures.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
@ingroup Tex2D
|
||||
@ingroup GLTex2D
|
||||
@brief Raw format is a CBGR24 rawBuf array of size w * h in row-major
|
||||
order.
|
||||
*/
|
||||
#define TEX2D_RAW 1
|
||||
|
||||
/**
|
||||
@ingroup Tex2D
|
||||
@ingroup GLTex2D
|
||||
@brief Depth format is a F64 depthBuf array of size w * h in row-major
|
||||
order.
|
||||
*/
|
||||
#define TEX2D_DEPTH 2
|
||||
|
||||
/**
|
||||
@ingroup Tex2D
|
||||
@brief The CTex2D class
|
||||
@ingroup GLTex2D
|
||||
@brief The texture class, just about everything reads from or writes to this.
|
||||
*/
|
||||
class CTex2D
|
||||
class CGLTex2D
|
||||
{
|
||||
I64 type; // Type, see TEX2D_ macros above
|
||||
I64 w; // Width
|
||||
|
@ -36,7 +35,7 @@ class CTex2D
|
|||
};
|
||||
|
||||
/**
|
||||
@ingroup Tex2D
|
||||
@ingroup GLTex2D
|
||||
@brief Initialize texture.
|
||||
|
||||
@param[in,out] tex Uninitialized texture to initialize.
|
||||
|
@ -46,7 +45,7 @@ class CTex2D
|
|||
@param[in] l (Optional) left offset for use with sprite textures.
|
||||
@param[in] t (Optional) top offset for use with sprite textures.
|
||||
*/
|
||||
U0 Tex2DInit(CTex2D *tex, I64 type, I64 w, I64 h, I64 l = 0, I64 t = 0)
|
||||
U0 GLTex2DInit(CGLTex2D *tex, I64 type, I64 w, I64 h, I64 l = 0, I64 t = 0)
|
||||
{
|
||||
tex->w = w;
|
||||
tex->h = h;
|
||||
|
@ -56,23 +55,23 @@ U0 Tex2DInit(CTex2D *tex, I64 type, I64 w, I64 h, I64 l = 0, I64 t = 0)
|
|||
|
||||
switch (type)
|
||||
{
|
||||
case (TEX2D_RAW):
|
||||
case TEX2D_RAW:
|
||||
tex->rawBuf = MAlloc(4 * tex->w * tex->h);
|
||||
break;
|
||||
|
||||
case (TEX2D_DEPTH):
|
||||
case TEX2D_DEPTH:
|
||||
tex->depthBuf = MAlloc(sizeof(F64) * tex->w * tex->h);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ingroup Tex2D
|
||||
@ingroup GLTex2D
|
||||
@brief Free texture.
|
||||
|
||||
@param[in,out] tex Texture to free.
|
||||
*/
|
||||
U0 Tex2DFree(CTex2D *tex)
|
||||
U0 GLTex2DFree(CGLTex2D *tex)
|
||||
{
|
||||
switch (tex->type)
|
||||
{
|
||||
|
@ -87,24 +86,24 @@ U0 Tex2DFree(CTex2D *tex)
|
|||
}
|
||||
|
||||
/**
|
||||
@ingroup Tex2D
|
||||
@ingroup GLTex2D
|
||||
@brief Fill texture with color. Only works with raw textures.
|
||||
|
||||
@param[in,out] tex Texture to color fill.
|
||||
@param[in] color Color to fill texture with.
|
||||
*/
|
||||
U0 Tex2DColorFill(CTex2D *tex, CBGR24 color)
|
||||
U0 GLTex2DColorFill(CGLTex2D *tex, CBGR24 color)
|
||||
{
|
||||
MemSetU32(tex->rawBuf, color, tex->w * tex->h);
|
||||
}
|
||||
|
||||
/**
|
||||
@ingroup Tex2D
|
||||
@ingroup GLTex2D
|
||||
@brief Reset depth texture. Set all pixels to far depth.
|
||||
|
||||
@param[in,out] tex Depth texture to reset.
|
||||
*/
|
||||
U0 Tex2DDepthReset(CTex2D *tex)
|
||||
U0 GLTex2DDepthReset(CGLTex2D *tex)
|
||||
{
|
||||
F64 depth = 2.0;
|
||||
I64 *iDepth = &depth;
|
||||
|
@ -112,7 +111,7 @@ U0 Tex2DDepthReset(CTex2D *tex)
|
|||
}
|
||||
|
||||
/**
|
||||
@ingroup Tex2D
|
||||
@ingroup GLTex2D
|
||||
@brief Draw texture directly to display buffer. Maps non-visible textures
|
||||
like depth to a visible palette when drawing for visual debugging.
|
||||
|
||||
|
@ -125,7 +124,7 @@ U0 Tex2DDepthReset(CTex2D *tex)
|
|||
@param[in] x X position on screen to draw texture.
|
||||
@param[in] y Y position on screen to draw texture.
|
||||
*/
|
||||
U0 Tex2DDebugDisp(CTex2D *tex, I64 x, I64 y)
|
||||
U0 GLTex2DDebugDisp(CGLTex2D *tex, I64 x, I64 y)
|
||||
{
|
||||
// i, j = sampling x, y position on texture
|
||||
I64 i, j;
|
||||
|
@ -141,7 +140,7 @@ U0 Tex2DDebugDisp(CTex2D *tex, I64 x, I64 y)
|
|||
switch (tex->type)
|
||||
{
|
||||
case TEX2D_RAW:
|
||||
text.fb_alias[(x + i) + (y + j) * GR_WIDTH]
|
||||
text.fb_alias[x + i + (y + j) * GR_WIDTH]
|
||||
= tex->rawBuf[i + j * tex->w];
|
||||
break;
|
||||
|
||||
|
@ -151,7 +150,7 @@ U0 Tex2DDebugDisp(CTex2D *tex, I64 x, I64 y)
|
|||
color.r = scaled;
|
||||
color.g = scaled;
|
||||
color.b = scaled;
|
||||
text.fb_alias[(x + i) + (y + j) * GR_WIDTH] = color;
|
||||
text.fb_alias[x + i + (y + j) * GR_WIDTH] = color;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +158,7 @@ U0 Tex2DDebugDisp(CTex2D *tex, I64 x, I64 y)
|
|||
}
|
||||
|
||||
/**
|
||||
@ingroup Tex2D
|
||||
@ingroup GLTex2D
|
||||
@brief Sample color from color textures at normalized UV coordinate
|
||||
(0.0-1.0). Coordinates over 1.0 loop causing a repeating texture effect.
|
||||
|
||||
|
@ -170,10 +169,12 @@ U0 Tex2DDebugDisp(CTex2D *tex, I64 x, I64 y)
|
|||
@param[in] u Normalized (0.0-1.0) x coordinate to sample from.
|
||||
@param[in] v Normalized (0.0-1.0) y coordinate to sample from.
|
||||
*/
|
||||
U0 Tex2DSampleNorm(CBGR24 *col, CTex2D *tex, F64 u, F64 v)
|
||||
U0 GLTex2DSampleNorm(CBGR24 *col, CGLTex2D *tex, F64 u, F64 v)
|
||||
{
|
||||
I64 x = u * tex->w;
|
||||
I64 y = v * tex->h;
|
||||
I64 x, y;
|
||||
|
||||
x = u * tex->w;
|
||||
y = v * tex->h;
|
||||
x %= tex->w;
|
||||
y %= tex->h;
|
||||
|
||||
|
@ -181,7 +182,7 @@ U0 Tex2DSampleNorm(CBGR24 *col, CTex2D *tex, F64 u, F64 v)
|
|||
}
|
||||
|
||||
/**
|
||||
@ingroup Tex2D
|
||||
@ingroup GLTex2D
|
||||
@brief Sample color from color textures at UV coordinate. Coordinates
|
||||
over texture dimensions loop causing a repeating texture effect.
|
||||
|
||||
|
@ -189,7 +190,7 @@ U0 Tex2DSampleNorm(CBGR24 *col, CTex2D *tex, F64 u, F64 v)
|
|||
@param[in] u X coordinate to sample from.
|
||||
@param[in] v Y coordinate to sample from.
|
||||
*/
|
||||
U0 Tex2DSampleCoord(CBGR24 *col, CTex2D *tex, I64 u, I64 v)
|
||||
U0 GLTex2DSampleCoord(CBGR24 *col, CGLTex2D *tex, I64 u, I64 v)
|
||||
{
|
||||
u %= tex->w;
|
||||
v %= tex->h;
|
||||
|
|
|
@ -1,23 +1,21 @@
|
|||
/**
|
||||
@ingroup Tex2D
|
||||
@brief Loads Half-Life texture from WAD file.
|
||||
@ingroup GLTex2D
|
||||
@brief Loads texture from Half-Life WAD file.
|
||||
|
||||
@param[in,out] tex Unitialized texture to load into.
|
||||
@param[in] wad WAD file to load from.
|
||||
@param[in] texName Name of texture lump in WAD file to load.
|
||||
*/
|
||||
U0 Tex2DLoadWAD(CTex2D *tex, CWAD *wad, U8 *texName)
|
||||
U0 GLTex2DLoadWAD(CGLTex2D *tex, CGLWAD *wad, U8 *texName)
|
||||
{
|
||||
if (wad->type != WAD_TYPE_HL)
|
||||
{
|
||||
"[ERROR] CAN NOT LOAD %s TEXTURE FROM NON-HALF-LIFE WAD %s. USE LOAD
|
||||
SPRITE/FLAT/WALL FOR DOOM WADS.\n", texName, wad->name;
|
||||
return;
|
||||
}
|
||||
I64 i, texIndex;
|
||||
U8 *pixel, *palette;
|
||||
CGLWADFileLump *lump;
|
||||
CGLWADTex *wadTex;
|
||||
CBGR24 color;
|
||||
|
||||
// Get lump handle
|
||||
CWADFileLumpHL *lump;
|
||||
I64 texIndex = WADFindLump(wad, texName, &lump);
|
||||
texIndex = GLWADFindLump(wad, texName, &lump);
|
||||
|
||||
if (texIndex < 0)
|
||||
{
|
||||
|
@ -26,28 +24,26 @@ U0 Tex2DLoadWAD(CTex2D *tex, CWAD *wad, U8 *texName)
|
|||
}
|
||||
|
||||
// Map texture class to WAD file buffer
|
||||
CWADTexHL *wadTex = wad->fileBuf + lump->filePos;
|
||||
wadTex = wad->fileBuf + lump->filePos;
|
||||
|
||||
Tex2DInit(tex, TEX2D_RAW, wadTex->w, wadTex->h);
|
||||
GLTex2DInit(tex, TEX2D_RAW, wadTex->w, wadTex->h);
|
||||
|
||||
// Map pixel array
|
||||
U8 *pixel = wad->fileBuf + lump->filePos + wadTex->offsets[0];
|
||||
pixel = wad->fileBuf + lump->filePos + wadTex->offsets[0];
|
||||
|
||||
// After the last byte of the fourth mipmap, there are two padding bytes,
|
||||
// then a palette of 24-bit color (R, G, B).
|
||||
U8 *palette = wad->fileBuf + lump->filePos + wadTex->offsets[3] +
|
||||
((wadTex->w * wadTex->h) / 64) + 2;
|
||||
palette = wad->fileBuf + lump->filePos + wadTex->offsets[3] +
|
||||
wadTex->w * wadTex->h / 64 + 2;
|
||||
// 1/64 here is the relative size of 4th mip map
|
||||
|
||||
I64 i;
|
||||
CBGR24 color;
|
||||
color.pad = 255; // Alpha
|
||||
|
||||
for (i = 0; i < wadTex->w * wadTex->h; i++)
|
||||
{
|
||||
color.r = palette[pixel[i] * 3];
|
||||
color.g = palette[(pixel[i] * 3) + 1];
|
||||
color.b = palette[(pixel[i] * 3) + 2];
|
||||
color.g = palette[pixel[i] * 3 + 1];
|
||||
color.b = palette[pixel[i] * 3 + 2];
|
||||
|
||||
tex->rawBuf[i] = color;
|
||||
|
||||
|
@ -59,108 +55,10 @@ U0 Tex2DLoadWAD(CTex2D *tex, CWAD *wad, U8 *texName)
|
|||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Tex2D
|
||||
@brief Loads DOOM patch at memory location into position on texture.
|
||||
|
||||
Relevant locations on texture should be initialized with a transparent
|
||||
alpha byte.
|
||||
|
||||
@param[in,out] tex Initialized texture to load into.
|
||||
@param[in] patch Memory location of patch to load from.
|
||||
@param[in] palette Array of 256 colors.
|
||||
@param[in] l Left (x) offset.
|
||||
@param[in] t Top (y) offset.
|
||||
*/
|
||||
U0 Tex2DLoadWADPatch(CTex2D *tex, CWADPatch *patch, CBGR24 *palette,
|
||||
I64 l, I64 t)
|
||||
{
|
||||
I64 x, y;
|
||||
CWADPost *post; // Current post being parsed.
|
||||
|
||||
// Direct pointer addition gives wierd results so these are
|
||||
// intermediate pointers:
|
||||
I64 patchAddr = patch;
|
||||
I64 cursor;
|
||||
|
||||
// Iterate through every column in patch
|
||||
for (x = 0; x < patch->w; x++)
|
||||
{
|
||||
// Point post to first post in current column
|
||||
cursor = patchAddr + patch->columnOffsets[x];
|
||||
post = cursor;
|
||||
|
||||
// Post with offset 255 is last post in column and is empty
|
||||
while (post->yOffset != 255)
|
||||
{
|
||||
// Draw every pixel in post to texture buffer
|
||||
for (y = 0; y < post->length; y++)
|
||||
{
|
||||
tex->rawBuf[(x + l) + (y + t + post->yOffset) * tex->w]
|
||||
= palette[post->pixels[y]];
|
||||
}
|
||||
|
||||
// Point post to next post in column
|
||||
cursor += post->length + 4; // 3 starting bytes + last pad byte
|
||||
post = cursor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ingroup Tex2D
|
||||
@brief Loads DOOM sprite from WAD file.
|
||||
|
||||
@param[in,out] tex Unitialized texture to load into.
|
||||
@param[in] wad WAD file to load from.
|
||||
@param[in] sprName Name of sprite in WAD file to load.
|
||||
*/
|
||||
U0 Tex2DLoadWADSprite(CTex2D *tex, CWAD *wad, U8 *sprName)
|
||||
{
|
||||
if (wad->type != WAD_TYPE_DOOM)
|
||||
{
|
||||
"[ERROR] CAN NOT LOAD %s SPRITE FROM NON-DOOM %s\n", sprName, wad->name;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get lump handle
|
||||
CWADFileLumpDoom *lump;
|
||||
I64 sprIndex = WADFindLump(wad, sprName, &lump);
|
||||
|
||||
if (sprIndex < 0)
|
||||
{
|
||||
"[ERROR] CAN NOT FIND %s SPRITE IN %s\n", sprName, wad->name;
|
||||
return;
|
||||
}
|
||||
|
||||
// Map patch class to sprite lump (which is in patch format)
|
||||
CWADPatch *patch = wad->fileBuf + lump->filePos;
|
||||
|
||||
Tex2DInit(tex, TEX2D_RAW, patch->w, patch->h, patch->l, patch->t);
|
||||
Tex2DColorFill(tex, 0); // To set alpha to 0 since patch's don't draw
|
||||
// the transparent pixels, only opaque ones.
|
||||
Tex2DLoadWADPatch(tex, patch, wad->paletteBuf, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ingroup Tex2D
|
||||
@brief Loads DOOM wall texture from WAD file.
|
||||
|
||||
@param[in,out] tex Uninitialized texture to load into.
|
||||
@param[in] wad WAD file to load from.
|
||||
@param[in] wallName Name of wall in WAD file to load.
|
||||
|
||||
U0 Tex2DLoadWADWall(CTex2D *tex, CWAD *wad, U8 *wallName)
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Tex2D
|
||||
@ingroup GLTex2D
|
||||
@brief BMP file header.
|
||||
*/
|
||||
class CBMPHeader
|
||||
class CGLBMPHeader
|
||||
{
|
||||
U8 szVersion[2]; // Should have 'BM' signature
|
||||
U32 nSize; // File size in bytes
|
||||
|
@ -190,7 +88,7 @@ class CBMPHeader
|
|||
};
|
||||
|
||||
/**
|
||||
@ingroup Tex2D
|
||||
@ingroup GLTex2D
|
||||
@brief Loads BMP image.
|
||||
|
||||
Supports standard uncompressed 24-bit color BMP images.
|
||||
|
@ -198,12 +96,16 @@ class CBMPHeader
|
|||
@param[in,out] tex Uninitialized texture to load into.
|
||||
@param[in] fname File name of BMP.
|
||||
*/
|
||||
U0 Tex2DLoadBMP(CTex2D *tex, U8 *fname, Bool mask = FALSE)
|
||||
U0 GLTex2DLoadBMP(CGLTex2D *tex, U8 *fname)
|
||||
{
|
||||
U8 *bmp = FileRead(fname);
|
||||
I64 imgPointer,
|
||||
xPx, yPx;
|
||||
U8 *bmp;
|
||||
|
||||
bmp = FileRead(fname);
|
||||
|
||||
// Map locations in buffer;
|
||||
CBMPHeader *info = bmp;
|
||||
CGLBMPHeader *info = bmp;
|
||||
|
||||
//if (StrMatch(bmp->szVersion, "BM") == 0)
|
||||
if (info->szVersion[0] != 'B' && info->szVersion[1] != 'M')
|
||||
|
@ -221,48 +123,21 @@ U0 Tex2DLoadBMP(CTex2D *tex, U8 *fname, Bool mask = FALSE)
|
|||
// Each pixel is 3 bytes in 24-bit BMP, however CTex2D uses CBGR24
|
||||
// which contains a final padding bit (32-bits per pixel). The rows
|
||||
// also increment in the opposite direction.
|
||||
I64 imgPointer = bmp + info->nOffset;
|
||||
I64 xPx, yPx;
|
||||
imgPointer = bmp + info->nOffset;
|
||||
|
||||
// Initialize with RAW format for 24-bit non-compressed color
|
||||
GLTex2DInit(tex, TEX2D_RAW, info->nWidth, info->nHeight);
|
||||
|
||||
// For checking if a color channel is greater than 0 for masks
|
||||
// U8 channel;
|
||||
|
||||
if (mask)
|
||||
for (yPx = 0; yPx < info->nHeight; yPx++)
|
||||
{
|
||||
/*
|
||||
// Initialize with MASK format for 1-bit non-compressed color
|
||||
Tex2DInit(tex, TEX2D_MASK, info->nWidth, info->nHeight);
|
||||
|
||||
for (yPx = 0; yPx < info->nHeight; yPx++)
|
||||
for (xPx = 0; xPx < info->nWidth; xPx++)
|
||||
{
|
||||
for (xPx = 0; xPx < info->nWidth; xPx++)
|
||||
{
|
||||
channel = *(imgPointer + (xPx + info->nWidth *
|
||||
(info->nHeight - yPx)) * 3);
|
||||
|
||||
if ((channel == 0 && invert = TRUE) ||
|
||||
(channel > 0 && invert = FALSE))
|
||||
{
|
||||
tex->maskBuf[(xPx + info->nWidth * yPx) / 8] | (1 << (xPx % 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
// Initialize with RAW format for 24-bit non-compressed color
|
||||
Tex2DInit(tex, TEX2D_RAW, info->nWidth, info->nHeight);
|
||||
|
||||
for (yPx = 0; yPx < info->nHeight; yPx++)
|
||||
{
|
||||
for (xPx = 0; xPx < info->nWidth; xPx++)
|
||||
{
|
||||
MemCopy(&tex->rawBuf[xPx + info->nWidth * yPx],
|
||||
imgPointer + (xPx + info->nWidth * (info->nHeight - yPx))
|
||||
* 3, 3);
|
||||
}
|
||||
MemCopy(&tex->rawBuf[xPx + info->nWidth * yPx],
|
||||
imgPointer + (xPx + info->nWidth * (info->nHeight - yPx))
|
||||
* 3, 3);
|
||||
}
|
||||
}
|
||||
|
||||
Free(bmp);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,267 +0,0 @@
|
|||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief Hash table type for Doom texture hash.
|
||||
*/
|
||||
#define HTT_DOOM_TEX 420
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief Doom texture hash table size.
|
||||
*/
|
||||
#define DOOM_TEX_TABLE_SIZE 256
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief Hash for quick access of textures by name.
|
||||
*/
|
||||
class CHashDoomTex : CHash
|
||||
{
|
||||
CTex2D tex;
|
||||
};
|
||||
|
||||
/**
|
||||
@ingroup Doom
|
||||
@brief Runtime Doom map.
|
||||
*/
|
||||
class CDoomMap
|
||||
{
|
||||
I64 pad;
|
||||
|
||||
CDoomVertex *vertexes;
|
||||
I64 nVertexes;
|
||||
|
||||
CDoomSide *sides;
|
||||
I64 nSides;
|
||||
|
||||
CDoomLine *lines;
|
||||
I64 nLines;
|
||||
|
||||
// CHashTable *texTable; // Hash table for quick access of textures
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief Load blockmap from WAD into Doom map. See CDoomBBox.
|
||||
|
||||
@param[in,out] map Doom map to load into.
|
||||
@param[in] wad WAD to load from.
|
||||
@param[in] lumpIndex Index of BLOCKMAP lump in WAD.
|
||||
|
||||
U0 DoomMapLoadBlockmap(CDoomMap *map, CWAD *wad, I64 lumpIndex)
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
Load vertexes from WAD into Doom map. See CDoomVertex.
|
||||
|
||||
@param[in,out] map Doom map to load into.
|
||||
@param[in] wad WAD to load from.
|
||||
@param[in] lumpIndex Index of VERTEXES lump in WAD.
|
||||
*/
|
||||
U0 DoomMapLoadVertexes(CDoomMap *map, CWAD *wad, I64 lumpIndex)
|
||||
{
|
||||
CWADFileLumpDoom *lump = &wad->doomLumps[lumpIndex];
|
||||
|
||||
if (StrNICompare("VERTEXES", lump->name, 8) != 0)
|
||||
{
|
||||
"[ERROR] EXPECTED VERTEXES LUMP INDEX DOES NOT POINT TO A
|
||||
VERTEXES LUMP\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// Map WAD vertex array
|
||||
CWADVertex *verts = wad->fileBuf + lump->filePos;
|
||||
|
||||
// Calculate and update number of vertexes
|
||||
I64 nVerts = lump->size / sizeof(CWADVertex);
|
||||
map->nVertexes = nVerts;
|
||||
|
||||
// Allocate memory for map vertexes
|
||||
map->vertexes = MAlloc(sizeof(CDoomVertex) * nVerts);
|
||||
|
||||
// Load I16 vertexes to I64 fixed point
|
||||
I32 xIntermediate;
|
||||
I32 yIntermediate;
|
||||
I64 i;
|
||||
for (i = 0; i < nVerts; i++)
|
||||
{
|
||||
// Load I16 to I32 to preserve sign at MSB when shifting 32 bits left
|
||||
// for I64 fixed point conversion.
|
||||
xIntermediate = verts[i].x;
|
||||
yIntermediate = verts[i].y;
|
||||
|
||||
map->vertexes[i].x = xIntermediate << 32;
|
||||
map->vertexes[i].y = yIntermediate << 32;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief Load sectors from WAD into Doom map. See CDoomSector.
|
||||
|
||||
@param[in,out] map Doom map to load into.
|
||||
@param[in] wad WAD to load from.
|
||||
@param[in] lumpIndex Index of SECTORS lump in WAD.
|
||||
|
||||
U0 DoomMapLoadSectors(CDoomMap *map, CWAD *wad, I64 lumpIndex)
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief Load sides from WAD into Doom map. See CDoomSide.
|
||||
|
||||
@param[in,out] map Doom map to load into.
|
||||
@param[in] wad WAD to load from.
|
||||
@param[in] lumpIndex Index of SIDEDEFS lump in WAD.
|
||||
*/
|
||||
U0 DoomMapLoadSides(CDoomMap *map, CWAD *wad, I64 lumpIndex)
|
||||
{
|
||||
CWADFileLumpDoom *lump = &wad->doomLumps[lumpIndex];
|
||||
|
||||
if (StrNICompare("SIDEDEFS", lump->name, 8) != 0)
|
||||
{
|
||||
"[ERROR] EXPECTED SIDEDEFS LUMP INDEX DOES NOT POINT TO A
|
||||
SIDEDEFS LUMP\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// Map WAD sidedef array
|
||||
CWADSidedef *sidedefs = wad->fileBuf + lump->filePos;
|
||||
|
||||
// Calculate and update number of sidedefs
|
||||
I64 nSidedefs = lump->size / sizeof(CWADSidedef);
|
||||
map->nSides = nSidedefs;
|
||||
|
||||
// Allocate memory for map sides
|
||||
map->sides = MAlloc(sizeof(CDoomSide) * nSidedefs);
|
||||
|
||||
I64 i;
|
||||
for (i = 0; i < nSidedefs; i++)
|
||||
{
|
||||
map->sides[i].xOffset = sidedefs[i].xOffset;
|
||||
map->sides[i].yOffset = sidedefs[i].yOffset;
|
||||
|
||||
/* Todo - Handle wall texture loading */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief Load lines from WAD into Doom map. See CDoomLine.
|
||||
|
||||
@param[in,out] map Doom map to load into.
|
||||
@param[in] wad WAD to load from.
|
||||
@param[in] lumpIndex Index of LINEDEFS lump in WAD.
|
||||
*/
|
||||
U0 DoomMapLoadLines(CDoomMap *map, CWAD *wad, I64 lumpIndex)
|
||||
{
|
||||
CWADFileLumpDoom *lump = &wad->doomLumps[lumpIndex];
|
||||
|
||||
if (StrNICompare("LINEDEFS", lump->name, 8) != 0)
|
||||
{
|
||||
"[ERROR] EXPECTED LINEDEFS LUMP INDEX DOES NOT POINT TO A
|
||||
LINEDEFS LUMP\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// Map WAD linedefs array
|
||||
CWADLinedef *linedefs = wad->fileBuf + lump->filePos;
|
||||
|
||||
// Calculate and update number of linedefs
|
||||
I64 nLinedefs = lump->size / sizeof(CWADLinedef);
|
||||
map->nLines = nLinedefs;
|
||||
|
||||
// Allocate memory for map linedefs
|
||||
map->lines = MAlloc(sizeof(CDoomLine) * nLinedefs);
|
||||
|
||||
I64 i;
|
||||
for (i = 0; i < nLinedefs; i++)
|
||||
{
|
||||
map->lines[i].v1 = &map->vertexes[linedefs[i].v1];
|
||||
map->lines[i].v2 = &map->vertexes[linedefs[i].v2];
|
||||
|
||||
map->lines[i].frontSide = &map->sides[linedefs[i].frontSidedef];
|
||||
map->lines[i].backSide = &map->sides[linedefs[i].backSidedef];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief Builds sector line lists and subsector numbers. Finds block
|
||||
bounding boxes for sectors.
|
||||
|
||||
@param[in,out] map Map to modify.
|
||||
|
||||
U0 DoomMapGroupLines(CDoomMap *map)
|
||||
{
|
||||
// Look up sector number for each subsector
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
@ingroup Doom
|
||||
@brief Load DOOM map from WAD file.
|
||||
|
||||
@param[in,out] map Uninitialized Doom map to load into.
|
||||
@param[in] wad WAD to load from.
|
||||
@param[in] mapName Map from WAD to load (max length is 8 characters).
|
||||
*/
|
||||
U0 DoomMapLoad(CDoomMap *map, CWAD *wad, U8 *mapName)
|
||||
{
|
||||
I64 mapLumpIndex = WADFindLump(wad, mapName, NULL);
|
||||
|
||||
if (mapLumpIndex < 0)
|
||||
{
|
||||
"[ERROR] UNABLE TO FIND MAP %s IN WAD\n", mapName;
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare texture hash table
|
||||
// map->texTable = HashTableNew(DOOM_TEX_TABLE_SIZE);
|
||||
|
||||
//I64 thingsIndex = mapLumpIndex + 1;
|
||||
|
||||
I64 vertexesIndex = mapLumpIndex + 4;
|
||||
DoomMapLoadVertexes(map, wad, vertexesIndex);
|
||||
|
||||
I64 sidedefsIndex = mapLumpIndex + 3;
|
||||
DoomMapLoadSides(map, wad, sidedefsIndex);
|
||||
|
||||
I64 linedefsIndex = mapLumpIndex + 2;
|
||||
DoomMapLoadLines(map, wad, linedefsIndex);
|
||||
|
||||
//I64 segsIndex = mapLumpIndex + 5;
|
||||
//I64 subsectorsIndex = mapLumpIndex + 6;
|
||||
//I64 rejectIndex = mapLumpIndex + 7;
|
||||
//I64 blockmapIndex = mapLumpIndex + 8;
|
||||
}
|
||||
|
||||
/**
|
||||
@ingroup Doom
|
||||
@brief Free Doom map.
|
||||
|
||||
@param[in,out] map Doom map to free.
|
||||
|
||||
U0 DoomMapFree(CDoomMap *map)
|
||||
{
|
||||
// Free(map->vertexes);
|
||||
// Free(map->lines);
|
||||
// Free(map->sides);
|
||||
}
|
||||
*/
|
|
@ -1,125 +0,0 @@
|
|||
/**
|
||||
@defgroup Doom Doom
|
||||
@brief Functions for loading Doom maps from WADs and rendering them.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ingroup Doom
|
||||
@brief Fixed point 2D vertex.
|
||||
*/
|
||||
class CDoomVertex
|
||||
{
|
||||
I64 x;
|
||||
I64 y;
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief Fixed point 2D bounding box.
|
||||
*/
|
||||
class CDoomBBox
|
||||
{
|
||||
I64 x1;
|
||||
I64 y1;
|
||||
I64 x2;
|
||||
I64 y2;
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief A sector is a 2D section of the map.
|
||||
*/
|
||||
class CDoomSector
|
||||
{
|
||||
I64 floorH; // Floor height
|
||||
I64 ceilingH; // Ceiling height
|
||||
|
||||
CTex2D *floorTex;
|
||||
CTex2D *ceilingTex;
|
||||
|
||||
I64 lightLevel;
|
||||
I64 special;
|
||||
I16 tag;
|
||||
|
||||
I64 nLines; // Total lines associated with sector
|
||||
//CDoomLine **lines; // Array of line pointers
|
||||
CDoomBBox blockBox[4]; // Bounding box for height changes
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief A side contains the textures applied to a line (wall).
|
||||
*/
|
||||
class CDoomSide
|
||||
{
|
||||
I64 xOffset;
|
||||
I64 yOffset;
|
||||
|
||||
CTex2D *upperTex;
|
||||
CTex2D *lowerTex;
|
||||
CTex2D *middleTex;
|
||||
|
||||
CDoomSector *sectorFacing;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief Lines make up the shape of the map. A one sided wall is a
|
||||
solid wall, while a two sided wall is a boundary between sectors.
|
||||
*/
|
||||
class CDoomLine
|
||||
{
|
||||
CDoomVertex *v1;
|
||||
CDoomVertex *v2;
|
||||
CDoomSide *frontSide;
|
||||
CDoomSide *backSide;
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief Clipped line that is used to make up subsectors.
|
||||
*/
|
||||
class CDoomSeg
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief List of segs indicating some or all visible walls that define
|
||||
a convex BSP leaf.
|
||||
*/
|
||||
class CDoomSubSector
|
||||
{
|
||||
CDoomSector *sector;
|
||||
I64 nLines;
|
||||
I64 firstLine;
|
||||
};
|
||||
|
||||
#define NF_SUBSECTOR 0x8000
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup Doom
|
||||
@brief Splits level down a line. On either side of the line is either
|
||||
another child node or a BSP leaf (subsector).
|
||||
*/
|
||||
class CDoomNode
|
||||
{
|
||||
I64 x; // Partition start coordinates
|
||||
I64 y;
|
||||
I64 xChange; // Change from start to end of partition line
|
||||
I64 yChange;
|
||||
CDoomBBox rightBox;
|
||||
CDoomBBox leftBox;
|
||||
CDoomNode *rightChild;
|
||||
CDoomNode *leftChild;
|
||||
};
|
||||
|
|
@ -1,58 +1,41 @@
|
|||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief Half-Life WAD type.
|
||||
*/
|
||||
#define WAD_TYPE_HL 1
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief Doom WAD type.
|
||||
*/
|
||||
#define WAD_TYPE_DOOM 2
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@ingroup GLWAD
|
||||
@brief Hash table type for lump hash.
|
||||
*/
|
||||
#define HTT_LUMP 69
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@ingroup GLWAD
|
||||
@brief Hash for quick access of lump pointer and index by name.
|
||||
*/
|
||||
class CHashLump : CHash
|
||||
class CHashGLWADLump : CHash
|
||||
{
|
||||
CWADFileLump *lump; // Pointer to lump
|
||||
// Access with lump->doom/lump->hl
|
||||
I64 lumpIndex; // Index of lump in WAD
|
||||
CGLWADFileLump *lump;
|
||||
I64 lumpIndex;
|
||||
};
|
||||
|
||||
/**
|
||||
@ingroup WAD
|
||||
@ingroup GLWAD
|
||||
@brief Class for WAD currently in memory.
|
||||
|
||||
Has easy access handles and a hash table to quickly find lumps.
|
||||
*/
|
||||
class CWAD
|
||||
class CGLWAD
|
||||
{
|
||||
U8 *name;
|
||||
U8 *fileBuf;
|
||||
CWADInfo *info; // Type, size, pointer to lumps
|
||||
CWADFileLumpDoom *doomLumps;// Quick access doom lumps
|
||||
CWADFileLumpHL *hlLumps; // Quick access half life lumps
|
||||
I64 type; // WAD type
|
||||
CGLWADInfo *info; // WAD info header handle
|
||||
CGLWADFileLump *lumps; // File lumps array handle
|
||||
CHashTable *lumpTable; // Hash table for quick access of
|
||||
// lumps by name.
|
||||
CHashLump *hashLumps; // Hashes for lumpTable.
|
||||
CBGR24 *paletteBuf; // Color palette 0 for texture loading if doom
|
||||
CHashGLWADLump *hashLumps; // Hashes for lumpTable.
|
||||
};
|
||||
|
||||
/**
|
||||
@ingroup WAD
|
||||
@ingroup GLWAD
|
||||
@brief Finds lump with name and returns it's index in the WAD. Also
|
||||
points input lump pointer to it if found.
|
||||
|
||||
|
@ -61,9 +44,9 @@ class CWAD
|
|||
@param[in,out] lump Points to lump if found.
|
||||
@return Lump index in WAD. -1 if not found.
|
||||
*/
|
||||
I64 WADFindLump(CWAD *wad, U8 *name, CWADFileLump **lump = NULL)
|
||||
I64 GLWADFindLump(CGLWAD *wad, U8 *name, CGLWADFileLump **lump = NULL)
|
||||
{
|
||||
CHashLump *lumpHash;
|
||||
CHashGLWADLump *lumpHash;
|
||||
lumpHash = HashFind(name, wad->lumpTable, HTT_LUMP);
|
||||
|
||||
if (lumpHash != NULL)
|
||||
|
@ -80,54 +63,48 @@ I64 WADFindLump(CWAD *wad, U8 *name, CWADFileLump **lump = NULL)
|
|||
}
|
||||
|
||||
/**
|
||||
@ingroup WAD
|
||||
@brief Loads WAD file.
|
||||
@ingroup GLWAD
|
||||
@brief Loads Half-Life WAD file.
|
||||
|
||||
@param[in,out] wad Uninitialized WAD to initialize.
|
||||
@param[in,out] wad Uninitialized WAD to load into.
|
||||
@param[in] fname File name of WAD.
|
||||
*/
|
||||
U0 WADLoad(CWAD *wad, U8 *fname)
|
||||
U0 GLWADLoad(CGLWAD *wad, U8 *fname)
|
||||
{
|
||||
I64 i;
|
||||
U32 *type;
|
||||
|
||||
wad->fileBuf = FileRead(fname);
|
||||
wad->name = StrNew(fname);
|
||||
|
||||
// For palette loading if doom WAD
|
||||
CWADFileLumpDoom *paletteLump;
|
||||
U8 *paletteColor;
|
||||
|
||||
// Map locations in buffer
|
||||
// Map info handle to buffer
|
||||
wad->info = wad->fileBuf;
|
||||
|
||||
// Allocate hash table
|
||||
wad->lumpTable = HashTableNew(wad->info->nLumps); // Table
|
||||
wad->hashLumps = CAlloc(wad->info->nLumps * // Hashes
|
||||
sizeof(CHashLump));
|
||||
sizeof(CHashGLWADLump));
|
||||
|
||||
I64 i;
|
||||
|
||||
// Check version and proceed accordingly
|
||||
U32 *type = wad->info->type; // Cast to U32
|
||||
// Check version
|
||||
type = wad->info->type; // Cast to U32
|
||||
|
||||
// 'WAD3': Half Life 'WAD2': Quake
|
||||
if (*type == 0x33444157 || *type == 0x32444157)
|
||||
{
|
||||
wad->type = WAD_TYPE_HL;
|
||||
|
||||
// Map lumps to buffer
|
||||
wad->hlLumps = wad->fileBuf + wad->info->lumpOffset;
|
||||
wad->lumps = wad->fileBuf + wad->info->lumpOffset;
|
||||
|
||||
for (i = 0; i < wad->info->nLumps; i++)
|
||||
{
|
||||
// Copy name to hash
|
||||
wad->hashLumps[i].str = CAlloc(17); // 16 + NULL
|
||||
MemCopy(wad->hashLumps[i].str,
|
||||
wad->hlLumps[i].name, 16);
|
||||
wad->hashLumps[i].str = CAlloc(17);
|
||||
MemCopy(wad->hashLumps[i].str, wad->lumps[i].name, 16);
|
||||
|
||||
// Set hash type
|
||||
wad->hashLumps[i].type = HTT_LUMP;
|
||||
|
||||
// Link lump to hash
|
||||
wad->hashLumps[i].lump = &wad->hlLumps[i];
|
||||
wad->hashLumps[i].lump = &wad->lumps[i];
|
||||
|
||||
// Set lump index in hash to this index
|
||||
wad->hashLumps[i].lumpIndex = i;
|
||||
|
@ -137,71 +114,28 @@ U0 WADLoad(CWAD *wad, U8 *fname)
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 'IWAD': Doom Internal 'PWAD': Doom Patch
|
||||
if (*type == 0x44415749 || *type == 0x44415750)
|
||||
{
|
||||
wad->type = WAD_TYPE_DOOM;
|
||||
|
||||
// Map lumps to buffer
|
||||
wad->doomLumps = wad->fileBuf + wad->info->lumpOffset;
|
||||
|
||||
for (i = 0; i < wad->info->nLumps - 10; i++)
|
||||
{
|
||||
// Copy name to hash
|
||||
wad->hashLumps[i].str = CAlloc(9); // 8 + NULL
|
||||
MemCopy(wad->hashLumps[i].str,
|
||||
wad->doomLumps[i].name, 8);
|
||||
|
||||
// Set hash type
|
||||
wad->hashLumps[i].type = HTT_LUMP;
|
||||
|
||||
// Link lump to hash
|
||||
wad->hashLumps[i].lump = &wad->doomLumps[i];
|
||||
|
||||
// Set lump index in hash to this index
|
||||
wad->hashLumps[i].lumpIndex = i;
|
||||
|
||||
// Add hash to table
|
||||
HashAdd(&wad->hashLumps[i], wad->lumpTable);
|
||||
}
|
||||
|
||||
// Load palette 0 for texture loading later if it exists
|
||||
if (WADFindLump(wad, "PLAYPAL", &paletteLump) != -1)
|
||||
{
|
||||
wad->paletteBuf = MAlloc(sizeof(CBGR24) * 256);
|
||||
paletteColor = wad->fileBuf + paletteLump->filePos;
|
||||
|
||||
// Load each 3-byte RGB color into 4 byte BGRA palette
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
wad->paletteBuf[i].r = paletteColor[i * 3];
|
||||
wad->paletteBuf[i].g = paletteColor[i * 3 + 1];
|
||||
wad->paletteBuf[i].b = paletteColor[i * 3 + 2];
|
||||
wad->paletteBuf[i].pad = 255; // Alpha
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Type not recognized
|
||||
U64 typeStr = 0;
|
||||
MemCopy(&typeStr, wad->type, 4);
|
||||
"[ERROR] %s WAD TYPE NOT RECOGNIZED: %s\n", typeStr;
|
||||
"[ERROR] %s WAD TYPE NOT RECOGNIZED: %4ts\n", fname, type;
|
||||
}
|
||||
|
||||
/**
|
||||
@ingroup WAD
|
||||
@ingroup GLWAD
|
||||
@brief Free WAD.
|
||||
|
||||
@param[in,out] wad WAD to free.
|
||||
*/
|
||||
U0 WADFree(CWAD *wad)
|
||||
U0 GLWADFree(CGLWAD *wad)
|
||||
{
|
||||
I64 i;
|
||||
Free(wad->name);
|
||||
Free(wad->lumpTable->body);
|
||||
Free(wad->lumpTable);
|
||||
Free(wad->hashLumps);
|
||||
Free(wad->fileBuf);
|
||||
}
|
||||
|
||||
for (i = 0; i < wad->info->nLumps; i++)
|
||||
{
|
||||
Free(wad->hashLumps[i].str);
|
||||
}
|
||||
Free(wad->hashLumps);
|
||||
|
||||
Free(wad->fileBuf);
|
||||
}
|
|
@ -1,15 +1,14 @@
|
|||
/**
|
||||
@defgroup WAD WAD
|
||||
@brief WAD file format management and parsing. Supports DOOM and
|
||||
Half-Life WADs.
|
||||
@defgroup GLWAD WAD File Loading
|
||||
@brief Half-Life WAD file format management and parsing.
|
||||
*/
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@ingroup GLWAD
|
||||
@brief WAD file header.
|
||||
*/
|
||||
class CWADInfo
|
||||
class CGLWADInfo
|
||||
{
|
||||
U8 type[4]; // Type of WAD, like IWAD/PWAD/WAD3
|
||||
I32 nLumps; // Number of lumps
|
||||
|
@ -17,22 +16,11 @@ class CWADInfo
|
|||
};
|
||||
|
||||
/**
|
||||
@ingroup WAD
|
||||
@brief DOOM file lump. These point to "lumps" or directories in the WAD.
|
||||
@ingroup GLWAD
|
||||
@brief Half-Life WAD file lump. These point to "lumps" or directories in
|
||||
the WAD.
|
||||
*/
|
||||
class CWADFileLumpDoom
|
||||
{
|
||||
I32 filePos; // Relative offset
|
||||
I32 size;
|
||||
U8 name[8];
|
||||
};
|
||||
|
||||
/**
|
||||
@ingroup WAD
|
||||
@brief Half-Life file lump. These point to "lumps" or directories in the
|
||||
WAD.
|
||||
*/
|
||||
class CWADFileLumpHL
|
||||
class CGLWADFileLump
|
||||
{
|
||||
I32 filePos; // Relative offset
|
||||
I32 diskSize; // Size of lump (compressed)
|
||||
|
@ -43,238 +31,12 @@ class CWADFileLumpHL
|
|||
U8 name[16];
|
||||
};
|
||||
|
||||
/**
|
||||
@ingroup WAD
|
||||
@brief Union of Half-Life and DOOM lump classes to return as a pointer
|
||||
from general purpose WAD functions like WADFindLump.
|
||||
*/
|
||||
union CWADFileLump
|
||||
{
|
||||
CWADFileLumpDoom doom;
|
||||
CWADFileLumpHL hl;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief Thing element from a DOOM WAD THINGS lump.
|
||||
|
||||
Describes an entity.
|
||||
*/
|
||||
class CWADThing
|
||||
{
|
||||
I16 x;
|
||||
I64 y;
|
||||
I16 angle;
|
||||
I16 type;
|
||||
I16 flags;
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief Linedef element from a DOOM WAD LINEDEFS lump.
|
||||
|
||||
Describes a line that makes up a wall/sector boundary on the map.
|
||||
*/
|
||||
class CWADLinedef
|
||||
{
|
||||
I16 v1; // Vertex 1
|
||||
I16 v2; // Vertex 2
|
||||
I16 flags;
|
||||
I16 type;
|
||||
I16 sectorTag;
|
||||
I16 frontSidedef; // Sidedefs hold texture data for each side of linedef
|
||||
I16 backSidedef;
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief Sidedef element from a DOOM WAD SIDEDEFS lump.
|
||||
|
||||
Describes a side of a line (wall) and what textures it uses as well as
|
||||
what sector it faces.
|
||||
*/
|
||||
class CWADSidedef
|
||||
{
|
||||
I16 xOffset; // Texture x offset
|
||||
I16 yOffset; // Texture y offset
|
||||
U8 upperTex[8]; // These are found in TEXTUREx lumps
|
||||
U8 lowerTex[8];
|
||||
U8 middleTex[8];
|
||||
I16 sectorFaces; // Sector this sidedef faces
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief Vertex element from a DOOM WAD VERTEXES lump.
|
||||
*/
|
||||
class CWADVertex
|
||||
{
|
||||
I16 x;
|
||||
I16 y;
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief Segment element from a DOOM WAD SEGS lump.
|
||||
|
||||
Describes a segment of a line that makes up the outline of a subsector
|
||||
(convex BSP leaf).
|
||||
*/
|
||||
class CWADSeg
|
||||
{
|
||||
I16 v1;
|
||||
I16 v2;
|
||||
I16 angle;
|
||||
I16 linedef;
|
||||
I16 direction;
|
||||
I16 offset;
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief Sector element from a DOOM WAD SECTORS lump.
|
||||
|
||||
Describes a 2D region of the map.
|
||||
*/
|
||||
class CWADSector
|
||||
{
|
||||
I16 floorHeight;
|
||||
I16 ceilingHeight;
|
||||
U8 floorTex[8];
|
||||
U8 ceilingTex[8];
|
||||
I16 lightLevel;
|
||||
I16 flags;
|
||||
I16 tag;
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief Sub-sector element from a DOOM WAD SSECTORS lump.
|
||||
|
||||
Describes a convex BSP leaf, meaning a convex sub section of a sector.
|
||||
*/
|
||||
class CWADSubSector
|
||||
{
|
||||
I16 nLinedefs;
|
||||
I16 firstLinedef;
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief Node element from a DOOM WAD NODES lump
|
||||
|
||||
Describes a node on a BSP tree. Each node splits a region of the map into
|
||||
two along a line, with a left/right side child which can either be another
|
||||
node or a subsector.
|
||||
*/
|
||||
class CWADNode
|
||||
{
|
||||
I16 x;
|
||||
I16 y;
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief DOOM Patch texture header.
|
||||
|
||||
Points to columns which are variable size arrays of CWADPost. This is a
|
||||
variable length class.
|
||||
*/
|
||||
class CWADPatch
|
||||
{
|
||||
U16 w;
|
||||
U16 h;
|
||||
I16 l; // Offsets to shift origin point when drawing
|
||||
I16 t;
|
||||
U32 columnOffsets[1]; // Array of offsets (relative to header) of size
|
||||
// width. If columns are identical they may point
|
||||
// to the same column in the file.
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief DOOM Post.
|
||||
|
||||
A post is a vertical segment of opaque pixels in the column of a patch
|
||||
texture. There may be multiple of these posts in a column, one after the
|
||||
other, with the end of a column being signifiged by a post with an offset
|
||||
of 255. This is a variable length class.
|
||||
*/
|
||||
class CWADPost
|
||||
{
|
||||
U8 yOffset; // Offset from start of column. This is 255 if
|
||||
// signaling end of column.
|
||||
U8 length; // Length is bytes/pixels
|
||||
U8 pad;
|
||||
U8 pixels[1]; // Size is equal to length. Each pixel points to a color
|
||||
// in the color palette.
|
||||
// Technically another U8 pad comes here but pixels is variable length
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief Header to DOOM TEXTUREx lumps.
|
||||
*/
|
||||
class CWADTexHeader
|
||||
{
|
||||
I32 nTextures; // Number of textures in TEXTUREx lump
|
||||
I32 offsets[1]; // Offsets to CWADMapTex's from start of this class
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief Information about DOOM patch and where to find it in the PNAMES
|
||||
lump.
|
||||
*/
|
||||
class CWADMapPatch
|
||||
{
|
||||
I16 l; // Left offset (x origin)
|
||||
I16 t; // Top offset (y origin)
|
||||
I16 patch; // Patch number listed in PNAMES lump
|
||||
I16 stepdir; // Obsolete, ignored by all DOOM versions
|
||||
I16 colormap; // Obsolete, ignored by all DOOM versions
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@brief Texture in a DOOM TEXTUREx lump.
|
||||
|
||||
A texture is composed of multiple patches. However it would have been
|
||||
too simple for this to point to these patches directly, instead it points
|
||||
to CWADMapPatch which describes where the patch is found in the PNAMES
|
||||
lump.
|
||||
*/
|
||||
class CWADMapTex
|
||||
{
|
||||
U8 name[8];
|
||||
I32 masked; // Boolean
|
||||
I16 width;
|
||||
U16 height;
|
||||
U8 columnDir[4]; // Obsolete, ignored by all DOOM versions
|
||||
I16 patchCount; // Number of patches that make up texture
|
||||
CWADMapPatch patches[1]; // Size dependent on patchCount
|
||||
};
|
||||
|
||||
/**
|
||||
@internal
|
||||
@ingroup WAD
|
||||
@ingroup GLWAD
|
||||
@brief Header to a Half-Life texture lump.
|
||||
*/
|
||||
class CWADTexHL
|
||||
class CGLWADTex
|
||||
{
|
||||
U8 name[16];
|
||||
U32 w;
|
||||
|
|
Loading…
Reference in a new issue