Import some fixes/improvements from trunk.

r3879: OpenGL: add support quad primitives
r3880: win32: add 5x window size
r3881: add big endian toggle to memview
r3889, r3891, r3893, r3895, r3909: line poly rendering
r3902: win32: allow debug console showage to be overridden with ini file [Display] Show Console=1
r3903: clear lag frame on 8 and 32bit keypad register reads
r3916: Lua - fix memory.readdword function (was returning signed values), same fix as r296 of GENS
This commit is contained in:
gocha 2011-02-06 03:07:20 +00:00
parent bb5a398d6f
commit 1fb85a8180
11 changed files with 191 additions and 107 deletions

View File

@ -3237,6 +3237,10 @@ u8 FASTCALL _MMU_ARM9_read08(u32 adr)
case REG_DISPA_DISP3DCNT+1: return readreg_DISP3DCNT(8,adr);
case REG_DISPA_DISP3DCNT+2: return readreg_DISP3DCNT(8,adr);
case REG_DISPA_DISP3DCNT+3: return readreg_DISP3DCNT(8,adr);
case REG_KEYINPUT:
LagFrameFlag=0;
break;
}
}
@ -3318,9 +3322,7 @@ u16 FASTCALL _MMU_ARM9_read16(u32 adr)
case REG_DISPA_DISP3DCNT: return readreg_DISP3DCNT(16,adr);
case REG_DISPA_DISP3DCNT+2: return readreg_DISP3DCNT(16,adr);
case 0x04000130:
case 0x04000136:
//not sure whether these should trigger from byte reads
case REG_KEYINPUT:
LagFrameFlag=0;
break;
@ -3449,8 +3451,12 @@ u32 FASTCALL _MMU_ARM9_read32(u32 adr)
}
case REG_GCDATAIN: return MMU_readFromGC<ARMCPU_ARM9>();
case REG_POWCNT1: return readreg_POWCNT1(32,adr);
case REG_POWCNT1: return readreg_POWCNT1(32,adr);
case REG_DISPA_DISP3DCNT: return readreg_DISP3DCNT(32,adr);
case REG_KEYINPUT:
LagFrameFlag=0;
break;
}
return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]);
}

View File

