NoGUI: general cleanup, add initialization stuff added in r5064, fixed the cocoa event loop not shutting down when not booting a game on OSX.

SysConf: removed the Save call in the dtor, this crashes on linux trying to read m_Filename (which might be already freed).
Common: set eol-style native, again.

Fixes Issue 2332

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5082 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
j4ck.fr0st 2010-02-19 17:05:26 +00:00
parent 0819740b6a
commit 3a5a7de906
17 changed files with 3025 additions and 3029 deletions

View File

@ -1,32 +1,32 @@
// 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/
#ifndef _ATOMIC_H_ #ifndef _ATOMIC_H_
#define _ATOMIC_H_ #define _ATOMIC_H_
#ifdef _WIN32 #ifdef _WIN32
#include "Atomic_Win32.h" #include "Atomic_Win32.h"
#else #else
// GCC-compatible compiler assumed! // GCC-compatible compiler assumed!
#include "Atomic_GCC.h" #include "Atomic_GCC.h"
#endif #endif
#endif #endif

View File

@ -1,118 +1,118 @@
// 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/
#ifndef _ATOMIC_GCC_H_ #ifndef _ATOMIC_GCC_H_
#define _ATOMIC_GCC_H_ #define _ATOMIC_GCC_H_
#include "Common.h" #include "Common.h"
// Atomic operations are performed in a single step by the CPU. It is // Atomic operations are performed in a single step by the CPU. It is
// impossible for other threads to see the operation "half-done." // impossible for other threads to see the operation "half-done."
// //
// Some atomic operations can be combined with different types of memory // Some atomic operations can be combined with different types of memory
// barriers called "Acquire semantics" and "Release semantics", defined below. // barriers called "Acquire semantics" and "Release semantics", defined below.
// //
// Acquire semantics: Future memory accesses cannot be relocated to before the // Acquire semantics: Future memory accesses cannot be relocated to before the
// operation. // operation.
// //
// Release semantics: Past memory accesses cannot be relocated to after the // Release semantics: Past memory accesses cannot be relocated to after the
// operation. // operation.
// //
// These barriers affect not only the compiler, but also the CPU. // These barriers affect not only the compiler, but also the CPU.
namespace Common namespace Common
{ {
inline void AtomicAdd(volatile u32& target, u32 value) { inline void AtomicAdd(volatile u32& target, u32 value) {
__sync_add_and_fetch(&target, value); __sync_add_and_fetch(&target, value);
} }
inline void AtomicAnd(volatile u32& target, u32 value) { inline void AtomicAnd(volatile u32& target, u32 value) {
__sync_and_and_fetch(&target, value); __sync_and_and_fetch(&target, value);
} }
inline void AtomicIncrement(volatile u32& target) { inline void AtomicIncrement(volatile u32& target) {
__sync_add_and_fetch(&target, 1); __sync_add_and_fetch(&target, 1);
} }
inline u32 AtomicLoad(volatile u32& src) { inline u32 AtomicLoad(volatile u32& src) {
return src; // 32-bit reads are always atomic. return src; // 32-bit reads are always atomic.
} }
inline u32 AtomicLoadAcquire(volatile u32& src) { inline u32 AtomicLoadAcquire(volatile u32& src) {
__sync_synchronize(); // TODO: May not be necessary. __sync_synchronize(); // TODO: May not be necessary.
return src; return src;
} }
inline void AtomicOr(volatile u32& target, u32 value) { inline void AtomicOr(volatile u32& target, u32 value) {
__sync_or_and_fetch(&target, value); __sync_or_and_fetch(&target, value);
} }
inline void AtomicStore(volatile u32& dest, u32 value) { inline void AtomicStore(volatile u32& dest, u32 value) {
dest = value; // 32-bit writes are always atomic. dest = value; // 32-bit writes are always atomic.
} }
inline void AtomicStoreRelease(volatile u32& dest, u32 value) { inline void AtomicStoreRelease(volatile u32& dest, u32 value) {
__sync_lock_test_and_set(&dest, value); // TODO: Wrong! This function is has acquire semantics. __sync_lock_test_and_set(&dest, value); // TODO: Wrong! This function is has acquire semantics.
} }
} }
// Old code kept here for reference in case we need the parts with __asm__ __volatile__. // Old code kept here for reference in case we need the parts with __asm__ __volatile__.
#if 0 #if 0
LONG SyncInterlockedIncrement(LONG *Dest) LONG SyncInterlockedIncrement(LONG *Dest)
{ {
#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__)) #if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
return __sync_add_and_fetch(Dest, 1); return __sync_add_and_fetch(Dest, 1);
#else #else
register int result; register int result;
__asm__ __volatile__("lock; xadd %0,%1" __asm__ __volatile__("lock; xadd %0,%1"
: "=r" (result), "=m" (*Dest) : "=r" (result), "=m" (*Dest)
: "0" (1), "m" (*Dest) : "0" (1), "m" (*Dest)
: "memory"); : "memory");
return result; return result;
#endif #endif
} }
LONG SyncInterlockedExchangeAdd(LONG *Dest, LONG Val) LONG SyncInterlockedExchangeAdd(LONG *Dest, LONG Val)
{ {
#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__)) #if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
return __sync_add_and_fetch(Dest, Val); return __sync_add_and_fetch(Dest, Val);
#else #else
register int result; register int result;
__asm__ __volatile__("lock; xadd %0,%1" __asm__ __volatile__("lock; xadd %0,%1"
: "=r" (result), "=m" (*Dest) : "=r" (result), "=m" (*Dest)
: "0" (Val), "m" (*Dest) : "0" (Val), "m" (*Dest)
: "memory"); : "memory");
return result; return result;
#endif #endif
} }
LONG SyncInterlockedExchange(LONG *Dest, LONG Val) LONG SyncInterlockedExchange(LONG *Dest, LONG Val)
{ {
#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__)) #if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
return __sync_lock_test_and_set(Dest, Val); return __sync_lock_test_and_set(Dest, Val);
#else #else
register int result; register int result;
__asm__ __volatile__("lock; xchg %0,%1" __asm__ __volatile__("lock; xchg %0,%1"
: "=r" (result), "=m" (*Dest) : "=r" (result), "=m" (*Dest)
: "0" (Val), "m" (*Dest) : "0" (Val), "m" (*Dest)
: "memory"); : "memory");
return result; return result;
#endif #endif
} }
#endif #endif
#endif #endif

View File

@ -1,81 +1,81 @@
// 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/
#ifndef _ATOMIC_WIN32_H_ #ifndef _ATOMIC_WIN32_H_
#define _ATOMIC_WIN32_H_ #define _ATOMIC_WIN32_H_
#include "Common.h" #include "Common.h"
#include <intrin.h> #include <intrin.h>
#include <Windows.h> #include <Windows.h>
// Atomic operations are performed in a single step by the CPU. It is // Atomic operations are performed in a single step by the CPU. It is
// impossible for other threads to see the operation "half-done." // impossible for other threads to see the operation "half-done."
// //
// Some atomic operations can be combined with different types of memory // Some atomic operations can be combined with different types of memory
// barriers called "Acquire semantics" and "Release semantics", defined below. // barriers called "Acquire semantics" and "Release semantics", defined below.
// //
// Acquire semantics: Future memory accesses cannot be relocated to before the // Acquire semantics: Future memory accesses cannot be relocated to before the
// operation. // operation.
// //
// Release semantics: Past memory accesses cannot be relocated to after the // Release semantics: Past memory accesses cannot be relocated to after the
// operation. // operation.
// //
// These barriers affect not only the compiler, but also the CPU. // These barriers affect not only the compiler, but also the CPU.
// //
// NOTE: Acquire and Release are not differentiated right now. They perform a // NOTE: Acquire and Release are not differentiated right now. They perform a
// full memory barrier instead of a "one-way" memory barrier. The newest // full memory barrier instead of a "one-way" memory barrier. The newest
// Windows SDK has Acquire and Release versions of some Interlocked* functions. // Windows SDK has Acquire and Release versions of some Interlocked* functions.
namespace Common namespace Common
{ {
inline void AtomicAdd(volatile u32& target, u32 value) { inline void AtomicAdd(volatile u32& target, u32 value) {
InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value); InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value);
} }
inline void AtomicAnd(volatile u32& target, u32 value) { inline void AtomicAnd(volatile u32& target, u32 value) {
_InterlockedAnd((volatile LONG*)&target, (LONG)value); _InterlockedAnd((volatile LONG*)&target, (LONG)value);
} }
inline void AtomicIncrement(volatile u32& target) { inline void AtomicIncrement(volatile u32& target) {
InterlockedIncrement((volatile LONG*)&target); InterlockedIncrement((volatile LONG*)&target);
} }
inline u32 AtomicLoad(volatile u32& src) { inline u32 AtomicLoad(volatile u32& src) {
return src; // 32-bit reads are always atomic. return src; // 32-bit reads are always atomic.
} }
inline u32 AtomicLoadAcquire(volatile u32& src) { inline u32 AtomicLoadAcquire(volatile u32& src) {
u32 result = src; // 32-bit reads are always atomic. u32 result = src; // 32-bit reads are always atomic.
_ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics. _ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics.
return result; return result;
} }
inline void AtomicOr(volatile u32& target, u32 value) { inline void AtomicOr(volatile u32& target, u32 value) {
_InterlockedOr((volatile LONG*)&target, (LONG)value); _InterlockedOr((volatile LONG*)&target, (LONG)value);
} }
inline void AtomicStore(volatile u32& dest, u32 value) { inline void AtomicStore(volatile u32& dest, u32 value) {
dest = value; // 32-bit writes are always atomic. dest = value; // 32-bit writes are always atomic.
} }
inline void AtomicStoreRelease(volatile u32& dest, u32 value) { inline void AtomicStoreRelease(volatile u32& dest, u32 value) {
_WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics. _WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics.
dest = value; // 32-bit writes are always atomic. dest = value; // 32-bit writes are always atomic.
} }
} }
#endif #endif

View File

@ -1,55 +1,55 @@
// 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/
#ifndef _CONSOLELISTENER_H #ifndef _CONSOLELISTENER_H
#define _CONSOLELISTENER_H #define _CONSOLELISTENER_H
#include "LogManager.h" #include "LogManager.h"
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#endif #endif
class ConsoleListener : public LogListener class ConsoleListener : public LogListener
{ {
public: public:
ConsoleListener(); ConsoleListener();
~ConsoleListener(); ~ConsoleListener();
void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console"); void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console");
void UpdateHandle(); void UpdateHandle();
void Close(); void Close();
bool IsOpen(); bool IsOpen();
void LetterSpace(int Width, int Height); void LetterSpace(int Width, int Height);
void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst); void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst);
void PixelSpace(int Left, int Top, int Width, int Height, bool); void PixelSpace(int Left, int Top, int Width, int Height, bool);
#ifdef _WIN32 #ifdef _WIN32
COORD GetCoordinates(int BytesRead, int BufferWidth); COORD GetCoordinates(int BytesRead, int BufferWidth);
#endif #endif
void Log(LogTypes::LOG_LEVELS, const char *Text); void Log(LogTypes::LOG_LEVELS, const char *Text);
void ClearScreen(bool Cursor = true); void ClearScreen(bool Cursor = true);
const char *getName() const { return "Console"; } const char *getName() const { return "Console"; }
private: private:
#ifdef _WIN32 #ifdef _WIN32
HWND GetHwnd(void); HWND GetHwnd(void);
HANDLE hConsole; HANDLE hConsole;
#endif #endif
}; };
#endif // _CONSOLELISTENER_H #endif // _CONSOLELISTENER_H

