Implement proper thread naming on linux. This fixes a segmentation fault with thte wiimote new configuration dialog when a thread was named without first calling ThreadInit.

Also take care of some more eols.


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5843 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Glenn Rice 2010-07-06 16:16:07 +00:00
parent e9e12ff100
commit 0e2b4d8306
22 changed files with 1456 additions and 1463 deletions

View file

@ -187,7 +187,8 @@ static int wiiuse_connect_single(struct wiimote_t* wm, char* address) {
str2ba(address, &addr.l2_bdaddr);
else
{
bacmp(bdaddr, BDADDR_ANY);
if (bacmp(bdaddr, BDADDR_ANY) == 0)
return 0;
/* use address of device discovered */
addr.l2_bdaddr = *bdaddr;

View file

@ -122,7 +122,7 @@ bool AlsaSound::AlsaInit()
ERROR_LOG(AUDIO, "Sample format not available: %s\n", snd_strerror(err));
return false;
}
err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &sample_rate, &dir);
if (err < 0)
{

View file

@ -37,11 +37,6 @@ namespace Common
#ifdef _WIN32
void InitThreading()
{
// Nothing to do in Win32 build.
}
CriticalSection::CriticalSection(int spincount)
{
if (spincount)
@ -306,7 +301,8 @@ namespace Common
#else // !WIN32, so must be POSIX threads
pthread_key_t threadname_key;
static pthread_key_t threadname_key;
static pthread_once_t threadname_key_once = PTHREAD_ONCE_INIT;
CriticalSection::CriticalSection(int spincount_unused)
{
@ -411,17 +407,6 @@ namespace Common
{
return pthread_equal(pthread_self(), thread_id) != 0;
}
void InitThreading() {
static int thread_init_done = 0;
if (thread_init_done)
return;
if (pthread_key_create(&threadname_key, NULL/*free*/) != 0)
perror("Unable to create thread name key: ");
thread_init_done++;
}
void SleepCurrentThread(int ms)
{
@ -433,16 +418,26 @@ namespace Common
usleep(1000 * 1);
}
static void FreeThreadName(void* threadname)
{
free(threadname);
}
static void ThreadnameKeyAlloc()
{
pthread_key_create(&threadname_key, FreeThreadName);
}
void SetCurrentThreadName(const TCHAR* szThreadName)
{
char *name = strdup(szThreadName);
// pthread_setspecific returns 0 on success
// free the string from strdup if fails
// creates a memory leak if it actually doesn't fail
// since we don't delete it once we delete the thread
// we are using a single threadname_key anyway for all threads
if(!pthread_setspecific(threadname_key, name))
free(name);
pthread_once(&threadname_key_once, ThreadnameKeyAlloc);
void* threadname;
if ((threadname = pthread_getspecific(threadname_key)) != NULL)
free(threadname);
pthread_setspecific(threadname_key, strdup(szThreadName));
INFO_LOG(COMMON, "%s(%s)\n", __FUNCTION__, szThreadName);
}

View file

@ -203,7 +203,6 @@ namespace Common
#endif
};
void InitThreading();
void SleepCurrentThread(int ms);
void SwitchCurrentThread(); // On Linux, this is equal to sleep 1ms

View file

@ -190,8 +190,6 @@ bool Init()
CPluginManager &pManager = CPluginManager::GetInstance();
SCoreStartupParameter &_CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter;
Common::InitThreading();
g_CoreStartupParameter = _CoreParameter;
// FIXME DEBUG_LOG(BOOT, dump_params());
Host_SetWaitCursor(true);

View file

@ -1,21 +1,21 @@
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
// Gekko related unions, structs, ...
//
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
// Gekko related unions, structs, ...
//
#ifndef _LUT_frsqrtex_h_
#define _LUT_frsqrtex_h_

View file

@ -1,167 +1,167 @@
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "PPCCache.h"
#include "../HW/Memmap.h"
#include "PowerPC.h"
namespace PowerPC
{
u32 plru_mask[8] = {11,11,19,19,37,37,69,69};
u32 plru_value[8] = {11,3,17,1,36,4,64,0};
InstructionCache::InstructionCache()
{
for (u32 m = 0; m < 0xff; m++)
{
u32 w = 0;
while (m & (1<<w)) w++;
way_from_valid[m] = w;
}
for (u32 m = 0; m < 128; m++)
{
u32 b[7];
for (int i = 0; i < 7; i++) b[i] = m & (1<<i);
u32 w;
if (b[0])
if (b[2])
if (b[6])
w = 7;
else
w = 6;
else
if (b[5])
w = 5;
else
w = 4;
else
if (b[1])
if (b[4])
w = 3;
else
w = 2;
else
if (b[3])
w = 1;
else
w = 0;
way_from_plru[m] = w;
}
}
void InstructionCache::Reset()
{
memset(valid, 0, sizeof(valid));
memset(plru, 0, sizeof(plru));
#ifdef FAST_ICACHE
memset(lookup_table, 0xff, sizeof(lookup_table));
memset(lookup_table_ex, 0xff, sizeof(lookup_table_ex));
memset(lookup_table_vmem, 0xff, sizeof(lookup_table_vmem));
#endif
}
void InstructionCache::Invalidate(u32 addr)
{
if (!HID0.ICE)
return;
// invalidates the whole set
u32 set = (addr >> 5) & 0x7f;
#ifdef FAST_ICACHE
for (int i = 0; i < 8; i++)
if (valid[set] & (1<<i))
{
if (tags[set][i] & (ICACHE_VMEM_BIT >> 12))
lookup_table_vmem[((tags[set][i] << 7) | set) & 0xfffff] = 0xff;
else if (tags[set][i] & (ICACHE_EXRAM_BIT >> 12))
lookup_table_ex[((tags[set][i] << 7) | set) & 0x1fffff] = 0xff;
else
lookup_table[((tags[set][i] << 7) | set) & 0xfffff] = 0xff;
}
#endif
valid[set] = 0;
}
u32 InstructionCache::ReadInstruction(u32 addr)
{
if (!HID0.ICE) // instuction cache is disabled
return Memory::ReadUnchecked_U32(addr);
u32 set = (addr >> 5) & 0x7f;
u32 tag = addr >> 12;
#ifdef FAST_ICACHE
u32 t;
if (addr & ICACHE_VMEM_BIT)
{
t = lookup_table_vmem[(addr>>5) & 0xfffff];
}
else if (addr & ICACHE_EXRAM_BIT)
{
t = lookup_table_ex[(addr>>5) & 0x1fffff];
}
else
{
t = lookup_table[(addr>>5) & 0xfffff];
}
#else
u32 t = 0xff;
for (u32 i = 0; i < 8; i++)
if (tags[set][i] == tag && (valid[set] & (1<<i)))
{
t = i;
break;
}
#endif
if (t == 0xff) // load to the cache
{
if (HID0.ILOCK) // instruction cache is locked
return Memory::ReadUnchecked_U32(addr);
// select a way
if (valid[set] != 0xff)
t = way_from_valid[valid[set]];
else
t = way_from_plru[plru[set]];
// load
u8 *p = Memory::GetPointer(addr & ~0x1f);
memcpy(data[set][t], p, 32);
#ifdef FAST_ICACHE
if (valid[set] & (1<<t))
{
if (tags[set][t] & (ICACHE_VMEM_BIT >> 12))
lookup_table_vmem[((tags[set][t] << 7) | set) & 0xfffff] = 0xff;
else if (tags[set][t] & (ICACHE_EXRAM_BIT >> 12))
lookup_table_ex[((tags[set][t] << 7) | set) & 0x1fffff] = 0xff;
else
lookup_table[((tags[set][t] << 7) | set) & 0xfffff] = 0xff;
}
if (addr & ICACHE_VMEM_BIT)
lookup_table_vmem[(addr>>5) & 0xfffff] = t;
else if (addr & ICACHE_EXRAM_BIT)
lookup_table_ex[(addr>>5) & 0x1fffff] = t;
else
lookup_table[(addr>>5) & 0xfffff] = t;
#endif
tags[set][t] = tag;
valid[set] |= 1<<t;
}
// update plru
plru[set] = (plru[set] & ~plru_mask[t]) | plru_value[t];
u32 res = Common::swap32(data[set][t][(addr>>2)&7]);
return res;
}
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "PPCCache.h"
#include "../HW/Memmap.h"
#include "PowerPC.h"
namespace PowerPC
{
u32 plru_mask[8] = {11,11,19,19,37,37,69,69};
u32 plru_value[8] = {11,3,17,1,36,4,64,0};
InstructionCache::InstructionCache()
{
for (u32 m = 0; m < 0xff; m++)
{
u32 w = 0;
while (m & (1<<w)) w++;
way_from_valid[m] = w;
}
for (u32 m = 0; m < 128; m++)
{
u32 b[7];
for (int i = 0; i < 7; i++) b[i] = m & (1<<i);
u32 w;
if (b[0])
if (b[2])
if (b[6])
w = 7;
else
w = 6;
else
if (b[5])
w = 5;
else
w = 4;
else
if (b[1])
if (b[4])
w = 3;
else
w = 2;
else
if (b[3])
w = 1;
else
w = 0;
way_from_plru[m] = w;
}
}
void InstructionCache::Reset()
{
memset(valid, 0, sizeof(valid));
memset(plru, 0, sizeof(plru));
#ifdef FAST_ICACHE
memset(lookup_table, 0xff, sizeof(lookup_table));
memset(lookup_table_ex, 0xff, sizeof(lookup_table_ex));
memset(lookup_table_vmem, 0xff, sizeof(lookup_table_vmem));
#endif
}
void InstructionCache::Invalidate(u32 addr)
{
if (!HID0.ICE)
return;
// invalidates the whole set
u32 set = (addr >> 5) & 0x7f;
#ifdef FAST_ICACHE
for (int i = 0; i < 8; i++)
if (valid[set] & (1<<i))
{
if (tags[set][i] & (ICACHE_VMEM_BIT >> 12))
lookup_table_vmem[((tags[set][i] << 7) | set) & 0xfffff] = 0xff;
else if (tags[set][i] & (ICACHE_EXRAM_BIT >> 12))
lookup_table_ex[((tags[set][i] << 7) | set) & 0x1fffff] = 0xff;
else
lookup_table[((tags[set][i] << 7) | set) & 0xfffff] = 0xff;
}
#endif
valid[set] = 0;
}
u32 InstructionCache::ReadInstruction(u32 addr)
{
if (!HID0.ICE) // instuction cache is disabled
return Memory::ReadUnchecked_U32(addr);
u32 set = (addr >> 5) & 0x7f;
u32 tag = addr >> 12;
#ifdef FAST_ICACHE
u32 t;
if (addr & ICACHE_VMEM_BIT)
{
t = lookup_table_vmem[(addr>>5) & 0xfffff];
}
else if (addr & ICACHE_EXRAM_BIT)
{
t = lookup_table_ex[(addr>>5) & 0x1fffff];
}
else
{
t = lookup_table[(addr>>5) & 0xfffff];
}
#else
u32 t = 0xff;
for (u32 i = 0; i < 8; i++)
if (tags[set][i] == tag && (valid[set] & (1<<i)))
{
t = i;
break;
}
#endif
if (t == 0xff) // load to the cache
{
if (HID0.ILOCK) // instruction cache is locked
return Memory::ReadUnchecked_U32(addr);
// select a way
if (valid[set] != 0xff)
t = way_from_valid[valid[set]];
else
t = way_from_plru[plru[set]];
// load
u8 *p = Memory::GetPointer(addr & ~0x1f);
memcpy(data[set][t], p, 32);
#ifdef FAST_ICACHE
if (valid[set] & (1<<t))
{
if (tags[set][t] & (ICACHE_VMEM_BIT >> 12))
lookup_table_vmem[((tags[set][t] << 7) | set) & 0xfffff] = 0xff;
else if (tags[set][t] & (ICACHE_EXRAM_BIT >> 12))
lookup_table_ex[((tags[set][t] << 7) | set) & 0x1fffff] = 0xff;
else
lookup_table[((tags[set][t] << 7) | set) & 0xfffff] = 0xff;
}
if (addr & ICACHE_VMEM_BIT)
lookup_table_vmem[(addr>>5) & 0xfffff] = t;
else if (addr & ICACHE_EXRAM_BIT)
lookup_table_ex[(addr>>5) & 0x1fffff] = t;
else
lookup_table[(addr>>5) & 0xfffff] = t;
#endif
tags[set][t] = tag;
valid[set] |= 1<<t;
}
// update plru
plru[set] = (plru[set] & ~plru_mask[t]) | plru_value[t];
u32 res = Common::swap32(data[set][t][(addr>>2)&7]);
return res;
}
}

View file

@ -1,28 +1,28 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _BPMEMLOADER_H_
#define _BPMEMLOADER_H_
#include "Common.h"
#include "../../../Core/VideoCommon/Src/BPMemory.h"
void InitBPMemory();
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _BPMEMLOADER_H_
#define _BPMEMLOADER_H_
#include "Common.h"
#include "../../../Core/VideoCommon/Src/BPMemory.h"
void InitBPMemory();
#endif

View file

@ -1,27 +1,27 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _CPMEMLOADER_H_
#define _CPMEMLOADER_H_
#include "Common.h"
#include "../../../Core/VideoCommon/Src/CPMemory.h"
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _CPMEMLOADER_H_
#define _CPMEMLOADER_H_
#include "Common.h"
#include "../../../Core/VideoCommon/Src/CPMemory.h"
#endif

View file

@ -1,42 +1,42 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _CLIPPER_H_
#define _CLIPPER_H_
#include "Common.h"
#include "NativeVertexFormat.h"
namespace Clipper
{
void Init();
void SetViewOffset();
void ProcessTriangle(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2);
void ProcessLine(OutputVertexData *v0, OutputVertexData *v1);
bool CullTest(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2, bool &backface);
void PerspectiveDivide(OutputVertexData *vertex);
}
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _CLIPPER_H_
#define _CLIPPER_H_
#include "Common.h"
#include "NativeVertexFormat.h"
namespace Clipper
{
void Init();
void SetViewOffset();
void ProcessTriangle(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2);
void ProcessLine(OutputVertexData *v0, OutputVertexData *v1);
bool CullTest(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2, bool &backface);
void PerspectiveDivide(OutputVertexData *vertex);
}
#endif

View file

@ -1,37 +1,37 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _DEBUGUTIL_H
#define _DEBUGUTIL_H
namespace DebugUtil
{
void Init();
void GetTextureBGRA(u8 *dst, u32 texmap, s32 mip, int width, int height);
void DumpActiveTextures();
void OnObjectBegin();
void OnObjectEnd();
void OnFrameEnd();
void DrawObjectBuffer(s16 x, s16 y, u8 *color, int buffer, const char *name);
}
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _DEBUGUTIL_H
#define _DEBUGUTIL_H
namespace DebugUtil
{
void Init();
void GetTextureBGRA(u8 *dst, u32 texmap, s32 mip, int width, int height);
void DumpActiveTextures();
void OnObjectBegin();
void OnObjectEnd();
void OnFrameEnd();
void DrawObjectBuffer(s16 x, s16 y, u8 *color, int buffer, const char *name);
}
#endif

View file

@ -1,32 +1,32 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _EFB_COPY_H_
#define _EFB_COPY_H_
#include "Common.h"
namespace EfbCopy
{
// Copy the EFB to RAM as a texture format or XFB
// Clear the EFB if needed
void CopyEfb();
}
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _EFB_COPY_H_
#define _EFB_COPY_H_
#include "Common.h"
namespace EfbCopy
{
// Copy the EFB to RAM as a texture format or XFB
// Clear the EFB if needed
void CopyEfb();
}
#endif

View file

@ -1,50 +1,50 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _SETUPUNIT_H_
#define _SETUPUNIT_H_
#include "Common.h"
#include "NativeVertexFormat.h"
class SetupUnit
{
u8 m_PrimType;
int m_VertexCounter;
OutputVertexData m_Vertices[3];
OutputVertexData *m_VertPointer[3];
OutputVertexData *m_VertWritePointer;
void SetupQuad();
void SetupTriangle();
void SetupTriStrip();
void SetupTriFan();
void SetupLine();
void SetupLineStrip();
void SetupPoint();
public:
void Init(u8 primitiveType);
OutputVertexData* GetVertex() { return m_VertWritePointer; }
void SetupVertex();
};
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _SETUPUNIT_H_
#define _SETUPUNIT_H_
#include "Common.h"
#include "NativeVertexFormat.h"
class SetupUnit
{
u8 m_PrimType;
int m_VertexCounter;
OutputVertexData m_Vertices[3];
OutputVertexData *m_VertPointer[3];
OutputVertexData *m_VertWritePointer;
void SetupQuad();
void SetupTriangle();
void SetupTriStrip();
void SetupTriFan();
void SetupLine();
void SetupLineStrip();
void SetupPoint();
public:
void Init(u8 primitiveType);
OutputVertexData* GetVertex() { return m_VertWritePointer; }
void SetupVertex();
};
#endif

View file

@ -1,29 +1,29 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _OPCODEDECODER_H_
#define _OPCODEDECODER_H_
#include "Common.h"
namespace TextureEncoder
{
void Encode(u8 *dest_ptr);
}
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _OPCODEDECODER_H_
#define _OPCODEDECODER_H_
#include "Common.h"
namespace TextureEncoder
{
void Encode(u8 *dest_ptr);
}
#endif

View file

@ -1,32 +1,32 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _TEXTURESAMPLER_H_
#define _TEXTURESAMPLER_H_
#include "Common.h"
namespace TextureSampler
{
void Sample(s32 s, s32 t, s32 lod, bool linear, u8 texmap, u8 *sample);
void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8 *sample);
}
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _TEXTURESAMPLER_H_
#define _TEXTURESAMPLER_H_
#include "Common.h"
namespace TextureSampler
{
void Sample(s32 s, s32 t, s32 lod, bool linear, u8 texmap, u8 *sample);
void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8 *sample);
}
#endif

View file

@ -1,494 +1,494 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include <math.h>
#include "TransformUnit.h"
#include "XFMemLoader.h"
#include "CPMemLoader.h"
#include "BPMemLoader.h"
#include "NativeVertexFormat.h"
#include "../../Plugin_VideoDX9/Src/Vec3.h"
namespace TransformUnit
{
void MultiplyVec2Mat24(const Vec3 &vec, const float *mat, Vec3 &result)
{
result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] + mat[3];
result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] + mat[7];
}
void MultiplyVec2Mat34(const Vec3 &vec, const float *mat, Vec3 &result)
{
result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] + mat[3];
result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] + mat[7];
result.z = mat[8] * vec.x + mat[9] * vec.y + mat[10] + mat[11];
}
void MultiplyVec3Mat33(const Vec3 &vec, const float *mat, Vec3 &result)
{
result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] * vec.z;
result.y = mat[3] * vec.x + mat[4] * vec.y + mat[5] * vec.z;
result.z = mat[6] * vec.x + mat[7] * vec.y + mat[8] * vec.z;
}
void MultiplyVec3Mat34(const Vec3 &vec, const float *mat, Vec3 &result)
{
result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] * vec.z + mat[3];
result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] * vec.z + mat[7];
result.z = mat[8] * vec.x + mat[9] * vec.y + mat[10] * vec.z + mat[11];
}
void MultipleVec3Perspective(const Vec3 &vec, const float *proj, Vec4 &result)
{
result.x = proj[0] * vec.x + proj[1] * vec.z;
result.y = proj[2] * vec.y + proj[3] * vec.z;
//result.z = (proj[4] * vec.z + proj[5]);
result.z = (proj[4] * vec.z + proj[5]) * (1.0f - (float)1e-7);
result.w = -vec.z;
}
void MultipleVec3Ortho(const Vec3 &vec, const float *proj, Vec4 &result)
{
result.x = proj[0] * vec.x + proj[1];
result.y = proj[2] * vec.y + proj[3];
result.z = proj[4] * vec.z + proj[5];
result.w = 1;
}
void TransformPosition(const InputVertexData *src, OutputVertexData *dst)
{
const float* mat = (const float*)&xfregs.posMatrices[src->posMtx * 4];
MultiplyVec3Mat34(src->position, mat, dst->mvPosition);
if (xfregs.projection[6] == 0)
{
MultipleVec3Perspective(dst->mvPosition, xfregs.projection, dst->projectedPosition);
}
else
{
MultipleVec3Ortho(dst->mvPosition, xfregs.projection, dst->projectedPosition);
}
}
void TransformNormal(const InputVertexData *src, bool nbt, OutputVertexData *dst)
{
const float* mat = (const float*)&xfregs.normalMatrices[(src->posMtx & 31) * 3];
if (nbt)
{
MultiplyVec3Mat33(src->normal[0], mat, dst->normal[0]);
MultiplyVec3Mat33(src->normal[1], mat, dst->normal[1]);
MultiplyVec3Mat33(src->normal[2], mat, dst->normal[2]);
dst->normal[0].normalize();
}
else
{
MultiplyVec3Mat33(src->normal[0], mat, dst->normal[0]);
dst->normal[0].normalize();
}
}
inline void TransformTexCoordRegular(const TexMtxInfo &texinfo, int coordNum, bool specialCase, const InputVertexData *srcVertex, OutputVertexData *dstVertex)
{
const Vec3 *src;
switch (texinfo.sourcerow)
{
case XF_SRCGEOM_INROW:
src = &srcVertex->position;
break;
case XF_SRCNORMAL_INROW:
src = &srcVertex->normal[0];
break;
case XF_SRCBINORMAL_T_INROW:
src = &srcVertex->normal[1];
break;
case XF_SRCBINORMAL_B_INROW:
src = &srcVertex->normal[2];
break;
default:
_assert_(texinfo.sourcerow >= XF_SRCTEX0_INROW && texinfo.sourcerow <= XF_SRCTEX7_INROW);
src = (Vec3*)srcVertex->texCoords[texinfo.sourcerow - XF_SRCTEX0_INROW];
break;
}
const float *mat = (const float*)&xfregs.posMatrices[srcVertex->texMtx[coordNum] * 4];
Vec3 *dst = &dstVertex->texCoords[coordNum];
if (texinfo.inputform == XF_TEXINPUT_AB11)
{
MultiplyVec2Mat34(*src, mat, *dst);
}
else
{
MultiplyVec3Mat34(*src, mat, *dst);
}
if (xfregs.dualTexTrans)
{
Vec3 tempCoord;
// normalize
const PostMtxInfo &postInfo = xfregs.postMtxInfo[coordNum];
const float *postMat = (const float*)&xfregs.postMatrices[postInfo.index * 4];
if (specialCase)
{
// no normalization
// q of input is 1
// q of output is unknown
tempCoord.x = dst->x;
tempCoord.y = dst->y;
dst->x = postMat[0] * tempCoord.x + postMat[1] * tempCoord.y + postMat[2] + postMat[3];
dst->y = postMat[4] * tempCoord.x + postMat[5] * tempCoord.y + postMat[6] + postMat[7];
dst->z = 1.0f;
}
else
{
if (postInfo.normalize)
tempCoord = dst->normalized();
else
tempCoord = *dst;
MultiplyVec3Mat34(tempCoord, postMat, *dst);
}
}
}
struct LightPointer
{
u32 reserved[3];
u8 color[4];
Vec3 cosatt;
Vec3 distatt;
Vec3 pos;
Vec3 dir;
};
inline void AddIntegerColor(const u8 *src, Vec3 &dst)
{
dst.x += src[1];
dst.y += src[2];
dst.z += src[3];
}
inline void AddScaledIntegerColor(const u8 *src, float scale, Vec3 &dst)
{
dst.x += src[1] * scale;
dst.y += src[2] * scale;
dst.z += src[3] * scale;
}
inline float Clamp(float val, float a, float b)
{
return val<a?a:val>b?b:val;
}
inline float SafeDivide(float n, float d)
{
return (d==0)?(n>0?1:0):n/d;
}
void LightColor(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChannel &chan, Vec3 &lightCol)
{
const LightPointer *light = (const LightPointer*)&xfregs.lights[0x10*lightNum];
if (!(chan.attnfunc & 1)) {
// atten disabled
switch (chan.diffusefunc) {
case LIGHTDIF_NONE:
AddIntegerColor(light->color, lightCol);
break;
case LIGHTDIF_SIGN:
{
Vec3 ldir = (light->pos - pos).normalized();
float diffuse = ldir * normal;
AddScaledIntegerColor(light->color, diffuse, lightCol);
}
break;
case LIGHTDIF_CLAMP:
{
Vec3 ldir = (light->pos - pos).normalized();
float diffuse = max(0.0f, ldir * normal);
AddScaledIntegerColor(light->color, diffuse, lightCol);
}
break;
default: _assert_(0);
}
}
else { // spec and spot
// not sure about divide by zero checks
Vec3 ldir = light->pos - pos;
float attn;
if (chan.attnfunc == 3) { // spot
float dist2 = ldir.length2();
float dist = sqrtf(dist2);
ldir = ldir / dist;
attn = max(0.0f, ldir * light->dir);
float cosAtt = light->cosatt.x + (light->cosatt.y * attn) + (light->cosatt.z * attn * attn);
float distAtt = light->distatt.x + (light->distatt.y * dist) + (light->distatt.z * dist2);
attn = SafeDivide(max(0.0f, cosAtt), distAtt);
}
else if (chan.attnfunc == 1) { // specular
// donko - what is going on here? 655.36 is a guess but seems about right.
attn = (light->pos * normal) > -655.36 ? max(0.0f, (light->dir * normal)) : 0;
ldir.set(1.0f, attn, attn * attn);
float cosAtt = max(0.0f, light->cosatt * ldir);
float distAtt = light->distatt * ldir;
attn = SafeDivide(max(0.0f, cosAtt), distAtt);
} else {
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include <math.h>
#include "TransformUnit.h"
#include "XFMemLoader.h"
#include "CPMemLoader.h"
#include "BPMemLoader.h"
#include "NativeVertexFormat.h"
#include "../../Plugin_VideoDX9/Src/Vec3.h"
namespace TransformUnit
{
void MultiplyVec2Mat24(const Vec3 &vec, const float *mat, Vec3 &result)
{
result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] + mat[3];
result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] + mat[7];
}
void MultiplyVec2Mat34(const Vec3 &vec, const float *mat, Vec3 &result)
{
result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] + mat[3];
result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] + mat[7];
result.z = mat[8] * vec.x + mat[9] * vec.y + mat[10] + mat[11];
}
void MultiplyVec3Mat33(const Vec3 &vec, const float *mat, Vec3 &result)
{
result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] * vec.z;
result.y = mat[3] * vec.x + mat[4] * vec.y + mat[5] * vec.z;
result.z = mat[6] * vec.x + mat[7] * vec.y + mat[8] * vec.z;
}
void MultiplyVec3Mat34(const Vec3 &vec, const float *mat, Vec3 &result)
{
result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] * vec.z + mat[3];
result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] * vec.z + mat[7];
result.z = mat[8] * vec.x + mat[9] * vec.y + mat[10] * vec.z + mat[11];
}
void MultipleVec3Perspective(const Vec3 &vec, const float *proj, Vec4 &result)
{
result.x = proj[0] * vec.x + proj[1] * vec.z;
result.y = proj[2] * vec.y + proj[3] * vec.z;
//result.z = (proj[4] * vec.z + proj[5]);
result.z = (proj[4] * vec.z + proj[5]) * (1.0f - (float)1e-7);
result.w = -vec.z;
}
void MultipleVec3Ortho(const Vec3 &vec, const float *proj, Vec4 &result)
{
result.x = proj[0] * vec.x + proj[1];
result.y = proj[2] * vec.y + proj[3];
result.z = proj[4] * vec.z + proj[5];
result.w = 1;
}
void TransformPosition(const InputVertexData *src, OutputVertexData *dst)
{
const float* mat = (const float*)&xfregs.posMatrices[src->posMtx * 4];
MultiplyVec3Mat34(src->position, mat, dst->mvPosition);
if (xfregs.projection[6] == 0)
{
MultipleVec3Perspective(dst->mvPosition, xfregs.projection, dst->projectedPosition);
}
else
{
MultipleVec3Ortho(dst->mvPosition, xfregs.projection, dst->projectedPosition);
}
}
void TransformNormal(const InputVertexData *src, bool nbt, OutputVertexData *dst)
{
const float* mat = (const float*)&xfregs.normalMatrices[(src->posMtx & 31) * 3];
if (nbt)
{
MultiplyVec3Mat33(src->normal[0], mat, dst->normal[0]);
MultiplyVec3Mat33(src->normal[1], mat, dst->normal[1]);
MultiplyVec3Mat33(src->normal[2], mat, dst->normal[2]);
dst->normal[0].normalize();
}
else
{
MultiplyVec3Mat33(src->normal[0], mat, dst->normal[0]);
dst->normal[0].normalize();
}
}
inline void TransformTexCoordRegular(const TexMtxInfo &texinfo, int coordNum, bool specialCase, const InputVertexData *srcVertex, OutputVertexData *dstVertex)
{
const Vec3 *src;
switch (texinfo.sourcerow)
{
case XF_SRCGEOM_INROW:
src = &srcVertex->position;
break;
case XF_SRCNORMAL_INROW:
src = &srcVertex->normal[0];
break;
case XF_SRCBINORMAL_T_INROW:
src = &srcVertex->normal[1];
break;
case XF_SRCBINORMAL_B_INROW:
src = &srcVertex->normal[2];
break;
default:
_assert_(texinfo.sourcerow >= XF_SRCTEX0_INROW && texinfo.sourcerow <= XF_SRCTEX7_INROW);
src = (Vec3*)srcVertex->texCoords[texinfo.sourcerow - XF_SRCTEX0_INROW];
break;
}
const float *mat = (const float*)&xfregs.posMatrices[srcVertex->texMtx[coordNum] * 4];
Vec3 *dst = &dstVertex->texCoords[coordNum];
if (texinfo.inputform == XF_TEXINPUT_AB11)
{
MultiplyVec2Mat34(*src, mat, *dst);
}
else
{
MultiplyVec3Mat34(*src, mat, *dst);
}
if (xfregs.dualTexTrans)
{
Vec3 tempCoord;
// normalize
const PostMtxInfo &postInfo = xfregs.postMtxInfo[coordNum];
const float *postMat = (const float*)&xfregs.postMatrices[postInfo.index * 4];
if (specialCase)
{
// no normalization
// q of input is 1
// q of output is unknown
tempCoord.x = dst->x;
tempCoord.y = dst->y;
dst->x = postMat[0] * tempCoord.x + postMat[1] * tempCoord.y + postMat[2] + postMat[3];
dst->y = postMat[4] * tempCoord.x + postMat[5] * tempCoord.y + postMat[6] + postMat[7];
dst->z = 1.0f;
}
else
{
if (postInfo.normalize)
tempCoord = dst->normalized();
else
tempCoord = *dst;
MultiplyVec3Mat34(tempCoord, postMat, *dst);
}
}
}
struct LightPointer
{
u32 reserved[3];
u8 color[4];
Vec3 cosatt;
Vec3 distatt;
Vec3 pos;
Vec3 dir;
};
inline void AddIntegerColor(const u8 *src, Vec3 &dst)
{
dst.x += src[1];
dst.y += src[2];
dst.z += src[3];
}
inline void AddScaledIntegerColor(const u8 *src, float scale, Vec3 &dst)
{
dst.x += src[1] * scale;
dst.y += src[2] * scale;
dst.z += src[3] * scale;
}
inline float Clamp(float val, float a, float b)
{
return val<a?a:val>b?b:val;
}
inline float SafeDivide(float n, float d)
{
return (d==0)?(n>0?1:0):n/d;
}
void LightColor(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChannel &chan, Vec3 &lightCol)
{
const LightPointer *light = (const LightPointer*)&xfregs.lights[0x10*lightNum];
if (!(chan.attnfunc & 1)) {
// atten disabled
switch (chan.diffusefunc) {
case LIGHTDIF_NONE:
AddIntegerColor(light->color, lightCol);
break;
case LIGHTDIF_SIGN:
{
Vec3 ldir = (light->pos - pos).normalized();
float diffuse = ldir * normal;
AddScaledIntegerColor(light->color, diffuse, lightCol);
}
break;
case LIGHTDIF_CLAMP:
{
Vec3 ldir = (light->pos - pos).normalized();
float diffuse = max(0.0f, ldir * normal);
AddScaledIntegerColor(light->color, diffuse, lightCol);
}
break;
default: _assert_(0);
}
}
else { // spec and spot
// not sure about divide by zero checks
Vec3 ldir = light->pos - pos;
float attn;
if (chan.attnfunc == 3) { // spot
float dist2 = ldir.length2();
float dist = sqrtf(dist2);
ldir = ldir / dist;
attn = max(0.0f, ldir * light->dir);
float cosAtt = light->cosatt.x + (light->cosatt.y * attn) + (light->cosatt.z * attn * attn);
float distAtt = light->distatt.x + (light->distatt.y * dist) + (light->distatt.z * dist2);
attn = SafeDivide(max(0.0f, cosAtt), distAtt);
}
else if (chan.attnfunc == 1) { // specular
// donko - what is going on here? 655.36 is a guess but seems about right.
attn = (light->pos * normal) > -655.36 ? max(0.0f, (light->dir * normal)) : 0;
ldir.set(1.0f, attn, attn * attn);
float cosAtt = max(0.0f, light->cosatt * ldir);
float distAtt = light->distatt * ldir;
attn = SafeDivide(max(0.0f, cosAtt), distAtt);
} else {
PanicAlert("LightColor");
return;
}
switch (chan.diffusefunc) {
case LIGHTDIF_NONE:
AddScaledIntegerColor(light->color, attn, lightCol);
break;
case LIGHTDIF_SIGN:
{
float difAttn = ldir * normal;
AddScaledIntegerColor(light->color, attn * difAttn, lightCol);
}
break;
case LIGHTDIF_CLAMP:
{
float difAttn = max(0.0f, ldir * normal);
AddScaledIntegerColor(light->color, attn * difAttn, lightCol);
}
break;
default: _assert_(0);
}
}
}
void LightAlpha(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChannel &chan, float &lightCol)
{
const LightPointer *light = (const LightPointer*)&xfregs.lights[0x10*lightNum];
if (!(chan.attnfunc & 1)) {
// atten disabled
switch (chan.diffusefunc) {
case LIGHTDIF_NONE:
lightCol += light->color[0];
break;
case LIGHTDIF_SIGN:
{
Vec3 ldir = (light->pos - pos).normalized();
float diffuse = ldir * normal;
lightCol += light->color[0] * diffuse;
}
break;
case LIGHTDIF_CLAMP:
{
Vec3 ldir = (light->pos - pos).normalized();
float diffuse = max(0.0f, ldir * normal);
lightCol += light->color[0] * diffuse;
}
break;
default: _assert_(0);
}
}
else { // spec and spot
Vec3 ldir = light->pos - pos;
float attn;
if (chan.attnfunc == 3) { // spot
float dist2 = ldir.length2();
float dist = sqrtf(dist2);
ldir = ldir / dist;
attn = max(0.0f, ldir * light->dir);
float cosAtt = light->cosatt.x + (light->cosatt.y * attn) + (light->cosatt.z * attn * attn);
float distAtt = light->distatt.x + (light->distatt.y * dist) + (light->distatt.z * dist2);
attn = SafeDivide(max(0.0f, cosAtt), distAtt);
}
else /* if (chan.attnfunc == 1) */ { // specular
// donko - what is going on here? 655.36 is a guess but seems about right.
attn = (light->pos * normal) > -655.36 ? max(0.0f, (light->dir * normal)) : 0;
ldir.set(1.0f, attn, attn * attn);
float cosAtt = light->cosatt * ldir;
float distAtt = light->distatt * ldir;
attn = SafeDivide(max(0.0f, cosAtt), distAtt);
}
switch (chan.diffusefunc) {
case LIGHTDIF_NONE:
lightCol += light->color[0] * attn;
break;
case LIGHTDIF_SIGN:
{
float difAttn = ldir * normal;
lightCol += light->color[0] * attn * difAttn;
}
break;
case LIGHTDIF_CLAMP:
{
float difAttn = max(0.0f, ldir * normal);
lightCol += light->color[0] * attn * difAttn;
}
break;
default: _assert_(0);
}
}
}
void TransformColor(const InputVertexData *src, OutputVertexData *dst)
{
for (u32 chan = 0; chan < xfregs.nNumChans; chan++)
{
// abgr
u8 matcolor[4];
u8 chancolor[4];
// color
LitChannel &colorchan = xfregs.color[chan];
if (colorchan.matsource)
*(u32*)matcolor = *(u32*)src->color[chan]; // vertex
else
*(u32*)matcolor = xfregs.matColor[chan];
if (colorchan.enablelighting)
{
Vec3 lightCol;
if (colorchan.ambsource)
{
// vertex
lightCol.x = src->color[chan][1];
lightCol.y = src->color[chan][2];
lightCol.z = src->color[chan][3];
}
else
{
u8 *ambColor = (u8*)&xfregs.ambColor[chan];
lightCol.x = ambColor[1];
lightCol.y = ambColor[2];
lightCol.z = ambColor[3];
}
u8 mask = colorchan.GetFullLightMask();
for (int i = 0; i < 8; ++i) {
if (mask&(1<<i))
LightColor(dst->mvPosition, dst->normal[0], i, colorchan, lightCol);
}
float inv = 1.0f / 255.0f;
chancolor[1] = (u8)(matcolor[1] * Clamp(lightCol.x * inv, 0.0f, 1.0f));
chancolor[2] = (u8)(matcolor[2] * Clamp(lightCol.y * inv, 0.0f, 1.0f));
chancolor[3] = (u8)(matcolor[3] * Clamp(lightCol.z * inv, 0.0f, 1.0f));
}
else
{
*(u32*)chancolor = *(u32*)matcolor;
}
// alpha
LitChannel &alphachan = xfregs.alpha[chan];
if (alphachan.matsource)
matcolor[0] = src->color[chan][0]; // vertex
else
matcolor[0] = xfregs.matColor[chan] & 0xff;
if (xfregs.alpha[chan].enablelighting)
{
float lightCol;
if (alphachan.ambsource)
lightCol = src->color[chan][0]; // vertex
else
lightCol = (float)(xfregs.ambColor[chan] & 0xff);
u8 mask = alphachan.GetFullLightMask();
for (int i = 0; i < 8; ++i) {
if (mask&(1<<i))
LightAlpha(dst->mvPosition, dst->normal[0], i, alphachan, lightCol);
}
chancolor[0] = (u8)(matcolor[0] * Clamp(lightCol / 255.0f, 0.0f, 1.0f));
}
else
{
chancolor[0] = matcolor[0];
}
// abgr -> rgba
*(u32*)dst->color[chan] = Common::swap32(*(u32*)chancolor);
}
}
void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst, bool specialCase)
{
for (u32 coordNum = 0; coordNum < xfregs.numTexGens; coordNum++)
{
const TexMtxInfo &texinfo = xfregs.texMtxInfo[coordNum];
switch (texinfo.texgentype)
{
case XF_TEXGEN_REGULAR:
TransformTexCoordRegular(texinfo, coordNum, specialCase, src, dst);
break;
case XF_TEXGEN_EMBOSS_MAP:
{
const LightPointer *light = (const LightPointer*)&xfregs.lights[0x10*texinfo.embosslightshift];
Vec3 ldir = (light->pos - dst->mvPosition).normalized();
float d1 = ldir * dst->normal[1];
float d2 = ldir * dst->normal[2];
dst->texCoords[coordNum].x = dst->texCoords[texinfo.embosssourceshift].x + d1;
dst->texCoords[coordNum].y = dst->texCoords[texinfo.embosssourceshift].y + d2;
dst->texCoords[coordNum].z = dst->texCoords[texinfo.embosssourceshift].z;
}
break;
case XF_TEXGEN_COLOR_STRGBC0:
_assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
_assert_(texinfo.inputform == XF_TEXINPUT_AB11);
dst->texCoords[coordNum].x = (float)dst->color[0][0] / 255.0f;
dst->texCoords[coordNum].y = (float)dst->color[0][1] / 255.0f;
dst->texCoords[coordNum].z = 1.0f;
break;
case XF_TEXGEN_COLOR_STRGBC1:
_assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
_assert_(texinfo.inputform == XF_TEXINPUT_AB11);
dst->texCoords[coordNum].x = (float)dst->color[1][0] / 255.0f;
dst->texCoords[coordNum].y = (float)dst->color[1][1] / 255.0f;
dst->texCoords[coordNum].z = 1.0f;
break;
default:
ERROR_LOG(VIDEO, "Bad tex gen type %i", texinfo.texgentype);
}
}
for (u32 coordNum = 0; coordNum < xfregs.numTexGens; coordNum++)
{
dst->texCoords[coordNum][0] *= (bpmem.texcoords[coordNum].s.scale_minus_1 + 1);
dst->texCoords[coordNum][1] *= (bpmem.texcoords[coordNum].t.scale_minus_1 + 1);
}
}
}
}
switch (chan.diffusefunc) {
case LIGHTDIF_NONE:
AddScaledIntegerColor(light->color, attn, lightCol);
break;
case LIGHTDIF_SIGN:
{
float difAttn = ldir * normal;
AddScaledIntegerColor(light->color, attn * difAttn, lightCol);
}
break;
case LIGHTDIF_CLAMP:
{
float difAttn = max(0.0f, ldir * normal);
AddScaledIntegerColor(light->color, attn * difAttn, lightCol);
}
break;
default: _assert_(0);
}
}
}
void LightAlpha(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChannel &chan, float &lightCol)
{
const LightPointer *light = (const LightPointer*)&xfregs.lights[0x10*lightNum];
if (!(chan.attnfunc & 1)) {
// atten disabled
switch (chan.diffusefunc) {
case LIGHTDIF_NONE:
lightCol += light->color[0];
break;
case LIGHTDIF_SIGN:
{
Vec3 ldir = (light->pos - pos).normalized();
float diffuse = ldir * normal;
lightCol += light->color[0] * diffuse;
}
break;
case LIGHTDIF_CLAMP:
{
Vec3 ldir = (light->pos - pos).normalized();
float diffuse = max(0.0f, ldir * normal);
lightCol += light->color[0] * diffuse;
}
break;
default: _assert_(0);
}
}
else { // spec and spot
Vec3 ldir = light->pos - pos;
float attn;
if (chan.attnfunc == 3) { // spot
float dist2 = ldir.length2();
float dist = sqrtf(dist2);
ldir = ldir / dist;
attn = max(0.0f, ldir * light->dir);
float cosAtt = light->cosatt.x + (light->cosatt.y * attn) + (light->cosatt.z * attn * attn);
float distAtt = light->distatt.x + (light->distatt.y * dist) + (light->distatt.z * dist2);
attn = SafeDivide(max(0.0f, cosAtt), distAtt);
}
else /* if (chan.attnfunc == 1) */ { // specular
// donko - what is going on here? 655.36 is a guess but seems about right.
attn = (light->pos * normal) > -655.36 ? max(0.0f, (light->dir * normal)) : 0;
ldir.set(1.0f, attn, attn * attn);
float cosAtt = light->cosatt * ldir;
float distAtt = light->distatt * ldir;
attn = SafeDivide(max(0.0f, cosAtt), distAtt);
}
switch (chan.diffusefunc) {
case LIGHTDIF_NONE:
lightCol += light->color[0] * attn;
break;
case LIGHTDIF_SIGN:
{
float difAttn = ldir * normal;
lightCol += light->color[0] * attn * difAttn;
}
break;
case LIGHTDIF_CLAMP:
{
float difAttn = max(0.0f, ldir * normal);
lightCol += light->color[0] * attn * difAttn;
}
break;
default: _assert_(0);
}
}
}
void TransformColor(const InputVertexData *src, OutputVertexData *dst)
{
for (u32 chan = 0; chan < xfregs.nNumChans; chan++)
{
// abgr
u8 matcolor[4];
u8 chancolor[4];
// color
LitChannel &colorchan = xfregs.color[chan];
if (colorchan.matsource)
*(u32*)matcolor = *(u32*)src->color[chan]; // vertex
else
*(u32*)matcolor = xfregs.matColor[chan];
if (colorchan.enablelighting)
{
Vec3 lightCol;
if (colorchan.ambsource)
{
// vertex
lightCol.x = src->color[chan][1];
lightCol.y = src->color[chan][2];
lightCol.z = src->color[chan][3];
}
else
{
u8 *ambColor = (u8*)&xfregs.ambColor[chan];
lightCol.x = ambColor[1];
lightCol.y = ambColor[2];
lightCol.z = ambColor[3];
}
u8 mask = colorchan.GetFullLightMask();
for (int i = 0; i < 8; ++i) {
if (mask&(1<<i))
LightColor(dst->mvPosition, dst->normal[0], i, colorchan, lightCol);
}
float inv = 1.0f / 255.0f;
chancolor[1] = (u8)(matcolor[1] * Clamp(lightCol.x * inv, 0.0f, 1.0f));
chancolor[2] = (u8)(matcolor[2] * Clamp(lightCol.y * inv, 0.0f, 1.0f));
chancolor[3] = (u8)(matcolor[3] * Clamp(lightCol.z * inv, 0.0f, 1.0f));
}
else
{
*(u32*)chancolor = *(u32*)matcolor;
}
// alpha
LitChannel &alphachan = xfregs.alpha[chan];
if (alphachan.matsource)
matcolor[0] = src->color[chan][0]; // vertex
else
matcolor[0] = xfregs.matColor[chan] & 0xff;
if (xfregs.alpha[chan].enablelighting)
{
float lightCol;
if (alphachan.ambsource)
lightCol = src->color[chan][0]; // vertex
else
lightCol = (float)(xfregs.ambColor[chan] & 0xff);
u8 mask = alphachan.GetFullLightMask();
for (int i = 0; i < 8; ++i) {
if (mask&(1<<i))
LightAlpha(dst->mvPosition, dst->normal[0], i, alphachan, lightCol);
}
chancolor[0] = (u8)(matcolor[0] * Clamp(lightCol / 255.0f, 0.0f, 1.0f));
}
else
{
chancolor[0] = matcolor[0];
}
// abgr -> rgba
*(u32*)dst->color[chan] = Common::swap32(*(u32*)chancolor);
}
}
void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst, bool specialCase)
{
for (u32 coordNum = 0; coordNum < xfregs.numTexGens; coordNum++)
{
const TexMtxInfo &texinfo = xfregs.texMtxInfo[coordNum];
switch (texinfo.texgentype)
{
case XF_TEXGEN_REGULAR:
TransformTexCoordRegular(texinfo, coordNum, specialCase, src, dst);
break;
case XF_TEXGEN_EMBOSS_MAP:
{
const LightPointer *light = (const LightPointer*)&xfregs.lights[0x10*texinfo.embosslightshift];
Vec3 ldir = (light->pos - dst->mvPosition).normalized();
float d1 = ldir * dst->normal[1];
float d2 = ldir * dst->normal[2];
dst->texCoords[coordNum].x = dst->texCoords[texinfo.embosssourceshift].x + d1;
dst->texCoords[coordNum].y = dst->texCoords[texinfo.embosssourceshift].y + d2;
dst->texCoords[coordNum].z = dst->texCoords[texinfo.embosssourceshift].z;
}
break;
case XF_TEXGEN_COLOR_STRGBC0:
_assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
_assert_(texinfo.inputform == XF_TEXINPUT_AB11);
dst->texCoords[coordNum].x = (float)dst->color[0][0] / 255.0f;
dst->texCoords[coordNum].y = (float)dst->color[0][1] / 255.0f;
dst->texCoords[coordNum].z = 1.0f;
break;
case XF_TEXGEN_COLOR_STRGBC1:
_assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
_assert_(texinfo.inputform == XF_TEXINPUT_AB11);
dst->texCoords[coordNum].x = (float)dst->color[1][0] / 255.0f;
dst->texCoords[coordNum].y = (float)dst->color[1][1] / 255.0f;
dst->texCoords[coordNum].z = 1.0f;
break;
default:
ERROR_LOG(VIDEO, "Bad tex gen type %i", texinfo.texgentype);
}
}
for (u32 coordNum = 0; coordNum < xfregs.numTexGens; coordNum++)
{
dst->texCoords[coordNum][0] *= (bpmem.texcoords[coordNum].s.scale_minus_1 + 1);
dst->texCoords[coordNum][1] *= (bpmem.texcoords[coordNum].t.scale_minus_1 + 1);
}
}
}