@ -30,6 +30,8 @@
#include "OGLRender.h"
#include "debug.h"
CACHE_ALIGN float material_8bit_to_float[255] = {0};
bool (*oglrender_init)() = 0;
bool (*oglrender_beginOpenGL)() = 0;
void (*oglrender_endOpenGL)() = 0;
@ -400,6 +402,9 @@ static char OGLInit(void)
if(!BEGINGL())
return 0;
for (u8 i = 0; i < 255; i++)
material_8bit_to_float[i] = (float)(i<<2)/255.f;
expandFreeTextures();
glPixelStorei(GL_PACK_ALIGNMENT,8);
@ -879,40 +884,6 @@ static void OGLRender()
BeginRenderPoly();
}
//since we havent got the whole pipeline working yet, lets use opengl for the projection
/* if(lastProjIndex != poly->projIndex) {
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(gfx3d.projlist->projMatrix[poly->projIndex]);
lastProjIndex = poly->projIndex;
}*/
/* glBegin(type==3?GL_TRIANGLES:GL_QUADS);
for(int j=0;j<type;j++) {
VERT* vert = &gfx3d.vertlist->list[poly->vertIndexes[j]];
u8 color[4] = {
material_5bit_to_8bit[vert->color[0]],
material_5bit_to_8bit[vert->color[1]],
material_5bit_to_8bit[vert->color[2]],
material_5bit_to_8bit[vert->color[3]]
};
//float tempCoord[4];
//Vector4Copy(tempCoord, vert->coord);
//we havent got the whole pipeline working yet, so we cant do this
////convert from ds device coords to opengl
//tempCoord[0] *= 2;
//tempCoord[1] *= 2;
//tempCoord[0] -= 1;
//tempCoord[1] -= 1;
//todo - edge flag?
glTexCoord2fv(vert->texcoord);
glColor4ubv((GLubyte*)color);
//glVertex4fv(tempCoord);
glVertex4fv(vert->coord);
}
glEnd();*/
if(lastViewport != poly->viewport)
{
VIEWPORT viewport;
@ -921,50 +892,26 @@ static void OGLRender()
lastViewport = poly->viewport;
}
glBegin(GL_TRIANGLES);
VERT *vert0 = &gfx3d.vertlist->list[poly->vertIndexes[0]];
float alpha = poly->getAlpha()/31.0f;
if(wireframe) alpha = 1.0;
float color0[4] = {
(vert0->color[0]<<2)/255.0f,
(vert0->color[1]<<2)/255.0f,
(vert0->color[2]<<2)/255.0f,
alpha
};
//this draws things as a fan to prepare for the day when the clipping is done in gfx3d
//and funny shaped polys find their way into here.
//of course it could really be drawn as a fan, i suppose.. i dont remember why we did it this way
for(int j = 1; j < (type-1); j++)
if (gfx3d_IsLinePoly(poly))
glBegin(GL_LINE_LOOP);
else if (type == 4)
glBegin(GL_QUADS);
else
glBegin(GL_TRIANGLES);
for(int j = 0; j < type; j++)
{
VERT *vert1 = &gfx3d.vertlist->list[poly->vertIndexes[j]];
VERT *vert2 = &gfx3d.vertlist->list[poly->vertIndexes[j+1]];
VERT *vert = &gfx3d.vertlist->list[poly->vertIndexes[j]];
float color1[4] = {
(vert1->color[0]<<2)/255.0f,
(vert1->color[1]<<2)/255.0f,
(vert1->color[2]<<2)/255.0f,
alpha
};
float color2[4] = {
(vert2->color[0]<<2)/255.0f,
(vert2->color[1]<<2)/255.0f,
(vert2->color[2]<<2)/255.0f,
alpha
};
glTexCoord2fv(vert0->texcoord);
glColor4fv((GLfloat*)color0);
glVertex4fv(vert0->coord);
glTexCoord2fv(vert1->texcoord);
glColor4fv((GLfloat*)color1);
glVertex4fv(vert1->coord);
glTexCoord2fv(vert2->texcoord);
glColor4fv((GLfloat*)color2);
glVertex4fv(vert2->coord);
glTexCoord2fv(vert->texcoord);
glColor4f(material_8bit_to_float[vert->color[0]],
material_8bit_to_float[vert->color[1]],
material_8bit_to_float[vert->color[2]],
alpha);
glVertex4fv(vert->coord);
}
glEnd();

View File

@ -2801,3 +2801,67 @@ void GFX3D_Clipper::clipPoly(POLY* poly, VERT** verts)
}
#endif
// "Workaround" for line poly
bool gfx3d_IsLinePoly(POLY *poly)
{
int type = poly->type;
VERT *vert1, *vert2;
if (type <= 2)
return true;
else if (type > 10)
return false;
// Method 1:
// Castlevania Portrait of Ruin - trajectory of ricochet
bool duplicatedVert[10];
for(int i = 0; i < type; i++)
duplicatedVert[i] = false;
for(int i = 0; i < type - 1; i++)
{
vert1 = &gfx3d.vertlist->list[poly->vertIndexes[i]];
for(int j = i + 1; j < type; j++)
{
vert2 = &gfx3d.vertlist->list[poly->vertIndexes[j]];
if (vert1->x == vert2->x && vert1->y == vert2->y && vert1->z == vert2->z)
{
duplicatedVert[j] = true;
}
}
}
int vertCount = type;
for(int i = 0; i < type; i++)
{
if (duplicatedVert[i])
vertCount--;
}
if (vertCount <= 2)
return true;
// Method 2:
// Castlevania Portrait of Ruin - warp stone
bool horizontalLine = true;
bool verticalLine = true;
vert1 = &gfx3d.vertlist->list[poly->vertIndexes[0]];
for(int i = 1; i < type && (horizontalLine || verticalLine); i++)
{
vert2 = &gfx3d.vertlist->list[poly->vertIndexes[i]];
if (vert1->coord[0] != vert2->coord[0])
{
verticalLine = false;
}
if (vert1->coord[1] != vert2->coord[1])
{
horizontalLine = false;
}
//the Z is different, and this method isn't even meant to catch that
if (vert1->coord[2] != vert2->coord[2])
return false;
}
if (horizontalLine || verticalLine)
return true;
return false;
}