View File

@ -1,398 +1,398 @@
// Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org> // Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
// Licensed under the terms of the GNU GPL, version 2 // Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>
#include "../Common.h" #include "../Common.h"
#include "tools.h" #include "tools.h"
// y**2 + x*y = x**3 + x + b // y**2 + x*y = x**3 + x + b
static u8 ec_b[30] = static u8 ec_b[30] =
{0x00,0x66,0x64,0x7e,0xde,0x6c,0x33,0x2c,0x7f,0x8c,0x09,0x23,0xbb,0x58,0x21 {0x00,0x66,0x64,0x7e,0xde,0x6c,0x33,0x2c,0x7f,0x8c,0x09,0x23,0xbb,0x58,0x21
,0x3b,0x33,0x3b,0x20,0xe9,0xce,0x42,0x81,0xfe,0x11,0x5f,0x7d,0x8f,0x90,0xad}; ,0x3b,0x33,0x3b,0x20,0xe9,0xce,0x42,0x81,0xfe,0x11,0x5f,0x7d,0x8f,0x90,0xad};
// order of the addition group of points // order of the addition group of points
static u8 ec_N[30] = static u8 ec_N[30] =
{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x13,0xe9,0x74,0xe7,0x2f,0x8a,0x69,0x22,0x03,0x1d,0x26,0x03,0xcf,0xe0,0xd7}; ,0x13,0xe9,0x74,0xe7,0x2f,0x8a,0x69,0x22,0x03,0x1d,0x26,0x03,0xcf,0xe0,0xd7};
// base point // base point
static u8 ec_G[60] = static u8 ec_G[60] =
{0x00,0xfa,0xc9,0xdf,0xcb,0xac,0x83,0x13,0xbb,0x21,0x39,0xf1,0xbb,0x75,0x5f {0x00,0xfa,0xc9,0xdf,0xcb,0xac,0x83,0x13,0xbb,0x21,0x39,0xf1,0xbb,0x75,0x5f
,0xef,0x65,0xbc,0x39,0x1f,0x8b,0x36,0xf8,0xf8,0xeb,0x73,0x71,0xfd,0x55,0x8b ,0xef,0x65,0xbc,0x39,0x1f,0x8b,0x36,0xf8,0xf8,0xeb,0x73,0x71,0xfd,0x55,0x8b
,0x01,0x00,0x6a,0x08,0xa4,0x19,0x03,0x35,0x06,0x78,0xe5,0x85,0x28,0xbe,0xbf ,0x01,0x00,0x6a,0x08,0xa4,0x19,0x03,0x35,0x06,0x78,0xe5,0x85,0x28,0xbe,0xbf
,0x8a,0x0b,0xef,0xf8,0x67,0xa7,0xca,0x36,0x71,0x6f,0x7e,0x01,0xf8,0x10,0x52}; ,0x8a,0x0b,0xef,0xf8,0x67,0xa7,0xca,0x36,0x71,0x6f,0x7e,0x01,0xf8,0x10,0x52};
/*static void elt_print(char *name, u8 *a) /*static void elt_print(char *name, u8 *a)
{ {
u32 i; u32 i;
printf("%s = ", name); printf("%s = ", name);
for (i = 0; i < 30; i++) for (i = 0; i < 30; i++)
printf("%02x", a[i]); printf("%02x", a[i]);
printf("\n"); printf("\n");
}*/ }*/
static void elt_copy(u8 *d, u8 *a) static void elt_copy(u8 *d, u8 *a)
{ {
memcpy(d, a, 30); memcpy(d, a, 30);
} }
static void elt_zero(u8 *d) static void elt_zero(u8 *d)
{ {
memset(d, 0, 30); memset(d, 0, 30);
} }
static int elt_is_zero(u8 *d) static int elt_is_zero(u8 *d)
{ {
u32 i; u32 i;
for (i = 0; i < 30; i++) for (i = 0; i < 30; i++)
if (d[i] != 0) if (d[i] != 0)
return 0; return 0;
return 1; return 1;
} }
static void elt_add(u8 *d, u8 *a, u8 *b) static void elt_add(u8 *d, u8 *a, u8 *b)
{ {
u32 i; u32 i;
for (i = 0; i < 30; i++) for (i = 0; i < 30; i++)
d[i] = a[i] ^ b[i]; d[i] = a[i] ^ b[i];
} }
static void elt_mul_x(u8 *d, u8 *a) static void elt_mul_x(u8 *d, u8 *a)
{ {
u8 carry, x, y; u8 carry, x, y;
u32 i; u32 i;
carry = a[0] & 1; carry = a[0] & 1;
x = 0; x = 0;
for (i = 0; i < 29; i++) { for (i = 0; i < 29; i++) {
y = a[i + 1]; y = a[i + 1];
d[i] = x ^ (y >> 7); d[i] = x ^ (y >> 7);
x = y << 1; x = y << 1;
} }
d[29] = x ^ carry; d[29] = x ^ carry;
d[20] ^= carry << 2; d[20] ^= carry << 2;
} }
static void elt_mul(u8 *d, u8 *a, u8 *b) static void elt_mul(u8 *d, u8 *a, u8 *b)
{ {
u32 i, n; u32 i, n;
u8 mask; u8 mask;
elt_zero(d); elt_zero(d);
i = 0; i = 0;
mask = 1; mask = 1;
for (n = 0; n < 233; n++) { for (n = 0; n < 233; n++) {
elt_mul_x(d, d); elt_mul_x(d, d);
if ((a[i] & mask) != 0) if ((a[i] & mask) != 0)
elt_add(d, d, b); elt_add(d, d, b);
mask >>= 1; mask >>= 1;
if (mask == 0) { if (mask == 0) {
mask = 0x80; mask = 0x80;
i++; i++;
} }
} }
} }
static const u8 square[16] = static const u8 square[16] =
{0x00,0x01,0x04,0x05,0x10,0x11,0x14,0x15,0x40,0x41,0x44,0x45,0x50,0x51,0x54,0x55}; {0x00,0x01,0x04,0x05,0x10,0x11,0x14,0x15,0x40,0x41,0x44,0x45,0x50,0x51,0x54,0x55};
static void elt_square_to_wide(u8 *d, u8 *a) static void elt_square_to_wide(u8 *d, u8 *a)
{ {
u32 i; u32 i;
for (i = 0; i < 30; i++) { for (i = 0; i < 30; i++) {
d[2*i] = square[a[i] >> 4]; d[2*i] = square[a[i] >> 4];
d[2*i + 1] = square[a[i] & 15]; d[2*i + 1] = square[a[i] & 15];
} }
} }
static void wide_reduce(u8 *d) static void wide_reduce(u8 *d)
{ {
u32 i; u32 i;
u8 x; u8 x;
for (i = 0; i < 30; i++) { for (i = 0; i < 30; i++) {
x = d[i]; x = d[i];
d[i + 19] ^= x >> 7; d[i + 19] ^= x >> 7;
d[i + 20] ^= x << 1; d[i + 20] ^= x << 1;
d[i + 29] ^= x >> 1; d[i + 29] ^= x >> 1;
d[i + 30] ^= x << 7; d[i + 30] ^= x << 7;
} }
x = d[30] & ~1; x = d[30] & ~1;
d[49] ^= x >> 7; d[49] ^= x >> 7;
d[50] ^= x << 1; d[50] ^= x << 1;
d[59] ^= x >> 1; d[59] ^= x >> 1;
d[30] &= 1; d[30] &= 1;
} }
static void elt_square(u8 *d, u8 *a) static void elt_square(u8 *d, u8 *a)
{ {
u8 wide[60]; u8 wide[60];
elt_square_to_wide(wide, a); elt_square_to_wide(wide, a);
wide_reduce(wide); wide_reduce(wide);
elt_copy(d, wide + 30); elt_copy(d, wide + 30);
} }
static void itoh_tsujii(u8 *d, u8 *a, u8 *b, u32 j) static void itoh_tsujii(u8 *d, u8 *a, u8 *b, u32 j)
{ {
u8 t[30]; u8 t[30];
elt_copy(t, a); elt_copy(t, a);
while (j--) { while (j--) {
elt_square(d, t); elt_square(d, t);
elt_copy(t, d); elt_copy(t, d);
} }
elt_mul(d, t, b); elt_mul(d, t, b);
} }
static void elt_inv(u8 *d, u8 *a) static void elt_inv(u8 *d, u8 *a)
{ {
u8 t[30]; u8 t[30];
u8 s[30]; u8 s[30];
itoh_tsujii(t, a, a, 1); itoh_tsujii(t, a, a, 1);
itoh_tsujii(s, t, a, 1); itoh_tsujii(s, t, a, 1);
itoh_tsujii(t, s, s, 3); itoh_tsujii(t, s, s, 3);
itoh_tsujii(s, t, a, 1); itoh_tsujii(s, t, a, 1);
itoh_tsujii(t, s, s, 7); itoh_tsujii(t, s, s, 7);
itoh_tsujii(s, t, t, 14); itoh_tsujii(s, t, t, 14);
itoh_tsujii(t, s, a, 1); itoh_tsujii(t, s, a, 1);
itoh_tsujii(s, t, t, 29); itoh_tsujii(s, t, t, 29);
itoh_tsujii(t, s, s, 58); itoh_tsujii(t, s, s, 58);
itoh_tsujii(s, t, t, 116); itoh_tsujii(s, t, t, 116);
elt_square(d, s); elt_square(d, s);
} }
/*static int point_is_on_curve(u8 *p) /*static int point_is_on_curve(u8 *p)
{ {
u8 s[30], t[30]; u8 s[30], t[30];
u8 *x, *y; u8 *x, *y;
x = p; x = p;
y = p + 30; y = p + 30;
elt_square(t, x); elt_square(t, x);
elt_mul(s, t, x); elt_mul(s, t, x);
elt_add(s, s, t); elt_add(s, s, t);
elt_square(t, y); elt_square(t, y);
elt_add(s, s, t); elt_add(s, s, t);
elt_mul(t, x, y); elt_mul(t, x, y);
elt_add(s, s, t); elt_add(s, s, t);
elt_add(s, s, ec_b); elt_add(s, s, ec_b);
return elt_is_zero(s); return elt_is_zero(s);
} }
*/ */
static int point_is_zero(u8 *p) static int point_is_zero(u8 *p)
{ {
return elt_is_zero(p) && elt_is_zero(p + 30); return elt_is_zero(p) && elt_is_zero(p + 30);
} }
static void point_double(u8 *r, u8 *p) static void point_double(u8 *r, u8 *p)
{ {
u8 s[30], t[30]; u8 s[30], t[30];
u8 *px, *py, *rx, *ry; u8 *px, *py, *rx, *ry;
px = p; px = p;
py = p + 30; py = p + 30;
rx = r; rx = r;
ry = r + 30; ry = r + 30;
if (elt_is_zero(px)) { if (elt_is_zero(px)) {
elt_zero(rx); elt_zero(rx);
elt_zero(ry); elt_zero(ry);
return; return;
} }
elt_inv(t, px); elt_inv(t, px);
elt_mul(s, py, t); elt_mul(s, py, t);
elt_add(s, s, px); elt_add(s, s, px);
elt_square(t, px); elt_square(t, px);
elt_square(rx, s); elt_square(rx, s);
elt_add(rx, rx, s); elt_add(rx, rx, s);
rx[29] ^= 1; rx[29] ^= 1;
elt_mul(ry, s, rx); elt_mul(ry, s, rx);
elt_add(ry, ry, rx); elt_add(ry, ry, rx);
elt_add(ry, ry, t); elt_add(ry, ry, t);
} }
static void point_add(u8 *r, u8 *p, u8 *q) static void point_add(u8 *r, u8 *p, u8 *q)
{ {
u8 s[30], t[30], u[30]; u8 s[30], t[30], u[30];
u8 *px, *py, *qx, *qy, *rx, *ry; u8 *px, *py, *qx, *qy, *rx, *ry;
px = p; px = p;
py = p + 30; py = p + 30;
qx = q; qx = q;
qy = q + 30; qy = q + 30;
rx = r; rx = r;
ry = r + 30; ry = r + 30;
if (point_is_zero(p)) { if (point_is_zero(p)) {
elt_copy(rx, qx); elt_copy(rx, qx);
elt_copy(ry, qy); elt_copy(ry, qy);
return; return;
} }
if (point_is_zero(q)) { if (point_is_zero(q)) {
elt_copy(rx, px); elt_copy(rx, px);
elt_copy(ry, py); elt_copy(ry, py);
return; return;
} }
elt_add(u, px, qx); elt_add(u, px, qx);
if (elt_is_zero(u)) { if (elt_is_zero(u)) {
elt_add(u, py, qy); elt_add(u, py, qy);
if (elt_is_zero(u)) if (elt_is_zero(u))
point_double(r, p); point_double(r, p);
else { else {
elt_zero(rx); elt_zero(rx);
elt_zero(ry); elt_zero(ry);
} }
return; return;
} }
elt_inv(t, u); elt_inv(t, u);
elt_add(u, py, qy); elt_add(u, py, qy);
elt_mul(s, t, u); elt_mul(s, t, u);
elt_square(t, s); elt_square(t, s);
elt_add(t, t, s); elt_add(t, t, s);
elt_add(t, t, qx); elt_add(t, t, qx);
t[29] ^= 1; t[29] ^= 1;
elt_mul(u, s, t); elt_mul(u, s, t);
elt_add(s, u, py); elt_add(s, u, py);
elt_add(rx, t, px); elt_add(rx, t, px);
elt_add(ry, s, rx); elt_add(ry, s, rx);
} }
static void point_mul(u8 *d, u8 *a, u8 *b) // a is bignum static void point_mul(u8 *d, u8 *a, u8 *b) // a is bignum
{ {
u32 i; u32 i;
u8 mask; u8 mask;
elt_zero(d); elt_zero(d);
elt_zero(d + 30); elt_zero(d + 30);
for (i = 0; i < 30; i++) for (i = 0; i < 30; i++)
for (mask = 0x80; mask != 0; mask >>= 1) { for (mask = 0x80; mask != 0; mask >>= 1) {
point_double(d, d); point_double(d, d);
if ((a[i] & mask) != 0) if ((a[i] & mask) != 0)
point_add(d, d, b); point_add(d, d, b);
} }
} }
void silly_random(u8 * rndArea, u8 count) void silly_random(u8 * rndArea, u8 count)
{ {
u16 i; u16 i;
srand((unsigned) (time(NULL))); srand((unsigned) (time(NULL)));
for(i=0;i<count;i++) for(i=0;i<count;i++)
{ {
rndArea[i]=rand(); rndArea[i]=rand();
} }
} }
void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash) void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash)
{ {
u8 e[30]; u8 e[30];
u8 kk[30]; u8 kk[30];
u8 m[30]; u8 m[30];
u8 minv[30]; u8 minv[30];
u8 mG[60]; u8 mG[60];
//FILE *fp; //FILE *fp;
elt_zero(e); elt_zero(e);
memcpy(e + 10, hash, 20); memcpy(e + 10, hash, 20);
//Changing random number generator to a lame one... //Changing random number generator to a lame one...
silly_random(m, sizeof(m)); silly_random(m, sizeof(m));
//fp = fopen("/dev/random", "rb"); //fp = fopen("/dev/random", "rb");
//if (fread(m, sizeof m, 1, fp) != 1) //if (fread(m, sizeof m, 1, fp) != 1)
// fatal("reading random"); // fatal("reading random");
//fclose(fp); //fclose(fp);
m[0] = 0; m[0] = 0;
// R = (mG).x // R = (mG).x
point_mul(mG, m, ec_G); point_mul(mG, m, ec_G);
elt_copy(R, mG); elt_copy(R, mG);
if (bn_compare(R, ec_N, 30) >= 0) if (bn_compare(R, ec_N, 30) >= 0)
bn_sub_modulus(R, ec_N, 30); bn_sub_modulus(R, ec_N, 30);
// S = m**-1*(e + Rk) (mod N) // S = m**-1*(e + Rk) (mod N)
elt_copy(kk, k); elt_copy(kk, k);
if (bn_compare(kk, ec_N, 30) >= 0) if (bn_compare(kk, ec_N, 30) >= 0)
bn_sub_modulus(kk, ec_N, 30); bn_sub_modulus(kk, ec_N, 30);
bn_mul(S, R, kk, ec_N, 30); bn_mul(S, R, kk, ec_N, 30);
bn_add(kk, S, e, ec_N, 30); bn_add(kk, S, e, ec_N, 30);
bn_inv(minv, m, ec_N, 30); bn_inv(minv, m, ec_N, 30);
bn_mul(S, minv, kk, ec_N, 30); bn_mul(S, minv, kk, ec_N, 30);
} }
int check_ecdsa(u8 *Q, u8 *R, u8 *S, u8 *hash) int check_ecdsa(u8 *Q, u8 *R, u8 *S, u8 *hash)
{ {
u8 Sinv[30]; u8 Sinv[30];
u8 e[30]; u8 e[30];
u8 w1[30], w2[30]; u8 w1[30], w2[30];
u8 r1[60], r2[60]; u8 r1[60], r2[60];
bn_inv(Sinv, S, ec_N, 30); bn_inv(Sinv, S, ec_N, 30);
elt_zero(e); elt_zero(e);
memcpy(e + 10, hash, 20); memcpy(e + 10, hash, 20);
bn_mul(w1, e, Sinv, ec_N, 30); bn_mul(w1, e, Sinv, ec_N, 30);
bn_mul(w2, R, Sinv, ec_N, 30); bn_mul(w2, R, Sinv, ec_N, 30);
point_mul(r1, w1, ec_G); point_mul(r1, w1, ec_G);
point_mul(r2, w2, Q); point_mul(r2, w2, Q);
point_add(r1, r1, r2); point_add(r1, r1, r2);
if (bn_compare(r1, ec_N, 30) >= 0) if (bn_compare(r1, ec_N, 30) >= 0)
bn_sub_modulus(r1, ec_N, 30); bn_sub_modulus(r1, ec_N, 30);
return (bn_compare(r1, R, 30) == 0); return (bn_compare(r1, R, 30) == 0);
} }
void ec_priv_to_pub(u8 *k, u8 *Q) void ec_priv_to_pub(u8 *k, u8 *Q)
{ {
point_mul(Q, k, ec_G); point_mul(Q, k, ec_G);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,138 +1,138 @@
/** /**
* \file md5.h * \file md5.h
* *
* Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org> * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
* All rights reserved. * All rights reserved.
* *
* Joined copyright on original XySSL code with: Christophe Devine * Joined copyright on original XySSL code with: Christophe Devine
* *
* 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; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* 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 for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef POLARSSL_MD5_H #ifndef POLARSSL_MD5_H
#define POLARSSL_MD5_H #define POLARSSL_MD5_H
/** /**
* \brief MD5 context structure * \brief MD5 context structure
*/ */
typedef struct typedef struct
{ {
unsigned long total[2]; /*!< number of bytes processed */ unsigned long total[2]; /*!< number of bytes processed */
unsigned long state[4]; /*!< intermediate digest state */ unsigned long state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */ unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */ unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */ unsigned char opad[64]; /*!< HMAC: outer padding */
} }
md5_context; md5_context;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/** /**
* \brief MD5 context setup * \brief MD5 context setup
* *
* \param ctx context to be initialized * \param ctx context to be initialized
*/ */
void md5_starts( md5_context *ctx ); void md5_starts( md5_context *ctx );
/** /**
* \brief MD5 process buffer * \brief MD5 process buffer
* *
* \param ctx MD5 context * \param ctx MD5 context
* \param input buffer holding the data * \param input buffer holding the data
* \param ilen length of the input data * \param ilen length of the input data
*/ */
void md5_update( md5_context *ctx, unsigned char *input, int ilen ); void md5_update( md5_context *ctx, unsigned char *input, int ilen );
/** /**
* \brief MD5 final digest * \brief MD5 final digest
* *
* \param ctx MD5 context * \param ctx MD5 context
* \param output MD5 checksum result * \param output MD5 checksum result
*/ */
void md5_finish( md5_context *ctx, unsigned char output[16] ); void md5_finish( md5_context *ctx, unsigned char output[16] );
/** /**
* \brief Output = MD5( input buffer ) * \brief Output = MD5( input buffer )
* *
* \param input buffer holding the data * \param input buffer holding the data
* \param ilen length of the input data * \param ilen length of the input data
* \param output MD5 checksum result * \param output MD5 checksum result
*/ */
void md5( unsigned char *input, int ilen, unsigned char output[16] ); void md5( unsigned char *input, int ilen, unsigned char output[16] );
/** /**
* \brief Output = MD5( file contents ) * \brief Output = MD5( file contents )
* *
* \param path input file name * \param path input file name
* \param output MD5 checksum result * \param output MD5 checksum result
* *
* \return 0 if successful, 1 if fopen failed, * \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed * or 2 if fread failed
*/ */
int md5_file( char *path, unsigned char output[16] ); int md5_file( char *path, unsigned char output[16] );
/** /**
* \brief MD5 HMAC context setup * \brief MD5 HMAC context setup
* *
* \param ctx HMAC context to be initialized * \param ctx HMAC context to be initialized
* \param key HMAC secret key * \param key HMAC secret key
* \param keylen length of the HMAC key * \param keylen length of the HMAC key
*/ */
void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen ); void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen );
/** /**
* \brief MD5 HMAC process buffer * \brief MD5 HMAC process buffer
* *
* \param ctx HMAC context * \param ctx HMAC context
* \param input buffer holding the data * \param input buffer holding the data
* \param ilen length of the input data * \param ilen length of the input data
*/ */
void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen ); void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen );
/** /**
* \brief MD5 HMAC final digest * \brief MD5 HMAC final digest
* *
* \param ctx HMAC context * \param ctx HMAC context
* \param output MD5 HMAC checksum result * \param output MD5 HMAC checksum result
*/ */
void md5_hmac_finish( md5_context *ctx, unsigned char output[16] ); void md5_hmac_finish( md5_context *ctx, unsigned char output[16] );
/** /**
* \brief Output = HMAC-MD5( hmac key, input buffer ) * \brief Output = HMAC-MD5( hmac key, input buffer )
* *
* \param key HMAC secret key * \param key HMAC secret key
* \param keylen length of the HMAC key * \param keylen length of the HMAC key
* \param input buffer holding the data * \param input buffer holding the data
* \param ilen length of the input data * \param ilen length of the input data
* \param output HMAC-MD5 result * \param output HMAC-MD5 result
*/ */
void md5_hmac( unsigned char *key, int keylen, void md5_hmac( unsigned char *key, int keylen,
unsigned char *input, int ilen, unsigned char *input, int ilen,
unsigned char output[16] ); unsigned char output[16] );
/** /**
* \brief Checkup routine * \brief Checkup routine
* *
* \return 0 if successful, or 1 if the test failed * \return 0 if successful, or 1 if the test failed
*/ */
int md5_self_test( int verbose ); int md5_self_test( int verbose );
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* md5.h */ #endif /* md5.h */

