dolphin/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp

822 lines
29 KiB
C++
Raw Normal View History

// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
// ---------------------------------------------------------------------------------------
// includes
// -------------
#include "Globals.h"
#include "Profiler.h"
#include "Config.h"
#include "VertexLoader.h"
#include "VertexManager.h"
#include "BPStructs.h"
#include "Render.h"
#include "OpcodeDecoding.h"
#include "TextureMngr.h"
#include "TextureDecoder.h"
#include "VertexShaderManager.h"
#include "PixelShaderManager.h"
#include "XFB.h"
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
// ---------------------------------------------------------------------------------------
// State translation lookup tables
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
// -------------
static const GLenum glSrcFactors[8] =
{
GL_ZERO,
GL_ONE,
GL_DST_COLOR,
GL_ONE_MINUS_DST_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA
};
static const GLenum glDestFactors[8] = {
GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR,
GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA
};
static const GLenum glCmpFuncs[8] = {
GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS
};
static const GLenum glLogicOpCodes[16] = {
GL_CLEAR, GL_SET, GL_COPY, GL_COPY_INVERTED, GL_NOOP, GL_INVERT, GL_AND, GL_NAND,
GL_OR, GL_NOR, GL_XOR, GL_EQUIV, GL_AND_REVERSE, GL_AND_INVERTED, GL_OR_REVERSE, GL_OR_INVERTED
};
void BPInit()
{
memset(&bpmem, 0, sizeof(bpmem));
bpmem.bpMask = 0xFFFFFF;
}
// Called at the end of every: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg
// TODO - turn into function table. The (future) DL jit can then call the functions directly,
// getting rid of dynamic dispatch.
void BPWritten(int addr, int changes, int newval)
{
//static int count = 0;
//ERROR_LOG("(%d) %x: %x\n", count++, addr, newval);
switch (addr)
{
case BPMEM_GENMODE:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
PRIM_LOG("genmode: texgen=%d, col=%d, ms_en=%d, tev=%d, culmode=%d, ind=%d, zfeeze=%d\n",
bpmem.genMode.numtexgens, bpmem.genMode.numcolchans,
bpmem.genMode.ms_en, bpmem.genMode.numtevstages+1, bpmem.genMode.cullmode,
bpmem.genMode.numindstages, bpmem.genMode.zfreeze);
// none, ccw, cw, ccw
if (bpmem.genMode.cullmode > 0) {
glEnable(GL_CULL_FACE);
glFrontFace(bpmem.genMode.cullmode == 2 ? GL_CCW : GL_CW);
}
else glDisable(GL_CULL_FACE);
PixelShaderMngr::SetGenModeChanged();
}
break;
case BPMEM_IND_MTX+0:
case BPMEM_IND_MTX+1:
case BPMEM_IND_MTX+2:
case BPMEM_IND_MTX+3:
case BPMEM_IND_MTX+4:
case BPMEM_IND_MTX+5:
case BPMEM_IND_MTX+6:
case BPMEM_IND_MTX+7:
case BPMEM_IND_MTX+8:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PixelShaderMngr::SetIndMatrixChanged((addr-BPMEM_IND_MTX)/3);
}
break;
case BPMEM_RAS1_SS0:
case BPMEM_RAS1_SS1:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PixelShaderMngr::SetIndTexScaleChanged();
}
break;
case BPMEM_ZMODE:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
PRIM_LOG("zmode: test=%d, func=%d, upd=%d\n", bpmem.zmode.testenable, bpmem.zmode.func,
bpmem.zmode.updateenable);
if (bpmem.zmode.testenable) {
glEnable(GL_DEPTH_TEST);
glDepthMask(bpmem.zmode.updateenable?GL_TRUE:GL_FALSE);
glDepthFunc(glCmpFuncs[bpmem.zmode.func]);
}
else {
// if the test is disabled write is disabled too
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
}
if (!bpmem.zmode.updateenable)
Renderer::SetRenderMode(Renderer::RM_Normal);
}
break;
case BPMEM_ALPHACOMPARE:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d\n", bpmem.alphaFunc.ref0,
bpmem.alphaFunc.ref1, bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1, bpmem.alphaFunc.logic);
PixelShaderMngr::SetAlpha(bpmem.alphaFunc);
}
break;
case BPMEM_CONSTANTALPHA:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PRIM_LOG("constalpha: alp=%d, en=%d\n", bpmem.dstalpha.alpha, bpmem.dstalpha.enable);
PixelShaderMngr::SetDestAlpha(bpmem.dstalpha);
}
break;
case BPMEM_LINEPTWIDTH:
{
float fratio = VertexShaderMngr::GetPixelAspectRatio();
if (bpmem.lineptwidth.linesize > 0)
glLineWidth((float)bpmem.lineptwidth.linesize * fratio / 6.0f); // scale by ratio of widths
if (bpmem.lineptwidth.pointsize > 0)
glPointSize((float)bpmem.lineptwidth.pointsize * fratio / 6.0f);
break;
}
case 0x43:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
case BPMEM_BLENDMODE:
if (changes & 0xFFFF) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PRIM_LOG("blendmode: en=%d, open=%d, colupd=%d, alphaupd=%d, dst=%d, src=%d, sub=%d, mode=%d\n",
bpmem.blendmode.blendenable, bpmem.blendmode.logicopenable, bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate,
bpmem.blendmode.dstfactor, bpmem.blendmode.srcfactor, bpmem.blendmode.subtract, bpmem.blendmode.logicmode);
if (changes & 1) {
if (bpmem.blendmode.blendenable) {
glEnable(GL_BLEND);
}
else glDisable(GL_BLEND);
}
if (changes & 2) {
if (Renderer::CanBlendLogicOp()) {
if (bpmem.blendmode.logicopenable) {
glEnable(GL_COLOR_LOGIC_OP);
PanicAlert("Logic Op Blend : %i", bpmem.blendmode.logicmode);
glLogicOp(glLogicOpCodes[bpmem.blendmode.logicmode]);
}
else glDisable(GL_COLOR_LOGIC_OP);
}
//else {
// if (bpmem.blendmode.logicopenable) {
// switch(bpmem.blendmode.logicmode) {
// case 0: // clear dst to 0
// glEnable(GL_BLEND);
// glBlendFunc(GL_ZERO, GL_ZERO);
// break;
// case 1: // set dst to 1
// glEnable(GL_BLEND);
// glBlendFunc(GL_ONE, GL_ONE);
// break;
// case 2: // set dst to src
// glDisable(GL_BLEND);
// break;
// case 3: // set dst to ~src
// glEnable(GL_BLEND);
// glBlendFunc(GL_ONE_MINUS_SRC_COLOR, GL_ZERO); //?
// break;
// case 4: // set dst to dst
// glEnable(GL_BLEND);
// glBlendFunc(GL_ZERO, GL_ONE); //?
// break;
// case 5: // set dst to ~dst
// glEnable(GL_BLEND);
// glBlendFunc(GL_ZERO, GL_ONE_MINUS_DST_COLOR); //?
// break;
// case 6: // set dst to src&dst
// case 7: // set dst to ~(src&dst)
// case 8: // set dst to src|dst
// case 9: // set dst to ~(src|dst)
// case 10: // set dst to src xor dst
// case 11: // set dst to ~(src xor dst)
// case 12: // set dst to src&~dst
// case 13: // set dst to ~src&dst
// case 14: // set dst to src|~dst
// case 15: // set dst to ~src|dst
// ERROR_LOG("logicopenable %d not supported\n", bpmem.blendmode.logicmode);
// break;
// }
// }
//}
}
if (changes & 4) {
// pointless
//if (bpmem.blendmode.dither) glEnable(GL_DITHER);
//else glDisable(GL_DITHER);
}
if (changes & 0xFE0) {
if (!bpmem.blendmode.subtract)
glBlendFunc(glSrcFactors[bpmem.blendmode.srcfactor], glDestFactors[bpmem.blendmode.dstfactor]);
}
if (changes & 0x800) {
glBlendEquation(bpmem.blendmode.subtract ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD);
if (bpmem.blendmode.subtract)
glBlendFunc(GL_ONE, GL_ONE);
else
glBlendFunc(glSrcFactors[bpmem.blendmode.srcfactor], glDestFactors[bpmem.blendmode.dstfactor]);
}
if (changes & 0x18)
SetColorMask();
}
break;
case BPMEM_FOGRANGE:
if (changes) {
// TODO(XK): Fog range format
//glFogi(GL_FOG_START, ...
//glFogi(GL_FOG_END, ...
}
break;
case BPMEM_FOGPARAM0:
case BPMEM_FOGBEXPONENT:
case BPMEM_FOGBMAGNITUDE:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
case BPMEM_FOGPARAM3:
//fog settings
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
//printf("%f %f magnitude: %x\n", bpmem.fog.a.GetA(),bpmem.fog.c_proj_fsel.GetC(), bpmem.fog.b_magnitude);
switch(bpmem.fog.c_proj_fsel.fsel)
{
case 0: // Off
glDisable(GL_FOG); // Should be what we do
break;
case 2: // Linear
glFogi(GL_FOG_MODE, GL_LINEAR);
glEnable(GL_FOG);
break;
case 4: // exp
glFogi(GL_FOG_MODE, GL_EXP);
glEnable(GL_FOG);
break;
case 5: // exp2
glFogi(GL_FOG_MODE, GL_EXP2);
glEnable(GL_FOG);
break;
case 6: // Backward exp
case 7: // Backward exp2
// TODO: Figure out how to do these in GL
//TEV_FSEL_BX, TEV_FSEL_BX2?
default:
printf("Non-Emulated Fog selection %d\n", bpmem.fog.c_proj_fsel.fsel);
break;
}
}
break;
case BPMEM_FOGCOLOR:
if (changes)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
float fogcolor[4] = { ((bpmem.fog.color>>16)&0xff)/255.0f, ((bpmem.fog.color>>8)&0xff)/255.0f, (bpmem.fog.color&0xff)/255.0f, (bpmem.fog.color>>24)/255.0f };
//printf("r: %f g: %f b: %f a: %f %x %x %x %f\n",fogcolor[0],fogcolor[1], fogcolor[2], fogcolor[3], bpmem.fogRangeAdj, bpmem.unknown15[0],bpmem.unknown15[1],bpmem.unknown15[2]);
glFogfv(GL_FOG_COLOR, fogcolor);
}
break;
case BPMEM_TEXINVALIDATE:
//TexCache_Invalidate();
break;
case BPMEM_SCISSOROFFSET:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
SetScissorRect();
}
break;
case BPMEM_SCISSORTL:
case BPMEM_SCISSORBR:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
if (!SetScissorRect()) {
if (addr == BPMEM_SCISSORBR )
ERROR_LOG("bad scissor!\n");
}
}
break;
case BPMEM_ZTEX1:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PRIM_LOG("ztex bias=0x%x\n", bpmem.ztex1.bias);
PixelShaderMngr::SetZTetureBias(bpmem.ztex1.bias);
}
break;
case BPMEM_ZTEX2:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
#ifdef _DEBUG
const char* pzop[] = {"DISABLE", "ADD", "REPLACE", "?"};
const char* pztype[] = {"Z8", "Z16", "Z24", "?"};
PRIM_LOG("ztex op=%s, type=%s\n", pzop[bpmem.ztex2.op], pztype[bpmem.ztex2.type]);
#endif
}
break;
case 0xf6: // ksel0
case 0xf7: // ksel1
case 0xf8: // ksel2
case 0xf9: // ksel3
case 0xfa: // ksel4
case 0xfb: // ksel5
case 0xfc: // ksel6
case 0xfd: // ksel7
if (changes)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PixelShaderMngr::SetTevKSelChanged(addr-0xf6);
}
break;
case 0x45: //GXSetDrawDone
VertexManager::Flush();
switch (newval & 0xFF)
{
case 0x02:
g_VideoInitialize.pSetPEFinish(); // may generate interrupt
DebugLog("GXSetDrawDone SetPEFinish (value: 0x%02X)", (newval & 0xFFFF));
break;
default:
DebugLog("GXSetDrawDone ??? (value 0x%02X)", (newval & 0xFFFF));
break;
}
break;
case BPMEM_PE_TOKEN_ID:
g_VideoInitialize.pSetPEToken(static_cast<u16>(newval & 0xFFFF), FALSE);
DebugLog("SetPEToken 0x%04x", (newval & 0xFFFF));
break;
case BPMEM_PE_TOKEN_INT_ID:
g_VideoInitialize.pSetPEToken(static_cast<u16>(newval & 0xFFFF), TRUE);
DebugLog("SetPEToken + INT 0x%04x", (newval & 0xFFFF));
break;
case 0x67: // set gp metric?
break;
case 0x52:
{
DVSTARTSUBPROFILE("LoadBPReg:swap");
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
TRectangle rc = {
(int)(bpmem.copyTexSrcXY.x),
(int)(bpmem.copyTexSrcXY.y),
(int)((bpmem.copyTexSrcXY.x + bpmem.copyTexSrcWH.x + 1)),
(int)((bpmem.copyTexSrcXY.y + bpmem.copyTexSrcWH.y + 1))
};
//Need another rc here to get it to scale.
TRectangle multirc = {
(int)(bpmem.copyTexSrcXY.x * MValueX),
(int)(bpmem.copyTexSrcXY.y * MValueY),
(int)((bpmem.copyTexSrcXY.x * MValueX + (bpmem.copyTexSrcWH.x + 1) * MValueX)),
(int)((bpmem.copyTexSrcXY.y * MValueY + (bpmem.copyTexSrcWH.y + 1) * MValueY))
};
UPE_Copy PE_copy;
PE_copy.Hex = bpmem.triggerEFBCopy;
if (PE_copy.copy_to_xfb == 0) {
if(g_Config.bEBFToTextureDisable) {
glViewport(rc.left,rc.bottom,rc.right,rc.top);
glScissor(rc.left,rc.bottom,rc.right,rc.top);
}
else
// EFB to texture
// for some reason it sets bpmem.zcontrol.pixel_format to PIXELFMT_Z24 every time a zbuffer format is given as a dest to GXSetTexCopyDst
TextureMngr::CopyRenderTargetToTexture(bpmem.copyTexDest<<5, bpmem.zcontrol.pixel_format==PIXELFMT_Z24, PE_copy.intensity_fmt>0,
(PE_copy.target_pixel_format/2)+((PE_copy.target_pixel_format&1)*8), PE_copy.half_scale>0, &rc);
}
else {
// EFB to XFB
if(g_Config.bUseXFB)
{
XFB_Write(Memory_GetPtr(bpmem.copyTexDest<<5), multirc, (bpmem.copyMipMapStrideChannels << 4), bpmem.copyTexSrcWH.y + 1, bpmem.dispcopyyscale / 256.0f);
}
else
{
Renderer::Swap(multirc);
}
g_VideoInitialize.pCopiedToXFB();
}
// clearing
if (PE_copy.clear) {
// clear color
Renderer::SetRenderMode(Renderer::RM_Normal);
u32 nRestoreZBufferTarget = Renderer::GetZBufferTarget();
glViewport(0, 0, Renderer::GetTargetWidth(), Renderer::GetTargetHeight());
// Always set the scissor in case it was set by the game and has not been reset
glScissor(multirc.left, (Renderer::GetTargetHeight() - multirc.bottom),
(multirc.right - multirc.left), (multirc.bottom - multirc.top));
VertexShaderMngr::SetViewportChanged();
// Since clear operations use the source rectangle, we have to do
// regular renders (glClear clears the entire buffer)
if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate || bpmem.zmode.updateenable)
{
GLbitfield bits = 0;
if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate) {
u32 clearColor = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
glClearColor(((clearColor>>16) & 0xff)*(1/255.0f),
((clearColor>>8 ) & 0xff)*(1/255.0f),
((clearColor>>0 ) & 0xff)*(1/255.0f),
((clearColor>>24) & 0xff)*(1/255.0f));
bits |= GL_COLOR_BUFFER_BIT;
}
if (bpmem.zmode.updateenable) {
glClearDepth((float)(bpmem.clearZValue&0xFFFFFF) / float(0xFFFFFF));
bits |= GL_DEPTH_BUFFER_BIT;
}
if (nRestoreZBufferTarget )
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); // don't clear ztarget here
glClear(bits);
}
if (bpmem.zmode.updateenable && nRestoreZBufferTarget) { // have to clear the target zbuffer
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
GL_REPORT_ERRORD();
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
// red should probably be the LSB
glClearColor(((bpmem.clearZValue>>0)&0xff)*(1/255.0f),
((bpmem.clearZValue>>8)&0xff)*(1/255.0f),
((bpmem.clearZValue>>16)&0xff)*(1/255.0f), 0);
glClear(GL_COLOR_BUFFER_BIT);
SetColorMask();
GL_REPORT_ERRORD();
}
if (nRestoreZBufferTarget) {
// restore target
GLenum s_drawbuffers[2] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
glDrawBuffers(2, s_drawbuffers);
}
SetScissorRect(); // reset the scissor rect
}
}
break;
case 0x65: //GXLoadTlut
{
DVSTARTSUBPROFILE("LoadBPReg:GXLoadTlut");
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
u32 tlutTMemAddr = (newval&0x3FF)<<9;
u32 tlutXferCount = (newval&0x1FFC00)>>5;
//do the transfer!!
u8 *ptr = g_VideoInitialize.pGetMemoryPointer((bpmem.tlutXferSrc)<<5);
if (ptr)
memcpy_gc(texMem + tlutTMemAddr, ptr, tlutXferCount);
// TODO(ector) : kill all textures that use this palette
// Not sure if it's a good idea, though. For now, we hash texture palettes
}
break;
default:
switch(addr & 0xFC) //texture sampler filter
{
case 0x28: // tevorder 0-3
case 0x2C: // tevorder 4-7
if (changes)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PixelShaderMngr::SetTevOrderChanged(addr - 0x28);
}
break;
case 0x80: // TEX MODE 0
case 0xA0:
if (changes)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
case 0x84://TEX MODE 1
case 0xA4:
break;
case 0x88://TEX IMAGE 0
case 0xA8:
if (changes)
{
//textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
case 0x8C://TEX IMAGE 1
case 0xAC:
if (changes)
{
//textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
case 0x90://TEX IMAGE 2
case 0xB0:
if (changes)
{
//textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
case 0x94://TEX IMAGE 3
case 0xB4:
if (changes)
{
//textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
case 0x98://TEX TLUT
case 0xB8:
if (changes)
{
//textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
case 0x9C://TEX UNKNOWN
case 0xBC:
//ERROR_LOG("texunknown%x = %x\n", addr, newval);
((u32*)&bpmem)[addr] = newval;
break;
case 0xE0:
case 0xE4:
if (addr&1) { // don't compare with changes!
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
int num = (addr>>1)&0x3;
PixelShaderMngr::SetColorChanged(bpmem.tevregs[num].high.type, num);
}
else
((u32*)&bpmem)[addr] = newval;
break;
default:
switch(addr&0xF0) {
case 0x10: // tevindirect 0-15
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PixelShaderMngr::SetTevIndirectChanged(addr-0x10);
}
break;
case 0x30:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PixelShaderMngr::SetTexDimsChanged((addr>>1)&0x7);
}
break;
case 0xC0:
case 0xD0:
if (changes)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PixelShaderMngr::SetTevCombinerChanged((addr&0x1f)/2);
}
break;
case 0x20:
case 0x80:
case 0x90:
case 0xA0:
case 0xB0:
default:
if (changes)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
/*switch(addr) {
case 0x01:
case 0x02:
case 0x03:
case 0x04: break; // copy filter values
case 0x0f: break; // mask
case 0x27: break; // tev ind order
case 0x44: break; // field mask
case 0x45: break; // draw done
case 0x46: break; // clock
case 0x49:
case 0x4a: break; // copy tex src
case 0x4b: break; // copy tex dest
case 0x4d: break; // copyMipMapStrideChannels
case 0x4e: break; // disp copy scale
case 0x4f: break; // clear color
case 0x50: break; // clear color
case 0x51: break; // casez
case 0x52: break; // trigger efb copy
case 0x53:
case 0x54: break; // more copy filters
case 0x55:
case 0x56: break; // bounding box
case 0x64:
case 0x65: break; // tlut src dest
case 0xe8: break; // fog range
case 0xe9:
case 0xea:
case 0xeb:
case 0xec:
case 0xed: break; // fog
case 0xfe: break; // mask
default:
// 0x58 = 0xf
// 0x69 = 0x49e
ERROR_LOG("bp%.2x = %x\n", addr, newval);
}*/
}
break;
}
break;
}
break;
}
}
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
void SetColorMask()
{
if (bpmem.blendmode.alphaupdate && bpmem.blendmode.colorupdate)
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
else if (bpmem.blendmode.alphaupdate)
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_TRUE);
else if (bpmem.blendmode.colorupdate)
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
}
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
// =======================================================================================
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
// case 0x52 > SetScissorRect()
// ---------------
// This function handles the OpenGL glScissor() function
// ---------------
// bpmem.scissorTL.x, y = 342x342
// bpmem.scissorBR.x, y = 981x821
// Renderer::GetTargetHeight() = the fixed ini file setting
// ---------------
bool SetScissorRect()
{
int xoff = bpmem.scissorOffset.x * 2 - 342;
int yoff = bpmem.scissorOffset.y * 2 - 342;
float rc_left = bpmem.scissorTL.x - xoff - 342; // left = 0
rc_left *= MValueX;
if (rc_left < 0) rc_left = 0;
float rc_top = bpmem.scissorTL.y - yoff - 342; // right = 0
rc_top *= MValueY;
if (rc_top < 0) rc_top = 0;
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
float rc_right = bpmem.scissorBR.x - xoff - 342; // right = 640
rc_right *= MValueX;
if (rc_right > 640 * MValueX) rc_right = 640 * MValueX;
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
float rc_bottom = bpmem.scissorBR.y - yoff - 342; // bottom = 480
rc_bottom *= MValueY;
if (rc_bottom > 480 * MValueY) rc_bottom = 480 * MValueY;
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
/*__Log("Scissor: lt=(%d,%d), rb=(%d,%d,%i), off=(%d,%d)\n",
rc_left, rc_top,
rc_right, rc_bottom, Renderer::GetTargetHeight(),
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
xoff, yoff
);*/
if (rc_right >= rc_left && rc_bottom >= rc_top )
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
{
glScissor(
(int)rc_left, // x = 0
Renderer::GetTargetHeight()-(int)(rc_bottom), // y = 0
(int)(rc_right-rc_left), // y = 0
(int)(rc_bottom-rc_top) // y = 0
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
);
return true;
}
return false;
}
Added the StretchToFit option to the config menu in the OpenGL plugin. This fixes the blackness in SSBM. I also added a keep aspect ratio option, it will keep your aspect ratio at 4:3, but then SSBM will have the blackness problem again. You find the options under the Enhancements window in the OpenGL configuration. I also added a wx debugging window for the OpenGL plugin. I connected it to the old console window that was in the plugin. Other than that it doesn't do anything at the moment but it could be useful to show all the current important information and parameter statuses and so on. Again there's a problem with wx windows collisions. Show() can't be used because then DLL_PROCESS_DETACH is called immediately after the window is opened, and if we open it with ShowModal() before we have loaded a game the main video window will be blocked. And we can't pass on any variables from a DllDebugger() that is called when Dolphin is started because the dll is reloaded and lose all variables sometime before a game is loaded. So we can't auto open the window that way. So I made the debugging window open as a game is loaded if it is enabled in the ini, the downside is that the ini setting will open the window even if we are not opening Dolphin with the -d flag. However, this will only affect people that have used the debugger at least once so in my opinion this is the most convenient solution. But feel free to come up with a better solution. Preferably some solution to how to use Show() and preventing DLL_PROCESS_DETACH to be called. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@812 8ced0084-cf51-0410-be5f-012b33b47a6e
2008-10-09 18:47:53 +00:00
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
void LoadBPReg(u32 value0)
{
DVSTARTPROFILE();
//handle the mask register
int opcode = value0 >> 24;
int oldval = ((u32*)&bpmem)[opcode];
int newval = (oldval & ~bpmem.bpMask) | (value0 & bpmem.bpMask);
int changes = (oldval ^ newval) & 0xFFFFFF;
//reset the mask register
if (opcode != 0xFE)
bpmem.bpMask = 0xFFFFFF;
//notify the video handling so it can update render states
BPWritten(opcode, changes, newval);
}
// Never called? Should probably be called when loading a saved state.
// Needs testing though.
void BPReload()
{
for (int i = 0; i < 254; i++)
{
switch (i) {
case 0x65:
case 0x45: //GXSetDrawDone
case BPMEM_PE_TOKEN_ID:
case BPMEM_PE_TOKEN_INT_ID:
case 0x67: // set gp metric?
case 0x52:
break;
default:
BPWritten(i, 0xFFFFFF, ((u32*)&bpmem)[i]);
}
}
}