diff options
author | StapleButter <thetotalworm@gmail.com> | 2017-03-02 00:49:44 +0100 |
---|---|---|
committer | StapleButter <thetotalworm@gmail.com> | 2017-03-02 00:49:44 +0100 |
commit | dcc0227b5620397974352c01a8885252739e4968 (patch) | |
tree | d0a331a20e34d0c1a484939b835f34cad3c15541 | |
parent | f7c481b2a17d6bdd5ebeca1687a681ba8d2385e7 (diff) |
textures.
well, it's a start.
-rw-r--r-- | GPU.h | 29 | ||||
-rw-r--r-- | GPU3D.cpp | 2 | ||||
-rw-r--r-- | GPU3D_Soft.cpp | 103 | ||||
-rw-r--r-- | melonDS.depend | 12 |
4 files changed, 133 insertions, 13 deletions
@@ -354,6 +354,35 @@ T ReadVRAM_OBJ(u32 addr) } +template<typename T> +T ReadVRAM_Texture(u32 addr) +{ + u32 ret = 0; + u32 mask = VRAMMap_Texture[(addr >> 17) & 0x3]; + + if (mask & (1<<0)) ret |= *(T*)&VRAM_A[addr & 0x1FFFF]; + if (mask & (1<<1)) ret |= *(T*)&VRAM_B[addr & 0x1FFFF]; + if (mask & (1<<2)) ret |= *(T*)&VRAM_C[addr & 0x1FFFF]; + if (mask & (1<<3)) ret |= *(T*)&VRAM_D[addr & 0x1FFFF]; + + return ret; +} + +template<typename T> +T ReadVRAM_TexPal(u32 addr) +{ + u32 ret = 0; + if (addr >= 0x18000) return 0; + u32 mask = VRAMMap_TexPal[(addr >> 14) & 0x7]; + + if (mask & (1<<4)) ret |= *(T*)&VRAM_E[addr & 0xFFFF]; + if (mask & (1<<5)) ret |= *(T*)&VRAM_F[addr & 0x3FFF]; + if (mask & (1<<6)) ret |= *(T*)&VRAM_G[addr & 0x3FFF]; + + return ret; +} + + void DisplaySwap(u32 val); void StartFrame(); @@ -1245,7 +1245,7 @@ void ExecuteCommand() case 0x22: // texcoord TexCoords[0] = ExecParams[0] & 0xFFFF; - TexCoords[1] = ExecParams[1] >> 16; + TexCoords[1] = ExecParams[0] >> 16; if ((TexParam >> 30) == 1) { TexCoords[0] = (TexCoords[0]*TexMatrix[0] + TexCoords[1]*TexMatrix[4] + TexMatrix[8] + TexMatrix[12]) >> 12; diff --git a/GPU3D_Soft.cpp b/GPU3D_Soft.cpp index 6ea1ba4..5418980 100644 --- a/GPU3D_Soft.cpp +++ b/GPU3D_Soft.cpp @@ -19,7 +19,7 @@ #include <stdio.h> #include <string.h> #include "NDS.h" -#include "GPU3D.h" +#include "GPU.h" namespace GPU3D @@ -48,8 +48,64 @@ void Reset() } -void RenderPixel(u32 attr, s32 x, s32 y, s32 z, u8 vr, u8 vg, u8 vb) +void TextureLookup(u32 texparam, u32 texpal, s16 s, s16 t, u8* r, u8* g, u8* b) { + u32 vramaddr = (texparam & 0xFFFF) << 3; + + u32 width = 8 << ((texparam >> 20) & 0x7); + u32 height = 8 << ((texparam >> 23) & 0x7); + + s >>= 4; + t >>= 4; + + // TODO: wraparound modes + s &= width-1; + t &= height-1; + + switch ((texparam >> 26) & 0x7) + { + case 3: // 16-color + { + vramaddr += (((t * width) + s) >> 1); + u8 pixel = GPU::ReadVRAM_Texture<u8>(vramaddr); + if (s & 0x1) pixel >>= 4; + else pixel &= 0xF; + + texpal <<= 4; + u16 color = GPU::ReadVRAM_TexPal<u16>(texpal + (pixel<<1)); + + *r = (color << 1) & 0x3E; if (*r) *r++; + *g = (color >> 4) & 0x3E; if (*g) *g++; + *b = (color >> 9) & 0x3E; if (*b) *b++; + } + break; + + case 4: // 256-color + { + vramaddr += ((t * width) + s); + u8 pixel = GPU::ReadVRAM_Texture<u8>(vramaddr); + + texpal <<= 4; + u16 color = GPU::ReadVRAM_TexPal<u16>(texpal + (pixel<<1)); + + *r = (color << 1) & 0x3E; if (*r) *r++; + *g = (color >> 4) & 0x3E; if (*g) *g++; + *b = (color >> 9) & 0x3E; if (*b) *b++; + } + break; + + default: + *r = (s)&0x3F; + *g = 0; + *b = (t)&0x3F; + break; + } +} + +void RenderPixel(Polygon* polygon, s32 x, s32 y, s32 z, u8 vr, u8 vg, u8 vb, s16 s, s16 t) +{ + u32 attr = polygon->Attr; + u32* depth = &DepthBuffer[(256*y) + x]; bool passdepth = false; @@ -65,10 +121,34 @@ void RenderPixel(u32 attr, s32 x, s32 y, s32 z, u8 vr, u8 vg, u8 vb) if (!passdepth) return; + u8 r, g, b; + + if (((polygon->TexParam >> 26) & 0x7) != 0) + { + // TODO: also take DISP3DCNT into account + + u8 tr, tg, tb; + TextureLookup(polygon->TexParam, polygon->TexPalette, s, t, &tr, &tg, &tb); + + // TODO: other blending modes + /*r = ((tr+1) * (vr+1) - 1) >> 6; + g = ((tg+1) * (vg+1) - 1) >> 6; + b = ((tb+1) * (vb+1) - 1) >> 6;*/ + r = tr; + g = tg; + b = tb; + } + else + { + r = vr; + g = vg; + b = vb; + } + u8* pixel = &ColorBuffer[((256*y) + x) * 4]; - pixel[0] = vr; - pixel[1] = vg; - pixel[2] = vb; + pixel[0] = r; + pixel[1] = g; + pixel[2] = b; pixel[3] = 31; // TODO: alpha // TODO: optional update for translucent pixels @@ -151,6 +231,8 @@ void RenderPolygon(Polygon* polygon) ybot = vtx->FinalPosition[1]; vbot = i; } + + //printf("v%d: %d,%d\n", i, vtx->FinalPosition[0], vtx->FinalPosition[1]); } // draw, line per line @@ -305,10 +387,16 @@ void RenderPolygon(Polygon* polygon) s32 gl = ((perspfactorl1 * vlcur->FinalColor[1]) + (perspfactorl2 * vlnext->FinalColor[1])) / (perspfactorl1 + perspfactorl2); s32 bl = ((perspfactorl1 * vlcur->FinalColor[2]) + (perspfactorl2 * vlnext->FinalColor[2])) / (perspfactorl1 + perspfactorl2); + s32 sl = ((perspfactorl1 * vlcur->TexCoords[0]) + (perspfactorl2 * vlnext->TexCoords[0])) / (perspfactorl1 + perspfactorl2); + s32 tl = ((perspfactorl1 * vlcur->TexCoords[1]) + (perspfactorl2 * vlnext->TexCoords[1])) / (perspfactorl1 + perspfactorl2); + s32 rr = ((perspfactorr1 * vrcur->FinalColor[0]) + (perspfactorr2 * vrnext->FinalColor[0])) / (perspfactorr1 + perspfactorr2); s32 gr = ((perspfactorr1 * vrcur->FinalColor[1]) + (perspfactorr2 * vrnext->FinalColor[1])) / (perspfactorr1 + perspfactorr2); s32 br = ((perspfactorr1 * vrcur->FinalColor[2]) + (perspfactorr2 * vrnext->FinalColor[2])) / (perspfactorr1 + perspfactorr2); + s32 sr = ((perspfactorr1 * vrcur->TexCoords[0]) + (perspfactorr2 * vrnext->TexCoords[0])) / (perspfactorr1 + perspfactorr2); + s32 tr = ((perspfactorr1 * vrcur->TexCoords[1]) + (perspfactorr2 * vrnext->TexCoords[1])) / (perspfactorr1 + perspfactorr2); + if (xr == xl) xr++; s32 xdiv = 0x1000 / (xr - xl); @@ -340,7 +428,10 @@ void RenderPolygon(Polygon* polygon) u32 vg = ((perspfactor1 * gl) + (perspfactor2 * gr)) / (perspfactor1 + perspfactor2); u32 vb = ((perspfactor1 * bl) + (perspfactor2 * br)) / (perspfactor1 + perspfactor2); - RenderPixel(polygon->Attr, x, y, z, vr>>3, vg>>3, vb>>3); + s16 s = ((perspfactor1 * sl) + (perspfactor2 * sr)) / (perspfactor1 + perspfactor2); + s16 t = ((perspfactor1 * tl) + (perspfactor2 * tr)) / (perspfactor1 + perspfactor2); + + RenderPixel(polygon, x, y, z, vr>>3, vg>>3, vb>>3, s, t); } } diff --git a/melonDS.depend b/melonDS.depend index 6ca48b0..67904b5 100644 --- a/melonDS.depend +++ b/melonDS.depend @@ -10,7 +10,7 @@ 1481161027 c:\documents\sources\melonds\types.h -1488405583 source:c:\documents\sources\melonds\nds.cpp +1488411597 source:c:\documents\sources\melonds\nds.cpp <stdio.h> <string.h> "NDS.h" @@ -87,7 +87,7 @@ "NDS.h" "SPI.h" -1488405475 source:c:\documents\sources\melonds\gpu2d.cpp +1488405741 source:c:\documents\sources\melonds\gpu2d.cpp <stdio.h> <string.h> "NDS.h" @@ -125,7 +125,7 @@ "NDS.h" "GPU.h" -1488227363 c:\documents\sources\melonds\gpu.h +1488410598 c:\documents\sources\melonds\gpu.h "GPU2D.h" "GPU3D.h" @@ -148,16 +148,16 @@ 1488239485 c:\documents\sources\melonds\gpu3d.h -1488239513 source:c:\documents\sources\melonds\gpu3d.cpp +1488410045 source:c:\documents\sources\melonds\gpu3d.cpp <stdio.h> <string.h> "NDS.h" "GPU.h" "FIFO.h" -1488390544 source:c:\documents\sources\melonds\gpu3d_soft.cpp +1488412022 source:c:\documents\sources\melonds\gpu3d_soft.cpp <stdio.h> <string.h> "NDS.h" - "GPU3D.h" + "GPU.h" |