File diff suppressed because it is too large Load Diff

View File

@ -1,138 +1,138 @@
/** /**
* \file sha1.h * \file sha1.h
* *
* Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org> * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
* All rights reserved. * All rights reserved.
* *
* Joined copyright on original XySSL code with: Christophe Devine * Joined copyright on original XySSL code with: Christophe Devine
* *
* 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; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* 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 for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef POLARSSL_SHA1_H #ifndef POLARSSL_SHA1_H
#define POLARSSL_SHA1_H #define POLARSSL_SHA1_H
/** /**
* \brief SHA-1 context structure * \brief SHA-1 context structure
*/ */
typedef struct typedef struct
{ {
unsigned long total[2]; /*!< number of bytes processed */ unsigned long total[2]; /*!< number of bytes processed */
unsigned long state[5]; /*!< intermediate digest state */ unsigned long state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */ unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */ unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */ unsigned char opad[64]; /*!< HMAC: outer padding */
} }
sha1_context; sha1_context;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/** /**
* \brief SHA-1 context setup * \brief SHA-1 context setup
* *
* \param ctx context to be initialized * \param ctx context to be initialized
*/ */
void sha1_starts( sha1_context *ctx ); void sha1_starts( sha1_context *ctx );
/** /**
* \brief SHA-1 process buffer * \brief SHA-1 process buffer
* *
* \param ctx SHA-1 context * \param ctx SHA-1 context
* \param input buffer holding the data * \param input buffer holding the data
* \param ilen length of the input data * \param ilen length of the input data
*/ */
void sha1_update( sha1_context *ctx, unsigned char *input, int ilen ); void sha1_update( sha1_context *ctx, unsigned char *input, int ilen );
/** /**
* \brief SHA-1 final digest * \brief SHA-1 final digest
* *
* \param ctx SHA-1 context * \param ctx SHA-1 context
* \param output SHA-1 checksum result * \param output SHA-1 checksum result
*/ */
void sha1_finish( sha1_context *ctx, unsigned char output[20] ); void sha1_finish( sha1_context *ctx, unsigned char output[20] );
/** /**
* \brief Output = SHA-1( input buffer ) * \brief Output = SHA-1( input buffer )
* *
* \param input buffer holding the data * \param input buffer holding the data
* \param ilen length of the input data * \param ilen length of the input data
* \param output SHA-1 checksum result * \param output SHA-1 checksum result
*/ */
void sha1( unsigned char *input, int ilen, unsigned char output[20] ); void sha1( unsigned char *input, int ilen, unsigned char output[20] );
/** /**
* \brief Output = SHA-1( file contents ) * \brief Output = SHA-1( file contents )
* *
* \param path input file name * \param path input file name
* \param output SHA-1 checksum result * \param output SHA-1 checksum result
* *
* \return 0 if successful, 1 if fopen failed, * \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed * or 2 if fread failed
*/ */
int sha1_file( char *path, unsigned char output[20] ); int sha1_file( char *path, unsigned char output[20] );
/** /**
* \brief SHA-1 HMAC context setup * \brief SHA-1 HMAC context setup
* *
* \param ctx HMAC context to be initialized * \param ctx HMAC context to be initialized
* \param key HMAC secret key * \param key HMAC secret key
* \param keylen length of the HMAC key * \param keylen length of the HMAC key
*/ */
void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen ); void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen );
/** /**
* \brief SHA-1 HMAC process buffer * \brief SHA-1 HMAC process buffer
* *
* \param ctx HMAC context * \param ctx HMAC context
* \param input buffer holding the data * \param input buffer holding the data
* \param ilen length of the input data * \param ilen length of the input data
*/ */
void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen ); void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen );
/** /**
* \brief SHA-1 HMAC final digest * \brief SHA-1 HMAC final digest
* *
* \param ctx HMAC context * \param ctx HMAC context
* \param output SHA-1 HMAC checksum result * \param output SHA-1 HMAC checksum result
*/ */
void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ); void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] );
/** /**
* \brief Output = HMAC-SHA-1( hmac key, input buffer ) * \brief Output = HMAC-SHA-1( hmac key, input buffer )
* *
* \param key HMAC secret key * \param key HMAC secret key
* \param keylen length of the HMAC key * \param keylen length of the HMAC key
* \param input buffer holding the data * \param input buffer holding the data
* \param ilen length of the input data * \param ilen length of the input data
* \param output HMAC-SHA-1 result * \param output HMAC-SHA-1 result
*/ */
void sha1_hmac( unsigned char *key, int keylen, void sha1_hmac( unsigned char *key, int keylen,
unsigned char *input, int ilen, unsigned char *input, int ilen,
unsigned char output[20] ); unsigned char output[20] );
/** /**
* \brief Checkup routine * \brief Checkup routine
* *
* \return 0 if successful, or 1 if the test failed * \return 0 if successful, or 1 if the test failed
*/ */
int sha1_self_test( int verbose ); int sha1_self_test( int verbose );
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* sha1.h */ #endif /* sha1.h */