View File

@ -450,4 +450,6 @@ bool gfx3d_loadstate(EMUFILE* is, int size);
void gfx3d_ClearStack();
bool gfx3d_IsLinePoly(POLY *poly);
#endif //_GFX3D_H_

View File

@ -1771,7 +1771,7 @@ DEFINE_LUA_FUNCTION(memory_readdword, "address")
int address = luaL_checkinteger(L,1);
unsigned long value = (unsigned long)(_MMU_read32<ARMCPU_ARM9>(address));
lua_settop(L,0);
lua_pushinteger(L, value);
lua_pushnumber(L, value); // can't use pushinteger in this case (out of range)
return 1;
}
DEFINE_LUA_FUNCTION(memory_readdwordsigned, "address")

View File

@ -223,16 +223,30 @@ FORCEINLINE edge_fx_fl::edge_fx_fl(int Top, int Bottom, VERT** verts, bool& fail
Y = Ceil28_4((fixed28_4)verts[Top]->y);
int YEnd = Ceil28_4((fixed28_4)verts[Bottom]->y);
Height = YEnd - Y;
X = Ceil28_4((fixed28_4)verts[Top]->x);
int XEnd = Ceil28_4((fixed28_4)verts[Bottom]->x);
int Width = XEnd - X; // can be negative
if(Height)
// even if Height == 0, give some info for horizontal line poly
if(Height != 0 || Width != 0)
{
long dN = long(verts[Bottom]->y - verts[Top]->y);
long dM = long(verts[Bottom]->x - verts[Top]->x);
long InitialNumerator = (long)(dM*16*Y - dM*verts[Top]->y + dN*verts[Top]->x - 1 + dN*16);
FloorDivMod(InitialNumerator,dN*16,X,ErrorTerm,failure);
FloorDivMod(dM*16,dN*16,XStep,Numerator,failure);
Denominator = dN*16;
if (dN != 0)
{
long InitialNumerator = (long)(dM*16*Y - dM*verts[Top]->y + dN*verts[Top]->x - 1 + dN*16);
FloorDivMod(InitialNumerator,dN*16,X,ErrorTerm,failure);
FloorDivMod(dM*16,dN*16,XStep,Numerator,failure);
Denominator = dN*16;
}
else
{
XStep = Width;
Numerator = 0;
ErrorTerm = 0;
Denominator = 1;
dN = 1;
}
float YPrestep = Fixed28_4ToFloat((fixed28_4)(Y*16 - verts[Top]->y));
float XPrestep = Fixed28_4ToFloat((fixed28_4)(X*16 - verts[Top]->x));
@ -296,6 +310,7 @@ static FORCEINLINE void alphaBlend(FragmentColor & dst, const FragmentColor & sr
}
}
// TODO: wire-frame
struct PolyAttr
{
u32 val;
@ -687,11 +702,23 @@ public:
}
//draws a single scanline
FORCEINLINE void drawscanline(edge_fx_fl *pLeft, edge_fx_fl *pRight)
FORCEINLINE void drawscanline(edge_fx_fl *pLeft, edge_fx_fl *pRight, bool lineHack)
{
int XStart = pLeft->X;
int width = pRight->X - XStart;
// HACK: workaround for vertical/slant line poly
if (lineHack && width == 0)
{
int leftWidth = pLeft->XStep;
if (pLeft->ErrorTerm + pLeft->Numerator >= pLeft->Denominator)
leftWidth++;
int rightWidth = pRight->XStep;
if (pRight->ErrorTerm + pRight->Numerator >= pRight->Denominator)
rightWidth++;
width = max(1, max(abs(leftWidth), abs(rightWidth)));
}
//these are the starting values, taken from the left edge
float invw = pLeft->invw.curr;
float u = pLeft->u.curr;
@ -730,15 +757,18 @@ public:
while(width-- > 0)
{
if(RENDERER && (x<0 || x>255)) {
bool outOfRange = false;
if(RENDERER && (x<0 || x>255))
outOfRange = true;
if(!RENDERER && (x<0 || x>=engine->width))
outOfRange = true;
if(!lineHack && outOfRange)
{
printf("rasterizer rendering at x=%d! oops!\n",x);
return;
}
if(!RENDERER && (x<0 || x>=engine->width)) {
printf("rasterizer rendering at x=%d! oops!\n",x);
return;
}
pixel(adr,color[0],color[1],color[2],u,v,1.0f/invw,z);
if(!outOfRange)
pixel(adr,color[0],color[1],color[2],u,v,1.0f/invw,z);
adr++;
x++;
@ -754,7 +784,7 @@ public:
//runs several scanlines, until an edge is finished
template<bool SLI>
void runscanlines(edge_fx_fl *left, edge_fx_fl *right,bool horizontal)
void runscanlines(edge_fx_fl *left, edge_fx_fl *right, bool horizontal, bool lineHack)
{
//oh lord, hack city for edge drawing
@ -763,13 +793,21 @@ public:
bool first=true;
static int runctr=0;
runctr++;
//HACK: special handling for horizontal line poly
if (lineHack && left->Height == 0 && right->Height == 0)
{
bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
if(draw) drawscanline(left,right,lineHack);
}
while(Height--) {
bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
if(draw) drawscanline(left,right);
if(draw) drawscanline(left,right,lineHack);
const int xl = left->X;
const int xr = right->X;
const int y = left->Y;
left->Step();
left->Step();
right->Step();
if(!RENDERER && _debug_thisPoly)
@ -868,7 +906,7 @@ public:
//I didnt reference anything for this algorithm but it seems like I've seen it somewhere before.
//Maybe it is like crow's algorithm
template<bool SLI>
void shape_engine(int type, bool backwards)
void shape_engine(int type, bool backwards, bool lineHack)
{
bool failure = false;
@ -906,7 +944,7 @@ public:
return;
bool horizontal = left.Y == right.Y;
runscanlines<SLI>(&left,&right,horizontal);
runscanlines<SLI>(&left,&right,horizontal, lineHack);
//if we ran out of an edge, step to the next one
if(right.Height == 0) {
@ -976,7 +1014,7 @@ public:
polyAttr.backfacing = engine->polyBackfacing[i];
shape_engine<SLI>(type,!polyAttr.backfacing);
shape_engine<SLI>(type,!polyAttr.backfacing, gfx3d_IsLinePoly(poly));
}
}

View File

@ -25,7 +25,6 @@
///////////////////////////////////////////////////////////////// Console
#if !defined(PUBLIC_RELEASE) || defined(DEVELOPER)
#define BUFFER_SIZE 100
HANDLE hConsole = NULL;
void printlog(const char *fmt, ...);
@ -117,9 +116,3 @@ void printlog(const char *fmt, ...)
va_end(list);
WriteConsole(hConsole,msg, (DWORD)strlen(msg), &tmp, 0);
}
#else
void OpenConsole() {}
void CloseConsole() {}
#endif

View File

@ -2553,8 +2553,6 @@ int _main()
char text[80];
GetINIPath();
path.ReadPathSettings();
CommonSettings.cheatsDisable = GetPrivateProfileBool("General", "cheatsDisable", false, IniName);
@ -3047,7 +3045,17 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
g_thread_init (NULL);
hAppInst=hThisInstance;
//OpenConsole(); // Init debug console
GetINIPath();
#if !defined(PUBLIC_RELEASE) || defined(DEVELOPER)
static const bool defaultConsoleEnable = true;
#else
static const bool defaultConsoleEnable = false;
#endif
if(GetPrivateProfileBool("Display", "Show Console", defaultConsoleEnable, IniName))
OpenConsole(); // Init debug console
int ret = _main();
@ -5389,6 +5397,11 @@ DOKEYDOWN:
ScaleScreen(windowSize, true);
WritePrivateProfileInt("Video","Window Size",windowSize,IniName);
break;
case IDC_WINDOW5X:
windowSize=5;
ScaleScreen(windowSize, true);
WritePrivateProfileInt("Video","Window Size",windowSize,IniName);
break;
case IDC_FORCERATIO:
if (ForceRatio) {

View File

@ -29,6 +29,7 @@
#include <windowsx.h>
#include <commctrl.h>
#include "memView.h"
#include "winutil.h"
using namespace std;
@ -430,6 +431,13 @@ LRESULT MemView_ViewBoxPaint(CMemView* wnd, HWND hCtl, WPARAM wParam, LPARAM lPa
for(i = 0; i < 16; i += 2)
{
u16 val = T1ReadWord(memory, ((line << 4) + i));
if(IsDlgCheckboxChecked(wnd->hWnd,IDC_BIG_ENDIAN))
{
char swp[2];
swp[0] = (val>>8)&0xFF;
swp[1] = val&0xFF;
val = *(u16*)swp;
}
if(wnd->sel && (wnd->selAddress == (addr + i)))
{
SetBkColor(mem_hdc, GetSysColor(COLOR_HIGHLIGHT));
@ -470,6 +478,15 @@ LRESULT MemView_ViewBoxPaint(CMemView* wnd, HWND hCtl, WPARAM wParam, LPARAM lPa
for(i = 0; i < 16; i += 4)
{
u32 val = T1ReadLong(memory, ((line << 4) + i));
if(IsDlgCheckboxChecked(wnd->hWnd,IDC_BIG_ENDIAN))
{
char swp[4];
swp[0] = (val>>24)&0xFF;
swp[1] = (val>>16)&0xFF;
swp[2] = (val>>8)&0xFF;
swp[3] = val&0xFF;
val = *(u32*)swp;
}
if(wnd->sel && (wnd->selAddress == (addr + i)))
{
SetBkColor(mem_hdc, GetSysColor(COLOR_HIGHLIGHT));

View File

@ -434,6 +434,7 @@
#define IDC_CAP0_ACTIVE 1078
#define IDC_CHECK10 1079
#define IDC_CAP0_RUNNING 1079
#define IDC_BIG_ENDIAN 1079
#define IDC_CHECK6 1080
#define IDC_CAP1_SRC 1080
#define IDC_CAP1_ONESHOT 1081
@ -452,6 +453,7 @@
#define IDC_EDIT1 1102
#define IDC_EDIT2 1103
#define IDC_EDIT3 1104
#define IDC_WINDOW5X 1105
#define IDC_EDIT_AUTHOR 1180
#define IDD_MATRIX_VIEWER 1200
#define IDM_MATRIX_VIEWER 1200
@ -690,6 +692,8 @@
#define MENU_PRINCIPAL 2012
#define RAMWATCH_MENU 2013
#define RECENTROMS 2014
#define IDD_FONTSETTINGS 2464
#define IDC_FONTCOMBO 2465
#define IDC_GI_FATOFS 4464
#define IDC_INTERPOLATECOLOR 4464
#define IDC_GI_FATSIZE 4465

Binary file not shown.