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); str2ba(address, &addr.l2_bdaddr);
else else
{ {
bacmp(bdaddr, BDADDR_ANY); if (bacmp(bdaddr, BDADDR_ANY) == 0)
return 0;
/* use address of device discovered */ /* use address of device discovered */
addr.l2_bdaddr = *bdaddr; 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)); ERROR_LOG(AUDIO, "Sample format not available: %s\n", snd_strerror(err));
return false; return false;
} }
err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &sample_rate, &dir); err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &sample_rate, &dir);
if (err < 0) if (err < 0)
{ {

View file

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

View file

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

View file

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

View file

@ -1,21 +1,21 @@
// Copyright (C) 2003 Dolphin Project. // Copyright (C) 2003 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
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// 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/
// Gekko related unions, structs, ... // Gekko related unions, structs, ...
// //
#ifndef _LUT_frsqrtex_h_ #ifndef _LUT_frsqrtex_h_
#define _LUT_frsqrtex_h_ #define _LUT_frsqrtex_h_

View file

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

View file

@ -1,28 +1,28 @@
// Copyright (C) 2003-2009 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
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// 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 _BPMEMLOADER_H_ #ifndef _BPMEMLOADER_H_
#define _BPMEMLOADER_H_ #define _BPMEMLOADER_H_
#include "Common.h" #include "Common.h"
#include "../../../Core/VideoCommon/Src/BPMemory.h" #include "../../../Core/VideoCommon/Src/BPMemory.h"
void InitBPMemory(); void InitBPMemory();
#endif #endif

View file

@ -1,27 +1,27 @@
// Copyright (C) 2003-2009 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
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// 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 _CPMEMLOADER_H_ #ifndef _CPMEMLOADER_H_
#define _CPMEMLOADER_H_ #define _CPMEMLOADER_H_
#include "Common.h" #include "Common.h"
#include "../../../Core/VideoCommon/Src/CPMemory.h" #include "../../../Core/VideoCommon/Src/CPMemory.h"
#endif #endif

View file

@ -1,42 +1,42 @@
// Copyright (C) 2003-2009 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
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// 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 _CLIPPER_H_ #ifndef _CLIPPER_H_
#define _CLIPPER_H_ #define _CLIPPER_H_
#include "Common.h" #include "Common.h"
#include "NativeVertexFormat.h" #include "NativeVertexFormat.h"
namespace Clipper namespace Clipper
{ {
void Init(); void Init();
void SetViewOffset(); void SetViewOffset();
void ProcessTriangle(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2); void ProcessTriangle(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2);
void ProcessLine(OutputVertexData *v0, OutputVertexData *v1); void ProcessLine(OutputVertexData *v0, OutputVertexData *v1);
bool CullTest(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2, bool &backface); bool CullTest(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2, bool &backface);
void PerspectiveDivide(OutputVertexData *vertex); void PerspectiveDivide(OutputVertexData *vertex);
} }
#endif #endif

View file

@ -1,37 +1,37 @@
// Copyright (C) 2003-2009 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
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// 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 _DEBUGUTIL_H #ifndef _DEBUGUTIL_H
#define _DEBUGUTIL_H #define _DEBUGUTIL_H
namespace DebugUtil namespace DebugUtil
{ {
void Init(); void Init();
void GetTextureBGRA(u8 *dst, u32 texmap, s32 mip, int width, int height); void GetTextureBGRA(u8 *dst, u32 texmap, s32 mip, int width, int height);
void DumpActiveTextures(); void DumpActiveTextures();
void OnObjectBegin(); void OnObjectBegin();
void OnObjectEnd(); void OnObjectEnd();
void OnFrameEnd(); void OnFrameEnd();
void DrawObjectBuffer(s16 x, s16 y, u8 *color, int buffer, const char *name); void DrawObjectBuffer(s16 x, s16 y, u8 *color, int buffer, const char *name);
} }
#endif #endif

View file

@ -1,32 +1,32 @@
// Copyright (C) 2003-2009 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
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// 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 _EFB_COPY_H_ #ifndef _EFB_COPY_H_
#define _EFB_COPY_H_ #define _EFB_COPY_H_
#include "Common.h" #include "Common.h"
namespace EfbCopy namespace EfbCopy
{ {
// Copy the EFB to RAM as a texture format or XFB // Copy the EFB to RAM as a texture format or XFB
// Clear the EFB if needed // Clear the EFB if needed
void CopyEfb(); void CopyEfb();
} }
#endif #endif

View file

@ -1,50 +1,50 @@
// Copyright (C) 2003-2009 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
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// 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 _SETUPUNIT_H_ #ifndef _SETUPUNIT_H_
#define _SETUPUNIT_H_ #define _SETUPUNIT_H_
#include "Common.h" #include "Common.h"
#include "NativeVertexFormat.h" #include "NativeVertexFormat.h"
class SetupUnit class SetupUnit
{ {
u8 m_PrimType; u8 m_PrimType;
int m_VertexCounter; int m_VertexCounter;
OutputVertexData m_Vertices[3]; OutputVertexData m_Vertices[3];
OutputVertexData *m_VertPointer[3]; OutputVertexData *m_VertPointer[3];
OutputVertexData *m_VertWritePointer; OutputVertexData *m_VertWritePointer;
void SetupQuad(); void SetupQuad();
void SetupTriangle(); void SetupTriangle();
void SetupTriStrip(); void SetupTriStrip();
void SetupTriFan(); void SetupTriFan();
void SetupLine(); void SetupLine();
void SetupLineStrip(); void SetupLineStrip();
void SetupPoint(); void SetupPoint();
public: public:
void Init(u8 primitiveType); void Init(u8 primitiveType);
OutputVertexData* GetVertex() { return m_VertWritePointer; } OutputVertexData* GetVertex() { return m_VertWritePointer; }
void SetupVertex(); void SetupVertex();
}; };
#endif #endif

View file

@ -1,29 +1,29 @@
// Copyright (C) 2003-2009 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
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// 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 _OPCODEDECODER_H_ #ifndef _OPCODEDECODER_H_
#define _OPCODEDECODER_H_ #define _OPCODEDECODER_H_
#include "Common.h" #include "Common.h"
namespace TextureEncoder namespace TextureEncoder
{ {
void Encode(u8 *dest_ptr); void Encode(u8 *dest_ptr);
} }
#endif #endif

View file

@ -1,32 +1,32 @@
// Copyright (C) 2003-2009 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
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// 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 _TEXTURESAMPLER_H_ #ifndef _TEXTURESAMPLER_H_
#define _TEXTURESAMPLER_H_ #define _TEXTURESAMPLER_H_
#include "Common.h" #include "Common.h"
namespace TextureSampler namespace TextureSampler
{ {
void Sample(s32 s, s32 t, s32 lod, bool linear, u8 texmap, u8 *sample); 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); void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8 *sample);
} }
#endif #endif