View File

@ -1,21 +1,21 @@
// Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org> // Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
// Licensed under the terms of the GNU GPL, version 2 // Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
#ifndef _TOOLS_H #ifndef _TOOLS_H
#define _TOOLS_H #define _TOOLS_H
#include "sha1.h" #include "sha1.h"
// bignum // bignum
int bn_compare(u8 *a, u8 *b, u32 n); int bn_compare(u8 *a, u8 *b, u32 n);
void bn_sub_modulus(u8 *a, u8 *N, u32 n); void bn_sub_modulus(u8 *a, u8 *N, u32 n);
void bn_add(u8 *d, u8 *a, u8 *b, u8 *N, u32 n); void bn_add(u8 *d, u8 *a, u8 *b, u8 *N, u32 n);
void bn_mul(u8 *d, u8 *a, u8 *b, u8 *N, u32 n); void bn_mul(u8 *d, u8 *a, u8 *b, u8 *N, u32 n);
void bn_inv(u8 *d, u8 *a, u8 *N, u32 n); // only for prime N void bn_inv(u8 *d, u8 *a, u8 *N, u32 n); // only for prime N
void bn_exp(u8 *d, u8 *a, u8 *N, u32 n, u8 *e, u32 en); void bn_exp(u8 *d, u8 *a, u8 *N, u32 n, u8 *e, u32 en);
void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash); void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash);
void ec_priv_to_pub(u8 *k, u8 *Q); void ec_priv_to_pub(u8 *k, u8 *Q);
#endif #endif

View File

