GFX: updated Dates, code formatting cleanup, code cleanup / organization, some unknown BPs uncovered, fixed OGL's config dialog bug, added another shader

DSPHLE: Some warning fixes and added some logging for unknown voice cases
Please report if anything has broken.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3884 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
omegadox 2009-07-26 09:52:35 +00:00
commit e4a9faeba4
57 changed files with 1139 additions and 955 deletions

View file

@ -0,0 +1,26 @@
// Omega's 3D Stereoscopic filtering (Amber/Blue)
// TODO: Need depth info!
uniform samplerRECT samp0 : register(s0);
void main(out float4 ocol0 : COLOR0, in float2 uv0 : TEXCOORD0)
{
float4 c0 = texRECT(samp0, uv0).rgba; // Source Color
float sep = 5;
float red = c0.r;
float green = c0.g;
float blue = c0.b;
// Left Eye (Amber)
float4 c2 = texRECT(samp0, uv0 + float2(sep,0)).rgba;
float amber = (c2.r + c2.g) / 2;
red = max(c0.r, amber);
green = max(c0.g, amber);
// Right Eye (Blue)
float4 c1 = texRECT(samp0, uv0 + float2(-sep,0)).rgba;
blue = max(c0.b, c1.b);
ocol0 = float4(red, green, blue, c0.a);
}

View file