View file

@ -1,37 +1,37 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _TRANSFORM_UNIT_H_
#define _TRANSFORM_UNIT_H_
struct InputVertexData;
struct OutputVertexData;
namespace TransformUnit
{
void MultiplyVec2Mat24(const float *vec, const float *mat, float *result);
void MultiplyVec2Mat34(const float *vec, const float *mat, float *result);
void MultiplyVec3Mat33(const float *vec, const float *mat, float *result);
void MultiplyVec3Mat34(const float *vec, const float *mat, float *result);
void TransformPosition(const InputVertexData *src, OutputVertexData *dst);
void TransformNormal(const InputVertexData *src, bool nbt, OutputVertexData *dst);
void TransformColor(const InputVertexData *src, OutputVertexData *dst);
void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst, bool specialCase);
}
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _TRANSFORM_UNIT_H_
#define _TRANSFORM_UNIT_H_
struct InputVertexData;
struct OutputVertexData;
namespace TransformUnit
{
void MultiplyVec2Mat24(const float *vec, const float *mat, float *result);
void MultiplyVec2Mat34(const float *vec, const float *mat, float *result);
void MultiplyVec3Mat33(const float *vec, const float *mat, float *result);
void MultiplyVec3Mat34(const float *vec, const float *mat, float *result);
void TransformPosition(const InputVertexData *src, OutputVertexData *dst);
void TransformNormal(const InputVertexData *src, bool nbt, OutputVertexData *dst);
void TransformColor(const InputVertexData *src, OutputVertexData *dst);
void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst, bool specialCase);
}
#endif