@ -1,149 +1,149 @@
// 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 "LinearDiskCache.h" #include "LinearDiskCache.h"
static const char ID[4] = {'D', 'C', 'A', 'C'}; static const char ID[4] = {'D', 'C', 'A', 'C'};
const int version = 4888; // TODO: Get from SVN_REV const int version = 4888; // TODO: Get from SVN_REV
LinearDiskCache::LinearDiskCache() LinearDiskCache::LinearDiskCache()
: file_(NULL), num_entries_(0) { : file_(NULL), num_entries_(0) {
} }
void LinearDiskCache::WriteHeader() { void LinearDiskCache::WriteHeader() {
fwrite(ID, 4, 1, file_); fwrite(ID, 4, 1, file_);
fwrite(&version, 4, 1, file_); fwrite(&version, 4, 1, file_);
} }
bool LinearDiskCache::ValidateHeader() { bool LinearDiskCache::ValidateHeader() {
char header_id[4]; char header_id[4];
int header_version; int header_version;
fread(&header_id, 4, 1, file_); fread(&header_id, 4, 1, file_);
fread(&header_version, 4, 1, file_); fread(&header_version, 4, 1, file_);
if (memcmp(header_id, ID, 4) != 0) if (memcmp(header_id, ID, 4) != 0)
return false; return false;
if (header_version != version) if (header_version != version)
return false; return false;
return true; return true;
} }
int LinearDiskCache::OpenAndRead(const char *filename, LinearDiskCacheReader *reader) { int LinearDiskCache::OpenAndRead(const char *filename, LinearDiskCacheReader *reader) {
int items_read_count = 0; int items_read_count = 0;
file_ = fopen(filename, "rb"); file_ = fopen(filename, "rb");
int file_size = 0; int file_size = 0;
if (file_) { if (file_) {
fseek(file_, 0, SEEK_END); fseek(file_, 0, SEEK_END);
file_size = (int)ftell(file_); file_size = (int)ftell(file_);
} }
bool file_corrupt = false; bool file_corrupt = false;
if (file_size == 0) { if (file_size == 0) {
if (file_) if (file_)
fclose(file_); fclose(file_);
// Reopen for writing. // Reopen for writing.
file_ = fopen(filename, "wb"); file_ = fopen(filename, "wb");
// Cache empty, let's initialize a header. // Cache empty, let's initialize a header.
WriteHeader(); WriteHeader();
num_entries_ = 0; num_entries_ = 0;
} else { } else {
// file_ must be != 0 here. // file_ must be != 0 here.
// Back to the start we go. // Back to the start we go.
fseek(file_, 0, SEEK_SET); fseek(file_, 0, SEEK_SET);
// Check that the file is valid // Check that the file is valid
if (!ValidateHeader()) { if (!ValidateHeader()) {
// Not valid - delete the file and start over. // Not valid - delete the file and start over.
fclose(file_); fclose(file_);
unlink(filename); unlink(filename);
// PanicAlert("LinearDiskCache file header broken."); // PanicAlert("LinearDiskCache file header broken.");
file_ = fopen(filename, "wb"); file_ = fopen(filename, "wb");
WriteHeader(); WriteHeader();
num_entries_ = 0; num_entries_ = 0;
} else { } else {
// Valid - blow through it. // Valid - blow through it.
// We're past the header already thanks to ValidateHeader. // We're past the header already thanks to ValidateHeader.
while (!feof(file_)) { while (!feof(file_)) {
int key_size, value_size; int key_size, value_size;
size_t key_size_size = fread(&key_size, 1, sizeof(key_size), file_); size_t key_size_size = fread(&key_size, 1, sizeof(key_size), file_);
size_t value_size_size = fread(&value_size, 1, sizeof(value_size), file_); size_t value_size_size = fread(&value_size, 1, sizeof(value_size), file_);
if (key_size_size == 0 && value_size_size == 0) { if (key_size_size == 0 && value_size_size == 0) {
// I guess feof isn't doing it's job - we're at the end. // I guess feof isn't doing it's job - we're at the end.
break; break;
} }
if (key_size <= 0 || value_size < 0 || key_size_size != 4 || value_size_size != 4) { if (key_size <= 0 || value_size < 0 || key_size_size != 4 || value_size_size != 4) {
// PanicAlert("Disk cache file %s corrupted/truncated! ks: %i vs %i kss %i vss %i", filename, // PanicAlert("Disk cache file %s corrupted/truncated! ks: %i vs %i kss %i vss %i", filename,
// key_size, value_size, key_size_size, value_size_size); // key_size, value_size, key_size_size, value_size_size);
file_corrupt = true; file_corrupt = true;
break; break;
} }
u8 *key = new u8[key_size]; u8 *key = new u8[key_size];
u8 *value = new u8[value_size]; u8 *value = new u8[value_size];
int actual_key_size = (int)fread(key, 1, key_size, file_); int actual_key_size = (int)fread(key, 1, key_size, file_);
int actual_value_size = (int)fread(value, 1, value_size, file_); int actual_value_size = (int)fread(value, 1, value_size, file_);
if (actual_key_size != key_size || actual_value_size != value_size) { if (actual_key_size != key_size || actual_value_size != value_size) {
// PanicAlert("Disk cache file %s corrupted/truncated! ks: %i actual ks: %i vs: %i actual vs: %i", filename, // PanicAlert("Disk cache file %s corrupted/truncated! ks: %i actual ks: %i vs: %i actual vs: %i", filename,
// key_size, actual_key_size, value_size, actual_value_size); // key_size, actual_key_size, value_size, actual_value_size);
file_corrupt = true; file_corrupt = true;
} else { } else {
reader->Read(key, key_size, value, value_size); reader->Read(key, key_size, value, value_size);
items_read_count++; items_read_count++;
} }
delete [] key; delete [] key;
delete [] value; delete [] value;
} }
fclose(file_); fclose(file_);
// Done reading. // Done reading.
// Reopen file for append. // Reopen file for append.
// At this point, ftell() will be at the end of the file, // At this point, ftell() will be at the end of the file,
// which happens to be exactly what we want. // which happens to be exactly what we want.
file_ = fopen(filename, "ab"); file_ = fopen(filename, "ab");
fseek(file_, 0, SEEK_END); fseek(file_, 0, SEEK_END);
} }
} }
if (file_corrupt) { if (file_corrupt) {
// Restore sanity, start over. // Restore sanity, start over.
fclose(file_); fclose(file_);
unlink(filename); unlink(filename);
file_ = fopen(filename, "wb+"); file_ = fopen(filename, "wb+");
WriteHeader(); WriteHeader();
} }
return items_read_count; return items_read_count;
} }
void LinearDiskCache::Append( void LinearDiskCache::Append(
const u8 *key, int key_size, const u8 *value, int value_size) { const u8 *key, int key_size, const u8 *value, int value_size) {
// Should do a check that we don't already have "key"? // Should do a check that we don't already have "key"?
fwrite(&key_size, 1, sizeof(key_size), file_); fwrite(&key_size, 1, sizeof(key_size), file_);
fwrite(&value_size, 1, sizeof(value_size), file_); fwrite(&value_size, 1, sizeof(value_size), file_);
fwrite(key, 1, key_size, file_); fwrite(key, 1, key_size, file_);
fwrite(value, 1, value_size, file_); fwrite(value, 1, value_size, file_);
} }
void LinearDiskCache::Sync() { void LinearDiskCache::Sync() {
fflush(file_); fflush(file_);
} }
void LinearDiskCache::Close() { void LinearDiskCache::Close() {
fclose(file_); fclose(file_);
file_ = 0; file_ = 0;
num_entries_ = 0; num_entries_ = 0;
} }

View File

@ -1,67 +1,67 @@
// 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/
#ifndef _LINEAR_DISKCACHE #ifndef _LINEAR_DISKCACHE
#define _LINEAR_DISKCACHE #define _LINEAR_DISKCACHE
#include "Common.h" #include "Common.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
// On disk format: // On disk format:
// uint32 'DCAC' // uint32 'DCAC'
// uint32 version; // svn_rev // uint32 version; // svn_rev
// uint32 key_length; // uint32 key_length;
// uint32 value_length; // uint32 value_length;
// .... key; // .... key;
// .... value; // .... value;
class LinearDiskCacheReader { class LinearDiskCacheReader {
public: public:
virtual void Read(const u8 *key, int key_size, const u8 *value, int value_size) = 0; virtual void Read(const u8 *key, int key_size, const u8 *value, int value_size) = 0;
}; };
// Dead simple unsorted key-value store with append functionality. // Dead simple unsorted key-value store with append functionality.
// No random read functionality, all reading is done in OpenAndRead. // No random read functionality, all reading is done in OpenAndRead.
// Keys and values can contain any characters, including \0. // Keys and values can contain any characters, including \0.
// //
// Suitable for caching generated shader bytecode between executions. // Suitable for caching generated shader bytecode between executions.
// Not tuned for extreme performance but should be reasonably fast. // Not tuned for extreme performance but should be reasonably fast.
// Does not support keys or values larger than 2GB, which should be reasonable. // Does not support keys or values larger than 2GB, which should be reasonable.
// Keys must have non-zero length; values can have zero length. // Keys must have non-zero length; values can have zero length.
class LinearDiskCache { class LinearDiskCache {
public: public:
LinearDiskCache(); LinearDiskCache();
// Returns the number of items read from the cache. // Returns the number of items read from the cache.
int OpenAndRead(const char *filename, LinearDiskCacheReader *reader); int OpenAndRead(const char *filename, LinearDiskCacheReader *reader);
void Close(); void Close();
void Sync(); void Sync();
// Appends a key-value pair to the store. // Appends a key-value pair to the store.
void Append(const u8 *key, int key_size, const u8 *value, int value_size); void Append(const u8 *key, int key_size, const u8 *value, int value_size);
private: private:
void WriteHeader(); void WriteHeader();
bool ValidateHeader(); bool ValidateHeader();
FILE *file_; FILE *file_;
int num_entries_; int num_entries_;
}; };
#endif // _LINEAR_DISKCACHE #endif // _LINEAR_DISKCACHE

View File

