From c2ddd1f83e1017ba9ae7b5067770b5da396f090f Mon Sep 17 00:00:00 2001 From: zeromus Date: Wed, 8 Apr 2009 05:17:36 +0000 Subject: [PATCH] major fixes to viewport handling which didn't work at all before since it was not executed per poly (closes out SF [1701567]). now advance wars battle scenes work --- desmume/src/OGLRender.cpp | 13 ++++++++++--- desmume/src/gfx3d.cpp | 22 +++++++++++++--------- desmume/src/gfx3d.h | 14 +++++++------- desmume/src/rasterize.cpp | 26 +++++++++++++++++++++----- 4 files changed, 51 insertions(+), 24 deletions(-) diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index e88e48336..da136c3b0 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -702,8 +702,6 @@ static void OGLRender() xglDepthMask(GL_TRUE); - glViewport(gfx3d.viewport.x,gfx3d.viewport.y,gfx3d.viewport.width,gfx3d.viewport.height); - float clearColor[4] = { ((float)(gfx3d.clearColor&0x1F))/31.0f, ((float)((gfx3d.clearColor>>5)&0x1F))/31.0f, @@ -723,7 +721,7 @@ static void OGLRender() //TODO - properly doublebuffer the display lists { - u32 lastTextureFormat = 0, lastTexturePalette = 0, lastPolyAttr = 0; + u32 lastTextureFormat = 0, lastTexturePalette = 0, lastPolyAttr = 0, lastViewport = 0xFFFFFFFF; // int lastProjIndex = -1; for(int i=0;icount;i++) { @@ -775,6 +773,15 @@ static void OGLRender() glVertex4fv(vert->coord); } glEnd();*/ + + if(lastViewport != poly->viewport) + { + VIEWPORT viewport; + viewport.decode(poly->viewport); + glViewport(viewport.x,viewport.y,viewport.width,viewport.height); + lastViewport = poly->viewport; + } + glBegin(GL_TRIANGLES); for(int j = 1; j < (type-1); j++) diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index 7fd0521ec..cf3d3f383 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -137,6 +137,7 @@ static CACHE_ALIGN float trans[4] = {0.0, 0.0, 0.0, 0.0}; static int transind = 0; static CACHE_ALIGN float scale[4] = {0.0, 0.0, 0.0, 0.0}; static int scaleind = 0; +static u32 viewport; //various other registers static float _t=0, _s=0; @@ -295,17 +296,22 @@ void gfx3d_reset() _s=0; last_t = 0; last_s = 0; + viewport = 0xBFFF0000; GFX_FIFOclear(); } void gfx3d_glViewPort(u32 v) { - //zero: NHerve messed with this in mod2 and mod3, but im still not sure its perfect. need to research this. - gfx3d.viewport.x = (v&0xFF); - gfx3d.viewport.y = (v&0xFF); - gfx3d.viewport.width = (((v>>16)&0xFF)+1)-(v&0xFF); - gfx3d.viewport.height = ((v>>24)+1)-((v>>8)&0xFF); + viewport = v; +} + +void VIEWPORT::decode(u32 v) +{ + x = (v&0xFF); + y = std::min(191,(int)(((v>>8)&0xFF))); + width = (((v>>16)&0xFF)+1)-(v&0xFF); + height = ((v>>24)+1)-((v>>8)&0xFF); } @@ -731,6 +737,7 @@ static void SetVertex() poly.polyAttr = polyAttr; poly.texParam = textureFormat; poly.texPalette = texturePalette; + poly.viewport = viewport; polylist->count++; } } @@ -2205,10 +2212,7 @@ SFORMAT SF_GFX3D[]={ { "GSWB", 4, 1, &gfx3d.wbuffer}, { "GSSM", 4, 1, &gfx3d.sortmode}, { "GSAR", 1, 1, &gfx3d.alphaTestRef}, - { "GSVX", 4, 1, &gfx3d.viewport.x}, - { "GSVY", 4, 1, &gfx3d.viewport.y}, - { "GSVW", 4, 1, &gfx3d.viewport.width}, - { "GSVH", 4, 1, &gfx3d.viewport.height}, + { "GSVP", 4, 1, &viewport}, { "GSCC", 4, 1, &gfx3d.clearColor}, { "GSCD", 4, 1, &gfx3d.clearDepth}, { "GSFC", 4, 4, gfx3d.fogColor}, diff --git a/desmume/src/gfx3d.h b/desmume/src/gfx3d.h index 33f3f343b..4d9dbbecd 100644 --- a/desmume/src/gfx3d.h +++ b/desmume/src/gfx3d.h @@ -64,6 +64,7 @@ struct POLY { u32 polyAttr, texParam, texPalette; //the hardware rendering params // int projIndex; //the index into the projlist that this poly uses u32 pad; + u32 viewport; bool isTranslucent() { @@ -118,6 +119,12 @@ struct VERTLIST { int count; }; + +struct VIEWPORT { + int x, y, width, height; + void decode(u32 v); +}; + //used to communicate state to the renderer struct GFX3D { @@ -153,13 +160,6 @@ struct GFX3D u8 alphaTestRef; - struct VIEWPORT { - VIEWPORT() - : x(0), y(0), width(256), height(256) - {} - int x, y, width, height; - } viewport; - u32 clearDepth; u32 clearColor; float fogColor[4]; diff --git a/desmume/src/rasterize.cpp b/desmume/src/rasterize.cpp index 6fe6a81cb..ddfef3aea 100644 --- a/desmume/src/rasterize.cpp +++ b/desmume/src/rasterize.cpp @@ -760,12 +760,21 @@ static void drawscanline(edge_fx_fl *pLeft, edge_fx_fl *pRight) //CONSIDER: in case some other math is wrong (shouldve been clipped OK), we might go out of bounds here. //better check the Y value. - //but, we think the math is always right + if(pLeft->Y<0 || pLeft->Y>191) { + printf("rasterizer rendering at y=%d! oops!\n",pLeft->Y); + return; + } + + int x = XStart; while(width-- > 0) { + if(x<0 || x>255) { + printf("rasterizer rendering at x=%d! oops!\n",x); + } pixel(adr,color[0],color[1],color[2],u,v,1.0f/invw,z); adr++; + x++; invw += dinvw_dx; u += du_dx; @@ -1173,6 +1182,8 @@ static void SoftRastRender() clipPoly(&gfx3d.polylist->list[gfx3d.indexlist[i]]); } + //printf("%d %d %d %d\n",gfx3d.viewport.x,gfx3d.viewport.y,gfx3d.viewport.width,gfx3d.viewport.height); + //viewport transforms for(int i=0;iviewport); + vert.coord[0] *= viewport.width; + vert.coord[0] += viewport.x; + vert.coord[1] *= viewport.height; + vert.coord[1] += viewport.y; + if(vert.coord[1]>192||vert.color[1]<0) { + int zzz=9; + } vert.coord[1] = 192 - vert.coord[1]; } }