@ -73,7 +73,8 @@ bool AVIDump::CreateFile()
NOTICE_LOG(VIDEO, "Opening AVI file (%s) for dumping", movie_file_name); NOTICE_LOG(VIDEO, "Opening AVI file (%s) for dumping", movie_file_name);
// TODO: Make this work with AVIFileOpenW without it throwing REGDB_E_CLASSNOTREG // TODO: Make this work with AVIFileOpenW without it throwing REGDB_E_CLASSNOTREG
HRESULT hr = AVIFileOpenA(&m_file, movie_file_name, OF_WRITE | OF_CREATE, NULL); HRESULT hr = AVIFileOpenA(&m_file, movie_file_name, OF_WRITE | OF_CREATE, NULL);
if (FAILED(hr)) { if (FAILED(hr))
{
if (hr == AVIERR_BADFORMAT) NOTICE_LOG(VIDEO, "The file couldn't be read, indicating a corrupt file or an unrecognized format."); if (hr == AVIERR_BADFORMAT) NOTICE_LOG(VIDEO, "The file couldn't be read, indicating a corrupt file or an unrecognized format.");
if (hr == AVIERR_MEMORY) NOTICE_LOG(VIDEO, "The file could not be opened because of insufficient memory."); if (hr == AVIERR_MEMORY) NOTICE_LOG(VIDEO, "The file could not be opened because of insufficient memory.");
if (hr == AVIERR_FILEREAD) NOTICE_LOG(VIDEO, "A disk error occurred while reading the file."); if (hr == AVIERR_FILEREAD) NOTICE_LOG(VIDEO, "A disk error occurred while reading the file.");
@ -82,13 +83,16 @@ bool AVIDump::CreateFile()
Stop(); Stop();
return false; return false;
} }
SetBitmapFormat(); SetBitmapFormat();
NOTICE_LOG(VIDEO, "Setting video format..."); NOTICE_LOG(VIDEO, "Setting video format...");
if (!SetVideoFormat()) { if (!SetVideoFormat())
{
NOTICE_LOG(VIDEO, "Setting video format failed"); NOTICE_LOG(VIDEO, "Setting video format failed");
Stop(); Stop();
return false; return false;
} }
if (!m_fileCount) { if (!m_fileCount) {
if (!SetCompressionOptions()) { if (!SetCompressionOptions()) {
NOTICE_LOG(VIDEO, "SetCompressionOptions failed"); NOTICE_LOG(VIDEO, "SetCompressionOptions failed");
@ -96,12 +100,16 @@ bool AVIDump::CreateFile()
return false; return false;
} }
} }
if (FAILED(AVIMakeCompressedStream(&m_streamCompressed, m_stream, &m_options, NULL))) {
if (FAILED(AVIMakeCompressedStream(&m_streamCompressed, m_stream, &m_options, NULL)))
{
NOTICE_LOG(VIDEO, "AVIMakeCompressedStream failed"); NOTICE_LOG(VIDEO, "AVIMakeCompressedStream failed");
Stop(); Stop();
return false; return false;
} }
if (FAILED(AVIStreamSetFormat(m_streamCompressed, 0, &m_bitmap, m_bitmap.biSize))) {
if (FAILED(AVIStreamSetFormat(m_streamCompressed, 0, &m_bitmap, m_bitmap.biSize)))
{
NOTICE_LOG(VIDEO, "AVIStreamSetFormat failed"); NOTICE_LOG(VIDEO, "AVIStreamSetFormat failed");
Stop(); Stop();
return false; return false;
@ -112,18 +120,24 @@ bool AVIDump::CreateFile()
void AVIDump::CloseFile() void AVIDump::CloseFile()
{ {
if (m_streamCompressed) { if (m_streamCompressed)
{
AVIStreamClose(m_streamCompressed); AVIStreamClose(m_streamCompressed);
m_streamCompressed = NULL; m_streamCompressed = NULL;
} }
if (m_stream) {
if (m_stream)
{
AVIStreamClose(m_stream); AVIStreamClose(m_stream);
m_stream = NULL; m_stream = NULL;
} }
if (m_file) {
if (m_file)
{
AVIFileRelease(m_file); AVIFileRelease(m_file);
m_file = NULL; m_file = NULL;
} }
AVIFileExit(); AVIFileExit();
} }
@ -140,7 +154,8 @@ void AVIDump::AddFrame(char *data)
m_totalBytes += m_byteBuffer; m_totalBytes += m_byteBuffer;
// Close the recording if the file is more than 2gb // Close the recording if the file is more than 2gb
// VfW can't properly save files over 2gb in size, but can keep writing to them up to 4gb. // VfW can't properly save files over 2gb in size, but can keep writing to them up to 4gb.
if (m_totalBytes >= 2000000000) { if (m_totalBytes >= 2000000000)
{
CloseFile(); CloseFile();
m_fileCount++; m_fileCount++;
CreateFile(); CreateFile();

View file

@ -34,4 +34,4 @@ public:
static void AddFrame(char *data); static void AddFrame(char *data);
}; };
#endif #endif // _AVIDUMP_H

View file

@ -17,11 +17,11 @@
// ------------------------------------------ // ------------------------------------------
// The plugins has to define these functions // Video plugin must define these functions
// ------------------------------------------ // ------------------------------------------
#ifndef _BPFUNCTIONS_H_ #ifndef _BPFUNCTIONS_H
#define _BPFUNCTIONS_H_ #define _BPFUNCTIONS_H
#include "BPMemory.h" #include "BPMemory.h"
#include "VideoCommon.h" #include "VideoCommon.h"
@ -37,22 +37,22 @@ enum
}; };
void FlushPipeline(); void FlushPipeline();
void SetGenerationMode(const Bypass &bp); void SetGenerationMode(const BPCmd &bp);
void SetScissor(const Bypass &bp); void SetScissor(const BPCmd &bp);
void SetLineWidth(const Bypass &bp); void SetLineWidth(const BPCmd &bp);
void SetDepthMode(const Bypass &bp); void SetDepthMode(const BPCmd &bp);
void SetBlendMode(const Bypass &bp); void SetBlendMode(const BPCmd &bp);
void SetDitherMode(const Bypass &bp); void SetDitherMode(const BPCmd &bp);
void SetLogicOpMode(const Bypass &bp); void SetLogicOpMode(const BPCmd &bp);
void SetColorMask(const Bypass &bp); void SetColorMask(const BPCmd &bp);
void CopyEFB(const Bypass &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const bool &scaleByHalf); void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const bool &scaleByHalf);
void RenderToXFB(const Bypass &bp, const EFBRectangle &rc, const float &yScale, const float &xfbLines, u32 xfbAddr, const u32 &dstWidth, const u32 &dstHeight); void RenderToXFB(const BPCmd &bp, const EFBRectangle &rc, const float &yScale, const float &xfbLines, u32 xfbAddr, const u32 &dstWidth, const u32 &dstHeight);
void ClearScreen(const Bypass &bp, const EFBRectangle &rc); void ClearScreen(const BPCmd &bp, const EFBRectangle &rc);
void RestoreRenderState(const Bypass &bp); void RestoreRenderState(const BPCmd &bp);
u8 *GetPointer(const u32 &address); u8 *GetPointer(const u32 &address);
bool GetConfig(const int &type); bool GetConfig(const int &type);
void SetSamplerState(const Bypass &bp); void SetSamplerState(const BPCmd &bp);
void SetInterlacingMode(const Bypass &bp); void SetInterlacingMode(const BPCmd &bp);
}; };
#endif // _BPFUNCTIONS_H_ #endif // _BPFUNCTIONS_H

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -16,7 +16,6 @@
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "Common.h" #include "Common.h"
#include "BPMemory.h" #include "BPMemory.h"
// BP state // BP state
@ -24,7 +23,7 @@
BPMemory bpmem; BPMemory bpmem;
// The plugin must implement this. // The plugin must implement this.
void BPWritten(const Bypass& bp); void BPWritten(const BPCmd& bp);
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg() // Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
void LoadBPReg(u32 value0) void LoadBPReg(u32 value0)
@ -35,7 +34,7 @@ void LoadBPReg(u32 value0)
int newval = (oldval & ~bpmem.bpMask) | (value0 & bpmem.bpMask); int newval = (oldval & ~bpmem.bpMask) | (value0 & bpmem.bpMask);
int changes = (oldval ^ newval) & 0xFFFFFF; int changes = (oldval ^ newval) & 0xFFFFFF;
Bypass bp = {opcode, changes, newval}; BPCmd bp = {opcode, changes, newval};
//reset the mask register //reset the mask register
if (opcode != 0xFE) if (opcode != 0xFE)
@ -50,18 +49,19 @@ void BPReload()
{ {
for (int i = 0; i < 254; i++) for (int i = 0; i < 254; i++)
{ {
switch (i) { switch (i)
case 0x41: {
case 0x45: //GXSetDrawDone case BPMEM_BLENDMODE:
case 0x52: case BPMEM_SETDRAWDONE:
case 0x65: case BPMEM_TRIGGER_EFB_COPY:
case 0x67: // set gp metric? case BPMEM_LOADTLUT1:
case BPMEM_PERF1:
case BPMEM_PE_TOKEN_ID: case BPMEM_PE_TOKEN_ID:
case BPMEM_PE_TOKEN_INT_ID: case BPMEM_PE_TOKEN_INT_ID:
// Cases in which we DON'T want to reload the BP // Cases in which we DON'T want to reload the BP
continue; continue;
default: default:
Bypass bp = {i, 0xFFFFFF, ((u32*)&bpmem)[i]}; BPCmd bp = {i, 0xFFFFFF, ((u32*)&bpmem)[i]};
BPWritten(bp); BPWritten(bp);
} }
} }

View file

@ -32,8 +32,8 @@
#define BPMEM_SCISSORTL 0x20 #define BPMEM_SCISSORTL 0x20
#define BPMEM_SCISSORBR 0x21 #define BPMEM_SCISSORBR 0x21
#define BPMEM_LINEPTWIDTH 0x22 #define BPMEM_LINEPTWIDTH 0x22
#define BPMEM_SU_COUNTER 0x23 #define BPMEM_PERF0_TRI 0x23
#define BPMEM_RAS_COUNTER 0x24 #define BPMEM_PERF0_QUAD 0x24
#define BPMEM_RAS1_SS0 0x25 #define BPMEM_RAS1_SS0 0x25
#define BPMEM_RAS1_SS1 0x26 #define BPMEM_RAS1_SS1 0x26
#define BPMEM_IREF 0x27 #define BPMEM_IREF 0x27
@ -46,7 +46,7 @@
#define BPMEM_ZCOMPARE 0x43 #define BPMEM_ZCOMPARE 0x43
#define BPMEM_FIELDMASK 0x44 #define BPMEM_FIELDMASK 0x44
#define BPMEM_SETDRAWDONE 0x45 #define BPMEM_SETDRAWDONE 0x45
#define BPMEM_CLOCK0 0x46 #define BPMEM_BUSCLOCK0 0x46
#define BPMEM_PE_TOKEN_ID 0x47 #define BPMEM_PE_TOKEN_ID 0x47
#define BPMEM_PE_TOKEN_INT_ID 0x48 #define BPMEM_PE_TOKEN_INT_ID 0x48
#define BPMEM_EFB_TL 0x49 #define BPMEM_EFB_TL 0x49
@ -63,18 +63,18 @@
#define BPMEM_CLEARBBOX1 0x55 #define BPMEM_CLEARBBOX1 0x55
#define BPMEM_CLEARBBOX2 0x56 #define BPMEM_CLEARBBOX2 0x56
#define BPMEM_UNKOWN_57 0x57 #define BPMEM_UNKOWN_57 0x57
#define BPMEM_UNKNOWN 0x58 #define BPMEM_REVBITS 0x58
#define BPMEM_SCISSOROFFSET 0x59 #define BPMEM_SCISSOROFFSET 0x59
#define BPMEM_UNKNOWN_60 0x60 #define BPMEM_UNKNOWN_60 0x60
#define BPMEM_UNKNOWN_61 0x61 #define BPMEM_UNKNOWN_61 0x61
#define BPMEM_UNKNOWN_62 0x62 #define BPMEM_UNKNOWN_62 0x62
#define BPMEM_UNKNOWN_63 0x63 #define BPMEM_TEXMODESYNC 0x63
#define BPMEM_LOADTLUT0 0x64 #define BPMEM_LOADTLUT0 0x64
#define BPMEM_LOADTLUT1 0x65 #define BPMEM_LOADTLUT1 0x65
#define BPMEM_TEXINVALIDATE 0x66 #define BPMEM_TEXINVALIDATE 0x66
#define BPMEM_SETGPMETRIC 0x67 #define BPMEM_PERF1 0x67
#define BPMEM_FIELDMODE 0x68 #define BPMEM_FIELDMODE 0x68
#define BPMEM_CLOCK1 0x69 #define BPMEM_BUSCLOCK1 0x69
#define BPMEM_TX_SETMODE0 0x80 // 0x80 + 4 #define BPMEM_TX_SETMODE0 0x80 // 0x80 + 4
#define BPMEM_TX_SETMODE1 0x84 // 0x84 + 4 #define BPMEM_TX_SETMODE1 0x84 // 0x84 + 4
#define BPMEM_TX_SETIMAGE0 0x88 // 0x88 + 4 #define BPMEM_TX_SETIMAGE0 0x88 // 0x88 + 4
@ -827,7 +827,7 @@ union UPE_Copy
// All of BP memory // All of BP memory
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
struct Bypass struct BPCmd
{ {
int address; int address;
int changes; int changes;
@ -911,4 +911,4 @@ extern BPMemory bpmem;
void LoadBPReg(u32 value0); void LoadBPReg(u32 value0);
#endif #endif // _BPMEMORY_H

View file

@ -40,27 +40,24 @@ void BPInit()
bpmem.bpMask = 0xFFFFFF; bpmem.bpMask = 0xFFFFFF;
} }
void BPWritten(const BPCmd& bp)
// ----------------------------------------------------------------------------------------------------------
// Write to the Bypass Memory (Bypass Raster State Registers)
/* ------------------
Called:
At the end of every: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg
TODO:
Turn into function table. The (future) DisplayList (DL) jit can then call the functions directly,
getting rid of dynamic dispatch. Unfortunately, few games use DLs properly - most\
just stuff geometry in them and don't put state changes there. */
// ----------------------------------------------------------------------------------------------------------
void BPWritten(const Bypass& bp)
{ {
// -------------------------------------------------------------------------------------------------------- /*
// First the pipeline is flushed then update the bpmem with the new value. ----------------------------------------------------------------------------------------------------------------
// Some of the BP cases have to call certain functions while others just update the bpmem. Purpose: Writes to the BP registers
// some bp cases check the changes variable, because they might not have to be updated all the time Called: At the end of every: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg
// NOTE: it seems not all bp cases like checking changes, so calling if (bp.changes == 0 ? false : true) How It Works: First the pipeline is flushed then update the bpmem with the new value.
// had to be ditched and the games seem to work fine with out it. Some of the BP cases have to call certain functions while others just update the bpmem.
// NOTE2: Yet Another Gamecube Documentation calls them Bypass Registers some bp cases check the changes variable, because they might not have to be updated all the time
// -------------------------------------------------------------------------------------------------------- NOTE: it seems not all bp cases like checking changes, so calling if (bp.changes == 0 ? false : true)
had to be ditched and the games seem to work fine with out it.
NOTE2: Yet Another Gamecube Documentation calls them Bypass Registers but possibly completely wrong
NOTE3: This controls the register groups: RAS1/2, SU, TF, TEV, C/Z, PEC
TODO: Turn into function table. The (future) DisplayList (DL) jit can then call the functions directly,
getting rid of dynamic dispatch. Unfortunately, few games use DLs properly - most\
just stuff geometry in them and don't put state changes there.
----------------------------------------------------------------------------------------------------------------
*/
// Debugging only, this lets you skip a bp update // Debugging only, this lets you skip a bp update
//static int times = 0; //static int times = 0;
@ -111,6 +108,9 @@ void BPWritten(const Bypass& bp)
case BPMEM_RAS1_SS1: // Index Texture Coordinate Scale 1 case BPMEM_RAS1_SS1: // Index Texture Coordinate Scale 1
PixelShaderManager::SetIndTexScaleChanged(0x0c); PixelShaderManager::SetIndTexScaleChanged(0x0c);
break; break;
// ----------------
// Scissor Control
// ----------------
case BPMEM_SCISSORTL: // Scissor Rectable Top, Left case BPMEM_SCISSORTL: // Scissor Rectable Top, Left
case BPMEM_SCISSORBR: // Scissor Rectable Bottom, Right case BPMEM_SCISSORBR: // Scissor Rectable Bottom, Right
case BPMEM_SCISSOROFFSET: // Scissor Offset case BPMEM_SCISSOROFFSET: // Scissor Offset
@ -299,29 +299,32 @@ void BPWritten(const Bypass& bp)
break; break;
} }
// ---------------------------------- // ----------------------------------
// Display Copy Filtering Control // Display Copy Filtering Control - GX_SetCopyFilter(u8 aa,u8 sample_pattern[12][2],u8 vf,u8 vfilter[7])
// Fields: Destination, Frame2Field, Gamma, Source // Fields: Destination, Frame2Field, Gamma, Source
// TODO: We might have to implement the gamma one, some games might need this, if they are too dark to see. // TODO: We might have to implement the gamma one, some games might need this, if they are too dark to see.
// ---------------------------------- // ----------------------------------
case BPMEM_DISPLAYCOPYFILER: case BPMEM_DISPLAYCOPYFILER: // if (aa) { use sample_pattern } else { use 666666 }
case BPMEM_DISPLAYCOPYFILER+1: case BPMEM_DISPLAYCOPYFILER+1: // if (aa) { use sample_pattern } else { use 666666 }
case BPMEM_DISPLAYCOPYFILER+2: case BPMEM_DISPLAYCOPYFILER+2: // if (aa) { use sample_pattern } else { use 666666 }
case BPMEM_DISPLAYCOPYFILER+3: case BPMEM_DISPLAYCOPYFILER+3: // if (aa) { use sample_pattern } else { use 666666 }
case BPMEM_COPYFILTER0: //GXSetCopyFilter case BPMEM_COPYFILTER0: // if (vf) { use vfilter } else { use 595000 }
case BPMEM_COPYFILTER1: case BPMEM_COPYFILTER1: // if (vf) { use vfilter } else { use 000015 }
break; break;
case BPMEM_FIELDMASK: // Interlacing Control // -----------------------------------
case BPMEM_FIELDMODE: // Interlacing Control
// -----------------------------------
case BPMEM_FIELDMASK: // GX_SetFieldMask(u8 even_mask,u8 odd_mask)
case BPMEM_FIELDMODE: // GX_SetFieldMode(u8 field_mode,u8 half_aspect_ratio)
SetInterlacingMode(bp); SetInterlacingMode(bp);
break; break;
// --------------------------------------------------- // ----------------------------------------
// Debugging/Profiling info, we don't care about them // Unimportant regs (Clock, Perf, ...)
// --------------------------------------------------- // ----------------------------------------
case BPMEM_CLOCK0: // Some Clock case BPMEM_BUSCLOCK0: // TB Bus Clock ?
case BPMEM_CLOCK1: // Some Clock case BPMEM_BUSCLOCK1: // TB Bus Clock ?
case BPMEM_SU_COUNTER: // Pixel or Poly Count case BPMEM_PERF0_TRI: // Perf: Triangles
case BPMEM_RAS_COUNTER: // Sound Count of something in the Texture Units case BPMEM_PERF0_QUAD: // Perf: Quads
case BPMEM_SETGPMETRIC: // Set the Graphic Processor Metric case BPMEM_PERF1: // Perf: Some Clock, Texels, TX, TC
break; break;
// ---------------- // ----------------
// EFB Copy config // EFB Copy config
@ -338,7 +341,7 @@ void BPWritten(const Bypass& bp)
case BPMEM_CLEAR_Z: // Z Components (24-bit Zbuffer) case BPMEM_CLEAR_Z: // Z Components (24-bit Zbuffer)
break; break;
// ------------------------- // -------------------------
// Bounding Box support // Bounding Box Control
// ------------------------- // -------------------------
case BPMEM_CLEARBBOX1: case BPMEM_CLEARBBOX1:
case BPMEM_CLEARBBOX2: { case BPMEM_CLEARBBOX2: {
@ -367,8 +370,9 @@ void BPWritten(const Bypass& bp)
#endif #endif
break; break;
} }
case BPMEM_ZCOMPARE: // Set the Z-Compare and EFB pixel format
case BPMEM_TEXINVALIDATE: // Used, if game has manual control the Texture Cache, which we don't allow case BPMEM_TEXINVALIDATE: // Used, if game has manual control the Texture Cache, which we don't allow
DEBUG_LOG(VIDEO, "BP Texture Invalid: %08x", bp.newvalue);
case BPMEM_ZCOMPARE: // Set the Z-Compare and EFB pixel format
case BPMEM_MIPMAP_STRIDE: // MipMap Stride Channel case BPMEM_MIPMAP_STRIDE: // MipMap Stride Channel
case BPMEM_COPYYSCALE: // Display Copy Y Scale case BPMEM_COPYYSCALE: // Display Copy Y Scale
case BPMEM_IREF: /* 24 RID case BPMEM_IREF: /* 24 RID
@ -380,7 +384,6 @@ void BPWritten(const Bypass& bp)
6 BI1 - Ind. Tex Stage 1 NTexMap 6 BI1 - Ind. Tex Stage 1 NTexMap
3 BC0 - Ind. Tex Stage 0 NTexCoord 3 BC0 - Ind. Tex Stage 0 NTexCoord
0 BI0 - Ind. Tex Stage 0 NTexMap */ 0 BI0 - Ind. Tex Stage 0 NTexMap */
break;
case BPMEM_TEV_KSEL: // Texture Environment Swap Mode Table 0 case BPMEM_TEV_KSEL: // Texture Environment Swap Mode Table 0
case BPMEM_TEV_KSEL+1:// Texture Environment Swap Mode Table 1 case BPMEM_TEV_KSEL+1:// Texture Environment Swap Mode Table 1
case BPMEM_TEV_KSEL+2:// Texture Environment Swap Mode Table 2 case BPMEM_TEV_KSEL+2:// Texture Environment Swap Mode Table 2
@ -389,27 +392,26 @@ void BPWritten(const Bypass& bp)
case BPMEM_TEV_KSEL+5:// Texture Environment Swap Mode Table 5 case BPMEM_TEV_KSEL+5:// Texture Environment Swap Mode Table 5
case BPMEM_TEV_KSEL+6:// Texture Environment Swap Mode Table 6 case BPMEM_TEV_KSEL+6:// Texture Environment Swap Mode Table 6
case BPMEM_TEV_KSEL+7:// Texture Environment Swap Mode Table 7 case BPMEM_TEV_KSEL+7:// Texture Environment Swap Mode Table 7
break;
case BPMEM_BP_MASK: // This Register can be used to limit to which bits of BP registers is actually written to. the mask is case BPMEM_BP_MASK: // This Register can be used to limit to which bits of BP registers is actually written to. the mask is
// only valid for the next BP command, and will reset itself. // only valid for the next BP command, and will reset itself.
case BPMEM_IND_IMASK: // Index Mask ? case BPMEM_IND_IMASK: // Index Mask ?
break; case BPMEM_REVBITS: // Always set to 0x0F when GX_InitRevBits() is called.
case BPMEM_UNKNOWN: // This is always set to 0xF at boot of any game, so this sounds like a useless reg
if (bp.newvalue != 0x0F)
PanicAlert("Unknown is not 0xF! val = 0x%08x", bp.newvalue);
break; break;
case BPMEM_UNKOWN_57: // Sunshine uses this: 0xAAA, 0x000, over and over, copy filter related? case BPMEM_UNKOWN_57: // Sunshine alternates this register between values 0x000 and 0xAAA
DEBUG_LOG(VIDEO, "Uknown BP Reg 0x57: %08x", bp.newvalue);
break; break;
case BPMEM_UNKNOWN_60: case BPMEM_UNKNOWN_60:
case BPMEM_UNKNOWN_61: case BPMEM_UNKNOWN_61:
case BPMEM_UNKNOWN_62: case BPMEM_UNKNOWN_62:
case BPMEM_UNKNOWN_63:
// Cases added due to: http://code.google.com/p/dolphin-emu/issues/detail?id=360#c90 // Cases added due to: http://code.google.com/p/dolphin-emu/issues/detail?id=360#c90
// Are these related to BBox? // Are these related to BBox?
break; break;
case BPMEM_TEXMODESYNC: // Always set to 0 when GX_TexModeSync() is called.
break;
// ------------------------------------------------ // ------------------------------------------------
// On Default, we try to look for other things // On Default, we try to look for other things
// before we give up and say its an unknown opcode // before we give up and say its an unknown opcode

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -262,4 +262,4 @@ extern VAT g_VtxAttr[8];
// Might move this into its own file later. // Might move this into its own file later.
void LoadCPReg(u32 SubCmd, u32 Value); void LoadCPReg(u32 SubCmd, u32 Value);
#endif #endif // _CPMEMORY_H

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -42,4 +42,4 @@ void VideoFifo_CheckSwapRequest();
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight); void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
void VideoFifo_CheckEFBAccess(); void VideoFifo_CheckEFBAccess();
#endif #endif // _FIFO_H

View file

@ -110,13 +110,15 @@ PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, int te
u8 *temp = SOIL_load_image(textureMap[key].c_str(), &width, &height, &channels, SOIL_LOAD_RGBA); u8 *temp = SOIL_load_image(textureMap[key].c_str(), &width, &height, &channels, SOIL_LOAD_RGBA);
if (temp == NULL) { if (temp == NULL)
{
ERROR_LOG(VIDEO, "Custom texture %s failed to load", textureMap[key].c_str(), width, height); ERROR_LOG(VIDEO, "Custom texture %s failed to load", textureMap[key].c_str(), width, height);
SOIL_free_image_data(temp); SOIL_free_image_data(temp);
return PC_TEX_FMT_NONE; return PC_TEX_FMT_NONE;
} }
if (width > 1024 || height > 1024) { if (width > 1024 || height > 1024)
{
ERROR_LOG(VIDEO, "Custom texture %s is too large (%ix%i); textures can only be 1024 pixels tall and wide", textureMap[key].c_str(), width, height); ERROR_LOG(VIDEO, "Custom texture %s is too large (%ix%i); textures can only be 1024 pixels tall and wide", textureMap[key].c_str(), width, height);
SOIL_free_image_data(temp); SOIL_free_image_data(temp);
return PC_TEX_FMT_NONE; return PC_TEX_FMT_NONE;

View file

@ -29,4 +29,4 @@ void Shutdown();
PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, int texformat, u8 *data); PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, int texformat, u8 *data);
}; };
#endif #endif // _HIRESTEXTURES_H

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -34,8 +34,10 @@ void InitLUTs()
{ {
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
shiftLookup[i] = 1.0f / float(1 << i); shiftLookup[i] = 1.0f / float(1 << i);
for (int i = 0; i < 64; i++) for (int i = 0; i < 64; i++)
lut6to8[i] = (i*255) / 63; lut6to8[i] = (i*255) / 63;
for (int i = 0; i < 256; i++) for (int i = 0; i < 256; i++)
{ {
lutu8tosfloat[i] = (float)(i - 128) / 127.0f; lutu8tosfloat[i] = (float)(i - 128) / 127.0f;

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -31,4 +31,4 @@ extern float shiftLookup[32];
void InitLUTs(); void InitLUTs();
#endif #endif // _LOOKUPTABLES_H

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -87,8 +87,9 @@ bool FifoCommandRunnable()
switch (Cmd) switch (Cmd)
{ {
case GX_NOP: case GX_NOP: // Hm, this means that we scan over nop streams pretty slowly...
// Hm, this means that we scan over nop streams pretty slowly... case GX_CMD_INVL_VC: // Invalidate Vertex Cache - no parameters
case 0x44: // zelda 4 swords calls it and checks the metrics registers after that
iCommandSize = 1; iCommandSize = 1;
break; break;
@ -100,6 +101,7 @@ bool FifoCommandRunnable()
case GX_LOAD_INDX_B: case GX_LOAD_INDX_B:
case GX_LOAD_INDX_C: case GX_LOAD_INDX_C:
case GX_LOAD_INDX_D: case GX_LOAD_INDX_D:
case GX_LOAD_BP_REG:
iCommandSize = 5; iCommandSize = 5;
break; break;
@ -107,19 +109,6 @@ bool FifoCommandRunnable()
iCommandSize = 9; iCommandSize = 9;
break; break;
case 0x44:
iCommandSize = 1;
// zelda 4 swords calls it and checks the metrics registers after that
break;
case GX_CMD_INVL_VC: // invalid vertex cache - no parameter?
iCommandSize = 1;
break;
case GX_LOAD_BP_REG:
iCommandSize = 5;
break;
case GX_LOAD_XF_REG: case GX_LOAD_XF_REG:
{ {
// check if we can read the header // check if we can read the header
@ -154,8 +143,9 @@ bool FifoCommandRunnable()
} }
else else
{ {
// TODO(Omega): Maybe dump FIFO to file on this error
char szTemp[1024]; char szTemp[1024];
sprintf(szTemp, "GFX: Unknown Opcode (0x%x).\n" sprintf(szTemp, "GFX FIFO: Unknown Opcode (0x%x).\n"
"This means one of the following:\n" "This means one of the following:\n"
"* The emulated GPU got desynced, disabling dual core can help\n" "* The emulated GPU got desynced, disabling dual core can help\n"
"* Command stream corrupted by some spurious memory bug\n" "* Command stream corrupted by some spurious memory bug\n"
@ -256,12 +246,11 @@ static void Decode()
} }
break; break;
case 0x44: case 0x44: // zelda 4 swords calls it and checks the metrics registers after that
DEBUG_LOG(VIDEO, "GX 0x44: %08x", Cmd); DEBUG_LOG(VIDEO, "GX 0x44: %08x", Cmd);
// zelda 4 swords calls it and checks the metrics registers after that
break; break;
case GX_CMD_INVL_VC:// Invalidate (vertex cache?) case GX_CMD_INVL_VC: // Invalidate Vertex Cache
DEBUG_LOG(VIDEO, "Invalidate (vertex cache?)"); DEBUG_LOG(VIDEO, "Invalidate (vertex cache?)");
break; break;

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -48,4 +48,4 @@ void OpcodeDecoder_Init();
void OpcodeDecoder_Shutdown(); void OpcodeDecoder_Shutdown();
void OpcodeDecoder_Run(); void OpcodeDecoder_Run();
#endif #endif // _OPCODE_DECODING_H

View file

@ -31,8 +31,10 @@
void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 dstAlphaEnable) void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 dstAlphaEnable)
{ {
u32 projtexcoords = 0; u32 projtexcoords = 0;
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; i++) { for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; i++)
if (bpmem.tevorders[i/2].getEnable(i&1)) { {
if (bpmem.tevorders[i/2].getEnable(i & 1))
{
int texcoord = bpmem.tevorders[i / 2].getTexCoord(i & 1); int texcoord = bpmem.tevorders[i / 2].getTexCoord(i & 1);
if (xfregs.texcoords[texcoord].texmtxinfo.projection) if (xfregs.texcoords[texcoord].texmtxinfo.projection)
projtexcoords |= 1 << texcoord; projtexcoords |= 1 << texcoord;
@ -58,7 +60,8 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 dstAlphaEnable
int hdr = 4; int hdr = 4;
u32* pcurvalue = &uid.values[hdr]; u32* pcurvalue = &uid.values[hdr];
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages+1; ++i) { for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
{
TevStageCombiner::ColorCombiner &cc = bpmem.combiners[i].colorC; TevStageCombiner::ColorCombiner &cc = bpmem.combiners[i].colorC;
TevStageCombiner::AlphaCombiner &ac = bpmem.combiners[i].alphaC; TevStageCombiner::AlphaCombiner &ac = bpmem.combiners[i].alphaC;
@ -71,7 +74,8 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 dstAlphaEnable
pcurvalue += 2; pcurvalue += 2;
} }
for (u32 i = 0; i < ((u32)bpmem.genMode.numtevstages+1)/2; ++i) { for (u32 i = 0; i < ((u32)bpmem.genMode.numtevstages+1) / 2; ++i)
{
u32 val0, val1; u32 val0, val1;
if (bpmem.tevorders[i].hex & 0x40) if (bpmem.tevorders[i].hex & 0x40)
val0 = bpmem.tevorders[i].hex & 0x3ff; val0 = bpmem.tevorders[i].hex & 0x3ff;
@ -86,6 +90,7 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 dstAlphaEnable
case 0: pcurvalue[0] = val0|(val1<<10); break; case 0: pcurvalue[0] = val0|(val1<<10); break;
case 1: pcurvalue[0] |= val0<<20; pcurvalue[1] = val1; pcurvalue++; break; case 1: pcurvalue[0] |= val0<<20; pcurvalue[1] = val1; pcurvalue++; break;
case 2: pcurvalue[1] |= (val0<<10)|(val1<<20); pcurvalue++; break; case 2: pcurvalue[1] |= (val0<<10)|(val1<<20); pcurvalue++; break;
default: PanicAlert("Uknown case for Tev Stages / 2: %08x", (i % 3));
} }
} }
@ -96,10 +101,12 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 dstAlphaEnable
else else
val0 = bpmem.tevorders[bpmem.genMode.numtevstages/2].hex & 0x380; val0 = bpmem.tevorders[bpmem.genMode.numtevstages/2].hex & 0x380;
switch (bpmem.genMode.numtevstages % 3) { switch (bpmem.genMode.numtevstages % 3)
{
case 0: pcurvalue[0] = val0; break; case 0: pcurvalue[0] = val0; break;
case 1: pcurvalue[0] |= val0 << 20; break; case 1: pcurvalue[0] |= val0 << 20; break;
case 2: pcurvalue[1] |= val0 << 10; pcurvalue++; break; case 2: pcurvalue[1] |= val0 << 10; pcurvalue++; break;
default: PanicAlert("Uknown case for Tev Stages: %08x", bpmem.genMode.numtevstages % 3);
} }
} }
@ -108,12 +115,15 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 dstAlphaEnable
uid.tevstages = (u32)(pcurvalue - &uid.values[0] - hdr); uid.tevstages = (u32)(pcurvalue - &uid.values[0] - hdr);
for (u32 i = 0; i < bpmem.genMode.numindstages; ++i) { for (u32 i = 0; i < bpmem.genMode.numindstages; ++i)
{
u32 val = bpmem.tevind[i].hex & 0x1fffff; // 21 bits u32 val = bpmem.tevind[i].hex & 0x1fffff; // 21 bits
switch (i % 3) { switch (i % 3)
{
case 0: pcurvalue[0] = val; break; case 0: pcurvalue[0] = val; break;
case 1: pcurvalue[0] |= val << 21; pcurvalue[1] = val >> 11; ++pcurvalue; break; case 1: pcurvalue[0] |= val << 21; pcurvalue[1] = val >> 11; ++pcurvalue; break;
case 2: pcurvalue[0] |= val << 10; ++pcurvalue; break; case 2: pcurvalue[0] |= val << 10; ++pcurvalue; break;
default: PanicAlert("Uknown case for Ind Stages: %08x", (i % 3));
} }
} }
@ -277,9 +287,9 @@ static const char *tevCInputTable2[] = // CC
"(textemp.aaa)", // TEXA, "(textemp.aaa)", // TEXA,
"rastemp", // RASC, "rastemp", // RASC,
"(rastemp.aaa)", // RASA, "(rastemp.aaa)", // RASA,
"float3(1.0f,1.0f,1.0f)", //ONE, "float3(1.0f,1.0f,1.0f)", // ONE
"float3(.5f,.5f,.5f)", //HALF, "float3(.5f,.5f,.5f)", // HALF
"konsttemp", //"konsttemp.rgb", //KONST, "konsttemp", //"konsttemp.rgb", // KONST
"float3(0.0f,0.0f,0.0f)", // ZERO "float3(0.0f,0.0f,0.0f)", // ZERO
"PADERROR", "PADERROR", "PADERROR", "PADERROR", "PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR", "PADERROR", "PADERROR", "PADERROR", "PADERROR",
@ -383,24 +393,27 @@ const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL
numStages, numTexgen, bpmem.genMode.numindstages); numStages, numTexgen, bpmem.genMode.numindstages);
int nIndirectStagesUsed = 0; int nIndirectStagesUsed = 0;
if (bpmem.genMode.numindstages > 0) { if (bpmem.genMode.numindstages > 0)
for (int i = 0; i < numStages; ++i) { {
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) { for (int i = 0; i < numStages; ++i)
{
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
nIndirectStagesUsed |= 1<<bpmem.tevind[i].bt; nIndirectStagesUsed |= 1<<bpmem.tevind[i].bt;
} }
} }
}
// Declare samplers // Declare samplers
if (texture_mask) { if (texture_mask)
{
WRITE(p, "uniform samplerRECT "); WRITE(p, "uniform samplerRECT ");
bool bfirst = true; bool bfirst = true;
for (int i = 0; i < 8; ++i) { for (int i = 0; i < 8; ++i)
if (texture_mask & (1<<i)) { if (texture_mask & (1<<i))
{
WRITE(p, "%s samp%d : register(s%d)", bfirst?"":",", i, i); WRITE(p, "%s samp%d : register(s%d)", bfirst?"":",", i, i);
bfirst = false; bfirst = false;
} }
}
WRITE(p, ";\n"); WRITE(p, ";\n");
} }
@ -433,11 +446,15 @@ const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL
WRITE(p, " out float depth : DEPTH,\n"); WRITE(p, " out float depth : DEPTH,\n");
// compute window position if needed because binding semantic WPOS is not widely supported // compute window position if needed because binding semantic WPOS is not widely supported
if (numTexgen < 7) { if (numTexgen < 7)
{
for (int i = 0; i < numTexgen; ++i) for (int i = 0; i < numTexgen; ++i)
WRITE(p, " in float3 uv%d : TEXCOORD%d, \n", i, i); WRITE(p, " in float3 uv%d : TEXCOORD%d, \n", i, i);
WRITE(p, " in float4 clipPos : TEXCOORD%d, \n", numTexgen); WRITE(p, " in float4 clipPos : TEXCOORD%d, \n", numTexgen);
} else { }
else
{
// wpos is in w of first 4 texcoords // wpos is in w of first 4 texcoords
for (int i = 0; i < numTexgen; ++i) for (int i = 0; i < numTexgen; ++i)
WRITE(p, " in float%d uv%d : TEXCOORD%d, \n", i<4?4:3, i, i); WRITE(p, " in float%d uv%d : TEXCOORD%d, \n", i<4?4:3, i, i);
@ -453,7 +470,8 @@ const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL
"float3 tevcoord;\n" "float3 tevcoord;\n"
"float2 wrappedcoord, tempcoord;\n\n"); "float2 wrappedcoord, tempcoord;\n\n");
for (int i = 0; i < numTexgen; ++i) { for (int i = 0; i < numTexgen; ++i)
{
// optional perspective divides // optional perspective divides
if (xfregs.texcoords[i].texmtxinfo.projection == XF_TEXPROJ_STQ) if (xfregs.texcoords[i].texmtxinfo.projection == XF_TEXPROJ_STQ)
WRITE(p, "uv%d.xy = uv%d.xy/uv%d.z;\n", i, i, i); WRITE(p, "uv%d.xy = uv%d.xy/uv%d.z;\n", i, i, i);
@ -463,16 +481,16 @@ const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL
} }
// indirect texture map lookup // indirect texture map lookup
for(u32 i = 0; i < bpmem.genMode.numindstages; ++i) { for(u32 i = 0; i < bpmem.genMode.numindstages; ++i)
if (nIndirectStagesUsed & (1<<i)) { {
if (nIndirectStagesUsed & (1<<i))
{
int texcoord = bpmem.tevindref.getTexCoord(i); int texcoord = bpmem.tevindref.getTexCoord(i);
if (texcoord < numTexgen) { if (texcoord < numTexgen)
WRITE(p, "tempcoord=uv%d.xy * "I_INDTEXSCALE"[%d].%s;\n", texcoord, i/2, (i&1)?"zw":"xy"); WRITE(p, "tempcoord=uv%d.xy * "I_INDTEXSCALE"[%d].%s;\n", texcoord, i/2, (i&1)?"zw":"xy");
} else
else {
WRITE(p, "tempcoord=float2(0.0f,0.0f);\n"); WRITE(p, "tempcoord=float2(0.0f,0.0f);\n");
}
char buffer[32]; char buffer[32];
sprintf(buffer, "float3 indtex%d", i); sprintf(buffer, "float3 indtex%d", i);
@ -481,51 +499,51 @@ const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL
} }
// HACK to handle cases where the tex gen is not enabled // HACK to handle cases where the tex gen is not enabled
if (numTexgen == 0) { if (numTexgen == 0)
WRITE(p, "float3 uv0 = float3(0.0f,0.0f,0.0f);\n"); WRITE(p, "float3 uv0 = float3(0.0f,0.0f,0.0f);\n");
}
for (int i = 0; i < numStages; i++) for (int i = 0; i < numStages; i++)
WriteStage(p, i, texture_mask); //build the equation for this stage WriteStage(p, i, texture_mask); //build the equation for this stage
if (numTexgen >= 7) { if (numTexgen >= 7)
WRITE(p, "float4 clipPos = float4(uv0.w, uv1.w, uv2.w, uv3.w);\n"); WRITE(p, "float4 clipPos = float4(uv0.w, uv1.w, uv2.w, uv3.w);\n");
}
// the screen space depth value = far z + (clip z / clip w) * z range // the screen space depth value = far z + (clip z / clip w) * z range
WRITE(p, "float zCoord = "I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * "I_ZBIAS"[1].y;\n"); WRITE(p, "float zCoord = "I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * "I_ZBIAS"[1].y;\n");
// use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format... // use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format...
if (bpmem.ztex2.op == ZTEXTURE_ADD) { if (bpmem.ztex2.op == ZTEXTURE_ADD)
WRITE(p, "depth = frac(dot("I_ZBIAS"[0].xyzw, textemp.xyzw) + "I_ZBIAS"[1].w + zCoord);\n"); WRITE(p, "depth = frac(dot("I_ZBIAS"[0].xyzw, textemp.xyzw) + "I_ZBIAS"[1].w + zCoord);\n");
} else if (bpmem.ztex2.op == ZTEXTURE_REPLACE)
else if (bpmem.ztex2.op == ZTEXTURE_REPLACE) {
WRITE(p, "depth = frac(dot("I_ZBIAS"[0].xyzw, textemp.xyzw) + "I_ZBIAS"[1].w);\n"); WRITE(p, "depth = frac(dot("I_ZBIAS"[0].xyzw, textemp.xyzw) + "I_ZBIAS"[1].w);\n");
} else
else {
WRITE(p, "depth = zCoord;\n"); WRITE(p, "depth = zCoord;\n");
}
//if (bpmem.genMode.numindstages ) WRITE(p, "prev.rg = indtex0.xy;\nprev.b = 0;\n"); //if (bpmem.genMode.numindstages ) WRITE(p, "prev.rg = indtex0.xy;\nprev.b = 0;\n");
if (!WriteAlphaTest(p, HLSL)) { if (!WriteAlphaTest(p, HLSL))
{
// alpha test will always fail, so restart the shader and just make it an empty function // alpha test will always fail, so restart the shader and just make it an empty function
p = pmainstart; p = pmainstart;
WRITE(p, "discard;\n"); WRITE(p, "discard;\n");
WRITE(p, "ocol0 = 0;\n"); WRITE(p, "ocol0 = 0;\n");
} }
else { else
if (dstAlphaEnable) { {
if (dstAlphaEnable)
WRITE(p, " ocol0 = float4(prev.rgb,"I_ALPHA"[0].w);\n"); WRITE(p, " ocol0 = float4(prev.rgb,"I_ALPHA"[0].w);\n");
} else { else
{
WriteFog(p); WriteFog(p);
WRITE(p, " ocol0 = prev;\n"); WRITE(p, " ocol0 = prev;\n");
} }
} }
WRITE(p, "}\n"); WRITE(p, "}\n");
if (text[sizeof(text) - 1] != 0x7C) if (text[sizeof(text) - 1] != 0x7C)
PanicAlert("PixelShader generator - buffer too small, canary has been eaten!"); PanicAlert("PixelShader generator - buffer too small, canary has been eaten!");
return text; return text;
} }
@ -540,20 +558,20 @@ static void WriteStage(char *&p, int n, u32 texture_mask)
bool bHasIndStage = bpmem.tevind[n].IsActive() && bpmem.tevind[n].bt < bpmem.genMode.numindstages; bool bHasIndStage = bpmem.tevind[n].IsActive() && bpmem.tevind[n].bt < bpmem.genMode.numindstages;
// HACK to handle cases where the tex gen is not enabled // HACK to handle cases where the tex gen is not enabled
if (!bHasTexCoord) { if (!bHasTexCoord)
texcoord = 0; texcoord = 0;
}
if (bHasIndStage) { if (bHasIndStage)
{
// perform the indirect op on the incoming regular coordinates using indtex%d as the offset coords // perform the indirect op on the incoming regular coordinates using indtex%d as the offset coords
if (bpmem.tevind[n].bs != ITBA_OFF) { if (bpmem.tevind[n].bs != ITBA_OFF)
{
// write the bump alpha // write the bump alpha
if (bpmem.tevind[n].fmt == ITF_8)
if (bpmem.tevind[n].fmt == ITF_8) {
WRITE(p, "alphabump = indtex%d.%s %s;\n", bpmem.tevind[n].bt, WRITE(p, "alphabump = indtex%d.%s %s;\n", bpmem.tevind[n].bt,
tevIndAlphaSel[bpmem.tevind[n].bs], tevIndAlphaScale[bpmem.tevind[n].fmt]); tevIndAlphaSel[bpmem.tevind[n].bs], tevIndAlphaScale[bpmem.tevind[n].fmt]);
} else
else { {
// donkopunchstania: really bad way to do this // donkopunchstania: really bad way to do this
// cannot always use fract because fract(1.0) is 0.0 when it needs to be 1.0 // cannot always use fract because fract(1.0) is 0.0 when it needs to be 1.0
// omitting fract seems to work as well // omitting fract seems to work as well
@ -574,73 +592,69 @@ static void WriteStage(char *&p, int n, u32 texture_mask)
WRITE(p, "indtevcrd%d.%s += %s;\n", n, tevIndBiasField[bpmem.tevind[n].bias], tevIndBiasAdd[bpmem.tevind[n].fmt]); WRITE(p, "indtevcrd%d.%s += %s;\n", n, tevIndBiasField[bpmem.tevind[n].bias], tevIndBiasAdd[bpmem.tevind[n].fmt]);
// multiply by offset matrix and scale // multiply by offset matrix and scale
if (bpmem.tevind[n].mid != 0) { if (bpmem.tevind[n].mid != 0)
if (bpmem.tevind[n].mid <= 3) { {
if (bpmem.tevind[n].mid <= 3)
{
int mtxidx = 2*(bpmem.tevind[n].mid-1); int mtxidx = 2*(bpmem.tevind[n].mid-1);
WRITE(p, "float2 indtevtrans%d = float2(dot("I_INDTEXMTX"[%d].xyz, indtevcrd%d), dot("I_INDTEXMTX"[%d].xyz, indtevcrd%d));\n", WRITE(p, "float2 indtevtrans%d = float2(dot("I_INDTEXMTX"[%d].xyz, indtevcrd%d), dot("I_INDTEXMTX"[%d].xyz, indtevcrd%d));\n",
n, mtxidx, n, mtxidx+1, n); n, mtxidx, n, mtxidx+1, n);
} }
else if (bpmem.tevind[n].mid <= 7 && bHasTexCoord) { // s matrix else if (bpmem.tevind[n].mid <= 7 && bHasTexCoord)
{ // s matrix
int mtxidx = 2*(bpmem.tevind[n].mid-5); int mtxidx = 2*(bpmem.tevind[n].mid-5);
WRITE(p, "float2 indtevtrans%d = "I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.xx;\n", n, mtxidx, texcoord, n); WRITE(p, "float2 indtevtrans%d = "I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.xx;\n", n, mtxidx, texcoord, n);
} }
else if (bpmem.tevind[n].mid <= 11 && bHasTexCoord) { // t matrix else if (bpmem.tevind[n].mid <= 11 && bHasTexCoord)
{ // t matrix
int mtxidx = 2*(bpmem.tevind[n].mid-9); int mtxidx = 2*(bpmem.tevind[n].mid-9);
WRITE(p, "float2 indtevtrans%d = "I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.yy;\n", n, mtxidx, texcoord, n); WRITE(p, "float2 indtevtrans%d = "I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.yy;\n", n, mtxidx, texcoord, n);
} }
else { else
WRITE(p, "float2 indtevtrans%d = 0;\n", n); WRITE(p, "float2 indtevtrans%d = 0;\n", n);
} }
} else
else {
WRITE(p, "float2 indtevtrans%d = 0;\n", n); WRITE(p, "float2 indtevtrans%d = 0;\n", n);
}
// wrapping // ---------
// Wrapping
// ---------
// wrap S // wrap S
if (bpmem.tevind[n].sw == ITW_OFF) { if (bpmem.tevind[n].sw == ITW_OFF)
WRITE(p, "wrappedcoord.x = uv%d.x;\n", texcoord); WRITE(p, "wrappedcoord.x = uv%d.x;\n", texcoord);
} else if (bpmem.tevind[n].sw == ITW_0)
else if (bpmem.tevind[n].sw == ITW_0) {
WRITE(p, "wrappedcoord.x = 0.0f;\n"); WRITE(p, "wrappedcoord.x = 0.0f;\n");
} else
else {
WRITE(p, "wrappedcoord.x = fmod( uv%d.x, %s );\n", texcoord, tevIndWrapStart[bpmem.tevind[n].sw]); WRITE(p, "wrappedcoord.x = fmod( uv%d.x, %s );\n", texcoord, tevIndWrapStart[bpmem.tevind[n].sw]);
}
// wrap T // wrap T
if (bpmem.tevind[n].tw == ITW_OFF) { if (bpmem.tevind[n].tw == ITW_OFF)
WRITE(p, "wrappedcoord.y = uv%d.y;\n", texcoord); WRITE(p, "wrappedcoord.y = uv%d.y;\n", texcoord);
} else if (bpmem.tevind[n].tw == ITW_0)
else if (bpmem.tevind[n].tw == ITW_0) {
WRITE(p, "wrappedcoord.y = 0.0f;\n"); WRITE(p, "wrappedcoord.y = 0.0f;\n");
} else
else {
WRITE(p, "wrappedcoord.y = fmod( uv%d.y, %s );\n", texcoord, tevIndWrapStart[bpmem.tevind[n].tw]); WRITE(p, "wrappedcoord.y = fmod( uv%d.y, %s );\n", texcoord, tevIndWrapStart[bpmem.tevind[n].tw]);
}
if (bpmem.tevind[n].fb_addprev) { if (bpmem.tevind[n].fb_addprev) // add previous tevcoord
// add previous tevcoord
WRITE(p, "tevcoord.xy += wrappedcoord + indtevtrans%d;\n", n); WRITE(p, "tevcoord.xy += wrappedcoord + indtevtrans%d;\n", n);
} else
else {
WRITE(p, "tevcoord.xy = wrappedcoord + indtevtrans%d;\n", n); WRITE(p, "tevcoord.xy = wrappedcoord + indtevtrans%d;\n", n);
} }
}
WRITE(p, "rastemp=%s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)],rasswap); WRITE(p, "rastemp=%s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)],rasswap);
if (bpmem.tevorders[n/2].getEnable(n&1)) { if (bpmem.tevorders[n/2].getEnable(n&1))
{
int texmap = bpmem.tevorders[n/2].getTexMap(n&1); int texmap = bpmem.tevorders[n/2].getTexMap(n&1);
if(!bHasIndStage) { if(!bHasIndStage)
{
// calc tevcord // calc tevcord
if(bHasTexCoord) { if(bHasTexCoord)
WRITE(p, "tevcoord.xy = uv%d.xy;\n", texcoord); WRITE(p, "tevcoord.xy = uv%d.xy;\n", texcoord);
} else { else
WRITE(p, "tevcoord.xy = float2(0.0f,0.0f);\n"); WRITE(p, "tevcoord.xy = float2(0.0f,0.0f);\n");
} }
}
SampleTexture(p, "textemp", "tevcoord", texswap, texmap, texture_mask); SampleTexture(p, "textemp", "tevcoord", texswap, texmap, texture_mask);
} }
@ -661,16 +675,19 @@ static void WriteStage(char *&p, int n, u32 texture_mask)
WRITE(p, "%s= ", tevCOutputTable[cc.dest]); WRITE(p, "%s= ", tevCOutputTable[cc.dest]);
// combine the color channel // combine the color channel
if (cc.bias != 3) { // if not compare if (cc.bias != 3) // if not compare
{
//normal color combiner goes here //normal color combiner goes here
WRITE(p, " %s*(%s%s",tevScaleTable[cc.shift],tevCInputTable[cc.d],tevOpTable[cc.op]); WRITE(p, " %s*(%s%s",tevScaleTable[cc.shift],tevCInputTable[cc.d],tevOpTable[cc.op]);
WRITE(p, "lerp(%s,%s,%s) %s);\n", WRITE(p, "lerp(%s,%s,%s) %s);\n",
tevCInputTable[cc.a], tevCInputTable[cc.b], tevCInputTable[cc.a], tevCInputTable[cc.b],
tevCInputTable[cc.c], tevBiasTable[cc.bias]); tevCInputTable[cc.c], tevBiasTable[cc.bias]);
} }
else { else
{
int cmp = (cc.shift<<1)|cc.op|8; // comparemode stored here int cmp = (cc.shift<<1)|cc.op|8; // comparemode stored here
switch(cmp) { switch(cmp)
{
case TEVCMP_R8_GT: case TEVCMP_R8_GT:
case TEVCMP_RGB8_GT: // per component compares case TEVCMP_RGB8_GT: // per component compares
WRITE(p, " %s + ((%s.%s > %s.%s) ? %s : float3(0.0f,0.0f,0.0f));\n", WRITE(p, " %s + ((%s.%s > %s.%s) ? %s : float3(0.0f,0.0f,0.0f));\n",
@ -704,17 +721,20 @@ static void WriteStage(char *&p, int n, u32 texture_mask)
// combine the alpha channel // combine the alpha channel
WRITE(p, "%s= ", tevAOutputTable[ac.dest]); WRITE(p, "%s= ", tevAOutputTable[ac.dest]);
if (ac.bias != 3) { // if not compare if (ac.bias != 3) // if not compare
{
//normal alpha combiner goes here //normal alpha combiner goes here
WRITE(p, " %s*(%s%s",tevScaleTable[ac.shift],tevAInputTable[ac.d],tevOpTable[ac.op]); WRITE(p, " %s*(%s%s",tevScaleTable[ac.shift],tevAInputTable[ac.d],tevOpTable[ac.op]);
WRITE(p, "lerp(%s,%s,%s) %s)\n", WRITE(p, "lerp(%s,%s,%s) %s)\n",
tevAInputTable[ac.a],tevAInputTable[ac.b], tevAInputTable[ac.a],tevAInputTable[ac.b],
tevAInputTable[ac.c],tevBiasTable[ac.bias]); tevAInputTable[ac.c],tevBiasTable[ac.bias]);
} }
else { else
{
//compare alpha combiner goes here //compare alpha combiner goes here
int cmp = (ac.shift<<1)|ac.op|8; // comparemode stored here int cmp = (ac.shift<<1)|ac.op|8; // comparemode stored here
switch(cmp) { switch(cmp)
{
case TEVCMP_R8_GT: case TEVCMP_R8_GT:
case TEVCMP_A8_GT: case TEVCMP_A8_GT:
WRITE(p, " %s + ((%s.%s > %s.%s) ? %s : 0)\n", WRITE(p, " %s + ((%s.%s > %s.%s) ? %s : 0)\n",
@ -746,6 +766,7 @@ static void WriteStage(char *&p, int n, u32 texture_mask)
if (ac.clamp) if (ac.clamp)
WRITE(p, "%s = clamp(%s,0.0f,1.0f);\n", tevAOutputTable[ac.dest],tevAOutputTable[ac.dest]); WRITE(p, "%s = clamp(%s,0.0f,1.0f);\n", tevAOutputTable[ac.dest],tevAOutputTable[ac.dest]);
WRITE(p, "\n"); WRITE(p, "\n");
} }
@ -784,7 +805,8 @@ void SampleTexture(char *&p, const char *destination, const char *texcoords, con
static void WriteAlphaCompare(char *&p, int num, int comp) static void WriteAlphaCompare(char *&p, int num, int comp)
{ {
switch(comp) { switch(comp)
{
case ALPHACMP_ALWAYS: WRITE(p, "(false)"); break; case ALPHACMP_ALWAYS: WRITE(p, "(false)"); break;
case ALPHACMP_NEVER: WRITE(p, "(true)"); break; case ALPHACMP_NEVER: WRITE(p, "(true)"); break;
case ALPHACMP_LEQUAL: WRITE(p, "(prev.a > %s)",alphaRef[num]); break; case ALPHACMP_LEQUAL: WRITE(p, "(prev.a > %s)",alphaRef[num]); break;
@ -793,6 +815,7 @@ static void WriteAlphaCompare(char *&p, int num, int comp)
case ALPHACMP_GREATER: WRITE(p, "(prev.a <= %s + %f)",alphaRef[num],epsilon8bit*0.5f);break; case ALPHACMP_GREATER: WRITE(p, "(prev.a <= %s + %f)",alphaRef[num],epsilon8bit*0.5f);break;
case ALPHACMP_EQUAL: WRITE(p, "(abs(prev.a-%s)>%f)",alphaRef[num],epsilon8bit*2); break; case ALPHACMP_EQUAL: WRITE(p, "(abs(prev.a-%s)>%f)",alphaRef[num],epsilon8bit*2); break;
case ALPHACMP_NEQUAL: WRITE(p, "(abs(prev.a-%s)<%f)",alphaRef[num],epsilon8bit*2); break; case ALPHACMP_NEQUAL: WRITE(p, "(abs(prev.a-%s)<%f)",alphaRef[num],epsilon8bit*2); break;
default: PanicAlert("Bad Alpha Compare! %08x", comp);
} }
} }
@ -802,55 +825,69 @@ static bool WriteAlphaTest(char *&p, bool HLSL)
u32 comp[2] = {bpmem.alphaFunc.comp0,bpmem.alphaFunc.comp1}; u32 comp[2] = {bpmem.alphaFunc.comp0,bpmem.alphaFunc.comp1};
//first kill all the simple cases //first kill all the simple cases
switch(op) { switch(op)
case 0: // and {
if (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) return true; case 0: // AND
if (comp[0] == ALPHACMP_NEVER || comp[1] == ALPHACMP_NEVER) { if (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS)
return true;
if (comp[0] == ALPHACMP_NEVER || comp[1] == ALPHACMP_NEVER)
{
WRITE(p, "discard;\n"); WRITE(p, "discard;\n");
return false; return false;
} }
break; break;
case 1: // or case 1: // OR
if (comp[0] == ALPHACMP_ALWAYS || comp[1] == ALPHACMP_ALWAYS) return true; if (comp[0] == ALPHACMP_ALWAYS || comp[1] == ALPHACMP_ALWAYS)
if (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER) { return true;
if (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)
{
WRITE(p, "discard;\n"); WRITE(p, "discard;\n");
return false; return false;
} }
break; break;
case 2: // xor case 2: // XOR
if ( (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS) ) return true; if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS))
if ( (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)) { return true;
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER))
{
WRITE(p, "discard;\n"); WRITE(p, "discard;\n");
return false; return false;
} }
break; break;
case 3: // xnor case 3: // XNOR
if ( (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS)) { if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS))
{
WRITE(p, "discard;\n"); WRITE(p, "discard;\n");
return false; return false;
} }
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)) if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER))
return true; return true;
break; break;
default: PanicAlert("bad logic for alpha test? %08x", op);
} }
// Seems we need discard for Cg and clip for d3d. sigh. // Seems we need discard for Cg and clip for d3d. sigh.
if (HLSL) if (HLSL)
WRITE(p, "clip( "); WRITE(p, "clip( ");
else { else
WRITE(p, "discard( "); WRITE(p, "discard( ");
}
WriteAlphaCompare(p, 0, bpmem.alphaFunc.comp0); WriteAlphaCompare(p, 0, bpmem.alphaFunc.comp0);
// negated because testing the inverse condition // negated because testing the inverse condition
switch (bpmem.alphaFunc.logic) { switch (bpmem.alphaFunc.logic)
{
case 0: WRITE(p, " || "); break; // and case 0: WRITE(p, " || "); break; // and
case 1: WRITE(p, " && "); break; // or case 1: WRITE(p, " && "); break; // or
case 2: WRITE(p, " == "); break; // xor case 2: WRITE(p, " == "); break; // xor
case 3: WRITE(p, " != "); break; // xnor case 3: WRITE(p, " != "); break; // xnor
default: break;
} }
WriteAlphaCompare(p, 1, bpmem.alphaFunc.comp1); WriteAlphaCompare(p, 1, bpmem.alphaFunc.comp1);
WRITE(p, ");\n"); WRITE(p, ");\n");
return true; return true;
} }
@ -858,12 +895,16 @@ static void WriteFog(char *&p)
{ {
bool enabled = bpmem.fog.c_proj_fsel.fsel == 0 ? false : true; bool enabled = bpmem.fog.c_proj_fsel.fsel == 0 ? false : true;
if (enabled) { if (enabled)
if (bpmem.fog.c_proj_fsel.proj == 0) { {
if (bpmem.fog.c_proj_fsel.proj == 0)
{
// perspective // perspective
// ze = A/(B - Zs) // ze = A/(B - Zs)
WRITE (p, " float ze = "I_FOG"[1].x / ("I_FOG"[1].y - depth);\n"); WRITE (p, " float ze = "I_FOG"[1].x / ("I_FOG"[1].y - depth);\n");
} else { }
else
{
// orthographic // orthographic
// ze = a*Zs // ze = a*Zs
WRITE (p, " float ze = "I_FOG"[1].x * depth;\n"); WRITE (p, " float ze = "I_FOG"[1].x * depth;\n");
@ -872,7 +913,8 @@ static void WriteFog(char *&p)
WRITE (p, " float fog = clamp(ze - "I_FOG"[1].z, 0.0f, 1.0f);\n"); WRITE (p, " float fog = clamp(ze - "I_FOG"[1].z, 0.0f, 1.0f);\n");
} }
switch (bpmem.fog.c_proj_fsel.fsel) { switch (bpmem.fog.c_proj_fsel.fsel)
{
case 2: // linear case 2: // linear
// empty // empty
break; break;
@ -890,9 +932,9 @@ static void WriteFog(char *&p)
WRITE(p, " fog = 1.0f - fog;\n"); WRITE(p, " fog = 1.0f - fog;\n");
WRITE(p, " fog = pow(2, -8.0f * fog * fog);\n"); WRITE(p, " fog = pow(2, -8.0f * fog * fog);\n");
break; break;
default: PanicAlert("Unknown Fog Type! %08x", bpmem.fog.c_proj_fsel.fsel);
} }
if (enabled) { if (enabled)
WRITE(p, " prev.rgb = (1.0f - fog) * prev.rgb + (fog * "I_FOG"[0].rgb);\n"); WRITE(p, " prev.rgb = (1.0f - fog) * prev.rgb + (fog * "I_FOG"[0].rgb);\n");
} }
}

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -15,8 +15,8 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#ifndef GCOGL_PIXELSHADER #ifndef GCOGL_PIXELSHADER_H
#define GCOGL_PIXELSHADER #define GCOGL_PIXELSHADER_H
#include "Common.h" #include "Common.h"
@ -48,10 +48,12 @@ public:
u32 values[PIXELSHADERUID_MAX_VALUES]; u32 values[PIXELSHADERUID_MAX_VALUES];
u16 tevstages, indstages; u16 tevstages, indstages;
PIXELSHADERUID() { PIXELSHADERUID()
{
memset(values, 0, PIXELSHADERUID_MAX_VALUES * 4); memset(values, 0, PIXELSHADERUID_MAX_VALUES * 4);
tevstages = indstages = 0; tevstages = indstages = 0;
} }
PIXELSHADERUID(const PIXELSHADERUID& r) PIXELSHADERUID(const PIXELSHADERUID& r)
{ {
tevstages = r.tevstages; tevstages = r.tevstages;
@ -61,9 +63,12 @@ public:
for (int i = 0; i < N; ++i) for (int i = 0; i < N; ++i)
values[i] = r.values[i]; values[i] = r.values[i];
} }
int GetNumValues() const {
int GetNumValues() const
{
return tevstages + indstages + 4; return tevstages + indstages + 4;
} }
bool operator <(const PIXELSHADERUID& _Right) const bool operator <(const PIXELSHADERUID& _Right) const
{ {
if (values[0] < _Right.values[0]) if (values[0] < _Right.values[0])
@ -71,7 +76,8 @@ public:
else if (values[0] > _Right.values[0]) else if (values[0] > _Right.values[0])
return false; return false;
int N = GetNumValues(); int N = GetNumValues();
for (int i = 1; i < N; ++i) { for (int i = 1; i < N; ++i)
{
if (values[i] < _Right.values[i]) if (values[i] < _Right.values[i])
return true; return true;
else if (values[i] > _Right.values[i]) else if (values[i] > _Right.values[i])
@ -79,12 +85,14 @@ public:
} }
return false; return false;
} }
bool operator ==(const PIXELSHADERUID& _Right) const bool operator ==(const PIXELSHADERUID& _Right) const
{ {
if (values[0] != _Right.values[0]) if (values[0] != _Right.values[0])
return false; return false;
int N = GetNumValues(); int N = GetNumValues();
for (int i = 1; i < N; ++i) { for (int i = 1; i < N; ++i)
{
if (values[i] != _Right.values[i]) if (values[i] != _Right.values[i])
return false; return false;
} }
@ -95,4 +103,4 @@ public:
const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL = false); const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL = false);
void GetPixelShaderId(PIXELSHADERUID &, u32 s_texturemask, u32 dstAlphaEnable); void GetPixelShaderId(PIXELSHADERUID &, u32 s_texturemask, u32 dstAlphaEnable);
#endif #endif // GCOGL_PIXELSHADER_H

View file

@ -202,6 +202,7 @@ void PixelShaderManager::SetConstants()
SetPSConstant4f(C_FOG + 1, a, b, bpmem.fog.c_proj_fsel.GetC(), 0); SetPSConstant4f(C_FOG + 1, a, b, bpmem.fog.c_proj_fsel.GetC(), 0);
s_bFogParamChanged = false; s_bFogParamChanged = false;
} }
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
lastCustomTexScale[i][0] = lastCustomTexScale[i][1] = 1.0f; lastCustomTexScale[i][0] = lastCustomTexScale[i][1] = 1.0f;
} }