@ -1,253 +1,253 @@
// 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/
// TODO: Make a more centralized version of this (for now every plugin that will use it will create its own context, which is weird). An object maybe? // TODO: Make a more centralized version of this (for now every plugin that will use it will create its own context, which is weird). An object maybe?
#include "OpenCL.h" #include "OpenCL.h"
#include "Common.h" #include "Common.h"
#include "Timer.h" #include "Timer.h"
namespace OpenCL namespace OpenCL
{ {
#if defined(HAVE_OPENCL) && HAVE_OPENCL #if defined(HAVE_OPENCL) && HAVE_OPENCL
cl_device_id device_id = NULL; cl_device_id device_id = NULL;
cl_context g_context = NULL; cl_context g_context = NULL;
cl_command_queue g_cmdq = NULL; cl_command_queue g_cmdq = NULL;
#endif #endif
bool g_bInitialized = false; bool g_bInitialized = false;
bool Initialize() bool Initialize()
{ {
if(g_bInitialized) if(g_bInitialized)
return true; return true;
#if defined(HAVE_OPENCL) && HAVE_OPENCL #if defined(HAVE_OPENCL) && HAVE_OPENCL
if(g_context) if(g_context)
return false; return false;
int err; // error code returned from api calls int err; // error code returned from api calls
// Connect to a compute device // Connect to a compute device
cl_uint numPlatforms; cl_uint numPlatforms;
cl_platform_id platform = NULL; cl_platform_id platform = NULL;
err = clGetPlatformIDs(0, NULL, &numPlatforms); err = clGetPlatformIDs(0, NULL, &numPlatforms);
if (err != CL_SUCCESS) if (err != CL_SUCCESS)
{ {
HandleCLError(err, "clGetPlatformIDs failed."); HandleCLError(err, "clGetPlatformIDs failed.");
return false; return false;
} }
if (0 < numPlatforms) if (0 < numPlatforms)
{ {
cl_platform_id* platforms = new cl_platform_id[numPlatforms]; cl_platform_id* platforms = new cl_platform_id[numPlatforms];
err = clGetPlatformIDs(numPlatforms, platforms, NULL); err = clGetPlatformIDs(numPlatforms, platforms, NULL);
if (err != CL_SUCCESS) if (err != CL_SUCCESS)
{ {
HandleCLError(err, "clGetPlatformIDs failed."); HandleCLError(err, "clGetPlatformIDs failed.");
return false; return false;
} }
char pbuf[100]; char pbuf[100];
err = clGetPlatformInfo(platforms[0], CL_PLATFORM_VENDOR, sizeof(pbuf), pbuf, NULL); err = clGetPlatformInfo(platforms[0], CL_PLATFORM_VENDOR, sizeof(pbuf), pbuf, NULL);
if (err != CL_SUCCESS) if (err != CL_SUCCESS)
{ {
HandleCLError(err, "clGetPlatformInfo failed."); HandleCLError(err, "clGetPlatformInfo failed.");
return false; return false;
} }
platform = platforms[0]; platform = platforms[0];
delete[] platforms; delete[] platforms;
} }
else else
{ {
PanicAlert("No OpenCL platform found."); PanicAlert("No OpenCL platform found.");
return false; return false;
} }
cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0}; cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0};
cl_context_properties* cprops = (NULL == platform) ? NULL : cps; cl_context_properties* cprops = (NULL == platform) ? NULL : cps;
int gpu = 1; // I think we should use CL_DEVICE_TYPE_ALL int gpu = 1; // I think we should use CL_DEVICE_TYPE_ALL
err = clGetDeviceIDs(platform, gpu ? CL_DEVICE_TYPE_GPU : CL_DEVICE_TYPE_CPU, 1, &device_id, NULL); err = clGetDeviceIDs(platform, gpu ? CL_DEVICE_TYPE_GPU : CL_DEVICE_TYPE_CPU, 1, &device_id, NULL);
if (err != CL_SUCCESS) if (err != CL_SUCCESS)
{ {
HandleCLError(err, "Failed to create a device group!"); HandleCLError(err, "Failed to create a device group!");
return false; return false;
} }
// Create a compute context // Create a compute context
g_context = clCreateContext(cprops, 1, &device_id, NULL, NULL, &err); g_context = clCreateContext(cprops, 1, &device_id, NULL, NULL, &err);
if (!g_context) if (!g_context)
{ {
HandleCLError(err, "Failed to create a compute context!"); HandleCLError(err, "Failed to create a compute context!");
return false; return false;
} }
// Create a command commands // Create a command commands
g_cmdq = clCreateCommandQueue(g_context, device_id, 0, &err); g_cmdq = clCreateCommandQueue(g_context, device_id, 0, &err);
if (!g_cmdq) if (!g_cmdq)
{ {
HandleCLError(err, "Failed to create a command commands!"); HandleCLError(err, "Failed to create a command commands!");
return false; return false;
} }
NOTICE_LOG(COMMON, "Initialized OpenCL!"); NOTICE_LOG(COMMON, "Initialized OpenCL!");
g_bInitialized = true; g_bInitialized = true;
return true; return true;
#else #else
return false; return false;
#endif #endif
} }
#if defined(HAVE_OPENCL) && HAVE_OPENCL #if defined(HAVE_OPENCL) && HAVE_OPENCL
cl_context GetContext() cl_context GetContext()
{ {
return g_context; return g_context;
} }
cl_command_queue GetCommandQueue() cl_command_queue GetCommandQueue()
{ {
return g_cmdq; return g_cmdq;
} }
cl_program CompileProgram(const char *Kernel) cl_program CompileProgram(const char *Kernel)
{ {
u32 compileStart = Common::Timer::GetTimeMs(); u32 compileStart = Common::Timer::GetTimeMs();
int err; int err;
cl_program program; cl_program program;
program = clCreateProgramWithSource(OpenCL::g_context, 1, (const char **) & Kernel, NULL, &err); program = clCreateProgramWithSource(OpenCL::g_context, 1, (const char **) & Kernel, NULL, &err);
if (!program) if (!program)
{ {
HandleCLError(err, "Error: Failed to create compute program!"); HandleCLError(err, "Error: Failed to create compute program!");
return NULL; return NULL;
} }
// Build the program executable // Build the program executable
err = clBuildProgram(program , 0, NULL, NULL, NULL, NULL); err = clBuildProgram(program , 0, NULL, NULL, NULL, NULL);
if(err != CL_SUCCESS) { if(err != CL_SUCCESS) {
char *errors[16384] = {0}; char *errors[16384] = {0};
err = clGetProgramBuildInfo(program, OpenCL::device_id, CL_PROGRAM_BUILD_LOG, sizeof(errors), err = clGetProgramBuildInfo(program, OpenCL::device_id, CL_PROGRAM_BUILD_LOG, sizeof(errors),
errors, NULL); errors, NULL);
ERROR_LOG(COMMON, "Error log:\n%s\n", errors); ERROR_LOG(COMMON, "Error log:\n%s\n", errors);
return NULL; return NULL;
} }
NOTICE_LOG(COMMON, "OpenCL CompileProgram took %.3f seconds", (float)(Common::Timer::GetTimeMs() - compileStart) / 1000.0); NOTICE_LOG(COMMON, "OpenCL CompileProgram took %.3f seconds", (float)(Common::Timer::GetTimeMs() - compileStart) / 1000.0);
return program; return program;
} }
cl_kernel CompileKernel(cl_program program, const char *Function) cl_kernel CompileKernel(cl_program program, const char *Function)
{ {
u32 compileStart = Common::Timer::GetTimeMs(); u32 compileStart = Common::Timer::GetTimeMs();
int err; int err;
// Create the compute kernel in the program we wish to run // Create the compute kernel in the program we wish to run
cl_kernel kernel = clCreateKernel(program, Function, &err); cl_kernel kernel = clCreateKernel(program, Function, &err);
if (!kernel || err != CL_SUCCESS) if (!kernel || err != CL_SUCCESS)
{ {
HandleCLError(err, "Failed to create compute kernel!"); HandleCLError(err, "Failed to create compute kernel!");
return NULL; return NULL;
} }
NOTICE_LOG(COMMON, "OpenCL CompileKernel took %.3f seconds", (float)(Common::Timer::GetTimeMs() - compileStart) / 1000.0); NOTICE_LOG(COMMON, "OpenCL CompileKernel took %.3f seconds", (float)(Common::Timer::GetTimeMs() - compileStart) / 1000.0);
return kernel; return kernel;
} }
#endif #endif
void Destroy() void Destroy()
{ {
#if defined(HAVE_OPENCL) && HAVE_OPENCL #if defined(HAVE_OPENCL) && HAVE_OPENCL
if(!g_context) if(!g_context)
return; return;
clReleaseCommandQueue(g_cmdq); clReleaseCommandQueue(g_cmdq);
clReleaseContext(g_context); clReleaseContext(g_context);
g_context = NULL; g_context = NULL;
g_cmdq = NULL; g_cmdq = NULL;
g_bInitialized = false; g_bInitialized = false;
#endif #endif
} }
void HandleCLError(cl_int error, char* str) void HandleCLError(cl_int error, char* str)
{ {
#if defined(HAVE_OPENCL) && HAVE_OPENCL #if defined(HAVE_OPENCL) && HAVE_OPENCL
char* name; char* name;
switch(error) switch(error)
{ {
#define CL_ERROR(x) case (x): name = #x; break #define CL_ERROR(x) case (x): name = #x; break
CL_ERROR(CL_SUCCESS); CL_ERROR(CL_SUCCESS);
CL_ERROR(CL_DEVICE_NOT_FOUND); CL_ERROR(CL_DEVICE_NOT_FOUND);
CL_ERROR(CL_DEVICE_NOT_AVAILABLE); CL_ERROR(CL_DEVICE_NOT_AVAILABLE);
CL_ERROR(CL_COMPILER_NOT_AVAILABLE); CL_ERROR(CL_COMPILER_NOT_AVAILABLE);
CL_ERROR(CL_MEM_OBJECT_ALLOCATION_FAILURE); CL_ERROR(CL_MEM_OBJECT_ALLOCATION_FAILURE);
CL_ERROR(CL_OUT_OF_RESOURCES); CL_ERROR(CL_OUT_OF_RESOURCES);
CL_ERROR(CL_OUT_OF_HOST_MEMORY); CL_ERROR(CL_OUT_OF_HOST_MEMORY);
CL_ERROR(CL_PROFILING_INFO_NOT_AVAILABLE); CL_ERROR(CL_PROFILING_INFO_NOT_AVAILABLE);
CL_ERROR(CL_MEM_COPY_OVERLAP); CL_ERROR(CL_MEM_COPY_OVERLAP);
CL_ERROR(CL_IMAGE_FORMAT_MISMATCH); CL_ERROR(CL_IMAGE_FORMAT_MISMATCH);
CL_ERROR(CL_IMAGE_FORMAT_NOT_SUPPORTED); CL_ERROR(CL_IMAGE_FORMAT_NOT_SUPPORTED);
CL_ERROR(CL_BUILD_PROGRAM_FAILURE); CL_ERROR(CL_BUILD_PROGRAM_FAILURE);
CL_ERROR(CL_MAP_FAILURE); CL_ERROR(CL_MAP_FAILURE);
CL_ERROR(CL_INVALID_VALUE); CL_ERROR(CL_INVALID_VALUE);
CL_ERROR(CL_INVALID_DEVICE_TYPE); CL_ERROR(CL_INVALID_DEVICE_TYPE);
CL_ERROR(CL_INVALID_PLATFORM); CL_ERROR(CL_INVALID_PLATFORM);
CL_ERROR(CL_INVALID_DEVICE); CL_ERROR(CL_INVALID_DEVICE);
CL_ERROR(CL_INVALID_CONTEXT); CL_ERROR(CL_INVALID_CONTEXT);
CL_ERROR(CL_INVALID_QUEUE_PROPERTIES); CL_ERROR(CL_INVALID_QUEUE_PROPERTIES);
CL_ERROR(CL_INVALID_COMMAND_QUEUE); CL_ERROR(CL_INVALID_COMMAND_QUEUE);
CL_ERROR(CL_INVALID_HOST_PTR); CL_ERROR(CL_INVALID_HOST_PTR);
CL_ERROR(CL_INVALID_MEM_OBJECT); CL_ERROR(CL_INVALID_MEM_OBJECT);
CL_ERROR(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR); CL_ERROR(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR);
CL_ERROR(CL_INVALID_IMAGE_SIZE); CL_ERROR(CL_INVALID_IMAGE_SIZE);
CL_ERROR(CL_INVALID_SAMPLER); CL_ERROR(CL_INVALID_SAMPLER);
CL_ERROR(CL_INVALID_BINARY); CL_ERROR(CL_INVALID_BINARY);
CL_ERROR(CL_INVALID_BUILD_OPTIONS); CL_ERROR(CL_INVALID_BUILD_OPTIONS);
CL_ERROR(CL_INVALID_PROGRAM); CL_ERROR(CL_INVALID_PROGRAM);
CL_ERROR(CL_INVALID_PROGRAM_EXECUTABLE); CL_ERROR(CL_INVALID_PROGRAM_EXECUTABLE);
CL_ERROR(CL_INVALID_KERNEL_NAME); CL_ERROR(CL_INVALID_KERNEL_NAME);
CL_ERROR(CL_INVALID_KERNEL_DEFINITION); CL_ERROR(CL_INVALID_KERNEL_DEFINITION);
CL_ERROR(CL_INVALID_KERNEL); CL_ERROR(CL_INVALID_KERNEL);
CL_ERROR(CL_INVALID_ARG_INDEX); CL_ERROR(CL_INVALID_ARG_INDEX);
CL_ERROR(CL_INVALID_ARG_VALUE); CL_ERROR(CL_INVALID_ARG_VALUE);
CL_ERROR(CL_INVALID_ARG_SIZE); CL_ERROR(CL_INVALID_ARG_SIZE);
CL_ERROR(CL_INVALID_KERNEL_ARGS); CL_ERROR(CL_INVALID_KERNEL_ARGS);
CL_ERROR(CL_INVALID_WORK_DIMENSION); CL_ERROR(CL_INVALID_WORK_DIMENSION);
CL_ERROR(CL_INVALID_WORK_GROUP_SIZE); CL_ERROR(CL_INVALID_WORK_GROUP_SIZE);
CL_ERROR(CL_INVALID_WORK_ITEM_SIZE); CL_ERROR(CL_INVALID_WORK_ITEM_SIZE);
CL_ERROR(CL_INVALID_GLOBAL_OFFSET); CL_ERROR(CL_INVALID_GLOBAL_OFFSET);
CL_ERROR(CL_INVALID_EVENT_WAIT_LIST); CL_ERROR(CL_INVALID_EVENT_WAIT_LIST);
CL_ERROR(CL_INVALID_EVENT); CL_ERROR(CL_INVALID_EVENT);
CL_ERROR(CL_INVALID_OPERATION); CL_ERROR(CL_INVALID_OPERATION);
CL_ERROR(CL_INVALID_GL_OBJECT); CL_ERROR(CL_INVALID_GL_OBJECT);
CL_ERROR(CL_INVALID_BUFFER_SIZE); CL_ERROR(CL_INVALID_BUFFER_SIZE);
CL_ERROR(CL_INVALID_MIP_LEVEL); CL_ERROR(CL_INVALID_MIP_LEVEL);
#undef CL_ERROR #undef CL_ERROR
default: default:
name = "Unknown error code"; name = "Unknown error code";
} }
if(!str) if(!str)
str = ""; str = "";
ERROR_LOG(COMMON, "OpenCL error: %s %s (%d)", str, name, error); ERROR_LOG(COMMON, "OpenCL error: %s %s (%d)", str, name, error);
#endif #endif
} }
} }