View file

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

View file

@ -1,75 +1,75 @@
// Copyright (C) 2003-2009 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
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// 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/
#include "Common.h" #include "Common.h"
#include "VertexFormatConverter.h" #include "VertexFormatConverter.h"
namespace VertexFormatConverter namespace VertexFormatConverter
{ {
void LoadNormal1_Byte(InputVertexData *dst, u8 *src) void LoadNormal1_Byte(InputVertexData *dst, u8 *src)
{ {
dst->normal[0].x = (float)(s8)src[0] / 128; dst->normal[0].x = (float)(s8)src[0] / 128;
dst->normal[0].y = (float)(s8)src[1] / 128; dst->normal[0].y = (float)(s8)src[1] / 128;
dst->normal[0].z = (float)(s8)src[2] / 128; dst->normal[0].z = (float)(s8)src[2] / 128;
} }
void LoadNormal1_Short(InputVertexData *dst, u8 *src) void LoadNormal1_Short(InputVertexData *dst, u8 *src)
{ {
dst->normal[0].x = (float)((s16*)src)[0] / 32768; dst->normal[0].x = (float)((s16*)src)[0] / 32768;
dst->normal[0].y = (float)((s16*)src)[1] / 32768; dst->normal[0].y = (float)((s16*)src)[1] / 32768;
dst->normal[0].z = (float)((s16*)src)[2] / 32768; dst->normal[0].z = (float)((s16*)src)[2] / 32768;
} }
void LoadNormal1_Float(InputVertexData *dst, u8 *src) void LoadNormal1_Float(InputVertexData *dst, u8 *src)
{ {
dst->normal[0].x = ((float*)src)[0]; dst->normal[0].x = ((float*)src)[0];
dst->normal[0].y = ((float*)src)[1]; dst->normal[0].y = ((float*)src)[1];
dst->normal[0].z = ((float*)src)[2]; dst->normal[0].z = ((float*)src)[2];
} }
void LoadNormal3_Byte(InputVertexData *dst, u8 *src) void LoadNormal3_Byte(InputVertexData *dst, u8 *src)
{ {
for (int i = 0, j = 0; i < 3; i++, j+=3) for (int i = 0, j = 0; i < 3; i++, j+=3)
{ {
dst->normal[i].x = (float)(s8)src[j + 0] / 128; dst->normal[i].x = (float)(s8)src[j + 0] / 128;
dst->normal[i].y = (float)(s8)src[j + 1] / 128; dst->normal[i].y = (float)(s8)src[j + 1] / 128;
dst->normal[i].z = (float)(s8)src[j + 2] / 128; dst->normal[i].z = (float)(s8)src[j + 2] / 128;
} }
} }
void LoadNormal3_Short(InputVertexData *dst, u8 *src) void LoadNormal3_Short(InputVertexData *dst, u8 *src)
{ {
for (int i = 0, j = 0; i < 3; i++, j+=3) for (int i = 0, j = 0; i < 3; i++, j+=3)
{ {
dst->normal[i].x = (float)((s16*)src)[j + 0] / 32768; dst->normal[i].x = (float)((s16*)src)[j + 0] / 32768;
dst->normal[i].y = (float)((s16*)src)[j + 1] / 32768; dst->normal[i].y = (float)((s16*)src)[j + 1] / 32768;
dst->normal[i].z = (float)((s16*)src)[j + 2] / 32768; dst->normal[i].z = (float)((s16*)src)[j + 2] / 32768;
} }
} }
void LoadNormal3_Float(InputVertexData *dst, u8 *src) void LoadNormal3_Float(InputVertexData *dst, u8 *src)
{ {
for (int i = 0, j = 0; i < 3; i++, j+=3) for (int i = 0, j = 0; i < 3; i++, j+=3)
{ {
dst->normal[i].x = ((float*)src)[j + 0]; dst->normal[i].x = ((float*)src)[j + 0];
dst->normal[i].y = ((float*)src)[j + 1]; dst->normal[i].y = ((float*)src)[j + 1];
dst->normal[i].z = ((float*)src)[j + 2]; dst->normal[i].z = ((float*)src)[j + 2];
} }
} }
} }