View file

@ -55,4 +55,4 @@ public:
}; };
#endif #endif // _PIXELSHADERMANAGER_H

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -77,7 +77,8 @@ struct DVPROFSTRUCT
~DVPROFSTRUCT() { ~DVPROFSTRUCT() {
std::list<DVPROFSTRUCT *>::iterator it = listpChild.begin(); std::list<DVPROFSTRUCT *>::iterator it = listpChild.begin();
while (it != listpChild.end()) { while (it != listpChild.end())
{
delete *it; delete *it;
*it = NULL; *it = NULL;
++it; ++it;
@ -150,12 +151,14 @@ void DVProfRegister(const char *pname)
// else add in a new profiler to the appropriate parent profiler // else add in a new profiler to the appropriate parent profiler
DVPROFSTRUCT* pprof = NULL; DVPROFSTRUCT* pprof = NULL;
if (g_listCurTracking.size() > 0) { if (g_listCurTracking.size() > 0)
{
_assert_( g_listCurTracking.back().pprof != NULL ); _assert_( g_listCurTracking.back().pprof != NULL );
g_listCurTracking.back().pprof->listpChild.push_back(new DVPROFSTRUCT()); g_listCurTracking.back().pprof->listpChild.push_back(new DVPROFSTRUCT());
pprof = g_listCurTracking.back().pprof->listpChild.back(); pprof = g_listCurTracking.back().pprof->listpChild.back();
} }
else { else
{
g_listProfilers.push_back(DVPROFSTRUCT()); g_listProfilers.push_back(DVPROFSTRUCT());
pprof = &g_listProfilers.back(); pprof = &g_listProfilers.back();
} }
@ -206,7 +209,9 @@ u64 DVProfWriteStruct(FILE* f, const DVPROFSTRUCT* p, int ident)
fprintf(f, "%*s%s - ", ident, "", p->pname); fprintf(f, "%*s%s - ", ident, "", p->pname);
std::list<DVPROFSTRUCT::DATA>::const_iterator ittime = p->listTimes.begin(); std::list<DVPROFSTRUCT::DATA>::const_iterator ittime = p->listTimes.begin();
u64 utime = 0; u64 utime = 0;
while (ittime != p->listTimes.end()) {
while (ittime != p->listTimes.end())
{
utime += ittime->dwTime; utime += ittime->dwTime;
if (ittime->dwUserData) if (ittime->dwUserData)
fprintf(f, "time: %d, user: 0x%8.8x", (u32)ittime->dwTime, ittime->dwUserData); fprintf(f, "time: %d, user: 0x%8.8x", (u32)ittime->dwTime, ittime->dwUserData);
@ -217,7 +222,8 @@ u64 DVProfWriteStruct(FILE* f, const DVPROFSTRUCT* p, int ident)
// yes this is necessary, maps have problems with constructors on their type // yes this is necessary, maps have problems with constructors on their type
std::map<std::string, DVTIMEINFO>::iterator ittimes = mapAggregateTimes.find(p->pname); std::map<std::string, DVTIMEINFO>::iterator ittimes = mapAggregateTimes.find(p->pname);
if (ittimes == mapAggregateTimes.end()) { if (ittimes == mapAggregateTimes.end())
{
ittimes = mapAggregateTimes.insert(std::map<std::string, DVTIMEINFO>::value_type(p->pname, DVTIMEINFO())).first; ittimes = mapAggregateTimes.insert(std::map<std::string, DVTIMEINFO>::value_type(p->pname, DVTIMEINFO())).first;
ittimes->second.uExclusive = 0; ittimes->second.uExclusive = 0;
ittimes->second.uInclusive = 0; ittimes->second.uInclusive = 0;
@ -230,14 +236,14 @@ u64 DVProfWriteStruct(FILE* f, const DVPROFSTRUCT* p, int ident)
std::list<DVPROFSTRUCT*>::const_iterator itprof = p->listpChild.begin(); std::list<DVPROFSTRUCT*>::const_iterator itprof = p->listpChild.begin();
u64 uex = utime; u64 uex = utime;
while (itprof != p->listpChild.end()) { while (itprof != p->listpChild.end())
{
uex -= DVProfWriteStruct(f, *itprof, ident+4); uex -= DVProfWriteStruct(f, *itprof, ident+4);
++itprof; ++itprof;
} }
if (uex > utime) { if (uex > utime)
uex = 0; uex = 0;
}
ittimes->second.uExclusive += uex; ittimes->second.uExclusive += uex;
return utime; return utime;
@ -252,7 +258,8 @@ void DVProfWrite(const char* pfilename, u32 frames)
mapAggregateTimes.clear(); mapAggregateTimes.clear();
std::list<DVPROFSTRUCT>::iterator it = g_listProfilers.begin(); std::list<DVPROFSTRUCT>::iterator it = g_listProfilers.begin();
while (it != g_listProfilers.end() ) { while (it != g_listProfilers.end() )
{
DVProfWriteStruct(f, &(*it), 0); DVProfWriteStruct(f, &(*it), 0);
++it; ++it;
} }
@ -263,7 +270,8 @@ void DVProfWrite(const char* pfilename, u32 frames)
u64 uTotal[2] = {0}; u64 uTotal[2] = {0};
double fiTotalTime[2]; double fiTotalTime[2];
for (iter = mapAggregateTimes.begin(); iter != mapAggregateTimes.end(); ++iter) { for (iter = mapAggregateTimes.begin(); iter != mapAggregateTimes.end(); ++iter)
{
uTotal[0] += iter->second.uExclusive; uTotal[0] += iter->second.uExclusive;
uTotal[1] += iter->second.uInclusive; uTotal[1] += iter->second.uInclusive;
} }
@ -275,10 +283,9 @@ void DVProfWrite(const char* pfilename, u32 frames)
fiTotalTime[1] = 1.0 / (double)uTotal[1]; fiTotalTime[1] = 1.0 / (double)uTotal[1];
// output the combined times // output the combined times
for (iter = mapAggregateTimes.begin(); iter != mapAggregateTimes.end(); ++iter) { for (iter = mapAggregateTimes.begin(); iter != mapAggregateTimes.end(); ++iter)
fprintf(f, "%s - ex: %f inc: %f\n", iter->first.c_str(), (float)((double)iter->second.uExclusive * fiTotalTime[0]), fprintf(f, "%s - ex: %f inc: %f\n", iter->first.c_str(), (float)((double)iter->second.uExclusive * fiTotalTime[0]),
(float)((double)iter->second.uInclusive * fiTotalTime[1])); (float)((double)iter->second.uInclusive * fiTotalTime[1]));
}
fclose(f); fclose(f);
} }

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -73,6 +73,6 @@ public:
~DVProfileFunc() {} ~DVProfileFunc() {}
}; };
#endif #endif // DVPROFILE && WIN32
#endif #endif // _PROFILER_H

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -95,7 +95,8 @@ u32 TexDecoder_GetSafeTextureHash(const u8 *src, int width, int height, int texf
int TexDecoder_GetBlockWidthInTexels(int format) int TexDecoder_GetBlockWidthInTexels(int format)
{ {
switch (format) { switch (format)
{
case GX_TF_I4: return 8; case GX_TF_I4: return 8;
case GX_TF_I8: return 8; case GX_TF_I8: return 8;
case GX_TF_IA4: return 8; case GX_TF_IA4: return 8;
@ -114,7 +115,8 @@ int TexDecoder_GetBlockWidthInTexels(int format)
// FIXME: Use reasonable values for block height // FIXME: Use reasonable values for block height
int TexDecoder_GetBlockHeightInTexels(int format) int TexDecoder_GetBlockHeightInTexels(int format)
{ {
switch (format) { /*switch (format)
{
case GX_TF_I4: return 1; case GX_TF_I4: return 1;
case GX_TF_I8: return 1; case GX_TF_I8: return 1;
case GX_TF_IA4: return 1; case GX_TF_IA4: return 1;
@ -127,13 +129,19 @@ int TexDecoder_GetBlockHeightInTexels(int format)
case GX_TF_C14X2: return 1; case GX_TF_C14X2: return 1;
case GX_TF_CMPR: return 8; case GX_TF_CMPR: return 8;
default: return 1; default: return 1;
} }*/
// Omega: I asssume the height would be the same as the width since it says 'block'
// width values look better than 1 anyways
// TODO: Confirm this
return TexDecoder_GetBlockWidthInTexels(format);
} }
//returns bytes //returns bytes
int TexDecoder_GetPaletteSize(int format) int TexDecoder_GetPaletteSize(int format)
{ {
switch (format) { switch (format)
{
case GX_TF_C4: return 16 * 2; case GX_TF_C4: return 16 * 2;
case GX_TF_C8: return 256 * 2; case GX_TF_C8: return 256 * 2;
case GX_TF_C14X2: return 16384 * 2; case GX_TF_C14X2: return 16384 * 2;
@ -317,7 +325,9 @@ void decodeDXTBlock(u32 *dst, const DXTBlock *src, int pitch)
{ {
colors[0] = makecol(red1, green1, blue1, 255); // Color 1 colors[0] = makecol(red1, green1, blue1, 255); // Color 1
colors[1] = makecol(red2, green2, blue2, 255); // Color 2 colors[1] = makecol(red2, green2, blue2, 255); // Color 2
colors[2] = makecol((int)ceil((float)(red1+red2)/2), (int)ceil((float)(green1+green2)/2), (int)ceil((float)(blue1+blue2)/2), 255); // Average colors[2] = makecol((int)ceil((float)(red1 + red2) / 2), // Average
(int)ceil((float)(green1 + green2) / 2),
(int)ceil((float)(blue1 + blue2) / 2), 255);
colors[3] = makecol(red2, green2, blue2, 0); // Color2 but transparent colors[3] = makecol(red2, green2, blue2, 0); // Color2 but transparent
} }
@ -426,7 +436,8 @@ PC_TexFormat TexDecoder_Decode_real(u8 *dst, const u8 *src, int width, int heigh
{ {
for (int y = 0; y < height; y += 4) for (int y = 0; y < height; y += 4)
for (int x = 0; x < width; x += 8) for (int x = 0; x < width; x += 8)
for (int iy = 0; iy < 4; iy++, src += 8) { for (int iy = 0; iy < 4; iy++, src += 8)
{
//decodebytesIA4((u32*)dst+(y+iy)*width+x, src, 8); //decodebytesIA4((u32*)dst+(y+iy)*width+x, src, 8);
decodebytesIA4((u16*)dst + (y + iy) * width + x, src); decodebytesIA4((u16*)dst + (y + iy) * width + x, src);
} }
@ -436,7 +447,8 @@ PC_TexFormat TexDecoder_Decode_real(u8 *dst, const u8 *src, int width, int heigh
{ {
for (int y = 0; y < height; y += 4) for (int y = 0; y < height; y += 4)
for (int x = 0; x < width; x += 4) for (int x = 0; x < width; x += 4)
for (int iy = 0; iy < 4; iy++, src += 8) { for (int iy = 0; iy < 4; iy++, src += 8)
{
u16 *ptr = (u16 *)dst + (y + iy) * width + x; u16 *ptr = (u16 *)dst + (y + iy) * width + x;
u16 *s = (u16 *)src; u16 *s = (u16 *)src;
for(int j = 0; j < 4; j++) for(int j = 0; j < 4; j++)
@ -466,7 +478,8 @@ PC_TexFormat TexDecoder_Decode_real(u8 *dst, const u8 *src, int width, int heigh
{ {
for (int y = 0; y < height; y += 4) for (int y = 0; y < height; y += 4)
for (int x = 0; x < width; x += 4) for (int x = 0; x < width; x += 4)
for (int iy = 0; iy < 4; iy++, src += 8) { for (int iy = 0; iy < 4; iy++, src += 8)
{
u16 *ptr = (u16 *)dst + (y + iy) * width + x; u16 *ptr = (u16 *)dst + (y + iy) * width + x;
u16 *s = (u16 *)src; u16 *s = (u16 *)src;
for(int j = 0; j < 4; j++) for(int j = 0; j < 4; j++)
@ -485,16 +498,14 @@ PC_TexFormat TexDecoder_Decode_real(u8 *dst, const u8 *src, int width, int heigh
return PC_TEX_FMT_BGRA32; return PC_TEX_FMT_BGRA32;
case GX_TF_RGBA8: // speed critical case GX_TF_RGBA8: // speed critical
{ {
for (int y = 0; y < height; y += 4) { for (int y = 0; y < height; y += 4)
for (int x = 0; x < width; x += 4) for (int x = 0; x < width; x += 4)
{ {
for (int iy = 0; iy < 4; iy++) { for (int iy = 0; iy < 4; iy++)
decodebytesARGB8_4((u32*)dst + (y+iy)*width + x, (u16*)src + 4 * iy, (u16*)src + 4 * iy + 16); decodebytesARGB8_4((u32*)dst + (y+iy)*width + x, (u16*)src + 4 * iy, (u16*)src + 4 * iy + 16);
}
src += 64; src += 64;
} }
} }
}
return PC_TEX_FMT_BGRA32; return PC_TEX_FMT_BGRA32;
case GX_TF_CMPR: // speed critical case GX_TF_CMPR: // speed critical
// The metroid games use this format almost exclusively. // The metroid games use this format almost exclusively.
@ -583,7 +594,8 @@ PC_TexFormat TexDecoder_Decode(u8 *dst, const u8 *src, int width, int height, in
{ {
for(int x=0; x < xcnt; x++) for(int x=0; x < xcnt; x++)
{ {
switch(retval) { switch(retval)
{
case PC_TEX_FMT_I8: case PC_TEX_FMT_I8:
{ {
// TODO: Is this an acceptable way to draw in I8? // TODO: Is this an acceptable way to draw in I8?

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -124,10 +124,10 @@ void LOADERDECL UpdateBoundingBox()
o[0] = (o[0] + 1.0f) * 320.0f; o[0] = (o[0] + 1.0f) * 320.0f;
o[1] = (o[1] + 1.0f) * 240.0f; o[1] = (o[1] + 1.0f) * 240.0f;
if (o[0] < g_VideoInitialize.pBBox[0]) g_VideoInitialize.pBBox[0] = std::max(0.0f, o[0]); if (o[0] < g_VideoInitialize.pBBox[0]) g_VideoInitialize.pBBox[0] = (u16)std::max(0.0f, o[0]);
if (o[0] > g_VideoInitialize.pBBox[1]) g_VideoInitialize.pBBox[1] = std::min(640.0f, o[0]); if (o[0] > g_VideoInitialize.pBBox[1]) g_VideoInitialize.pBBox[1] = (u16)std::min(640.0f, o[0]);
if (o[1] < g_VideoInitialize.pBBox[2]) g_VideoInitialize.pBBox[2] = std::max(0.0f, o[1]); if (o[1] < g_VideoInitialize.pBBox[2]) g_VideoInitialize.pBBox[2] = (u16)std::max(0.0f, o[1]);
if (o[1] > g_VideoInitialize.pBBox[3]) g_VideoInitialize.pBBox[3] = std::min(480.0f, o[1]); if (o[1] > g_VideoInitialize.pBBox[3]) g_VideoInitialize.pBBox[3] = (u16)std::min(480.0f, o[1]);
/* /*
if (GetAsyncKeyState(VK_LSHIFT)) { if (GetAsyncKeyState(VK_LSHIFT)) {
ERROR_LOG(VIDEO, "XForm: %f %f %f to %f %f", p[0], p[1], p[2], o[0], o[1]); ERROR_LOG(VIDEO, "XForm: %f %f %f to %f %f", p[0], p[1], p[2], o[0], o[1]);

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -52,16 +52,19 @@ class VERTEXSHADERUID
public: public:
u32 values[9]; u32 values[9];
VERTEXSHADERUID() { VERTEXSHADERUID()
{
memset(values, 0, sizeof(values)); memset(values, 0, sizeof(values));
} }
VERTEXSHADERUID(const VERTEXSHADERUID& r) { VERTEXSHADERUID(const VERTEXSHADERUID& r)
{
for (size_t i = 0; i < sizeof(values) / sizeof(u32); ++i) for (size_t i = 0; i < sizeof(values) / sizeof(u32); ++i)
values[i] = r.values[i]; values[i] = r.values[i];
} }
int GetNumValues() const { int GetNumValues() const
{
return (((values[0] >> 23) & 0xf) * 3 + 3) / 4 + 3; // numTexGens*3/4+1 return (((values[0] >> 23) & 0xf) * 3 + 3) / 4 + 3; // numTexGens*3/4+1
} }
@ -72,7 +75,8 @@ public:
else if (values[0] > _Right.values[0]) else if (values[0] > _Right.values[0])
return false; return false;
int N = GetNumValues(); int N = GetNumValues();
for (int i = 1; i < N; ++i) { for (int i = 1; i < N; ++i)
{
if (values[i] < _Right.values[i]) if (values[i] < _Right.values[i])
return true; return true;
else if (values[i] > _Right.values[i]) else if (values[i] > _Right.values[i])
@ -86,7 +90,8 @@ public:
if (values[0] != _Right.values[0]) if (values[0] != _Right.values[0])
return false; return false;
int N = GetNumValues(); int N = GetNumValues();
for (int i = 1; i < N; ++i) { for (int i = 1; i < N; ++i)
{
if (values[i] != _Right.values[i]) if (values[i] != _Right.values[i])
return false; return false;
} }
@ -97,4 +102,4 @@ public:
const char *GenerateVertexShader(u32 components); const char *GenerateVertexShader(u32 components);
void GetVertexShaderId(VERTEXSHADERUID& vid, u32 components); void GetVertexShaderId(VERTEXSHADERUID& vid, u32 components);
#endif #endif // GCOGL_VERTEXSHADER_H

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -72,14 +72,13 @@ void VertexShaderManager::Init()
void VertexShaderManager::Shutdown() void VertexShaderManager::Shutdown()
{ {
} }
// =======================================================================================
// Syncs the shader constant buffers with xfmem // Syncs the shader constant buffers with xfmem
// ---------------- // TODO: A cleaner way to control the matricies without making a mess in the parameters field
void VertexShaderManager::SetConstants(bool proj_hax_1,bool Hack_hack1 ,float Hack_value1 ,bool Hack_hack2 ,float Hack_value2 ,bool freeLook) void VertexShaderManager::SetConstants(bool proj_hax_1,bool Hack_hack1 ,float Hack_value1 ,bool Hack_hack2 ,float Hack_value2 ,bool freeLook)
{ {
// TODO: Is this still needed?
//nTransformMatricesChanged[0] = 0; nTransformMatricesChanged[1] = 256; //nTransformMatricesChanged[0] = 0; nTransformMatricesChanged[1] = 256;
//nNormalMatricesChanged[0] = 0; nNormalMatricesChanged[1] = 96; //nNormalMatricesChanged[0] = 0; nNormalMatricesChanged[1] = 96;
//nPostTransformMatricesChanged[0] = 0; nPostTransformMatricesChanged[1] = 256; //nPostTransformMatricesChanged[0] = 0; nPostTransformMatricesChanged[1] = 256;
@ -90,7 +89,8 @@ void VertexShaderManager::SetConstants(bool proj_hax_1,bool Hack_hack1 ,float Ha
//bPosNormalMatrixChanged = bTexMatricesChanged[0] = bTexMatricesChanged[1] = true; //bPosNormalMatrixChanged = bTexMatricesChanged[0] = bTexMatricesChanged[1] = true;
//nMaterialsChanged = 15; //nMaterialsChanged = 15;
if (nTransformMatricesChanged[0] >= 0) { if (nTransformMatricesChanged[0] >= 0)
{
int startn = nTransformMatricesChanged[0] / 4; int startn = nTransformMatricesChanged[0] / 4;
int endn = (nTransformMatricesChanged[1] + 3) / 4; int endn = (nTransformMatricesChanged[1] + 3) / 4;
const float* pstart = (const float*)&xfmem[startn * 4]; const float* pstart = (const float*)&xfmem[startn * 4];
@ -98,7 +98,8 @@ void VertexShaderManager::SetConstants(bool proj_hax_1,bool Hack_hack1 ,float Ha
SetVSConstant4fv(C_TRANSFORMMATRICES + i, pstart); SetVSConstant4fv(C_TRANSFORMMATRICES + i, pstart);
nTransformMatricesChanged[0] = nTransformMatricesChanged[1] = -1; nTransformMatricesChanged[0] = nTransformMatricesChanged[1] = -1;
} }
if (nNormalMatricesChanged[0] >= 0) { if (nNormalMatricesChanged[0] >= 0)
{
int startn = nNormalMatricesChanged[0] / 3; int startn = nNormalMatricesChanged[0] / 3;
int endn = (nNormalMatricesChanged[1] + 2) / 3; int endn = (nNormalMatricesChanged[1] + 2) / 3;
const float* pnstart = (const float*)&xfmem[XFMEM_NORMALMATRICES+3*startn]; const float* pnstart = (const float*)&xfmem[XFMEM_NORMALMATRICES+3*startn];
@ -109,7 +110,8 @@ void VertexShaderManager::SetConstants(bool proj_hax_1,bool Hack_hack1 ,float Ha
nNormalMatricesChanged[0] = nNormalMatricesChanged[1] = -1; nNormalMatricesChanged[0] = nNormalMatricesChanged[1] = -1;
} }
if (nPostTransformMatricesChanged[0] >= 0) { if (nPostTransformMatricesChanged[0] >= 0)
{
int startn = nPostTransformMatricesChanged[0] / 4; int startn = nPostTransformMatricesChanged[0] / 4;
int endn = (nPostTransformMatricesChanged[1] + 3 ) / 4; int endn = (nPostTransformMatricesChanged[1] + 3 ) / 4;
const float* pstart = (const float*)&xfmem[XFMEM_POSTMATRICES + startn * 4]; const float* pstart = (const float*)&xfmem[XFMEM_POSTMATRICES + startn * 4];
@ -117,13 +119,15 @@ void VertexShaderManager::SetConstants(bool proj_hax_1,bool Hack_hack1 ,float Ha
SetVSConstant4fv(C_POSTTRANSFORMMATRICES + i, pstart); SetVSConstant4fv(C_POSTTRANSFORMMATRICES + i, pstart);
} }
if (nLightsChanged[0] >= 0) { if (nLightsChanged[0] >= 0)
{
// lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats // lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats
int istart = nLightsChanged[0] / 0x10; int istart = nLightsChanged[0] / 0x10;
int iend = (nLightsChanged[1] + 15) / 0x10; int iend = (nLightsChanged[1] + 15) / 0x10;
const float* xfmemptr = (const float*)&xfmem[0x10 * istart + XFMEM_LIGHTS]; const float* xfmemptr = (const float*)&xfmem[0x10 * istart + XFMEM_LIGHTS];
for (int i = istart; i < iend; ++i) { for (int i = istart; i < iend; ++i)
{
u32 color = *(const u32*)(xfmemptr + 3); u32 color = *(const u32*)(xfmemptr + 3);
SetVSConstant4f(C_LIGHTS + 5 * i, SetVSConstant4f(C_LIGHTS + 5 * i,
((color >> 24) & 0xFF) / 255.0f, ((color >> 24) & 0xFF) / 255.0f,
@ -131,11 +135,14 @@ void VertexShaderManager::SetConstants(bool proj_hax_1,bool Hack_hack1 ,float Ha
((color >> 8) & 0xFF) / 255.0f, ((color >> 8) & 0xFF) / 255.0f,
((color) & 0xFF) / 255.0f); ((color) & 0xFF) / 255.0f);
xfmemptr += 4; xfmemptr += 4;
for (int j = 0; j < 4; ++j, xfmemptr += 3) {
for (int j = 0; j < 4; ++j, xfmemptr += 3)
{
if (j == 1 && if (j == 1 &&
fabs(xfmemptr[0]) < 0.00001f && fabs(xfmemptr[0]) < 0.00001f &&
fabs(xfmemptr[1]) < 0.00001f && fabs(xfmemptr[1]) < 0.00001f &&
fabs(xfmemptr[2]) < 0.00001f) { fabs(xfmemptr[2]) < 0.00001f)
{
// dist attenuation, make sure not equal to 0!!! // dist attenuation, make sure not equal to 0!!!
SetVSConstant4f(C_LIGHTS+5*i+j+1, 0.00001f, xfmemptr[1], xfmemptr[2], 0); SetVSConstant4f(C_LIGHTS+5*i+j+1, 0.00001f, xfmemptr[1], xfmemptr[2], 0);
} }
@ -147,15 +154,17 @@ void VertexShaderManager::SetConstants(bool proj_hax_1,bool Hack_hack1 ,float Ha
nLightsChanged[0] = nLightsChanged[1] = -1; nLightsChanged[0] = nLightsChanged[1] = -1;
} }
if (nMaterialsChanged) { if (nMaterialsChanged)
for (int i = 0; i < 4; ++i) { {
for (int i = 0; i < 4; ++i)
if (nMaterialsChanged & (1 << i)) if (nMaterialsChanged & (1 << i))
SetVSConstant4fv(C_MATERIALS + i, &s_fMaterials[4 * i]); SetVSConstant4fv(C_MATERIALS + i, &s_fMaterials[4 * i]);
}
nMaterialsChanged = 0; nMaterialsChanged = 0;
} }
if (bPosNormalMatrixChanged) { if (bPosNormalMatrixChanged)
{
bPosNormalMatrixChanged = false; bPosNormalMatrixChanged = false;
float* pos = (float*)xfmem + MatrixIndexA.PosNormalMtxIdx * 4; float* pos = (float*)xfmem + MatrixIndexA.PosNormalMtxIdx * 4;
@ -169,44 +178,54 @@ void VertexShaderManager::SetConstants(bool proj_hax_1,bool Hack_hack1 ,float Ha
SetVSConstant4fv(C_POSNORMALMATRIX+5, norm + 6); SetVSConstant4fv(C_POSNORMALMATRIX+5, norm + 6);
} }
if (bTexMatricesChanged[0]) { if (bTexMatricesChanged[0])
{
bTexMatricesChanged[0] = false; bTexMatricesChanged[0] = false;
float* fptrs[] = {
float* fptrs[] =
{
(float*)xfmem + MatrixIndexA.Tex0MtxIdx * 4, (float*)xfmem + MatrixIndexA.Tex1MtxIdx * 4, (float*)xfmem + MatrixIndexA.Tex0MtxIdx * 4, (float*)xfmem + MatrixIndexA.Tex1MtxIdx * 4,
(float*)xfmem + MatrixIndexA.Tex2MtxIdx * 4, (float*)xfmem + MatrixIndexA.Tex3MtxIdx * 4 (float*)xfmem + MatrixIndexA.Tex2MtxIdx * 4, (float*)xfmem + MatrixIndexA.Tex3MtxIdx * 4
}; };
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i)
{
SetVSConstant4fv(C_TEXMATRICES+3 * i, fptrs[i]); SetVSConstant4fv(C_TEXMATRICES+3 * i, fptrs[i]);
SetVSConstant4fv(C_TEXMATRICES+3 * i + 1, fptrs[i] + 4); SetVSConstant4fv(C_TEXMATRICES+3 * i + 1, fptrs[i] + 4);
SetVSConstant4fv(C_TEXMATRICES+3 * i + 2, fptrs[i] + 8); SetVSConstant4fv(C_TEXMATRICES+3 * i + 2, fptrs[i] + 8);
} }
} }
if (bTexMatricesChanged[1]) { if (bTexMatricesChanged[1])
{
bTexMatricesChanged[1] = false; bTexMatricesChanged[1] = false;
float* fptrs[] = {(float*)xfmem + MatrixIndexB.Tex4MtxIdx * 4, (float*)xfmem + MatrixIndexB.Tex5MtxIdx * 4, float* fptrs[] = {(float*)xfmem + MatrixIndexB.Tex4MtxIdx * 4, (float*)xfmem + MatrixIndexB.Tex5MtxIdx * 4,
(float*)xfmem + MatrixIndexB.Tex6MtxIdx * 4, (float*)xfmem + MatrixIndexB.Tex7MtxIdx * 4 }; (float*)xfmem + MatrixIndexB.Tex6MtxIdx * 4, (float*)xfmem + MatrixIndexB.Tex7MtxIdx * 4 };
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i)
{
SetVSConstant4fv(C_TEXMATRICES+3 * i + 12, fptrs[i]); SetVSConstant4fv(C_TEXMATRICES+3 * i + 12, fptrs[i]);
SetVSConstant4fv(C_TEXMATRICES+3 * i + 12 + 1, fptrs[i] + 4); SetVSConstant4fv(C_TEXMATRICES+3 * i + 12 + 1, fptrs[i] + 4);
SetVSConstant4fv(C_TEXMATRICES+3 * i + 12 + 2, fptrs[i] + 8); SetVSConstant4fv(C_TEXMATRICES+3 * i + 12 + 2, fptrs[i] + 8);
} }
} }
if (bViewportChanged) { if (bViewportChanged)
{
bViewportChanged = false; bViewportChanged = false;
// This is so implementation-dependent that we can't have it here. // This is so implementation-dependent that we can't have it here.
UpdateViewport(); UpdateViewport();
} }
if (bProjectionChanged) { if (bProjectionChanged)
{
bProjectionChanged = false; bProjectionChanged = false;
if (xfregs.rawProjection[6] == 0) { // Perspective if (xfregs.rawProjection[6] == 0)
{
// Perspective
g_fProjectionMatrix[0] = xfregs.rawProjection[0]; g_fProjectionMatrix[0] = xfregs.rawProjection[0];
g_fProjectionMatrix[1] = 0.0f; g_fProjectionMatrix[1] = 0.0f;
g_fProjectionMatrix[2] = xfregs.rawProjection[1]; g_fProjectionMatrix[2] = xfregs.rawProjection[1];
@ -247,7 +266,9 @@ void VertexShaderManager::SetConstants(bool proj_hax_1,bool Hack_hack1 ,float Ha
SETSTAT_FT(stats.gproj_14, g_fProjectionMatrix[14]); SETSTAT_FT(stats.gproj_14, g_fProjectionMatrix[14]);
SETSTAT_FT(stats.gproj_15, g_fProjectionMatrix[15]); SETSTAT_FT(stats.gproj_15, g_fProjectionMatrix[15]);
} }
else { // Orthographic Projection else
{
// Orthographic Projection
g_fProjectionMatrix[0] = xfregs.rawProjection[0]; g_fProjectionMatrix[0] = xfregs.rawProjection[0];
g_fProjectionMatrix[1] = 0.0f; g_fProjectionMatrix[1] = 0.0f;
g_fProjectionMatrix[2] = 0.0f; g_fProjectionMatrix[2] = 0.0f;
@ -295,7 +316,8 @@ void VertexShaderManager::SetConstants(bool proj_hax_1,bool Hack_hack1 ,float Ha
PRIM_LOG("Projection: %f %f %f %f %f %f\n", xfregs.rawProjection[0], xfregs.rawProjection[1], xfregs.rawProjection[2], xfregs.rawProjection[3], xfregs.rawProjection[4], xfregs.rawProjection[5]); PRIM_LOG("Projection: %f %f %f %f %f %f\n", xfregs.rawProjection[0], xfregs.rawProjection[1], xfregs.rawProjection[2], xfregs.rawProjection[3], xfregs.rawProjection[4], xfregs.rawProjection[5]);
if (freeLook) { if (freeLook)
{
Matrix44 mtxA; Matrix44 mtxA;
Matrix44 mtxB; Matrix44 mtxB;
Matrix44 viewMtx; Matrix44 viewMtx;
@ -311,7 +333,8 @@ void VertexShaderManager::SetConstants(bool proj_hax_1,bool Hack_hack1 ,float Ha
SetVSConstant4fv(C_PROJECTION+2, &mtxA.data[8]); SetVSConstant4fv(C_PROJECTION+2, &mtxA.data[8]);
SetVSConstant4fv(C_PROJECTION+3, &mtxA.data[12]); SetVSConstant4fv(C_PROJECTION+3, &mtxA.data[12]);
} }
else { else
{
SetVSConstant4fv(C_PROJECTION, &g_fProjectionMatrix[0]); SetVSConstant4fv(C_PROJECTION, &g_fProjectionMatrix[0]);
SetVSConstant4fv(C_PROJECTION+1, &g_fProjectionMatrix[4]); SetVSConstant4fv(C_PROJECTION+1, &g_fProjectionMatrix[4]);
SetVSConstant4fv(C_PROJECTION+2, &g_fProjectionMatrix[8]); SetVSConstant4fv(C_PROJECTION+2, &g_fProjectionMatrix[8]);
@ -343,54 +366,66 @@ void VertexShaderManager::InvalidateXFRange(int start, int end)
bTexMatricesChanged[1] = true; bTexMatricesChanged[1] = true;
} }
if (start < XFMEM_POSMATRICES_END) { if (start < XFMEM_POSMATRICES_END)
if (nTransformMatricesChanged[0] == -1) { {
if (nTransformMatricesChanged[0] == -1)
{
nTransformMatricesChanged[0] = start; nTransformMatricesChanged[0] = start;
nTransformMatricesChanged[1] = end>XFMEM_POSMATRICES_END?XFMEM_POSMATRICES_END:end; nTransformMatricesChanged[1] = end>XFMEM_POSMATRICES_END?XFMEM_POSMATRICES_END:end;
} }
else { else
{
if (nTransformMatricesChanged[0] > start) nTransformMatricesChanged[0] = start; if (nTransformMatricesChanged[0] > start) nTransformMatricesChanged[0] = start;
if (nTransformMatricesChanged[1] < end) nTransformMatricesChanged[1] = end>XFMEM_POSMATRICES_END?XFMEM_POSMATRICES_END:end; if (nTransformMatricesChanged[1] < end) nTransformMatricesChanged[1] = end>XFMEM_POSMATRICES_END?XFMEM_POSMATRICES_END:end;
} }
} }
if (start < XFMEM_NORMALMATRICES_END && end > XFMEM_NORMALMATRICES) { if (start < XFMEM_NORMALMATRICES_END && end > XFMEM_NORMALMATRICES)
{
int _start = start < XFMEM_NORMALMATRICES ? 0 : start-XFMEM_NORMALMATRICES; int _start = start < XFMEM_NORMALMATRICES ? 0 : start-XFMEM_NORMALMATRICES;
int _end = end < XFMEM_NORMALMATRICES_END ? end-XFMEM_NORMALMATRICES : XFMEM_NORMALMATRICES_END-XFMEM_NORMALMATRICES; int _end = end < XFMEM_NORMALMATRICES_END ? end-XFMEM_NORMALMATRICES : XFMEM_NORMALMATRICES_END-XFMEM_NORMALMATRICES;
if (nNormalMatricesChanged[0] == -1 ) { if (nNormalMatricesChanged[0] == -1)
{
nNormalMatricesChanged[0] = _start; nNormalMatricesChanged[0] = _start;
nNormalMatricesChanged[1] = _end; nNormalMatricesChanged[1] = _end;
} }
else { else
{
if (nNormalMatricesChanged[0] > _start) nNormalMatricesChanged[0] = _start; if (nNormalMatricesChanged[0] > _start) nNormalMatricesChanged[0] = _start;
if (nNormalMatricesChanged[1] < _end) nNormalMatricesChanged[1] = _end; if (nNormalMatricesChanged[1] < _end) nNormalMatricesChanged[1] = _end;
} }
} }
if (start < XFMEM_POSTMATRICES_END && end > XFMEM_POSTMATRICES) { if (start < XFMEM_POSTMATRICES_END && end > XFMEM_POSTMATRICES)
{
int _start = start < XFMEM_POSTMATRICES ? XFMEM_POSTMATRICES : start-XFMEM_POSTMATRICES; int _start = start < XFMEM_POSTMATRICES ? XFMEM_POSTMATRICES : start-XFMEM_POSTMATRICES;
int _end = end < XFMEM_POSTMATRICES_END ? end-XFMEM_POSTMATRICES : XFMEM_POSTMATRICES_END-XFMEM_POSTMATRICES; int _end = end < XFMEM_POSTMATRICES_END ? end-XFMEM_POSTMATRICES : XFMEM_POSTMATRICES_END-XFMEM_POSTMATRICES;
if (nPostTransformMatricesChanged[0] == -1 ) { if (nPostTransformMatricesChanged[0] == -1)
{
nPostTransformMatricesChanged[0] = _start; nPostTransformMatricesChanged[0] = _start;
nPostTransformMatricesChanged[1] = _end; nPostTransformMatricesChanged[1] = _end;
} }
else { else
{
if (nPostTransformMatricesChanged[0] > _start) nPostTransformMatricesChanged[0] = _start; if (nPostTransformMatricesChanged[0] > _start) nPostTransformMatricesChanged[0] = _start;
if (nPostTransformMatricesChanged[1] < _end) nPostTransformMatricesChanged[1] = _end; if (nPostTransformMatricesChanged[1] < _end) nPostTransformMatricesChanged[1] = _end;
} }
} }
if (start < XFMEM_LIGHTS_END && end > XFMEM_LIGHTS) { if (start < XFMEM_LIGHTS_END && end > XFMEM_LIGHTS)
{
int _start = start < XFMEM_LIGHTS ? XFMEM_LIGHTS : start-XFMEM_LIGHTS; int _start = start < XFMEM_LIGHTS ? XFMEM_LIGHTS : start-XFMEM_LIGHTS;
int _end = end < XFMEM_LIGHTS_END ? end-XFMEM_LIGHTS : XFMEM_LIGHTS_END-XFMEM_LIGHTS; int _end = end < XFMEM_LIGHTS_END ? end-XFMEM_LIGHTS : XFMEM_LIGHTS_END-XFMEM_LIGHTS;
if (nLightsChanged[0] == -1 ) { if (nLightsChanged[0] == -1 )
{
nLightsChanged[0] = _start; nLightsChanged[0] = _start;
nLightsChanged[1] = _end; nLightsChanged[1] = _end;
} }
else { else
{
if (nLightsChanged[0] > _start) nLightsChanged[0] = _start; if (nLightsChanged[0] > _start) nLightsChanged[0] = _start;
if (nLightsChanged[1] < _end) nLightsChanged[1] = _end; if (nLightsChanged[1] < _end) nLightsChanged[1] = _end;
} }
@ -399,7 +434,8 @@ void VertexShaderManager::InvalidateXFRange(int start, int end)
void VertexShaderManager::SetTexMatrixChangedA(u32 Value) void VertexShaderManager::SetTexMatrixChangedA(u32 Value)
{ {
if (MatrixIndexA.Hex != Value) { if (MatrixIndexA.Hex != Value)
{
VertexManager::Flush(); VertexManager::Flush();
if (MatrixIndexA.PosNormalMtxIdx != (Value&0x3f)) if (MatrixIndexA.PosNormalMtxIdx != (Value&0x3f))
bPosNormalMatrixChanged = true; bPosNormalMatrixChanged = true;
@ -410,7 +446,8 @@ void VertexShaderManager::SetTexMatrixChangedA(u32 Value)
void VertexShaderManager::SetTexMatrixChangedB(u32 Value) void VertexShaderManager::SetTexMatrixChangedB(u32 Value)
{ {
if (MatrixIndexB.Hex != Value) { if (MatrixIndexB.Hex != Value)
{
VertexManager::Flush(); VertexManager::Flush();
bTexMatricesChanged[1] = true; bTexMatricesChanged[1] = true;
MatrixIndexB.Hex = Value; MatrixIndexB.Hex = Value;
@ -420,7 +457,8 @@ void VertexShaderManager::SetTexMatrixChangedB(u32 Value)
void VertexShaderManager::SetViewport(float* _Viewport) void VertexShaderManager::SetViewport(float* _Viewport)
{ {
// Workaround for paper mario, yep this is bizarre. // Workaround for paper mario, yep this is bizarre.
for (size_t i = 0; i < ARRAYSIZE(xfregs.rawViewport); ++i) { for (size_t i = 0; i < ARRAYSIZE(xfregs.rawViewport); ++i)
{
if (*(u32*)(_Viewport + i) == 0x7f800000) // invalid fp number if (*(u32*)(_Viewport + i) == 0x7f800000) // invalid fp number
return; return;
} }
@ -448,7 +486,7 @@ void VertexShaderManager::SetMaterialColor(int index, u32 data)
s_fMaterials[ind++] = ((data >> 24) & 0xFF) / 255.0f; s_fMaterials[ind++] = ((data >> 24) & 0xFF) / 255.0f;
s_fMaterials[ind++] = ((data >> 16) & 0xFF) / 255.0f; s_fMaterials[ind++] = ((data >> 16) & 0xFF) / 255.0f;
s_fMaterials[ind++] = ((data >> 8) & 0xFF) / 255.0f; s_fMaterials[ind++] = ((data >> 8) & 0xFF) / 255.0f;
s_fMaterials[ind] = ((data)&0xFF)/255.0f; s_fMaterials[ind] = ( data & 0xFF) / 255.0f;
} }
void VertexShaderManager::TranslateView(float x, float y) void VertexShaderManager::TranslateView(float x, float y)
@ -458,9 +496,8 @@ void VertexShaderManager::TranslateView(float x, float y)
Matrix33::Multiply(s_viewInvRotationMatrix, vector, result); Matrix33::Multiply(s_viewInvRotationMatrix, vector, result);
for(int i = 0; i < 3; i++) { for(int i = 0; i < 3; i++)
s_fViewTranslationVector[i] += result[i]; s_fViewTranslationVector[i] += result[i];
}
bProjectionChanged = true; bProjectionChanged = true;
} }

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -46,4 +46,4 @@ public:
void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4); void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4);
void SetVSConstant4fv(int const_number, const float *f); void SetVSConstant4fv(int const_number, const float *f);
#endif #endif // _VERTEXSHADERMANAGER_H

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -45,7 +45,8 @@ static void DoState(PointerWrap &p)
Fifo_DoState(p); Fifo_DoState(p);
} }
void VideoCommon_DoState(PointerWrap &p) { void VideoCommon_DoState(PointerWrap &p)
{
DoState(p); DoState(p);
//TODO: search for more data that should be saved and add it here //TODO: search for more data that should be saved and add it here
} }

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -15,12 +15,12 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#ifndef __VIDEOSTATE_H #ifndef _VIDEOSTATE_H
#define __VIDEOSTATE_H #define _VIDEOSTATE_H
#include "Common.h" #include "Common.h"
#include "ChunkFile.h" #include "ChunkFile.h"
void VideoCommon_DoState(PointerWrap &p); void VideoCommon_DoState(PointerWrap &p);
#endif #endif // _VIDEOSTATE_H

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -52,29 +52,6 @@
#define GX_SRC_REG 0 #define GX_SRC_REG 0
#define GX_SRC_VTX 1 #define GX_SRC_VTX 1
struct Light
{
u32 useless[3];
u32 color; //rgba
float a0; //attenuation
float a1;
float a2;
float k0; //k stuff
float k1;
float k2;
union
{
struct {
float dpos[3];
float ddir[3]; // specular lights only
};
struct {
float sdir[3];
float shalfangle[3]; // specular lights only
};
};
};
#define LIGHTDIF_NONE 0 #define LIGHTDIF_NONE 0
#define LIGHTDIF_SIGN 1 #define LIGHTDIF_SIGN 1
#define LIGHTDIF_CLAMP 2 #define LIGHTDIF_CLAMP 2
@ -84,6 +61,41 @@ struct Light
#define LIGHTATTN_NONE 2 #define LIGHTATTN_NONE 2
#define LIGHTATTN_DIR 3 #define LIGHTATTN_DIR 3
#define XFMEM_SIZE 0x8000
#define XFMEM_POSMATRICES 0x000
#define XFMEM_POSMATRICES_END 0x100
#define XFMEM_NORMALMATRICES 0x400
#define XFMEM_NORMALMATRICES_END 0x460
#define XFMEM_POSTMATRICES 0x500
#define XFMEM_POSTMATRICES_END 0x600
#define XFMEM_LIGHTS 0x600
#define XFMEM_LIGHTS_END 0x680
#define XFMEM_ERROR 0x1000
#define XFMEM_DIAG 0x1001
#define XFMEM_STATE0 0x1002
#define XFMEM_STATE1 0x1003
#define XFMEM_CLOCK 0x1004
#define XFMEM_CLIPDISABLE 0x1005
#define XFMEM_SETGPMETRIC 0x1006
#define XFMEM_VTXSPECS 0x1008
#define XFMEM_SETNUMCHAN 0x1009
#define XFMEM_SETCHAN0_AMBCOLOR 0x100a
#define XFMEM_SETCHAN1_AMBCOLOR 0x100b
#define XFMEM_SETCHAN0_MATCOLOR 0x100c
#define XFMEM_SETCHAN1_MATCOLOR 0x100d
#define XFMEM_SETCHAN0_COLOR 0x100e
#define XFMEM_SETCHAN1_COLOR 0x100f
#define XFMEM_SETCHAN0_ALPHA 0x1010
#define XFMEM_SETCHAN1_ALPHA 0x1011
#define XFMEM_DUALTEX 0x1012
#define XFMEM_SETMATRIXINDA 0x1018
#define XFMEM_SETMATRIXINDB 0x1019
#define XFMEM_SETVIEWPORT 0x101a
#define XFMEM_SETPROJECTION 0x1020
#define XFMEM_SETNUMTEXGENS 0x103f
#define XFMEM_SETTEXMTXINFO 0x1040
#define XFMEM_SETPOSMTXINFO 0x1050
union LitChannel union LitChannel
{ {
struct struct
@ -113,13 +125,6 @@ union LitChannel
} }
}; };
struct ColorChannel
{
u32 ambColor;
u32 matColor;
LitChannel color;
LitChannel alpha;
};
union INVTXSPEC union INVTXSPEC
{ {
@ -159,6 +164,52 @@ union PostMtxInfo
u32 hex; u32 hex;
}; };
struct Light
{
u32 useless[3];
u32 color; //rgba
float a0; //attenuation
float a1;
float a2;
float k0; //k stuff
float k1;
float k2;
union
{
struct {
float dpos[3];
float ddir[3]; // specular lights only
};
struct {
float sdir[3];
float shalfangle[3]; // specular lights only
};
};
};
struct ColorChannel
{
u32 ambColor;
u32 matColor;
LitChannel color;
LitChannel alpha;
};
struct Viewport
{
float wd;
float ht;
float nearZ;
float xOrig;
float yOrig;
float farZ;
};
struct TexCoordInfo struct TexCoordInfo
{ {
TexMtxInfo texmtxinfo; TexMtxInfo texmtxinfo;
@ -177,25 +228,9 @@ struct XFRegisters
float rawProjection[7]; float rawProjection[7];
}; };
#define XFMEM_SIZE 0x8000
#define XFMEM_POSMATRICES 0x000
#define XFMEM_POSMATRICES_END 0x100
#define XFMEM_NORMALMATRICES 0x400
#define XFMEM_NORMALMATRICES_END 0x460
#define XFMEM_POSTMATRICES 0x500
#define XFMEM_POSTMATRICES_END 0x600
#define XFMEM_LIGHTS 0x600
#define XFMEM_LIGHTS_END 0x680
struct Viewport
{
float wd;
float ht;
float nearZ;
float xOrig;
float yOrig;
float farZ;
};
extern XFRegisters xfregs; extern XFRegisters xfregs;
extern u32 xfmem[XFMEM_SIZE]; extern u32 xfmem[XFMEM_SIZE];
@ -203,4 +238,4 @@ extern u32 xfmem[XFMEM_SIZE];
void LoadXFReg(u32 transferSize, u32 address, u32 *pData); void LoadXFReg(u32 transferSize, u32 address, u32 *pData);
void LoadIndexedXF(u32 val, int array); void LoadIndexedXF(u32 val, int array);
#endif #endif // _XFMEMORY_H

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -32,161 +32,145 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
address = baseAddress + i; address = baseAddress + i;
// Setup a Matrix // Setup a Matrix
if (address < 0x1000) if (address < XFMEM_ERROR)
{ {
VertexManager::Flush(); VertexManager::Flush();
VertexShaderManager::InvalidateXFRange(address, address + transferSize); VertexShaderManager::InvalidateXFRange(address, address + transferSize);
//PRIM_LOG("xfmem write: 0x%x-0x%x\n", address, address+transferSize); //PRIM_LOG("xfmem write: 0x%x-0x%x\n", address, address+transferSize);
u32* p1 = &xfmem[address]; memcpy_gc((u32*)&xfmem[address], &pData[i], transferSize*4);
memcpy_gc(p1, &pData[i], transferSize*4);
i += transferSize; i += transferSize;
} }
else if (address >= XFMEM_SETTEXMTXINFO && address <= XFMEM_SETTEXMTXINFO+7)
{
xfregs.texcoords[address - XFMEM_SETTEXMTXINFO].texmtxinfo.hex = pData[i];
}
else if (address >= XFMEM_SETPOSMTXINFO && address <= XFMEM_SETPOSMTXINFO+7)
{
xfregs.texcoords[address - XFMEM_SETPOSMTXINFO].postmtxinfo.hex = pData[i];
}
else if (address < 0x2000) else if (address < 0x2000)
{ {
u32 data = pData[i]; u32 data = pData[i];
switch (address) switch (address)
{ {
case 0x1000: // error case XFMEM_ERROR:
case XFMEM_DIAG:
case XFMEM_STATE0: // internal state 0
case XFMEM_STATE1: // internal state 1
case XFMEM_CLOCK:
case XFMEM_SETGPMETRIC:
break; break;
case 0x1001: // diagnostics
case XFMEM_CLIPDISABLE:
//if (data & 1) {} // disable clipping detection
//if (data & 2) {} // disable trivial rejection
//if (data & 4) {} // disable cpoly clipping acceleration
break; break;
case 0x1002: // internal state 0
break; case XFMEM_VTXSPECS: //__GXXfVtxSpecs, wrote 0004
case 0x1003: // internal state 1
break;
case 0x1004: // xf_clock
break;
case 0x1005: // clipdisable
if (data & 1) { // disable clipping detection
}
if (data & 2) { // disable trivial rejection
}
if (data & 4) { // disable cpoly clipping acceleration
}
break;
case 0x1006: //SetGPMetric
break;
case 0x1008: //__GXXfVtxSpecs, wrote 0004
xfregs.hostinfo = *(INVTXSPEC*)&data; xfregs.hostinfo = *(INVTXSPEC*)&data;
break; break;
case 0x1009: //GXSetNumChans (no)
if ((u32)xfregs.nNumChans != (data & 3)) { case XFMEM_SETNUMCHAN:
if ((u32)xfregs.nNumChans != (data & 3))
{
VertexManager::Flush(); VertexManager::Flush();
xfregs.nNumChans = data & 3; xfregs.nNumChans = data & 3;
} }
break; break;
case 0x100a: //GXSetChanAmbientcolor
if (xfregs.colChans[0].ambColor != data) {
VertexManager::Flush();
xfregs.colChans[0].ambColor = data;
VertexShaderManager::SetMaterialColor(0, data);
}
break;
case 0x100b: //GXSetChanAmbientcolor
if (xfregs.colChans[1].ambColor != data) {
VertexManager::Flush();
xfregs.colChans[1].ambColor = data;
VertexShaderManager::SetMaterialColor(1, data);
}
break;
case 0x100c: //GXSetChanMatcolor (rgba)
if (xfregs.colChans[0].matColor != data) {
VertexManager::Flush();
xfregs.colChans[0].matColor = data;
VertexShaderManager::SetMaterialColor(2, data);
}
break;
case 0x100d: //GXSetChanMatcolor (rgba)
if (xfregs.colChans[1].matColor != data) {
VertexManager::Flush();
xfregs.colChans[1].matColor = data;
VertexShaderManager::SetMaterialColor(3, data);
}
break;
case 0x100e: // color0 case XFMEM_SETCHAN0_AMBCOLOR: // Channel Ambient Color
if (xfregs.colChans[0].color.hex != (data & 0x7fff) ) { case XFMEM_SETCHAN1_AMBCOLOR:
{
u8 chan = address - XFMEM_SETCHAN0_AMBCOLOR;
if (xfregs.colChans[chan].ambColor != data)
{
VertexManager::Flush(); VertexManager::Flush();
xfregs.colChans[0].color.hex = data; xfregs.colChans[chan].ambColor = data;
VertexShaderManager::SetMaterialColor(chan, data);
} }
break; break;
case 0x100f: // color1 }
if (xfregs.colChans[1].color.hex != (data & 0x7fff) ) {
case XFMEM_SETCHAN0_MATCOLOR: // Channel Material Color
case XFMEM_SETCHAN1_MATCOLOR:
{
u8 chan = address - XFMEM_SETCHAN0_MATCOLOR;
if (xfregs.colChans[chan].matColor != data)
{
VertexManager::Flush(); VertexManager::Flush();
xfregs.colChans[1].color.hex = data; xfregs.colChans[chan].matColor = data;
VertexShaderManager::SetMaterialColor(address - XFMEM_SETCHAN0_AMBCOLOR, data);
} }
break; break;
case 0x1010: // alpha0 }
if (xfregs.colChans[0].alpha.hex != (data & 0x7fff) ) {
case XFMEM_SETCHAN0_COLOR: // Channel Color
case XFMEM_SETCHAN1_COLOR:
{
u8 chan = address - XFMEM_SETCHAN0_COLOR;
if (xfregs.colChans[chan].color.hex != (data & 0x7fff))
{
VertexManager::Flush(); VertexManager::Flush();
xfregs.colChans[0].alpha.hex = data; xfregs.colChans[chan].color.hex = data;
} }
break; break;
case 0x1011: // alpha1 }
if (xfregs.colChans[1].alpha.hex != (data & 0x7fff) ) {
case XFMEM_SETCHAN0_ALPHA: // Channel Alpha
case XFMEM_SETCHAN1_ALPHA:
{
u8 chan = address - XFMEM_SETCHAN0_ALPHA;
if (xfregs.colChans[chan].alpha.hex != (data & 0x7fff))
{
VertexManager::Flush(); VertexManager::Flush();
xfregs.colChans[1].alpha.hex = data; xfregs.colChans[chan].alpha.hex = data;
} }
break; break;
case 0x1012: // dual tex transform }
if (xfregs.bEnableDualTexTransform != (data & 1)) {
case XFMEM_DUALTEX:
if (xfregs.bEnableDualTexTransform != (data & 1))
{
VertexManager::Flush(); VertexManager::Flush();
xfregs.bEnableDualTexTransform = data & 1; xfregs.bEnableDualTexTransform = data & 1;
} }
break; break;
case 0x1013:
case 0x1014: case XFMEM_SETMATRIXINDA:
case 0x1015:
case 0x1016:
case 0x1017:
DEBUG_LOG(VIDEO, "xf addr: %x=%x\n", address, data);
break;
case 0x1018:
//_assert_msg_(GX_XF, 0, "XF matrixindex0"); //_assert_msg_(GX_XF, 0, "XF matrixindex0");
VertexShaderManager::SetTexMatrixChangedA(data); // ? VertexShaderManager::SetTexMatrixChangedA(data); // ?
break; break;
case 0x1019: case XFMEM_SETMATRIXINDB:
//_assert_msg_(GX_XF, 0, "XF matrixindex1"); //_assert_msg_(GX_XF, 0, "XF matrixindex1");
VertexShaderManager::SetTexMatrixChangedB(data); // ? VertexShaderManager::SetTexMatrixChangedB(data); // ?
break; break;
case 0x101a: case XFMEM_SETVIEWPORT:
VertexManager::Flush(); VertexManager::Flush();
VertexShaderManager::SetViewport((float*)&pData[i]); VertexShaderManager::SetViewport((float*)&pData[i]);
PixelShaderManager::SetViewport((float*)&pData[i]); PixelShaderManager::SetViewport((float*)&pData[i]);
i += 6; i += 6;
break; break;
case 0x101c: // paper mario writes 16777216.0f, 1677721.75 case XFMEM_SETPROJECTION:
break;
case 0x101f: // paper mario writes 16777216.0f, 5033165.0f
break;
case 0x1020:
VertexManager::Flush(); VertexManager::Flush();
VertexShaderManager::SetProjection((float*)&pData[i]); VertexShaderManager::SetProjection((float*)&pData[i]);
i += 7; i += 7;
return; break;
case 0x103f: // GXSetNumTexGens case XFMEM_SETNUMTEXGENS: // GXSetNumTexGens
if ((u32)xfregs.numTexGens != data) { if ((u32)xfregs.numTexGens != data)
{
VertexManager::Flush(); VertexManager::Flush();
xfregs.numTexGens = data; xfregs.numTexGens = data;
} }
break; break;
case 0x1040: xfregs.texcoords[0].texmtxinfo.hex = data; break; // Maybe these are for Normals?
case 0x1041: xfregs.texcoords[1].texmtxinfo.hex = data; break; case 0x1048: //xfregs.texcoords[0].nrmmtxinfo.hex = data; break; ??
case 0x1042: xfregs.texcoords[2].texmtxinfo.hex = data; break;
case 0x1043: xfregs.texcoords[3].texmtxinfo.hex = data; break;
case 0x1044: xfregs.texcoords[4].texmtxinfo.hex = data; break;
case 0x1045: xfregs.texcoords[5].texmtxinfo.hex = data; break;
case 0x1046: xfregs.texcoords[6].texmtxinfo.hex = data; break;
case 0x1047: xfregs.texcoords[7].texmtxinfo.hex = data; break;
case 0x1048:
case 0x1049: case 0x1049:
case 0x104a: case 0x104a:
case 0x104b: case 0x104b:
@ -194,27 +178,25 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
case 0x104d: case 0x104d:
case 0x104e: case 0x104e:
case 0x104f: case 0x104f:
DEBUG_LOG(VIDEO, "xf addr: %x=%x\n", address, data); DEBUG_LOG(VIDEO, "Possible Normal Mtx XF reg?: %x=%x\n", address, data);
break; break;
case 0x1050: xfregs.texcoords[0].postmtxinfo.hex = data; break;
case 0x1051: xfregs.texcoords[1].postmtxinfo.hex = data; break;
case 0x1052: xfregs.texcoords[2].postmtxinfo.hex = data; break;
case 0x1053: xfregs.texcoords[3].postmtxinfo.hex = data; break;
case 0x1054: xfregs.texcoords[4].postmtxinfo.hex = data; break;
case 0x1055: xfregs.texcoords[5].postmtxinfo.hex = data; break;
case 0x1056: xfregs.texcoords[6].postmtxinfo.hex = data; break;
case 0x1057: xfregs.texcoords[7].postmtxinfo.hex = data; break;
// --------------
// Unknown Regs
// --------------
case 0x1013:
case 0x1014:
case 0x1015:
case 0x1016:
case 0x1017:
case 0x101c: // paper mario writes 16777216.0f, 1677721.75
case 0x101f: // paper mario writes 16777216.0f, 5033165.0f
default: default:
DEBUG_LOG(VIDEO, "xf addr: %x=%x\n", address, data); WARN_LOG(VIDEO, "Unknown XF Reg: %x=%x\n", address, data);
break; break;
} }
} }
else if (address >= 0x4000)
{
// MessageBox(NULL, "1", "1", MB_OK);
//4010 __GXSetGenMode
}
} }
} }

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -15,4 +15,9 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#ifndef _XFSTRUCTS_H
#define _XFSTRUCTS_H
#include "XFMemory.h" #include "XFMemory.h"
#endif // _XFSTRUCTS_H

View file

@ -426,8 +426,12 @@
</File> </File>
</Filter> </Filter>
<Filter <Filter
Name="Sections" Name="Register Sections"
> >
<File
RelativePath=".\Src\BPFunctions.h"
>
</File>
<File <File
RelativePath=".\Src\BPMemory.cpp" RelativePath=".\Src\BPMemory.cpp"
> >
@ -436,6 +440,14 @@
RelativePath=".\Src\BPMemory.h" RelativePath=".\Src\BPMemory.h"
> >
</File> </File>
<File
RelativePath=".\Src\BPStructs.cpp"
>
</File>
<File
RelativePath=".\Src\BPStructs.h"
>
</File>
<File <File
RelativePath=".\Src\CPMemory.cpp" RelativePath=".\Src\CPMemory.cpp"
> >
@ -492,6 +504,14 @@
RelativePath=".\Src\AVIDump.h" RelativePath=".\Src\AVIDump.h"
> >
</File> </File>
<File
RelativePath=".\Src\HiresTextures.cpp"
>
</File>
<File
RelativePath=".\Src\HiresTextures.h"
>
</File>
<File <File
RelativePath=".\Src\ImageWrite.cpp" RelativePath=".\Src\ImageWrite.cpp"
> >
@ -516,6 +536,14 @@
RelativePath=".\Src\LookUpTables.h" RelativePath=".\Src\LookUpTables.h"
> >
</File> </File>
<File
RelativePath=".\Src\NativeVertexWriter.cpp"
>
</File>
<File
RelativePath=".\Src\NativeVertexWriter.h"
>
</File>
<File <File
RelativePath=".\Src\Profiler.cpp" RelativePath=".\Src\Profiler.cpp"
> >
@ -568,6 +596,10 @@
<Filter <Filter
Name="Vertex Loading" Name="Vertex Loading"
> >
<File
RelativePath=".\Src\DataReader.h"
>
</File>
<File <File
RelativePath=".\Src\VertexLoader.cpp" RelativePath=".\Src\VertexLoader.cpp"
> >
@ -608,23 +640,18 @@
RelativePath=".\Src\VertexLoader_TextCoord.h" RelativePath=".\Src\VertexLoader_TextCoord.h"
> >
</File> </File>
<File
RelativePath=".\Src\VertexLoaderManager.cpp"
>
</File>
<File
RelativePath=".\Src\VertexLoaderManager.h"
>
</File>
</Filter> </Filter>
<File <Filter
RelativePath=".\Src\BPFunctions.h" Name="Decoding"
> >
</File>
<File
RelativePath=".\Src\BPStructs.cpp"
>
</File>
<File
RelativePath=".\Src\BPStructs.h"
>
</File>
<File
RelativePath=".\Src\DataReader.h"
>
</File>
<File <File
RelativePath=".\Src\Fifo.cpp" RelativePath=".\Src\Fifo.cpp"
> >
@ -633,30 +660,6 @@
RelativePath=".\Src\Fifo.h" RelativePath=".\Src\Fifo.h"
> >
</File> </File>
<File
RelativePath=".\Src\HiresTextures.cpp"
>
</File>
<File
RelativePath=".\Src\HiresTextures.h"
>
</File>
<File
RelativePath=".\Src\memcpy_amd.cpp"
>
</File>
<File
RelativePath=".\Src\NativeVertexFormat.h"
>
</File>
<File
RelativePath=".\Src\NativeVertexWriter.cpp"
>
</File>
<File
RelativePath=".\Src\NativeVertexWriter.h"
>
</File>
<File <File
RelativePath=".\Src\OpcodeDecoding.cpp" RelativePath=".\Src\OpcodeDecoding.cpp"
> >
@ -665,10 +668,6 @@
RelativePath=".\Src\OpcodeDecoding.h" RelativePath=".\Src\OpcodeDecoding.h"
> >
</File> </File>
<File
RelativePath=".\Src\SConscript"
>
</File>
<File <File
RelativePath=".\Src\TextureDecoder.cpp" RelativePath=".\Src\TextureDecoder.cpp"
> >
@ -677,12 +676,17 @@
RelativePath=".\Src\TextureDecoder.h" RelativePath=".\Src\TextureDecoder.h"
> >
</File> </File>
</Filter>
<File <File
RelativePath=".\Src\VertexLoaderManager.cpp" RelativePath=".\Src\memcpy_amd.cpp"
> >
</File> </File>
<File <File
RelativePath=".\Src\VertexLoaderManager.h" RelativePath=".\Src\NativeVertexFormat.h"
>
</File>
<File
RelativePath=".\Src\SConscript"
> >
</File> </File>
<File <File

View file

@ -143,7 +143,7 @@ clear_buffer:
} }
// SetupAccelerator // SetupAccelerator
const s16 *read_ptr = (s16*)GetARAMPointer(PB.CurAddr); const s16 *read_ptr = (s16*)GetARAMPointer(PB.CurAddr);
if (PB.RemLength < rem_samples) if (PB.RemLength < (u32)rem_samples)
{ {
// finish-up loop // finish-up loop
for (u32 i = 0; i < PB.RemLength; i++) for (u32 i = 0; i < PB.RemLength; i++)
@ -202,7 +202,7 @@ clear_buffer:
// SetupAccelerator // SetupAccelerator
const s8 *read_ptr = (s8*)GetARAMPointer(PB.CurAddr); const s8 *read_ptr = (s8*)GetARAMPointer(PB.CurAddr);
if (PB.RemLength < rem_samples) if (PB.RemLength < (u32)rem_samples)
{ {
// finish-up loop // finish-up loop
for (u32 i = 0; i < PB.RemLength; i++) for (u32 i = 0; i < PB.RemLength; i++)
@ -365,7 +365,7 @@ void CUCode_Zelda::RenderVoice_Raw(ZeldaVoicePB &PB, s16 *_Buffer, int _Size)
// The PB.StopOnSilence check is a hack, we should check the buffers and enter this // The PB.StopOnSilence check is a hack, we should check the buffers and enter this
// only when the buffer is completely 0 (i.e. when the music has finished fading out) // only when the buffer is completely 0 (i.e. when the music has finished fading out)
if (PB.StopOnSilence || PB.RemLength < _RealSize) if (PB.StopOnSilence || PB.RemLength < (u32)_RealSize)
{ {
WARN_LOG(DSPHLE, "Raw: END"); WARN_LOG(DSPHLE, "Raw: END");
// Let's ignore this entire case since it doesn't seem to happen // Let's ignore this entire case since it doesn't seem to happen
@ -517,8 +517,8 @@ void CUCode_Zelda::RenderAddVoice(ZeldaVoicePB &PB, s32* _LeftBuffer, s32* _Righ
switch (PB.Format) switch (PB.Format)
{ {
// Synthesized sounds // Synthesized sounds
case 0x0003: WARN_LOG(DSPHLE, "PB Format 0x03 used!");
case 0x0000: // Example: Magic meter filling up in ZWW case 0x0000: // Example: Magic meter filling up in ZWW
case 0x0003:
RenderSynth_RectWave(PB, m_VoiceBuffer, _Size); RenderSynth_RectWave(PB, m_VoiceBuffer, _Size);
break; break;
@ -533,7 +533,7 @@ void CUCode_Zelda::RenderAddVoice(ZeldaVoicePB &PB, s32* _LeftBuffer, s32* _Righ
break; break;
// These are more "synth" formats - square wave, saw wave etc. // These are more "synth" formats - square wave, saw wave etc.
case 0x0002: case 0x0002: WARN_LOG(DSPHLE, "PB Format 0x02 used!");
case 0x0004: // Example: Big Pikmin onion mothership landing/building a bridge in Pikmin case 0x0004: // Example: Big Pikmin onion mothership landing/building a bridge in Pikmin
case 0x0007: // Example: "success" SFX in Pikmin 1, Pikmin 2 in a cave, not sure what sound it is. case 0x0007: // Example: "success" SFX in Pikmin 1, Pikmin 2 in a cave, not sure what sound it is.
case 0x000b: // Example: SFX in area selection menu in Pikmin case 0x000b: // Example: SFX in area selection menu in Pikmin

View file

@ -100,7 +100,7 @@ void FlushPipeline()
VertexManager::Flush(); VertexManager::Flush();
} }
void SetGenerationMode(const Bypass &bp) void SetGenerationMode(const BPCmd &bp)
{ {
// dev->SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]); // dev->SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]);
Renderer::SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]); Renderer::SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]);
@ -123,17 +123,17 @@ void SetGenerationMode(const Bypass &bp)
} }
} }
void SetScissor(const Bypass &bp) void SetScissor(const BPCmd &bp)
{ {
Renderer::SetScissorRect(); Renderer::SetScissorRect();
} }
void SetLineWidth(const Bypass &bp) void SetLineWidth(const BPCmd &bp)
{ {
// We can't change line width in D3D unless we use ID3DXLine // We can't change line width in D3D unless we use ID3DXLine
float psize = float(bpmem.lineptwidth.pointsize) * 6.0f; float psize = float(bpmem.lineptwidth.pointsize) * 6.0f;
Renderer::SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&psize)); Renderer::SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&psize));
} }
void SetDepthMode(const Bypass &bp) void SetDepthMode(const BPCmd &bp)
{ {
if (bpmem.zmode.testenable) if (bpmem.zmode.testenable)
{ {
@ -159,7 +159,7 @@ void SetDepthMode(const Bypass &bp)
// Renderer::SetRenderMode(Renderer::RM_Normal); // Renderer::SetRenderMode(Renderer::RM_Normal);
} }
void SetBlendMode(const Bypass &bp) void SetBlendMode(const BPCmd &bp)
{ {
if (bp.changes & 1) if (bp.changes & 1)
Renderer::SetRenderState(D3DRS_ALPHABLENDENABLE, bpmem.blendmode.blendenable); Renderer::SetRenderState(D3DRS_ALPHABLENDENABLE, bpmem.blendmode.blendenable);
@ -196,15 +196,15 @@ void SetBlendMode(const Bypass &bp)
Renderer::SetRenderState(D3DRS_BLENDOP, bpmem.blendmode.subtract ? D3DBLENDOP_SUBTRACT : D3DBLENDOP_ADD); Renderer::SetRenderState(D3DRS_BLENDOP, bpmem.blendmode.subtract ? D3DBLENDOP_SUBTRACT : D3DBLENDOP_ADD);
} }
} }
void SetDitherMode(const Bypass &bp) void SetDitherMode(const BPCmd &bp)
{ {
Renderer::SetRenderState(D3DRS_DITHERENABLE,bpmem.blendmode.dither); Renderer::SetRenderState(D3DRS_DITHERENABLE,bpmem.blendmode.dither);
} }
void SetLogicOpMode(const Bypass &bp) void SetLogicOpMode(const BPCmd &bp)
{ {
// Logic op blending. D3D can't do this but can fake some modes. // Logic op blending. D3D can't do this but can fake some modes.
} }
void SetColorMask(const Bypass &bp) void SetColorMask(const BPCmd &bp)
{ {
DWORD write = 0; DWORD write = 0;
if (bpmem.blendmode.alphaupdate) if (bpmem.blendmode.alphaupdate)
@ -215,7 +215,7 @@ void SetColorMask(const Bypass &bp)
Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, write); Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, write);
} }
void CopyEFB(const Bypass &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const bool &scaleByHalf) void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const bool &scaleByHalf)
{ {
// TODO: Scale EFBRectangle correctly // TODO: Scale EFBRectangle correctly
@ -223,13 +223,13 @@ void CopyEFB(const Bypass &bp, const EFBRectangle &rc, const u32 &address, const
TextureCache::CopyEFBToRenderTarget(bpmem.copyTexDest<<5, &rec); TextureCache::CopyEFBToRenderTarget(bpmem.copyTexDest<<5, &rec);
} }
void RenderToXFB(const Bypass &bp, const EFBRectangle &rc, const float &yScale, const float &xfbLines, u32 xfbAddr, const u32 &dstWidth, const u32 &dstHeight) void RenderToXFB(const BPCmd &bp, const EFBRectangle &rc, const float &yScale, const float &xfbLines, u32 xfbAddr, const u32 &dstWidth, const u32 &dstHeight)
{ {
Renderer::SwapBuffers(); Renderer::SwapBuffers();
PRIM_LOG("Renderer::SwapBuffers()"); PRIM_LOG("Renderer::SwapBuffers()");
g_VideoInitialize.pCopiedToXFB(); g_VideoInitialize.pCopiedToXFB();
} }
void ClearScreen(const Bypass &bp, const EFBRectangle &rc) void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
{ {
// TODO: Scale EFBRectangle correctly // TODO: Scale EFBRectangle correctly
@ -263,7 +263,7 @@ void ClearScreen(const Bypass &bp, const EFBRectangle &rc)
D3D::dev->Clear(0, NULL, clearflags, col, clearZ, 0); D3D::dev->Clear(0, NULL, clearflags, col, clearZ, 0);
} }
void RestoreRenderState(const Bypass &bp) void RestoreRenderState(const BPCmd &bp)
{ {
//Renderer::SetRenderMode(Renderer::RM_Normal); //Renderer::SetRenderMode(Renderer::RM_Normal);
} }
@ -287,7 +287,7 @@ u8 *GetPointer(const u32 &address)
{ {
return g_VideoInitialize.pGetMemoryPointer(address); return g_VideoInitialize.pGetMemoryPointer(address);
} }
void SetSamplerState(const Bypass &bp) void SetSamplerState(const BPCmd &bp)
{ {
FourTexUnits &tex = bpmem.tex[(bp.address & 0xE0) == 0xA0]; FourTexUnits &tex = bpmem.tex[(bp.address & 0xE0) == 0xA0];
int stage = (bp.address & 3);//(addr>>4)&2; int stage = (bp.address & 3);//(addr>>4)&2;
@ -326,7 +326,7 @@ void SetSamplerState(const Bypass &bp)
//sprintf(temp,"lod %f",tm0.lod_bias/4.0f); //sprintf(temp,"lod %f",tm0.lod_bias/4.0f);
//g_VideoInitialize.pLog(temp); //g_VideoInitialize.pLog(temp);
} }
void SetInterlacingMode(const Bypass &bp) void SetInterlacingMode(const BPCmd &bp)
{ {
// TODO // TODO
} }

View file

@ -47,7 +47,7 @@ void FlushPipeline()
{ {
VertexManager::Flush(); VertexManager::Flush();
} }
void SetGenerationMode(const Bypass &bp) void SetGenerationMode(const BPCmd &bp)
{ {
// none, ccw, cw, ccw // none, ccw, cw, ccw
if (bpmem.genMode.cullmode > 0) if (bpmem.genMode.cullmode > 0)
@ -60,13 +60,13 @@ void SetGenerationMode(const Bypass &bp)
} }
void SetScissor(const Bypass &bp) void SetScissor(const BPCmd &bp)
{ {
if (!Renderer::SetScissorRect()) if (!Renderer::SetScissorRect())
if (bp.address == BPMEM_SCISSORBR) if (bp.address == BPMEM_SCISSORBR)
ERROR_LOG(VIDEO, "bad scissor!"); ERROR_LOG(VIDEO, "bad scissor!");
} }
void SetLineWidth(const Bypass &bp) void SetLineWidth(const BPCmd &bp)
{ {
float fratio = xfregs.rawViewport[0] != 0 ? ((float)Renderer::GetTargetWidth() / EFB_WIDTH) : 1.0f; float fratio = xfregs.rawViewport[0] != 0 ? ((float)Renderer::GetTargetWidth() / EFB_WIDTH) : 1.0f;
if (bpmem.lineptwidth.linesize > 0) if (bpmem.lineptwidth.linesize > 0)
@ -74,7 +74,7 @@ void SetLineWidth(const Bypass &bp)
if (bpmem.lineptwidth.pointsize > 0) if (bpmem.lineptwidth.pointsize > 0)
glPointSize((float)bpmem.lineptwidth.pointsize * fratio / 6.0f); glPointSize((float)bpmem.lineptwidth.pointsize * fratio / 6.0f);
} }
void SetDepthMode(const Bypass &bp) void SetDepthMode(const BPCmd &bp)
{ {
if (bpmem.zmode.testenable) if (bpmem.zmode.testenable)
{ {
@ -89,18 +89,18 @@ void SetDepthMode(const Bypass &bp)
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
} }
} }
void SetBlendMode(const Bypass &bp) void SetBlendMode(const BPCmd &bp)
{ {
Renderer::SetBlendMode(false); Renderer::SetBlendMode(false);
} }
void SetDitherMode(const Bypass &bp) void SetDitherMode(const BPCmd &bp)
{ {
if (bpmem.blendmode.dither) if (bpmem.blendmode.dither)
glEnable(GL_DITHER); glEnable(GL_DITHER);
else else
glDisable(GL_DITHER); glDisable(GL_DITHER);
} }
void SetLogicOpMode(const Bypass &bp) void SetLogicOpMode(const BPCmd &bp)
{ {
if (bpmem.blendmode.logicopenable) if (bpmem.blendmode.logicopenable)
{ {
@ -111,12 +111,12 @@ void SetLogicOpMode(const Bypass &bp)
glDisable(GL_COLOR_LOGIC_OP); glDisable(GL_COLOR_LOGIC_OP);
} }
void SetColorMask(const Bypass &bp) void SetColorMask(const BPCmd &bp)
{ {
Renderer::SetColorMask(); Renderer::SetColorMask();
} }
void CopyEFB(const Bypass &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const bool &scaleByHalf) void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const bool &scaleByHalf)
{ {
// bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format) // bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format)
if (!g_Config.bEFBCopyDisable) if (!g_Config.bEFBCopyDisable)
@ -126,12 +126,12 @@ void CopyEFB(const Bypass &bp, const EFBRectangle &rc, const u32 &address, const
TextureMngr::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc); TextureMngr::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
} }
void RenderToXFB(const Bypass &bp, const EFBRectangle &rc, const float &yScale, const float &xfbLines, u32 xfbAddr, const u32 &dstWidth, const u32 &dstHeight) void RenderToXFB(const BPCmd &bp, const EFBRectangle &rc, const float &yScale, const float &xfbLines, u32 xfbAddr, const u32 &dstWidth, const u32 &dstHeight)
{ {
Renderer::RenderToXFB(xfbAddr, dstWidth, dstHeight, rc); Renderer::RenderToXFB(xfbAddr, dstWidth, dstHeight, rc);
} }
void ClearScreen(const Bypass &bp, const EFBRectangle &rc) void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
{ {
bool colorEnable = bpmem.blendmode.colorupdate; bool colorEnable = bpmem.blendmode.colorupdate;
bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate); bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate);
@ -146,7 +146,7 @@ void ClearScreen(const Bypass &bp, const EFBRectangle &rc)
} }
} }
void RestoreRenderState(const Bypass &bp) void RestoreRenderState(const BPCmd &bp)
{ {
Renderer::RestoreGLState(); Renderer::RestoreGLState();
} }
@ -170,11 +170,11 @@ u8 *GetPointer(const u32 &address)
{ {
return g_VideoInitialize.pGetMemoryPointer(address); return g_VideoInitialize.pGetMemoryPointer(address);
} }
void SetSamplerState(const Bypass &bp) void SetSamplerState(const BPCmd &bp)
{ {
// TODO // TODO
} }
void SetInterlacingMode(const Bypass &bp) void SetInterlacingMode(const BPCmd &bp)
{ {
// TODO // TODO
} }

View file

@ -54,7 +54,6 @@ void Config::Load()
iniFile.Get("Settings", "SafeTextureCache", &bSafeTextureCache, false); // Settings iniFile.Get("Settings", "SafeTextureCache", &bSafeTextureCache, false); // Settings
iniFile.Get("Settings", "ShowFPS", &bShowFPS, false); // Settings iniFile.Get("Settings", "ShowFPS", &bShowFPS, false); // Settings
iniFile.Get("Settings", "OverlayStats", &bOverlayStats, false); iniFile.Get("Settings", "OverlayStats", &bOverlayStats, false);
iniFile.Get("Settings", "OverlayBlendStats", &bOverlayBlendStats, false);
iniFile.Get("Settings", "OverlayProjStats", &bOverlayProjStats, false); iniFile.Get("Settings", "OverlayProjStats", &bOverlayProjStats, false);
iniFile.Get("Settings", "ShowEFBCopyRegions", &bShowEFBCopyRegions, false); iniFile.Get("Settings", "ShowEFBCopyRegions", &bShowEFBCopyRegions, false);
iniFile.Get("Settings", "DLOptimize", &iCompileDLsLevel, 0); iniFile.Get("Settings", "DLOptimize", &iCompileDLsLevel, 0);
@ -148,7 +147,6 @@ void Config::Save()
iniFile.Set("Settings", "SafeTextureCache", bSafeTextureCache); iniFile.Set("Settings", "SafeTextureCache", bSafeTextureCache);
iniFile.Set("Settings", "ShowFPS", bShowFPS); iniFile.Set("Settings", "ShowFPS", bShowFPS);
iniFile.Set("Settings", "OverlayStats", bOverlayStats); iniFile.Set("Settings", "OverlayStats", bOverlayStats);
iniFile.Set("Settings", "OverlayBlendStats", bOverlayBlendStats);
iniFile.Set("Settings", "OverlayProjStats", bOverlayProjStats); iniFile.Set("Settings", "OverlayProjStats", bOverlayProjStats);
iniFile.Set("Settings", "DLOptimize", iCompileDLsLevel); iniFile.Set("Settings", "DLOptimize", iCompileDLsLevel);
iniFile.Set("Settings", "Show", iCompileDLsLevel); iniFile.Set("Settings", "Show", iCompileDLsLevel);

View file

@ -73,7 +73,6 @@ struct Config
// Information // Information
bool bShowFPS; bool bShowFPS;
bool bOverlayStats; bool bOverlayStats;
bool bOverlayBlendStats;
bool bOverlayProjStats; bool bOverlayProjStats;
bool bTexFmtOverlayEnable; bool bTexFmtOverlayEnable;
bool bTexFmtOverlayCenter; bool bTexFmtOverlayCenter;

View file

@ -56,7 +56,6 @@ BEGIN_EVENT_TABLE(GFXConfigDialogOGL,wxDialog)
EVT_CHECKBOX(ID_WIREFRAME, GFXConfigDialogOGL::AdvancedSettingsChanged) EVT_CHECKBOX(ID_WIREFRAME, GFXConfigDialogOGL::AdvancedSettingsChanged)
EVT_CHECKBOX(ID_SHOWFPS, GFXConfigDialogOGL::AdvancedSettingsChanged) EVT_CHECKBOX(ID_SHOWFPS, GFXConfigDialogOGL::AdvancedSettingsChanged)
EVT_CHECKBOX(ID_STATISTICS, GFXConfigDialogOGL::AdvancedSettingsChanged) EVT_CHECKBOX(ID_STATISTICS, GFXConfigDialogOGL::AdvancedSettingsChanged)
EVT_CHECKBOX(ID_BLENDSTATS, GFXConfigDialogOGL::AdvancedSettingsChanged)
EVT_CHECKBOX(ID_PROJSTATS, GFXConfigDialogOGL::AdvancedSettingsChanged) EVT_CHECKBOX(ID_PROJSTATS, GFXConfigDialogOGL::AdvancedSettingsChanged)
EVT_CHECKBOX(ID_SHOWEFBCOPYREGIONS, GFXConfigDialogOGL::AdvancedSettingsChanged) EVT_CHECKBOX(ID_SHOWEFBCOPYREGIONS, GFXConfigDialogOGL::AdvancedSettingsChanged)
EVT_CHECKBOX(ID_SHADERERRORS, GFXConfigDialogOGL::AdvancedSettingsChanged) EVT_CHECKBOX(ID_SHADERERRORS, GFXConfigDialogOGL::AdvancedSettingsChanged)
@ -100,9 +99,7 @@ GFXConfigDialogOGL::~GFXConfigDialogOGL()
} }
void GFXConfigDialogOGL::OnClose(wxCloseEvent& event) void GFXConfigDialogOGL::OnClose(wxCloseEvent& event)
{ {
g_Config.Save(); //INFO_LOG(CONSOLE, "OnClose");
INFO_LOG(CONSOLE, "OnClose");
// notice that we don't run wxEntryCleanup(); here so the dll will still be loaded // notice that we don't run wxEntryCleanup(); here so the dll will still be loaded
/* JP: Yes, it seems like Close() does not do that. It only runs EndModal() or something /* JP: Yes, it seems like Close() does not do that. It only runs EndModal() or something
@ -113,18 +110,20 @@ void GFXConfigDialogOGL::OnClose(wxCloseEvent& event)
//EndModal(0); //EndModal(0);
// Allow wxWidgets to close and unload the window // Allow wxWidgets to close and unload the window
event.Skip(); //event.Skip();
CloseWindow();
} }
void GFXConfigDialogOGL::CloseClick(wxCommandEvent& WXUNUSED (event)) void GFXConfigDialogOGL::CloseClick(wxCommandEvent& WXUNUSED (event))
{ {
INFO_LOG(CONSOLE, "CloseClick"); //INFO_LOG(CONSOLE, "CloseClick");
// If we run wxEntryCleanup() the class will be entirely deleted, and the destructor will be run // If we run wxEntryCleanup() the class will be entirely deleted, and the destructor will be run
//g_Config.Save(); //g_Config.Save();
//wxEntryCleanup(); //wxEntryCleanup();
Close(); //Close();
CloseWindow();
} }
/////////////////////////////// ///////////////////////////////
@ -354,8 +353,6 @@ void GFXConfigDialogOGL::CreateGUIControls()
m_ShowFPS->SetValue(g_Config.bShowFPS); m_ShowFPS->SetValue(g_Config.bShowFPS);
m_Statistics = new wxCheckBox(m_PageAdvanced, ID_STATISTICS, wxT("Overlay some statistics"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_Statistics = new wxCheckBox(m_PageAdvanced, ID_STATISTICS, wxT("Overlay some statistics"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_Statistics->SetValue(g_Config.bOverlayStats); m_Statistics->SetValue(g_Config.bOverlayStats);
m_BlendStats = new wxCheckBox(m_PageAdvanced, ID_BLENDSTATS, wxT("Overlay Blend Stats"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_BlendStats->SetValue(g_Config.bOverlayBlendStats);
m_ProjStats = new wxCheckBox(m_PageAdvanced, ID_PROJSTATS, wxT("Overlay Projection Stats"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_ProjStats = new wxCheckBox(m_PageAdvanced, ID_PROJSTATS, wxT("Overlay Projection Stats"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_ProjStats->SetValue(g_Config.bOverlayProjStats); m_ProjStats->SetValue(g_Config.bOverlayProjStats);
m_ShowEFBCopyRegions = new wxCheckBox(m_PageAdvanced, ID_SHOWEFBCOPYREGIONS, wxT("Show EFB Copy Regions"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_ShowEFBCopyRegions = new wxCheckBox(m_PageAdvanced, ID_SHOWEFBCOPYREGIONS, wxT("Show EFB Copy Regions"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
@ -463,11 +460,10 @@ void GFXConfigDialogOGL::CreateGUIControls()
sInfo->Add(m_ShowFPS, wxGBPosition(0, 0), wxGBSpan(1, 2), wxALL, 5); sInfo->Add(m_ShowFPS, wxGBPosition(0, 0), wxGBSpan(1, 2), wxALL, 5);
sInfo->Add(m_ShaderErrors, wxGBPosition(1, 0), wxGBSpan(1, 2), wxALL, 5); sInfo->Add(m_ShaderErrors, wxGBPosition(1, 0), wxGBSpan(1, 2), wxALL, 5);
sInfo->Add(m_Statistics, wxGBPosition(2, 0), wxGBSpan(1, 2), wxALL, 5); sInfo->Add(m_Statistics, wxGBPosition(2, 0), wxGBSpan(1, 2), wxALL, 5);
sInfo->Add(m_BlendStats, wxGBPosition(3, 0), wxGBSpan(1, 2), wxALL, 5); sInfo->Add(m_ProjStats, wxGBPosition(3, 0), wxGBSpan(1, 2), wxALL, 5);
sInfo->Add(m_ProjStats, wxGBPosition(4, 0), wxGBSpan(1, 2), wxALL, 5); sInfo->Add(m_ShowEFBCopyRegions, wxGBPosition(4, 0), wxGBSpan(1, 2), wxALL, 5);
sInfo->Add(m_ShowEFBCopyRegions, wxGBPosition(5, 0), wxGBSpan(1, 2), wxALL, 5); sInfo->Add(m_TexFmtOverlay, wxGBPosition(5, 0), wxGBSpan(1, 1), wxALL, 5);
sInfo->Add(m_TexFmtOverlay, wxGBPosition(6, 0), wxGBSpan(1, 1), wxALL, 5); sInfo->Add(m_TexFmtCenter, wxGBPosition(5, 1), wxGBSpan(1, 1), wxALL, 5);
sInfo->Add(m_TexFmtCenter, wxGBPosition(6, 1), wxGBSpan(1, 1), wxALL, 5);
sbInfo->Add(sInfo); sbInfo->Add(sInfo);
wxBoxSizer *sRenderBoxRow1 = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *sRenderBoxRow1 = new wxBoxSizer(wxHORIZONTAL);
@ -711,9 +707,6 @@ void GFXConfigDialogOGL::AdvancedSettingsChanged(wxCommandEvent& event)
TextureMngr::ClearRenderTargets(); TextureMngr::ClearRenderTargets();
g_Config.bCopyEFBToRAM = false; g_Config.bCopyEFBToRAM = false;
break; break;
case ID_BLENDSTATS:
g_Config.bOverlayBlendStats = m_BlendStats->IsChecked();
break;
case ID_PROJSTATS: case ID_PROJSTATS:
g_Config.bOverlayProjStats = m_ProjStats->IsChecked(); g_Config.bOverlayProjStats = m_ProjStats->IsChecked();
break; break;
@ -725,6 +718,13 @@ void GFXConfigDialogOGL::AdvancedSettingsChanged(wxCommandEvent& event)
UpdateGUI(); UpdateGUI();
} }
void GFXConfigDialogOGL::CloseWindow()
{
// Save the config to INI
g_Config.Save();
EndModal(1);
}
void GFXConfigDialogOGL::UpdateGUI() void GFXConfigDialogOGL::UpdateGUI()
{ {

View file

@ -113,7 +113,6 @@ class GFXConfigDialogOGL : public wxDialog
wxCheckBox *m_ShowFPS; wxCheckBox *m_ShowFPS;
wxCheckBox *m_ShaderErrors; wxCheckBox *m_ShaderErrors;
wxCheckBox *m_Statistics; wxCheckBox *m_Statistics;
wxCheckBox *m_BlendStats;
wxCheckBox *m_ProjStats; wxCheckBox *m_ProjStats;
wxCheckBox *m_ShowEFBCopyRegions; wxCheckBox *m_ShowEFBCopyRegions;
wxCheckBox *m_TexFmtOverlay; wxCheckBox *m_TexFmtOverlay;
@ -171,7 +170,6 @@ class GFXConfigDialogOGL : public wxDialog
ID_SHOWFPS, ID_SHOWFPS,
ID_SHADERERRORS, ID_SHADERERRORS,
ID_STATISTICS, ID_STATISTICS,
ID_BLENDSTATS,
ID_PROJSTATS, ID_PROJSTATS,
ID_SHOWEFBCOPYREGIONS, ID_SHOWEFBCOPYREGIONS,
ID_TEXFMTOVERLAY, ID_TEXFMTOVERLAY,
@ -214,6 +212,7 @@ class GFXConfigDialogOGL : public wxDialog
void EditShaderClick(wxCommandEvent& event); void EditShaderClick(wxCommandEvent& event);
void GeneralSettingsChanged(wxCommandEvent& event); void GeneralSettingsChanged(wxCommandEvent& event);
void AdvancedSettingsChanged(wxCommandEvent& event); void AdvancedSettingsChanged(wxCommandEvent& event);
void CloseWindow();
}; };
#endif // _OGL_CONFIGDIALOG_H_ #endif // _OGL_CONFIGDIALOG_H_

View file

@ -67,7 +67,7 @@ Make AA apply instantly during gameplay if possible
GFXConfigDialogOGL *m_ConfigFrame = NULL; GFXConfigDialogOGL *m_ConfigFrame = NULL;
#include "Debugger/Debugger.h" #include "Debugger/Debugger.h"
GFXDebuggerOGL *m_DebuggerFrame = NULL; GFXDebuggerOGL *m_DebuggerFrame = NULL;
#endif #endif // HAVE_WX
#include "Config.h" #include "Config.h"
#include "LookUpTables.h" #include "LookUpTables.h"
@ -97,6 +97,8 @@ GFXDebuggerOGL *m_DebuggerFrame = NULL;
SVideoInitialize g_VideoInitialize; SVideoInitialize g_VideoInitialize;
PLUGIN_GLOBALS* globals = NULL; PLUGIN_GLOBALS* globals = NULL;
bool allowConfigShow = true;
// Logging // Logging
int GLScissorX, GLScissorY, GLScissorW, GLScissorH; int GLScissorX, GLScissorY, GLScissorW, GLScissorH;
@ -108,6 +110,10 @@ static Common::Event s_swapResponseEvent;
static volatile u32 s_efbAccessRequested = false; static volatile u32 s_efbAccessRequested = false;
static Common::Event s_efbResponseEvent; static Common::Event s_efbResponseEvent;
#if defined(HAVE_WX) && HAVE_WX
#endif // HAVE_WX
void GetDllInfo (PLUGIN_INFO* _PluginInfo) void GetDllInfo (PLUGIN_INFO* _PluginInfo)
{ {
@ -169,13 +175,17 @@ void DllDebugger(HWND _hParent, bool Show) { }
void DllConfig(HWND _hParent) void DllConfig(HWND _hParent)
{ {
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
if (!m_ConfigFrame) //if (!m_ConfigFrame)
if (allowConfigShow) // Prevent user to show more than 1 config window at same time
{
m_ConfigFrame = new GFXConfigDialogOGL(GetParentedWxWindow(_hParent)); m_ConfigFrame = new GFXConfigDialogOGL(GetParentedWxWindow(_hParent));
else if (!m_ConfigFrame->GetParent()->IsShown())
m_ConfigFrame->Close(true); //else if (!m_ConfigFrame->GetParent()->IsShown())
// m_ConfigFrame->Close(true);
#if defined(_WIN32) #if defined(_WIN32)
// Search for avaliable resolutions // Search for avaliable resolutions
DWORD iModeNum = 0; DWORD iModeNum = 0;
@ -294,13 +304,16 @@ void DllConfig(HWND _hParent)
} }
// Only allow one open at a time // Only allow one open at a time
if (!m_ConfigFrame->IsShown()) //if (!m_ConfigFrame->IsShown())
{ //{
allowConfigShow = false;
m_ConfigFrame->CreateGUIControls(); m_ConfigFrame->CreateGUIControls();
m_ConfigFrame->ShowModal(); allowConfigShow = m_ConfigFrame->ShowModal() == 1 ? true : false;
} }
else //}
m_ConfigFrame->Hide(); //else
// m_ConfigFrame->Hide();
#endif #endif
} }