View File

@ -1,70 +1,70 @@
// 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/
#ifndef __OPENCL_H__ #ifndef __OPENCL_H__
#define __OPENCL_H__ #define __OPENCL_H__
#include "Common.h" #include "Common.h"
// Change to #if 1 if you want to test OpenCL (and you have it) on Windows // Change to #if 1 if you want to test OpenCL (and you have it) on Windows
#if 0 #if 0
#pragma comment(lib, "OpenCL.lib") #pragma comment(lib, "OpenCL.lib")
#define HAVE_OPENCL 1 #define HAVE_OPENCL 1
#endif #endif
#if defined(HAVE_OPENCL) && HAVE_OPENCL #if defined(HAVE_OPENCL) && HAVE_OPENCL
#ifdef __APPLE__ #ifdef __APPLE__
#include <OpenCL/opencl.h> #include <OpenCL/opencl.h>
#else #else
#include <CL/cl.h> #include <CL/cl.h>
#endif #endif
#else #else
typedef void *cl_context; typedef void *cl_context;
typedef void *cl_command_queue; typedef void *cl_command_queue;
typedef void *cl_program; typedef void *cl_program;
typedef void *cl_kernel; typedef void *cl_kernel;
typedef void *cl_mem; typedef void *cl_mem;
typedef void *cl_int; typedef void *cl_int;
#endif #endif
namespace OpenCL namespace OpenCL
{ {
#if defined(HAVE_OPENCL) && HAVE_OPENCL #if defined(HAVE_OPENCL) && HAVE_OPENCL
extern cl_device_id device_id; extern cl_device_id device_id;
extern cl_context g_context; extern cl_context g_context;
extern cl_command_queue g_cmdq; extern cl_command_queue g_cmdq;
#endif #endif
bool Initialize(); bool Initialize();
cl_context GetContext(); cl_context GetContext();
cl_command_queue GetCommandQueue(); cl_command_queue GetCommandQueue();
void Destroy(); void Destroy();
cl_program CompileProgram(const char *Kernel); cl_program CompileProgram(const char *Kernel);
cl_kernel CompileKernel(cl_program program, const char *Function); cl_kernel CompileKernel(cl_program program, const char *Function);
void HandleCLError(cl_int error, char* str = 0); void HandleCLError(cl_int error, char* str = 0);
} }
#endif #endif

View File

@ -1,175 +1,173 @@
// 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 "FileUtil.h" #include "FileUtil.h"
#include "SysConf.h" #include "SysConf.h"
SysConf::SysConf() SysConf::SysConf()
: m_IsValid(false) : m_IsValid(false)
{ {
if (LoadFromFile(File::GetUserPath(F_WIISYSCONF_IDX))) if (LoadFromFile(File::GetUserPath(F_WIISYSCONF_IDX)))
m_IsValid = true; m_IsValid = true;
} }
void SysConf::Reload() void SysConf::Reload()
{ {
if (m_IsValid) if (m_IsValid)
return; return;
if (LoadFromFile(File::GetUserPath(F_WIISYSCONF_IDX))) if (LoadFromFile(File::GetUserPath(F_WIISYSCONF_IDX)))
m_IsValid = true; m_IsValid = true;
}
SysConf::~SysConf()
{
if (!m_IsValid)
return;
for (size_t i = 0; i < m_Entries.size() - 1; i++)
{
delete [] m_Entries.at(i).data;
m_Entries.at(i).data = NULL;
}
}
bool SysConf::LoadFromFile(const char *filename)
{
// Basic check
u64 size = File::GetSize(filename);
if (size == 0)
return false; //most likely: file does not exist
if (size != SYSCONF_SIZE)
{
PanicAlert("Your SYSCONF file is the wrong size - should be 0x%04x (but is 0x%04x)",
SYSCONF_SIZE, size);
return false;
}
FILE* f = fopen(filename, "rb");
if (f == NULL)
return false;
bool result = LoadFromFileInternal(f);
if (result)
{
// OK, done!
m_Filename = filename;
}
fclose(f);
return result;
}
bool SysConf::LoadFromFileInternal(FILE *f)
{
// Fill in infos
if (fread(&m_Header.version, sizeof(m_Header.version), 1, f) != 1) return false;
if (fread(&m_Header.numEntries, sizeof(m_Header.numEntries), 1, f) != 1) return false;
m_Header.numEntries = Common::swap16(m_Header.numEntries) + 1;
for (u16 index = 0; index < m_Header.numEntries; index++)
{
SSysConfEntry tmpEntry;
if (fread(&tmpEntry.offset, sizeof(tmpEntry.offset), 1, f) != 1) return false;
tmpEntry.offset = Common::swap16(tmpEntry.offset);
m_Entries.push_back(tmpEntry);
}
// Last offset is an invalid entry. We ignore it throughout this class
for (size_t i = 0; i < m_Entries.size() - 1; i++)
{
SSysConfEntry& curEntry = m_Entries.at(i);
if (fseek(f, curEntry.offset, SEEK_SET) != 0) return false;
u8 description = 0;
if (fread(&description, sizeof(description), 1, f) != 1) return false;
// Data type
curEntry.type = (SysconfType)((description & 0xe0) >> 5);
// Length of name in bytes - 1
curEntry.nameLength = (description & 0x1f) + 1;
// Name
if (fread(&curEntry.name, curEntry.nameLength, 1, f) != 1) return false;
curEntry.name[curEntry.nameLength] = '\0';
// Get length of data
curEntry.dataLength = 0;
switch (curEntry.type)
{
case Type_BigArray:
if (fread(&curEntry.dataLength, 2, 1, f) != 1) return false;
curEntry.dataLength = Common::swap16(curEntry.dataLength);
break;
case Type_SmallArray:
if (fread(&curEntry.dataLength, 1, 1, f) != 1) return false;
break;
case Type_Byte:
case Type_Bool:
curEntry.dataLength = 1;
break;
case Type_Short:
curEntry.dataLength = 2;
break;
case Type_Long:
curEntry.dataLength = 4;
break;
default:
PanicAlert("Unknown entry type %i in SYSCONF (%s@%x)!",
curEntry.type, curEntry.name, curEntry.offset);
return false;
}
// Fill in the actual data
if (curEntry.dataLength)
{
curEntry.data = new u8[curEntry.dataLength];
if (fread(curEntry.data, curEntry.dataLength, 1, f) != 1) return false;
}
}
return true;
}
bool SysConf::SaveToFile(const char *filename)
{
FILE *f = fopen(filename, "r+b");
if (f == NULL)
return false;
for (size_t i = 0; i < m_Entries.size() - 1; i++)
{
// Seek to after the name of this entry
if (fseek(f, m_Entries.at(i).offset + m_Entries.at(i).nameLength + 1, SEEK_SET) != 0) return false;
// We may have to write array length value...
if (m_Entries.at(i).type == Type_BigArray)
{
u16 tmpDataLength = Common::swap16(m_Entries.at(i).dataLength);
if (fwrite(&tmpDataLength, 2, 1, f) != 1) return false;
}
else if (m_Entries.at(i).type == Type_SmallArray)
{
if (fwrite(&m_Entries.at(i).dataLength, 1, 1, f) != 1) return false;
}
// Now write the actual data
if (fwrite(m_Entries.at(i).data, m_Entries.at(i).dataLength, 1, f) != 1) return false;
}
fclose(f);
return true;
}
bool SysConf::Save()
{
return SaveToFile(m_Filename.c_str());
} }
SysConf::~SysConf()
{
if (!m_IsValid)
return;
Save();
for (size_t i = 0; i < m_Entries.size() - 1; i++)
{
delete [] m_Entries.at(i).data;
m_Entries.at(i).data = NULL;
}
}
bool SysConf::LoadFromFile(const char *filename)
{
// Basic check
u64 size = File::GetSize(filename);
if (size == 0)
return false; //most likely: file does not exist
if (size != SYSCONF_SIZE)
{
PanicAlert("Your SYSCONF file is the wrong size - should be 0x%04x (but is 0x%04x)",
SYSCONF_SIZE, size);
return false;
}
FILE* f = fopen(filename, "rb");
if (f == NULL)
return false;
bool result = LoadFromFileInternal(f);
if (result)
{
// OK, done!
m_Filename = filename;
}
fclose(f);
return result;
}
bool SysConf::LoadFromFileInternal(FILE *f)
{
// Fill in infos
if (fread(&m_Header.version, sizeof(m_Header.version), 1, f) != 1) return false;
if (fread(&m_Header.numEntries, sizeof(m_Header.numEntries), 1, f) != 1) return false;
m_Header.numEntries = Common::swap16(m_Header.numEntries) + 1;
for (u16 index = 0; index < m_Header.numEntries; index++)
{
SSysConfEntry tmpEntry;
if (fread(&tmpEntry.offset, sizeof(tmpEntry.offset), 1, f) != 1) return false;
tmpEntry.offset = Common::swap16(tmpEntry.offset);
m_Entries.push_back(tmpEntry);
}
// Last offset is an invalid entry. We ignore it throughout this class
for (size_t i = 0; i < m_Entries.size() - 1; i++)
{
SSysConfEntry& curEntry = m_Entries.at(i);
if (fseek(f, curEntry.offset, SEEK_SET) != 0) return false;
u8 description = 0;
if (fread(&description, sizeof(description), 1, f) != 1) return false;
// Data type
curEntry.type = (SysconfType)((description & 0xe0) >> 5);
// Length of name in bytes - 1
curEntry.nameLength = (description & 0x1f) + 1;
// Name
if (fread(&curEntry.name, curEntry.nameLength, 1, f) != 1) return false;
curEntry.name[curEntry.nameLength] = '\0';
// Get length of data
curEntry.dataLength = 0;
switch (curEntry.type)
{
case Type_BigArray:
if (fread(&curEntry.dataLength, 2, 1, f) != 1) return false;
curEntry.dataLength = Common::swap16(curEntry.dataLength);
break;
case Type_SmallArray:
if (fread(&curEntry.dataLength, 1, 1, f) != 1) return false;
break;
case Type_Byte:
case Type_Bool:
curEntry.dataLength = 1;
break;
case Type_Short:
curEntry.dataLength = 2;
break;
case Type_Long:
curEntry.dataLength = 4;
break;
default:
PanicAlert("Unknown entry type %i in SYSCONF (%s@%x)!",
curEntry.type, curEntry.name, curEntry.offset);
return false;
}
// Fill in the actual data
if (curEntry.dataLength)
{
curEntry.data = new u8[curEntry.dataLength];
if (fread(curEntry.data, curEntry.dataLength, 1, f) != 1) return false;
}
}
return true;
}
bool SysConf::SaveToFile(const char *filename)
{
FILE *f = fopen(filename, "r+b");
if (f == NULL)
return false;
for (size_t i = 0; i < m_Entries.size() - 1; i++)
{
// Seek to after the name of this entry
if (fseek(f, m_Entries.at(i).offset + m_Entries.at(i).nameLength + 1, SEEK_SET) != 0) return false;
// We may have to write array length value...
if (m_Entries.at(i).type == Type_BigArray)
{
u16 tmpDataLength = Common::swap16(m_Entries.at(i).dataLength);
if (fwrite(&tmpDataLength, 2, 1, f) != 1) return false;
}
else if (m_Entries.at(i).type == Type_SmallArray)
{
if (fwrite(&m_Entries.at(i).dataLength, 1, 1, f) != 1) return false;
}
// Now write the actual data
if (fwrite(m_Entries.at(i).data, m_Entries.at(i).dataLength, 1, f) != 1) return false;
}
fclose(f);
return true;
}
bool SysConf::Save()
{
return SaveToFile(m_Filename.c_str());
}