View file

@ -1,35 +1,35 @@
// Copyright (C) 2003-2009 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
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// 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 _VERTEXFORMATCONVERTER_H #ifndef _VERTEXFORMATCONVERTER_H
#define _VERTEXFORMATCONVERTER_H #define _VERTEXFORMATCONVERTER_H
#include "NativeVertexFormat.h" #include "NativeVertexFormat.h"
namespace VertexFormatConverter namespace VertexFormatConverter
{ {
typedef void (*NormalConverter)(InputVertexData*, u8*); typedef void (*NormalConverter)(InputVertexData*, u8*);
void LoadNormal1_Byte(InputVertexData *dst, u8 *src); void LoadNormal1_Byte(InputVertexData *dst, u8 *src);
void LoadNormal1_Short(InputVertexData *dst, u8 *src); void LoadNormal1_Short(InputVertexData *dst, u8 *src);
void LoadNormal1_Float(InputVertexData *dst, u8 *src); void LoadNormal1_Float(InputVertexData *dst, u8 *src);
void LoadNormal3_Byte(InputVertexData *dst, u8 *src); void LoadNormal3_Byte(InputVertexData *dst, u8 *src);
void LoadNormal3_Short(InputVertexData *dst, u8 *src); void LoadNormal3_Short(InputVertexData *dst, u8 *src);
void LoadNormal3_Float(InputVertexData *dst, u8 *src); void LoadNormal3_Float(InputVertexData *dst, u8 *src);
} }
#endif #endif

View file

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

View file

@ -1,20 +1,20 @@
// Copyright (C) 2003-2009 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
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// 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/
#include "NativeVertexFormat.h" #include "NativeVertexFormat.h"
#include "../../../Core/VideoCommon/Src/VertexLoader_Position.h" #include "../../../Core/VideoCommon/Src/VertexLoader_Position.h"

View file

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