View file

@ -1,75 +1,75 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include "VertexFormatConverter.h"
namespace VertexFormatConverter
{
void LoadNormal1_Byte(InputVertexData *dst, u8 *src)
{
dst->normal[0].x = (float)(s8)src[0] / 128;
dst->normal[0].y = (float)(s8)src[1] / 128;
dst->normal[0].z = (float)(s8)src[2] / 128;
}
void LoadNormal1_Short(InputVertexData *dst, u8 *src)
{
dst->normal[0].x = (float)((s16*)src)[0] / 32768;
dst->normal[0].y = (float)((s16*)src)[1] / 32768;
dst->normal[0].z = (float)((s16*)src)[2] / 32768;
}
void LoadNormal1_Float(InputVertexData *dst, u8 *src)
{
dst->normal[0].x = ((float*)src)[0];
dst->normal[0].y = ((float*)src)[1];
dst->normal[0].z = ((float*)src)[2];
}
void LoadNormal3_Byte(InputVertexData *dst, u8 *src)
{
for (int i = 0, j = 0; i < 3; i++, j+=3)
{
dst->normal[i].x = (float)(s8)src[j + 0] / 128;
dst->normal[i].y = (float)(s8)src[j + 1] / 128;
dst->normal[i].z = (float)(s8)src[j + 2] / 128;
}
}
void LoadNormal3_Short(InputVertexData *dst, u8 *src)
{
for (int i = 0, j = 0; i < 3; i++, j+=3)
{
dst->normal[i].x = (float)((s16*)src)[j + 0] / 32768;
dst->normal[i].y = (float)((s16*)src)[j + 1] / 32768;
dst->normal[i].z = (float)((s16*)src)[j + 2] / 32768;
}
}
void LoadNormal3_Float(InputVertexData *dst, u8 *src)
{
for (int i = 0, j = 0; i < 3; i++, j+=3)
{
dst->normal[i].x = ((float*)src)[j + 0];
dst->normal[i].y = ((float*)src)[j + 1];
dst->normal[i].z = ((float*)src)[j + 2];
}
}
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include "VertexFormatConverter.h"
namespace VertexFormatConverter
{
void LoadNormal1_Byte(InputVertexData *dst, u8 *src)
{
dst->normal[0].x = (float)(s8)src[0] / 128;
dst->normal[0].y = (float)(s8)src[1] / 128;
dst->normal[0].z = (float)(s8)src[2] / 128;
}
void LoadNormal1_Short(InputVertexData *dst, u8 *src)
{
dst->normal[0].x = (float)((s16*)src)[0] / 32768;
dst->normal[0].y = (float)((s16*)src)[1] / 32768;
dst->normal[0].z = (float)((s16*)src)[2] / 32768;
}
void LoadNormal1_Float(InputVertexData *dst, u8 *src)
{
dst->normal[0].x = ((float*)src)[0];
dst->normal[0].y = ((float*)src)[1];
dst->normal[0].z = ((float*)src)[2];
}
void LoadNormal3_Byte(InputVertexData *dst, u8 *src)
{
for (int i = 0, j = 0; i < 3; i++, j+=3)
{
dst->normal[i].x = (float)(s8)src[j + 0] / 128;
dst->normal[i].y = (float)(s8)src[j + 1] / 128;
dst->normal[i].z = (float)(s8)src[j + 2] / 128;
}
}
void LoadNormal3_Short(InputVertexData *dst, u8 *src)
{
for (int i = 0, j = 0; i < 3; i++, j+=3)
{
dst->normal[i].x = (float)((s16*)src)[j + 0] / 32768;
dst->normal[i].y = (float)((s16*)src)[j + 1] / 32768;
dst->normal[i].z = (float)((s16*)src)[j + 2] / 32768;
}
}
void LoadNormal3_Float(InputVertexData *dst, u8 *src)
{
for (int i = 0, j = 0; i < 3; i++, j+=3)
{
dst->normal[i].x = ((float*)src)[j + 0];
dst->normal[i].y = ((float*)src)[j + 1];
dst->normal[i].z = ((float*)src)[j + 2];
}
}
}

View file

@ -1,35 +1,35 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _VERTEXFORMATCONVERTER_H
#define _VERTEXFORMATCONVERTER_H
#include "NativeVertexFormat.h"
namespace VertexFormatConverter
{
typedef void (*NormalConverter)(InputVertexData*, u8*);
void LoadNormal1_Byte(InputVertexData *dst, u8 *src);
void LoadNormal1_Short(InputVertexData *dst, u8 *src);
void LoadNormal1_Float(InputVertexData *dst, u8 *src);
void LoadNormal3_Byte(InputVertexData *dst, u8 *src);
void LoadNormal3_Short(InputVertexData *dst, u8 *src);
void LoadNormal3_Float(InputVertexData *dst, u8 *src);
}
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _VERTEXFORMATCONVERTER_H
#define _VERTEXFORMATCONVERTER_H
#include "NativeVertexFormat.h"
namespace VertexFormatConverter
{
typedef void (*NormalConverter)(InputVertexData*, u8*);
void LoadNormal1_Byte(InputVertexData *dst, u8 *src);
void LoadNormal1_Short(InputVertexData *dst, u8 *src);
void LoadNormal1_Float(InputVertexData *dst, u8 *src);
void LoadNormal3_Byte(InputVertexData *dst, u8 *src);
void LoadNormal3_Short(InputVertexData *dst, u8 *src);
void LoadNormal3_Float(InputVertexData *dst, u8 *src);
}
#endif

View file

@ -1,78 +1,78 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _VERTEXLOADER_H_
#define _VERTEXLOADER_H_
#include "Common.h"
#include "NativeVertexFormat.h"
#include "VertexFormatConverter.h"
#include "CPMemLoader.h"
class SetupUnit;
class VertexLoader
{
u32 m_VertexSize;
VAT* m_CurrentVat;
TPipelineFunction m_positionLoader;
TPipelineFunction m_normalLoader;
TPipelineFunction m_colorLoader[2];
TPipelineFunction m_texCoordLoader[8];
VertexFormatConverter::NormalConverter m_normalConverter;
InputVertexData m_Vertex;
typedef void (*AttributeLoader)(VertexLoader*, InputVertexData*, u8);
struct AttrLoaderCall
{
AttributeLoader loader;
u8 index;
};
AttrLoaderCall m_AttributeLoaders[1+8+1+1+2+8];
int m_NumAttributeLoaders;
void AddAttributeLoader(AttributeLoader loader, u8 index=0);
// attribute loader functions
static void LoadPosMtx(VertexLoader *vertexLoader, InputVertexData *vertex, u8 unused);
static void LoadTexMtx(VertexLoader *vertexLoader, InputVertexData *vertex, u8 index);
static void LoadPosition(VertexLoader *vertexLoader, InputVertexData *vertex, u8 unused);
static void LoadNormal(VertexLoader *vertexLoader, InputVertexData *vertex, u8 unused);
static void LoadColor(VertexLoader *vertexLoader, InputVertexData *vertex, u8 index);
static void LoadTexCoord(VertexLoader *vertexLoader, InputVertexData *vertex, u8 index);
SetupUnit *m_SetupUnit;
bool m_TexGenSpecialCase;
public:
VertexLoader();
~VertexLoader();
void SetFormat(u8 attributeIndex, u8 primitiveType);
u32 GetVertexSize() { return m_VertexSize; }
void LoadVertex();
};
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _VERTEXLOADER_H_
#define _VERTEXLOADER_H_
#include "Common.h"
#include "NativeVertexFormat.h"
#include "VertexFormatConverter.h"
#include "CPMemLoader.h"
class SetupUnit;
class VertexLoader
{
u32 m_VertexSize;
VAT* m_CurrentVat;
TPipelineFunction m_positionLoader;
TPipelineFunction m_normalLoader;
TPipelineFunction m_colorLoader[2];
TPipelineFunction m_texCoordLoader[8];
VertexFormatConverter::NormalConverter m_normalConverter;
InputVertexData m_Vertex;
typedef void (*AttributeLoader)(VertexLoader*, InputVertexData*, u8);
struct AttrLoaderCall
{
AttributeLoader loader;
u8 index;
};
AttrLoaderCall m_AttributeLoaders[1+8+1+1+2+8];
int m_NumAttributeLoaders;
void AddAttributeLoader(AttributeLoader loader, u8 index=0);
// attribute loader functions
static void LoadPosMtx(VertexLoader *vertexLoader, InputVertexData *vertex, u8 unused);
static void LoadTexMtx(VertexLoader *vertexLoader, InputVertexData *vertex, u8 index);
static void LoadPosition(VertexLoader *vertexLoader, InputVertexData *vertex, u8 unused);
static void LoadNormal(VertexLoader *vertexLoader, InputVertexData *vertex, u8 unused);
static void LoadColor(VertexLoader *vertexLoader, InputVertexData *vertex, u8 index);
static void LoadTexCoord(VertexLoader *vertexLoader, InputVertexData *vertex, u8 index);
SetupUnit *m_SetupUnit;
bool m_TexGenSpecialCase;
public:
VertexLoader();
~VertexLoader();
void SetFormat(u8 attributeIndex, u8 primitiveType);
u32 GetVertexSize() { return m_VertexSize; }
void LoadVertex();
};
#endif

View file

@ -1,20 +1,20 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "NativeVertexFormat.h"
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "NativeVertexFormat.h"
#include "../../../Core/VideoCommon/Src/VertexLoader_Position.h"

View file

@ -1,249 +1,249 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _XFMEMLOADER_H_
#define _XFMEMLOADER_H_
#include "Common.h"
/////////////
// Lighting
/////////////
#define XF_TEXPROJ_ST 0
#define XF_TEXPROJ_STQ 1
#define XF_TEXINPUT_AB11 0
#define XF_TEXINPUT_ABC1 1
#define XF_TEXGEN_REGULAR 0
#define XF_TEXGEN_EMBOSS_MAP 1 // used when bump mapping
#define XF_TEXGEN_COLOR_STRGBC0 2
#define XF_TEXGEN_COLOR_STRGBC1 3
#define XF_SRCGEOM_INROW 0 // input is abc
#define XF_SRCNORMAL_INROW 1 // input is abc
#define XF_SRCCOLORS_INROW 2
#define XF_SRCBINORMAL_T_INROW 3 // input is abc
#define XF_SRCBINORMAL_B_INROW 4 // input is abc
#define XF_SRCTEX0_INROW 5
#define XF_SRCTEX1_INROW 6
#define XF_SRCTEX2_INROW 7
#define XF_SRCTEX3_INROW 8
#define XF_SRCTEX4_INROW 9
#define XF_SRCTEX5_INROW 10
#define XF_SRCTEX6_INROW 11
#define XF_SRCTEX7_INROW 12
#define GX_SRC_REG 0
#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_SIGN 1
#define LIGHTDIF_CLAMP 2
#define LIGHTATTN_SPEC 0 // specular attenuation
#define LIGHTATTN_SPOT 1 // distance/spotlight attenuation
#define LIGHTATTN_NONE 2
#define LIGHTATTN_DIR 3
union LitChannel
{
struct
{
unsigned matsource : 1;
unsigned enablelighting : 1;
unsigned lightMask0_3 : 4;
unsigned ambsource : 1;
unsigned diffusefunc : 2; // LIGHTDIF_X
unsigned attnfunc : 2; // LIGHTATTN_X
unsigned lightMask4_7 : 4;
unsigned unused : 17;
};
u32 hex;
unsigned int GetFullLightMask() const
{
return enablelighting ? (lightMask0_3 | (lightMask4_7 << 4)) : 0;
}
};
union INVTXSPEC
{
struct
{
unsigned numcolors : 2;
unsigned numnormals : 2; // 0 - nothing, 1 - just normal, 2 - normals and binormals
unsigned numtextures : 4;
unsigned unused : 24;
};
u32 hex;
};
union TXFMatrixIndexA
{
struct
{
unsigned PosNormalMtxIdx : 6;
unsigned Tex0MtxIdx : 6;
unsigned Tex1MtxIdx : 6;
unsigned Tex2MtxIdx : 6;
unsigned Tex3MtxIdx : 6;
};
struct
{
u32 Hex : 30;
u32 unused : 2;
};
};
union TXFMatrixIndexB
{
struct
{
unsigned Tex4MtxIdx : 6;
unsigned Tex5MtxIdx : 6;
unsigned Tex6MtxIdx : 6;
unsigned Tex7MtxIdx : 6;
};
struct
{
u32 Hex : 24;
u32 unused : 8;
};
};
struct Viewport
{
float wd;
float ht;
float zRange;
float xOrig;
float yOrig;
float farZ;
};
union TexMtxInfo
{
struct
{
unsigned unknown : 1;
unsigned projection : 1; // XF_TEXPROJ_X
unsigned inputform : 2; // XF_TEXINPUT_X
unsigned texgentype : 3; // XF_TEXGEN_X
unsigned sourcerow : 5; // XF_SRCGEOM_X
unsigned embosssourceshift : 3; // what generated texcoord to use
unsigned embosslightshift : 3; // light index that is used
};
u32 hex;
};
union PostMtxInfo
{
struct
{
unsigned index : 6; // base row of dual transform matrix
unsigned unused : 2;
unsigned normalize : 1; // normalize before send operation
};
u32 hex;
};
struct XFRegisters
{
u32 posMatrices[256]; // 0x0000 - 0x00ff
u32 unk0[768]; // 0x0100 - 0x03ff
u32 normalMatrices[96]; // 0x0400 - 0x045f
u32 unk1[160]; // 0x0460 - 0x04ff
u32 postMatrices[256]; // 0x0500 - 0x05ff
u32 lights[128]; // 0x0600 - 0x067f
u32 unk2[2432]; // 0x0680 - 0x0fff
u32 error; // 0x1000
u32 diag; // 0x1001
u32 state0; // 0x1002
u32 state1; // 0x1003
u32 xfClock; // 0x1004
u32 clipDisable; // 0x1005
u32 perf0; // 0x1006
u32 perf1; // 0x1007
INVTXSPEC hostinfo; // 0x1008 number of textures,colors,normals from vertex input
u32 nNumChans; // 0x1009
u32 ambColor[2]; // 0x100a, 0x100b
u32 matColor[2]; // 0x100c, 0x100d
LitChannel color[2]; // 0x100e, 0x100f
LitChannel alpha[2]; // 0x1010, 0x1011
u32 dualTexTrans; // 0x1012
u32 unk3; // 0x1013
u32 unk4; // 0x1014
u32 unk5; // 0x1015
u32 unk6; // 0x1016
u32 unk7; // 0x1017
TXFMatrixIndexA MatrixIndexA; // 0x1018
TXFMatrixIndexB MatrixIndexB; // 0x1019
Viewport viewport; // 0x101a - 0x101f
float projection[7]; // 0x1020 - 0x1026
u32 unk8[24]; // 0x1027 - 0x103e
u32 numTexGens; // 0x103f
TexMtxInfo texMtxInfo[8]; // 0x1040 - 0x1047
u32 unk9[8]; // 0x1048 - 0x104f
PostMtxInfo postMtxInfo[8]; // 0x1050 - 0x1057
};
#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
extern XFRegisters xfregs;
void InitXFMemory();
void XFWritten(u32 transferSize, u32 baseAddress);
void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData);
void LoadIndexedXF(u32 val, int array);
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _XFMEMLOADER_H_
#define _XFMEMLOADER_H_
#include "Common.h"
/////////////
// Lighting
/////////////
#define XF_TEXPROJ_ST 0
#define XF_TEXPROJ_STQ 1
#define XF_TEXINPUT_AB11 0
#define XF_TEXINPUT_ABC1 1
#define XF_TEXGEN_REGULAR 0
#define XF_TEXGEN_EMBOSS_MAP 1 // used when bump mapping
#define XF_TEXGEN_COLOR_STRGBC0 2
#define XF_TEXGEN_COLOR_STRGBC1 3
#define XF_SRCGEOM_INROW 0 // input is abc
#define XF_SRCNORMAL_INROW 1 // input is abc
#define XF_SRCCOLORS_INROW 2
#define XF_SRCBINORMAL_T_INROW 3 // input is abc
#define XF_SRCBINORMAL_B_INROW 4 // input is abc
#define XF_SRCTEX0_INROW 5
#define XF_SRCTEX1_INROW 6
#define XF_SRCTEX2_INROW 7
#define XF_SRCTEX3_INROW 8
#define XF_SRCTEX4_INROW 9
#define XF_SRCTEX5_INROW 10
#define XF_SRCTEX6_INROW 11
#define XF_SRCTEX7_INROW 12
#define GX_SRC_REG 0
#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_SIGN 1
#define LIGHTDIF_CLAMP 2
#define LIGHTATTN_SPEC 0 // specular attenuation
#define LIGHTATTN_SPOT 1 // distance/spotlight attenuation
#define LIGHTATTN_NONE 2
#define LIGHTATTN_DIR 3
union LitChannel
{
struct
{
unsigned matsource : 1;
unsigned enablelighting : 1;
unsigned lightMask0_3 : 4;
unsigned ambsource : 1;
unsigned diffusefunc : 2; // LIGHTDIF_X
unsigned attnfunc : 2; // LIGHTATTN_X
unsigned lightMask4_7 : 4;
unsigned unused : 17;
};
u32 hex;
unsigned int GetFullLightMask() const
{
return enablelighting ? (lightMask0_3 | (lightMask4_7 << 4)) : 0;
}
};
union INVTXSPEC
{
struct
{
unsigned numcolors : 2;
unsigned numnormals : 2; // 0 - nothing, 1 - just normal, 2 - normals and binormals
unsigned numtextures : 4;
unsigned unused : 24;
};
u32 hex;
};
union TXFMatrixIndexA
{
struct
{
unsigned PosNormalMtxIdx : 6;
unsigned Tex0MtxIdx : 6;
unsigned Tex1MtxIdx : 6;
unsigned Tex2MtxIdx : 6;
unsigned Tex3MtxIdx : 6;
};
struct
{
u32 Hex : 30;
u32 unused : 2;
};
};
union TXFMatrixIndexB
{
struct
{
unsigned Tex4MtxIdx : 6;
unsigned Tex5MtxIdx : 6;
unsigned Tex6MtxIdx : 6;
unsigned Tex7MtxIdx : 6;
};
struct
{
u32 Hex : 24;
u32 unused : 8;
};
};
struct Viewport
{
float wd;
float ht;
float zRange;
float xOrig;
float yOrig;
float farZ;
};
union TexMtxInfo
{
struct
{
unsigned unknown : 1;
unsigned projection : 1; // XF_TEXPROJ_X
unsigned inputform : 2; // XF_TEXINPUT_X
unsigned texgentype : 3; // XF_TEXGEN_X
unsigned sourcerow : 5; // XF_SRCGEOM_X
unsigned embosssourceshift : 3; // what generated texcoord to use
unsigned embosslightshift : 3; // light index that is used
};
u32 hex;
};
union PostMtxInfo
{
struct
{
unsigned index : 6; // base row of dual transform matrix
unsigned unused : 2;
unsigned normalize : 1; // normalize before send operation
};
u32 hex;
};
struct XFRegisters
{
u32 posMatrices[256]; // 0x0000 - 0x00ff
u32 unk0[768]; // 0x0100 - 0x03ff
u32 normalMatrices[96]; // 0x0400 - 0x045f
u32 unk1[160]; // 0x0460 - 0x04ff
u32 postMatrices[256]; // 0x0500 - 0x05ff
u32 lights[128]; // 0x0600 - 0x067f
u32 unk2[2432]; // 0x0680 - 0x0fff
u32 error; // 0x1000
u32 diag; // 0x1001
u32 state0; // 0x1002
u32 state1; // 0x1003
u32 xfClock; // 0x1004
u32 clipDisable; // 0x1005
u32 perf0; // 0x1006
u32 perf1; // 0x1007
INVTXSPEC hostinfo; // 0x1008 number of textures,colors,normals from vertex input
u32 nNumChans; // 0x1009
u32 ambColor[2]; // 0x100a, 0x100b
u32 matColor[2]; // 0x100c, 0x100d
LitChannel color[2]; // 0x100e, 0x100f
LitChannel alpha[2]; // 0x1010, 0x1011
u32 dualTexTrans; // 0x1012
u32 unk3; // 0x1013
u32 unk4; // 0x1014
u32 unk5; // 0x1015
u32 unk6; // 0x1016
u32 unk7; // 0x1017
TXFMatrixIndexA MatrixIndexA; // 0x1018
TXFMatrixIndexB MatrixIndexB; // 0x1019
Viewport viewport; // 0x101a - 0x101f
float projection[7]; // 0x1020 - 0x1026
u32 unk8[24]; // 0x1027 - 0x103e
u32 numTexGens; // 0x103f
TexMtxInfo texMtxInfo[8]; // 0x1040 - 0x1047
u32 unk9[8]; // 0x1048 - 0x104f
PostMtxInfo postMtxInfo[8]; // 0x1050 - 0x1057
};
#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
extern XFRegisters xfregs;
void InitXFMemory();
void XFWritten(u32 transferSize, u32 baseAddress);
void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData);
void LoadIndexedXF(u32 val, int array);
#endif