View File

@ -1,129 +1,129 @@
// 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/
#ifndef __SYSCONF_MANAGER_h__ #ifndef __SYSCONF_MANAGER_h__
#define __SYSCONF_MANAGER_h__ #define __SYSCONF_MANAGER_h__
#include <string> #include <string>
#include <vector> #include <vector>
// This class is meant to edit the values in a given Wii SYSCONF file // This class is meant to edit the values in a given Wii SYSCONF file
// It currently does not add/remove/rearrange sections, // It currently does not add/remove/rearrange sections,
// instead only modifies exiting sections' data // instead only modifies exiting sections' data
#define SYSCONF_SIZE 0x4000 #define SYSCONF_SIZE 0x4000
enum SysconfType enum SysconfType
{ {
Type_BigArray = 1, Type_BigArray = 1,
Type_SmallArray, Type_SmallArray,
Type_Byte, Type_Byte,
Type_Short, Type_Short,
Type_Long, Type_Long,
Type_Unknown, Type_Unknown,
Type_Bool Type_Bool
}; };
struct SSysConfHeader struct SSysConfHeader
{ {
char version[4]; char version[4];
u16 numEntries; u16 numEntries;
}; };
struct SSysConfEntry struct SSysConfEntry
{ {
u16 offset; u16 offset;
SysconfType type; SysconfType type;
u8 nameLength; u8 nameLength;
char name[32]; char name[32];
u16 dataLength; u16 dataLength;
u8* data; u8* data;
template<class T> template<class T>
T GetData() { return *(T*)data; } T GetData() { return *(T*)data; }
}; };
class SysConf class SysConf
{ {
private: private:
SSysConfHeader m_Header; SSysConfHeader m_Header;
std::string m_Filename; std::string m_Filename;
std::vector<SSysConfEntry> m_Entries; std::vector<SSysConfEntry> m_Entries;
bool m_IsValid; bool m_IsValid;
public: public:
SysConf(); SysConf();
~SysConf(); ~SysConf();
bool IsValid() { return m_IsValid; } bool IsValid() { return m_IsValid; }
void Reload(); void Reload();
template<class T> template<class T>
T GetData(const char* sectionName) T GetData(const char* sectionName)
{ {
if (!m_IsValid) if (!m_IsValid)
{ {
PanicAlert("Trying to read from invalid SYSCONF"); PanicAlert("Trying to read from invalid SYSCONF");
return 0; return 0;
} }
size_t index = 0; size_t index = 0;
for (; index < m_Entries.size() - 1; index++) for (; index < m_Entries.size() - 1; index++)
{ {
if (strcmp(m_Entries.at(index).name, sectionName) == 0) if (strcmp(m_Entries.at(index).name, sectionName) == 0)
break; break;
} }
if (index == m_Entries.size() - 1) if (index == m_Entries.size() - 1)
{ {
PanicAlert("Section %s not found in SYSCONF", sectionName); PanicAlert("Section %s not found in SYSCONF", sectionName);
return 0; return 0;
} }
return m_Entries.at(index).GetData<T>(); return m_Entries.at(index).GetData<T>();
} }
template<class T> template<class T>
bool SetData(const char* sectionName, T newValue) bool SetData(const char* sectionName, T newValue)
{ {
if (!m_IsValid) if (!m_IsValid)
return false; return false;
size_t index = 0; size_t index = 0;
for (; index < m_Entries.size() - 1; index++) for (; index < m_Entries.size() - 1; index++)
{ {
if (strcmp(m_Entries.at(index).name, sectionName) == 0) if (strcmp(m_Entries.at(index).name, sectionName) == 0)
break; break;
} }
if (index == m_Entries.size() - 1) if (index == m_Entries.size() - 1)
{ {
PanicAlert("Section %s not found in SYSCONF", sectionName); PanicAlert("Section %s not found in SYSCONF", sectionName);
return false; return false;
} }
*(T*)m_Entries.at(index).data = newValue; *(T*)m_Entries.at(index).data = newValue;
return true; return true;
} }
bool Save(); bool Save();
bool SaveToFile(const char* filename); bool SaveToFile(const char* filename);
bool LoadFromFile(const char* filename); bool LoadFromFile(const char* filename);
private: private:
bool LoadFromFileInternal(FILE *f); bool LoadFromFileInternal(FILE *f);
}; };
#endif // __SYSCONF_MANAGER_h__ #endif // __SYSCONF_MANAGER_h__

View File

@ -44,15 +44,12 @@
#include "cmdline.h" #include "cmdline.h"
#include "Thread.h" #include "Thread.h"
#include "PowerPC/PowerPC.h" #include "PowerPC/PowerPC.h"
#include "PluginManager.h" #include "PluginManager.h"
#include "ConfigManager.h"
#include "LogManager.h"
#include "BootManager.h" #include "BootManager.h"
void* g_pCodeWindow = NULL;
void* main_frame = NULL;
// OK, this thread boundary is DANGEROUS on linux
// wxPostEvent / wxAddPendingEvent is the solution.
void Host_NotifyMapLoaded(){} void Host_NotifyMapLoaded(){}
void Host_ShowJitResults(unsigned int address){} void Host_ShowJitResults(unsigned int address){}
@ -99,7 +96,7 @@ void Host_SysMessage(const char *fmt, ...)
msg[len - 1] = '\n'; msg[len - 1] = '\n';
msg[len] = '\0'; msg[len] = '\0';
} }
fprintf(stderr, msg); fprintf(stderr, "%s", msg);
} }
void Host_UpdateLeds(int led_bits) void Host_UpdateLeds(int led_bits)
@ -167,6 +164,7 @@ int appleMain(int argc, char *argv[]);
@end @end
volatile bool running;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@ -182,9 +180,10 @@ int main(int argc, char *argv[])
NSEvent *event = [[NSEvent alloc] init]; NSEvent *event = [[NSEvent alloc] init];
[thread cocoaThreadStart]; [thread cocoaThreadStart];
running = true;
//cocoa event loop //cocoa event loop
while(true) while(running)
{ {
event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ]; event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ];
if(cocoaSendEvent(event)) if(cocoaSendEvent(event))
@ -212,7 +211,7 @@ int main(int argc, char* argv[])
{ {
gengetopt_args_info args_info; gengetopt_args_info args_info;
if (cmdline_parser (argc, argv, &args_info) != 0) if (cmdline_parser(argc, argv, &args_info) != 0)
return(1); return(1);
if (args_info.inputs_num < 1) if (args_info.inputs_num < 1)
@ -224,30 +223,29 @@ int main(int argc, char* argv[])
updateMainFrameEvent.Init(); updateMainFrameEvent.Init();
cpu_info.Detect(); cpu_info.Detect();
LogManager::Init();
EventHandler::Init();
SConfig::Init();
CPluginManager::Init();
CPluginManager::GetInstance().ScanForPlugins(); CPluginManager::GetInstance().ScanForPlugins();
// check to see if ~/Library/Application Support/Dolphin exists; if not, create it if (BootManager::BootCore(bootFile)) //no use running the loop when booting fails
char AppSupportDir[MAXPATHLEN];
snprintf(AppSupportDir, sizeof(AppSupportDir), "%s/Library/Application Support", getenv("HOME"));
if (!File::Exists(AppSupportDir) || !File::IsDirectory(AppSupportDir))
PanicAlert("Could not open ~/Library/Application Support");
strncat(AppSupportDir, "/Dolphin", sizeof(AppSupportDir));
if (!File::Exists(AppSupportDir))
File::CreateDir(AppSupportDir);
if (!File::IsDirectory(AppSupportDir))
PanicAlert("~/Library/Application Support/Dolphin exists, but is not a directory");
chdir(AppSupportDir);
BootManager::BootCore(bootFile);
while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN)
{ {
updateMainFrameEvent.Wait(); while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN)
{
updateMainFrameEvent.Wait();
}
} }
#if defined(HAVE_COCOA) && HAVE_COCOA
running = false;
#endif
CPluginManager::Shutdown();
SConfig::Shutdown();
EventHandler::Shutdown();
LogManager::Shutdown();
cmdline_parser_free (&args_info); cmdline_parser_free (&args_info);
return(0); return(0);