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.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _ATOMIC_H_
#define _ATOMIC_H_
#ifdef _WIN32
#include "Atomic_Win32.h"
#else
// GCC-compatible compiler assumed!
#include "Atomic_GCC.h"
#endif
#endif
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _ATOMIC_H_
#define _ATOMIC_H_
#ifdef _WIN32
#include "Atomic_Win32.h"
#else
// GCC-compatible compiler assumed!
#include "Atomic_GCC.h"
#endif
#endif

View File

@ -1,118 +1,118 @@
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _ATOMIC_GCC_H_
#define _ATOMIC_GCC_H_
#include "Common.h"
// Atomic operations are performed in a single step by the CPU. It is
// impossible for other threads to see the operation "half-done."
//
// Some atomic operations can be combined with different types of memory
// barriers called "Acquire semantics" and "Release semantics", defined below.
//
// Acquire semantics: Future memory accesses cannot be relocated to before the
// operation.
//
// Release semantics: Past memory accesses cannot be relocated to after the
// operation.
//
// These barriers affect not only the compiler, but also the CPU.
namespace Common
{
inline void AtomicAdd(volatile u32& target, u32 value) {
__sync_add_and_fetch(&target, value);
}
inline void AtomicAnd(volatile u32& target, u32 value) {
__sync_and_and_fetch(&target, value);
}
inline void AtomicIncrement(volatile u32& target) {
__sync_add_and_fetch(&target, 1);
}
inline u32 AtomicLoad(volatile u32& src) {
return src; // 32-bit reads are always atomic.
}
inline u32 AtomicLoadAcquire(volatile u32& src) {
__sync_synchronize(); // TODO: May not be necessary.
return src;
}
inline void AtomicOr(volatile u32& target, u32 value) {
__sync_or_and_fetch(&target, value);
}
inline void AtomicStore(volatile u32& dest, u32 value) {
dest = value; // 32-bit writes are always atomic.
}
inline void AtomicStoreRelease(volatile u32& dest, u32 value) {
__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__.
#if 0
LONG SyncInterlockedIncrement(LONG *Dest)
{
#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
return __sync_add_and_fetch(Dest, 1);
#else
register int result;
__asm__ __volatile__("lock; xadd %0,%1"
: "=r" (result), "=m" (*Dest)
: "0" (1), "m" (*Dest)
: "memory");
return result;
#endif
}
LONG SyncInterlockedExchangeAdd(LONG *Dest, LONG Val)
{
#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
return __sync_add_and_fetch(Dest, Val);
#else
register int result;
__asm__ __volatile__("lock; xadd %0,%1"
: "=r" (result), "=m" (*Dest)
: "0" (Val), "m" (*Dest)
: "memory");
return result;
#endif
}
LONG SyncInterlockedExchange(LONG *Dest, LONG Val)
{
#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
return __sync_lock_test_and_set(Dest, Val);
#else
register int result;
__asm__ __volatile__("lock; xchg %0,%1"
: "=r" (result), "=m" (*Dest)
: "0" (Val), "m" (*Dest)
: "memory");
return result;
#endif
}
#endif
#endif
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _ATOMIC_GCC_H_
#define _ATOMIC_GCC_H_
#include "Common.h"
// Atomic operations are performed in a single step by the CPU. It is
// impossible for other threads to see the operation "half-done."
//
// Some atomic operations can be combined with different types of memory
// barriers called "Acquire semantics" and "Release semantics", defined below.
//
// Acquire semantics: Future memory accesses cannot be relocated to before the
// operation.
//
// Release semantics: Past memory accesses cannot be relocated to after the
// operation.
//
// These barriers affect not only the compiler, but also the CPU.
namespace Common
{
inline void AtomicAdd(volatile u32& target, u32 value) {
__sync_add_and_fetch(&target, value);
}
inline void AtomicAnd(volatile u32& target, u32 value) {
__sync_and_and_fetch(&target, value);
}
inline void AtomicIncrement(volatile u32& target) {
__sync_add_and_fetch(&target, 1);
}
inline u32 AtomicLoad(volatile u32& src) {
return src; // 32-bit reads are always atomic.
}
inline u32 AtomicLoadAcquire(volatile u32& src) {
__sync_synchronize(); // TODO: May not be necessary.
return src;
}
inline void AtomicOr(volatile u32& target, u32 value) {
__sync_or_and_fetch(&target, value);
}
inline void AtomicStore(volatile u32& dest, u32 value) {
dest = value; // 32-bit writes are always atomic.
}
inline void AtomicStoreRelease(volatile u32& dest, u32 value) {
__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__.
#if 0
LONG SyncInterlockedIncrement(LONG *Dest)
{
#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
return __sync_add_and_fetch(Dest, 1);
#else
register int result;
__asm__ __volatile__("lock; xadd %0,%1"
: "=r" (result), "=m" (*Dest)
: "0" (1), "m" (*Dest)
: "memory");
return result;
#endif
}
LONG SyncInterlockedExchangeAdd(LONG *Dest, LONG Val)
{
#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
return __sync_add_and_fetch(Dest, Val);
#else
register int result;
__asm__ __volatile__("lock; xadd %0,%1"
: "=r" (result), "=m" (*Dest)
: "0" (Val), "m" (*Dest)
: "memory");
return result;
#endif
}
LONG SyncInterlockedExchange(LONG *Dest, LONG Val)
{
#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
return __sync_lock_test_and_set(Dest, Val);
#else
register int result;
__asm__ __volatile__("lock; xchg %0,%1"
: "=r" (result), "=m" (*Dest)
: "0" (Val), "m" (*Dest)
: "memory");
return result;
#endif
}
#endif
#endif

View File

@ -1,81 +1,81 @@
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _ATOMIC_WIN32_H_
#define _ATOMIC_WIN32_H_
#include "Common.h"
#include <intrin.h>
#include <Windows.h>
// Atomic operations are performed in a single step by the CPU. It is
// impossible for other threads to see the operation "half-done."
//
// Some atomic operations can be combined with different types of memory
// barriers called "Acquire semantics" and "Release semantics", defined below.
//
// Acquire semantics: Future memory accesses cannot be relocated to before the
// operation.
//
// Release semantics: Past memory accesses cannot be relocated to after the
// operation.
//
// These barriers affect not only the compiler, but also the CPU.
//
// NOTE: Acquire and Release are not differentiated right now. They perform a
// full memory barrier instead of a "one-way" memory barrier. The newest
// Windows SDK has Acquire and Release versions of some Interlocked* functions.
namespace Common
{
inline void AtomicAdd(volatile u32& target, u32 value) {
InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value);
}
inline void AtomicAnd(volatile u32& target, u32 value) {
_InterlockedAnd((volatile LONG*)&target, (LONG)value);
}
inline void AtomicIncrement(volatile u32& target) {
InterlockedIncrement((volatile LONG*)&target);
}
inline u32 AtomicLoad(volatile u32& src) {
return src; // 32-bit reads are always atomic.
}
inline u32 AtomicLoadAcquire(volatile u32& src) {
u32 result = src; // 32-bit reads are always atomic.
_ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics.
return result;
}
inline void AtomicOr(volatile u32& target, u32 value) {
_InterlockedOr((volatile LONG*)&target, (LONG)value);
}
inline void AtomicStore(volatile u32& dest, u32 value) {
dest = value; // 32-bit writes are always atomic.
}
inline void AtomicStoreRelease(volatile u32& dest, u32 value) {
_WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics.
dest = value; // 32-bit writes are always atomic.
}
}
#endif
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _ATOMIC_WIN32_H_
#define _ATOMIC_WIN32_H_
#include "Common.h"
#include <intrin.h>
#include <Windows.h>
// Atomic operations are performed in a single step by the CPU. It is
// impossible for other threads to see the operation "half-done."
//
// Some atomic operations can be combined with different types of memory
// barriers called "Acquire semantics" and "Release semantics", defined below.
//
// Acquire semantics: Future memory accesses cannot be relocated to before the
// operation.
//
// Release semantics: Past memory accesses cannot be relocated to after the
// operation.
//
// These barriers affect not only the compiler, but also the CPU.
//
// NOTE: Acquire and Release are not differentiated right now. They perform a
// full memory barrier instead of a "one-way" memory barrier. The newest
// Windows SDK has Acquire and Release versions of some Interlocked* functions.
namespace Common
{
inline void AtomicAdd(volatile u32& target, u32 value) {
InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value);
}
inline void AtomicAnd(volatile u32& target, u32 value) {
_InterlockedAnd((volatile LONG*)&target, (LONG)value);
}
inline void AtomicIncrement(volatile u32& target) {
InterlockedIncrement((volatile LONG*)&target);
}
inline u32 AtomicLoad(volatile u32& src) {
return src; // 32-bit reads are always atomic.
}
inline u32 AtomicLoadAcquire(volatile u32& src) {
u32 result = src; // 32-bit reads are always atomic.
_ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics.
return result;
}
inline void AtomicOr(volatile u32& target, u32 value) {
_InterlockedOr((volatile LONG*)&target, (LONG)value);
}
inline void AtomicStore(volatile u32& dest, u32 value) {
dest = value; // 32-bit writes are always atomic.
}
inline void AtomicStoreRelease(volatile u32& dest, u32 value) {
_WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics.
dest = value; // 32-bit writes are always atomic.
}
}
#endif

View File

@ -1,55 +1,55 @@
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _CONSOLELISTENER_H
#define _CONSOLELISTENER_H
#include "LogManager.h"
#ifdef _WIN32
#include <windows.h>
#endif
class ConsoleListener : public LogListener
{
public:
ConsoleListener();
~ConsoleListener();
void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console");
void UpdateHandle();
void Close();
bool IsOpen();
void LetterSpace(int Width, int Height);
void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst);
void PixelSpace(int Left, int Top, int Width, int Height, bool);
#ifdef _WIN32
COORD GetCoordinates(int BytesRead, int BufferWidth);
#endif
void Log(LogTypes::LOG_LEVELS, const char *Text);
void ClearScreen(bool Cursor = true);
const char *getName() const { return "Console"; }
private:
#ifdef _WIN32
HWND GetHwnd(void);
HANDLE hConsole;
#endif
};
#endif // _CONSOLELISTENER_H
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _CONSOLELISTENER_H
#define _CONSOLELISTENER_H
#include "LogManager.h"
#ifdef _WIN32
#include <windows.h>
#endif
class ConsoleListener : public LogListener
{
public:
ConsoleListener();
~ConsoleListener();
void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console");
void UpdateHandle();
void Close();
bool IsOpen();
void LetterSpace(int Width, int Height);
void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst);
void PixelSpace(int Left, int Top, int Width, int Height, bool);
#ifdef _WIN32
COORD GetCoordinates(int BytesRead, int BufferWidth);
#endif
void Log(LogTypes::LOG_LEVELS, const char *Text);
void ClearScreen(bool Cursor = true);
const char *getName() const { return "Console"; }
private:
#ifdef _WIN32
HWND GetHwnd(void);
HANDLE hConsole;
#endif
};
#endif // _CONSOLELISTENER_H

View File

@ -1,398 +1,398 @@
// Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
// Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include "../Common.h"
#include "tools.h"
// y**2 + x*y = x**3 + x + b
static u8 ec_b[30] =
{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};
// order of the addition group of points
static u8 ec_N[30] =
{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};
// base point
static u8 ec_G[60] =
{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
,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};
/*static void elt_print(char *name, u8 *a)
{
u32 i;
printf("%s = ", name);
for (i = 0; i < 30; i++)
printf("%02x", a[i]);
printf("\n");
}*/
static void elt_copy(u8 *d, u8 *a)
{
memcpy(d, a, 30);
}
static void elt_zero(u8 *d)
{
memset(d, 0, 30);
}
static int elt_is_zero(u8 *d)
{
u32 i;
for (i = 0; i < 30; i++)
if (d[i] != 0)
return 0;
return 1;
}
static void elt_add(u8 *d, u8 *a, u8 *b)
{
u32 i;
for (i = 0; i < 30; i++)
d[i] = a[i] ^ b[i];
}
static void elt_mul_x(u8 *d, u8 *a)
{
u8 carry, x, y;
u32 i;
carry = a[0] & 1;
x = 0;
for (i = 0; i < 29; i++) {
y = a[i + 1];
d[i] = x ^ (y >> 7);
x = y << 1;
}
d[29] = x ^ carry;
d[20] ^= carry << 2;
}
static void elt_mul(u8 *d, u8 *a, u8 *b)
{
u32 i, n;
u8 mask;
elt_zero(d);
i = 0;
mask = 1;
for (n = 0; n < 233; n++) {
elt_mul_x(d, d);
if ((a[i] & mask) != 0)
elt_add(d, d, b);
mask >>= 1;
if (mask == 0) {
mask = 0x80;
i++;
}
}
}
static const u8 square[16] =
{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)
{
u32 i;
for (i = 0; i < 30; i++) {
d[2*i] = square[a[i] >> 4];
d[2*i + 1] = square[a[i] & 15];
}
}
static void wide_reduce(u8 *d)
{
u32 i;
u8 x;
for (i = 0; i < 30; i++) {
x = d[i];
d[i + 19] ^= x >> 7;
d[i + 20] ^= x << 1;
d[i + 29] ^= x >> 1;
d[i + 30] ^= x << 7;
}
x = d[30] & ~1;
d[49] ^= x >> 7;
d[50] ^= x << 1;
d[59] ^= x >> 1;
d[30] &= 1;
}
static void elt_square(u8 *d, u8 *a)
{
u8 wide[60];
elt_square_to_wide(wide, a);
wide_reduce(wide);
elt_copy(d, wide + 30);
}
static void itoh_tsujii(u8 *d, u8 *a, u8 *b, u32 j)
{
u8 t[30];
elt_copy(t, a);
while (j--) {
elt_square(d, t);
elt_copy(t, d);
}
elt_mul(d, t, b);
}
static void elt_inv(u8 *d, u8 *a)
{
u8 t[30];
u8 s[30];
itoh_tsujii(t, a, a, 1);
itoh_tsujii(s, t, a, 1);
itoh_tsujii(t, s, s, 3);
itoh_tsujii(s, t, a, 1);
itoh_tsujii(t, s, s, 7);
itoh_tsujii(s, t, t, 14);
itoh_tsujii(t, s, a, 1);
itoh_tsujii(s, t, t, 29);
itoh_tsujii(t, s, s, 58);
itoh_tsujii(s, t, t, 116);
elt_square(d, s);
}
/*static int point_is_on_curve(u8 *p)
{
u8 s[30], t[30];
u8 *x, *y;
x = p;
y = p + 30;
elt_square(t, x);
elt_mul(s, t, x);
elt_add(s, s, t);
elt_square(t, y);
elt_add(s, s, t);
elt_mul(t, x, y);
elt_add(s, s, t);
elt_add(s, s, ec_b);
return elt_is_zero(s);
}
*/
static int point_is_zero(u8 *p)
{
return elt_is_zero(p) && elt_is_zero(p + 30);
}
static void point_double(u8 *r, u8 *p)
{
u8 s[30], t[30];
u8 *px, *py, *rx, *ry;
px = p;
py = p + 30;
rx = r;
ry = r + 30;
if (elt_is_zero(px)) {
elt_zero(rx);
elt_zero(ry);
return;
}
elt_inv(t, px);
elt_mul(s, py, t);
elt_add(s, s, px);
elt_square(t, px);
elt_square(rx, s);
elt_add(rx, rx, s);
rx[29] ^= 1;
elt_mul(ry, s, rx);
elt_add(ry, ry, rx);
elt_add(ry, ry, t);
}
static void point_add(u8 *r, u8 *p, u8 *q)
{
u8 s[30], t[30], u[30];
u8 *px, *py, *qx, *qy, *rx, *ry;
px = p;
py = p + 30;
qx = q;
qy = q + 30;
rx = r;
ry = r + 30;
if (point_is_zero(p)) {
elt_copy(rx, qx);
elt_copy(ry, qy);
return;
}
if (point_is_zero(q)) {
elt_copy(rx, px);
elt_copy(ry, py);
return;
}
elt_add(u, px, qx);
if (elt_is_zero(u)) {
elt_add(u, py, qy);
if (elt_is_zero(u))
point_double(r, p);
else {
elt_zero(rx);
elt_zero(ry);
}
return;
}
elt_inv(t, u);
elt_add(u, py, qy);
elt_mul(s, t, u);
elt_square(t, s);
elt_add(t, t, s);
elt_add(t, t, qx);
t[29] ^= 1;
elt_mul(u, s, t);
elt_add(s, u, py);
elt_add(rx, t, px);
elt_add(ry, s, rx);
}
static void point_mul(u8 *d, u8 *a, u8 *b) // a is bignum
{
u32 i;
u8 mask;
elt_zero(d);
elt_zero(d + 30);
for (i = 0; i < 30; i++)
for (mask = 0x80; mask != 0; mask >>= 1) {
point_double(d, d);
if ((a[i] & mask) != 0)
point_add(d, d, b);
}
}
void silly_random(u8 * rndArea, u8 count)
{
u16 i;
srand((unsigned) (time(NULL)));
for(i=0;i<count;i++)
{
rndArea[i]=rand();
}
}
void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash)
{
u8 e[30];
u8 kk[30];
u8 m[30];
u8 minv[30];
u8 mG[60];
//FILE *fp;
elt_zero(e);
memcpy(e + 10, hash, 20);
//Changing random number generator to a lame one...
silly_random(m, sizeof(m));
//fp = fopen("/dev/random", "rb");
//if (fread(m, sizeof m, 1, fp) != 1)
// fatal("reading random");
//fclose(fp);
m[0] = 0;
// R = (mG).x
point_mul(mG, m, ec_G);
elt_copy(R, mG);
if (bn_compare(R, ec_N, 30) >= 0)
bn_sub_modulus(R, ec_N, 30);
// S = m**-1*(e + Rk) (mod N)
elt_copy(kk, k);
if (bn_compare(kk, ec_N, 30) >= 0)
bn_sub_modulus(kk, ec_N, 30);
bn_mul(S, R, kk, ec_N, 30);
bn_add(kk, S, e, ec_N, 30);
bn_inv(minv, m, ec_N, 30);
bn_mul(S, minv, kk, ec_N, 30);
}
int check_ecdsa(u8 *Q, u8 *R, u8 *S, u8 *hash)
{
u8 Sinv[30];
u8 e[30];
u8 w1[30], w2[30];
u8 r1[60], r2[60];
bn_inv(Sinv, S, ec_N, 30);
elt_zero(e);
memcpy(e + 10, hash, 20);
bn_mul(w1, e, Sinv, ec_N, 30);
bn_mul(w2, R, Sinv, ec_N, 30);
point_mul(r1, w1, ec_G);
point_mul(r2, w2, Q);
point_add(r1, r1, r2);
if (bn_compare(r1, ec_N, 30) >= 0)
bn_sub_modulus(r1, ec_N, 30);
return (bn_compare(r1, R, 30) == 0);
}
void ec_priv_to_pub(u8 *k, u8 *Q)
{
point_mul(Q, k, ec_G);
}
// Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
// Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include "../Common.h"
#include "tools.h"
// y**2 + x*y = x**3 + x + b
static u8 ec_b[30] =
{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};
// order of the addition group of points
static u8 ec_N[30] =
{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};
// base point
static u8 ec_G[60] =
{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
,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};
/*static void elt_print(char *name, u8 *a)
{
u32 i;
printf("%s = ", name);
for (i = 0; i < 30; i++)
printf("%02x", a[i]);
printf("\n");
}*/
static void elt_copy(u8 *d, u8 *a)
{
memcpy(d, a, 30);
}
static void elt_zero(u8 *d)
{
memset(d, 0, 30);
}
static int elt_is_zero(u8 *d)
{
u32 i;
for (i = 0; i < 30; i++)
if (d[i] != 0)
return 0;
return 1;
}
static void elt_add(u8 *d, u8 *a, u8 *b)
{
u32 i;
for (i = 0; i < 30; i++)
d[i] = a[i] ^ b[i];
}
static void elt_mul_x(u8 *d, u8 *a)
{
u8 carry, x, y;
u32 i;
carry = a[0] & 1;
x = 0;
for (i = 0; i < 29; i++) {
y = a[i + 1];
d[i] = x ^ (y >> 7);
x = y << 1;
}
d[29] = x ^ carry;
d[20] ^= carry << 2;
}
static void elt_mul(u8 *d, u8 *a, u8 *b)
{
u32 i, n;
u8 mask;
elt_zero(d);
i = 0;
mask = 1;
for (n = 0; n < 233; n++) {
elt_mul_x(d, d);
if ((a[i] & mask) != 0)
elt_add(d, d, b);
mask >>= 1;
if (mask == 0) {
mask = 0x80;
i++;
}
}
}
static const u8 square[16] =
{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)
{
u32 i;
for (i = 0; i < 30; i++) {
d[2*i] = square[a[i] >> 4];
d[2*i + 1] = square[a[i] & 15];
}
}
static void wide_reduce(u8 *d)
{
u32 i;
u8 x;
for (i = 0; i < 30; i++) {
x = d[i];
d[i + 19] ^= x >> 7;
d[i + 20] ^= x << 1;
d[i + 29] ^= x >> 1;
d[i + 30] ^= x << 7;
}
x = d[30] & ~1;
d[49] ^= x >> 7;
d[50] ^= x << 1;
d[59] ^= x >> 1;
d[30] &= 1;
}
static void elt_square(u8 *d, u8 *a)
{
u8 wide[60];
elt_square_to_wide(wide, a);
wide_reduce(wide);
elt_copy(d, wide + 30);
}
static void itoh_tsujii(u8 *d, u8 *a, u8 *b, u32 j)
{
u8 t[30];
elt_copy(t, a);
while (j--) {
elt_square(d, t);
elt_copy(t, d);
}
elt_mul(d, t, b);
}
static void elt_inv(u8 *d, u8 *a)
{
u8 t[30];
u8 s[30];
itoh_tsujii(t, a, a, 1);
itoh_tsujii(s, t, a, 1);
itoh_tsujii(t, s, s, 3);
itoh_tsujii(s, t, a, 1);
itoh_tsujii(t, s, s, 7);
itoh_tsujii(s, t, t, 14);
itoh_tsujii(t, s, a, 1);
itoh_tsujii(s, t, t, 29);
itoh_tsujii(t, s, s, 58);
itoh_tsujii(s, t, t, 116);
elt_square(d, s);
}
/*static int point_is_on_curve(u8 *p)
{
u8 s[30], t[30];
u8 *x, *y;
x = p;
y = p + 30;
elt_square(t, x);
elt_mul(s, t, x);
elt_add(s, s, t);
elt_square(t, y);
elt_add(s, s, t);
elt_mul(t, x, y);
elt_add(s, s, t);
elt_add(s, s, ec_b);
return elt_is_zero(s);
}
*/
static int point_is_zero(u8 *p)
{
return elt_is_zero(p) && elt_is_zero(p + 30);
}
static void point_double(u8 *r, u8 *p)
{
u8 s[30], t[30];
u8 *px, *py, *rx, *ry;
px = p;
py = p + 30;
rx = r;
ry = r + 30;
if (elt_is_zero(px)) {
elt_zero(rx);
elt_zero(ry);
return;
}
elt_inv(t, px);
elt_mul(s, py, t);
elt_add(s, s, px);
elt_square(t, px);
elt_square(rx, s);
elt_add(rx, rx, s);
rx[29] ^= 1;
elt_mul(ry, s, rx);
elt_add(ry, ry, rx);
elt_add(ry, ry, t);
}
static void point_add(u8 *r, u8 *p, u8 *q)
{
u8 s[30], t[30], u[30];
u8 *px, *py, *qx, *qy, *rx, *ry;
px = p;
py = p + 30;
qx = q;
qy = q + 30;
rx = r;
ry = r + 30;
if (point_is_zero(p)) {
elt_copy(rx, qx);
elt_copy(ry, qy);
return;
}
if (point_is_zero(q)) {
elt_copy(rx, px);
elt_copy(ry, py);
return;
}
elt_add(u, px, qx);
if (elt_is_zero(u)) {
elt_add(u, py, qy);
if (elt_is_zero(u))
point_double(r, p);
else {
elt_zero(rx);
elt_zero(ry);
}
return;
}
elt_inv(t, u);
elt_add(u, py, qy);
elt_mul(s, t, u);
elt_square(t, s);
elt_add(t, t, s);
elt_add(t, t, qx);
t[29] ^= 1;
elt_mul(u, s, t);
elt_add(s, u, py);
elt_add(rx, t, px);
elt_add(ry, s, rx);
}
static void point_mul(u8 *d, u8 *a, u8 *b) // a is bignum
{
u32 i;
u8 mask;
elt_zero(d);
elt_zero(d + 30);
for (i = 0; i < 30; i++)
for (mask = 0x80; mask != 0; mask >>= 1) {
point_double(d, d);
if ((a[i] & mask) != 0)
point_add(d, d, b);
}
}
void silly_random(u8 * rndArea, u8 count)
{
u16 i;
srand((unsigned) (time(NULL)));
for(i=0;i<count;i++)
{
rndArea[i]=rand();
}
}
void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash)
{
u8 e[30];
u8 kk[30];
u8 m[30];
u8 minv[30];
u8 mG[60];
//FILE *fp;
elt_zero(e);
memcpy(e + 10, hash, 20);
//Changing random number generator to a lame one...
silly_random(m, sizeof(m));
//fp = fopen("/dev/random", "rb");
//if (fread(m, sizeof m, 1, fp) != 1)
// fatal("reading random");
//fclose(fp);
m[0] = 0;
// R = (mG).x
point_mul(mG, m, ec_G);
elt_copy(R, mG);
if (bn_compare(R, ec_N, 30) >= 0)
bn_sub_modulus(R, ec_N, 30);
// S = m**-1*(e + Rk) (mod N)
elt_copy(kk, k);
if (bn_compare(kk, ec_N, 30) >= 0)
bn_sub_modulus(kk, ec_N, 30);
bn_mul(S, R, kk, ec_N, 30);
bn_add(kk, S, e, ec_N, 30);
bn_inv(minv, m, ec_N, 30);
bn_mul(S, minv, kk, ec_N, 30);
}
int check_ecdsa(u8 *Q, u8 *R, u8 *S, u8 *hash)
{
u8 Sinv[30];
u8 e[30];
u8 w1[30], w2[30];
u8 r1[60], r2[60];
bn_inv(Sinv, S, ec_N, 30);
elt_zero(e);
memcpy(e + 10, hash, 20);
bn_mul(w1, e, Sinv, ec_N, 30);
bn_mul(w2, R, Sinv, ec_N, 30);
point_mul(r1, w1, ec_G);
point_mul(r2, w2, Q);
point_add(r1, r1, r2);
if (bn_compare(r1, ec_N, 30) >= 0)
bn_sub_modulus(r1, ec_N, 30);
return (bn_compare(r1, R, 30) == 0);
}
void ec_priv_to_pub(u8 *k, u8 *Q)
{
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
*
* Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
* All rights reserved.
*
* Joined copyright on original XySSL code with: Christophe Devine
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_MD5_H
#define POLARSSL_MD5_H
/**
* \brief MD5 context structure
*/
typedef struct
{
unsigned long total[2]; /*!< number of bytes processed */
unsigned long state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
}
md5_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD5 context setup
*
* \param ctx context to be initialized
*/
void md5_starts( md5_context *ctx );
/**
* \brief MD5 process buffer
*
* \param ctx MD5 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md5_update( md5_context *ctx, unsigned char *input, int ilen );
/**
* \brief MD5 final digest
*
* \param ctx MD5 context
* \param output MD5 checksum result
*/
void md5_finish( md5_context *ctx, unsigned char output[16] );
/**
* \brief Output = MD5( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD5 checksum result
*/
void md5( unsigned char *input, int ilen, unsigned char output[16] );
/**
* \brief Output = MD5( file contents )
*
* \param path input file name
* \param output MD5 checksum result
*
* \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed
*/
int md5_file( char *path, unsigned char output[16] );
/**
* \brief MD5 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen );
/**
* \brief MD5 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen );
/**
* \brief MD5 HMAC final digest
*
* \param ctx HMAC context
* \param output MD5 HMAC checksum result
*/
void md5_hmac_finish( md5_context *ctx, unsigned char output[16] );
/**
* \brief Output = HMAC-MD5( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-MD5 result
*/
void md5_hmac( unsigned char *key, int keylen,
unsigned char *input, int ilen,
unsigned char output[16] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int md5_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* md5.h */
/**
* \file md5.h
*
* Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
* All rights reserved.
*
* Joined copyright on original XySSL code with: Christophe Devine
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_MD5_H
#define POLARSSL_MD5_H
/**
* \brief MD5 context structure
*/
typedef struct
{
unsigned long total[2]; /*!< number of bytes processed */
unsigned long state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
}
md5_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD5 context setup
*
* \param ctx context to be initialized
*/
void md5_starts( md5_context *ctx );
/**
* \brief MD5 process buffer
*
* \param ctx MD5 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md5_update( md5_context *ctx, unsigned char *input, int ilen );
/**
* \brief MD5 final digest
*
* \param ctx MD5 context
* \param output MD5 checksum result
*/
void md5_finish( md5_context *ctx, unsigned char output[16] );
/**
* \brief Output = MD5( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD5 checksum result
*/
void md5( unsigned char *input, int ilen, unsigned char output[16] );
/**
* \brief Output = MD5( file contents )
*
* \param path input file name
* \param output MD5 checksum result
*
* \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed
*/
int md5_file( char *path, unsigned char output[16] );
/**
* \brief MD5 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen );
/**
* \brief MD5 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen );
/**
* \brief MD5 HMAC final digest
*
* \param ctx HMAC context
* \param output MD5 HMAC checksum result
*/
void md5_hmac_finish( md5_context *ctx, unsigned char output[16] );
/**
* \brief Output = HMAC-MD5( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-MD5 result
*/
void md5_hmac( unsigned char *key, int keylen,
unsigned char *input, int ilen,
unsigned char output[16] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int md5_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* md5.h */

File diff suppressed because it is too large Load Diff

View File

@ -1,138 +1,138 @@
/**
* \file sha1.h
*
* Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
* All rights reserved.
*
* Joined copyright on original XySSL code with: Christophe Devine
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_SHA1_H
#define POLARSSL_SHA1_H
/**
* \brief SHA-1 context structure
*/
typedef struct
{
unsigned long total[2]; /*!< number of bytes processed */
unsigned long state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
}
sha1_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA-1 context setup
*
* \param ctx context to be initialized
*/
void sha1_starts( sha1_context *ctx );
/**
* \brief SHA-1 process buffer
*
* \param ctx SHA-1 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void sha1_update( sha1_context *ctx, unsigned char *input, int ilen );
/**
* \brief SHA-1 final digest
*
* \param ctx SHA-1 context
* \param output SHA-1 checksum result
*/
void sha1_finish( sha1_context *ctx, unsigned char output[20] );
/**
* \brief Output = SHA-1( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output SHA-1 checksum result
*/
void sha1( unsigned char *input, int ilen, unsigned char output[20] );
/**
* \brief Output = SHA-1( file contents )
*
* \param path input file name
* \param output SHA-1 checksum result
*
* \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed
*/
int sha1_file( char *path, unsigned char output[20] );
/**
* \brief SHA-1 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen );
/**
* \brief SHA-1 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen );
/**
* \brief SHA-1 HMAC final digest
*
* \param ctx HMAC context
* \param output SHA-1 HMAC checksum result
*/
void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] );
/**
* \brief Output = HMAC-SHA-1( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-SHA-1 result
*/
void sha1_hmac( unsigned char *key, int keylen,
unsigned char *input, int ilen,
unsigned char output[20] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int sha1_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* sha1.h */
/**
* \file sha1.h
*
* Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
* All rights reserved.
*
* Joined copyright on original XySSL code with: Christophe Devine
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_SHA1_H
#define POLARSSL_SHA1_H
/**
* \brief SHA-1 context structure
*/
typedef struct
{
unsigned long total[2]; /*!< number of bytes processed */
unsigned long state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
}
sha1_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA-1 context setup
*
* \param ctx context to be initialized
*/
void sha1_starts( sha1_context *ctx );
/**
* \brief SHA-1 process buffer
*
* \param ctx SHA-1 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void sha1_update( sha1_context *ctx, unsigned char *input, int ilen );
/**
* \brief SHA-1 final digest
*
* \param ctx SHA-1 context
* \param output SHA-1 checksum result
*/
void sha1_finish( sha1_context *ctx, unsigned char output[20] );
/**
* \brief Output = SHA-1( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output SHA-1 checksum result
*/
void sha1( unsigned char *input, int ilen, unsigned char output[20] );
/**
* \brief Output = SHA-1( file contents )
*
* \param path input file name
* \param output SHA-1 checksum result
*
* \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed
*/
int sha1_file( char *path, unsigned char output[20] );
/**
* \brief SHA-1 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen );
/**
* \brief SHA-1 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen );
/**
* \brief SHA-1 HMAC final digest
*
* \param ctx HMAC context
* \param output SHA-1 HMAC checksum result
*/
void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] );
/**
* \brief Output = HMAC-SHA-1( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-SHA-1 result
*/
void sha1_hmac( unsigned char *key, int keylen,
unsigned char *input, int ilen,
unsigned char output[20] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int sha1_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* sha1.h */

View File

@ -1,21 +1,21 @@
// Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
// Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
#ifndef _TOOLS_H
#define _TOOLS_H
#include "sha1.h"
// bignum
int bn_compare(u8 *a, u8 *b, 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_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_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 ec_priv_to_pub(u8 *k, u8 *Q);
#endif
// Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
// Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
#ifndef _TOOLS_H
#define _TOOLS_H
#include "sha1.h"
// bignum
int bn_compare(u8 *a, u8 *b, 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_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_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 ec_priv_to_pub(u8 *k, u8 *Q);
#endif

View File

@ -1,149 +1,149 @@
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "LinearDiskCache.h"
static const char ID[4] = {'D', 'C', 'A', 'C'};
const int version = 4888; // TODO: Get from SVN_REV
LinearDiskCache::LinearDiskCache()
: file_(NULL), num_entries_(0) {
}
void LinearDiskCache::WriteHeader() {
fwrite(ID, 4, 1, file_);
fwrite(&version, 4, 1, file_);
}
bool LinearDiskCache::ValidateHeader() {
char header_id[4];
int header_version;
fread(&header_id, 4, 1, file_);
fread(&header_version, 4, 1, file_);
if (memcmp(header_id, ID, 4) != 0)
return false;
if (header_version != version)
return false;
return true;
}
int LinearDiskCache::OpenAndRead(const char *filename, LinearDiskCacheReader *reader) {
int items_read_count = 0;
file_ = fopen(filename, "rb");
int file_size = 0;
if (file_) {
fseek(file_, 0, SEEK_END);
file_size = (int)ftell(file_);
}
bool file_corrupt = false;
if (file_size == 0) {
if (file_)
fclose(file_);
// Reopen for writing.
file_ = fopen(filename, "wb");
// Cache empty, let's initialize a header.
WriteHeader();
num_entries_ = 0;
} else {
// file_ must be != 0 here.
// Back to the start we go.
fseek(file_, 0, SEEK_SET);
// Check that the file is valid
if (!ValidateHeader()) {
// Not valid - delete the file and start over.
fclose(file_);
unlink(filename);
// PanicAlert("LinearDiskCache file header broken.");
file_ = fopen(filename, "wb");
WriteHeader();
num_entries_ = 0;
} else {
// Valid - blow through it.
// We're past the header already thanks to ValidateHeader.
while (!feof(file_)) {
int key_size, value_size;
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_);
if (key_size_size == 0 && value_size_size == 0) {
// I guess feof isn't doing it's job - we're at the end.
break;
}
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,
// key_size, value_size, key_size_size, value_size_size);
file_corrupt = true;
break;
}
u8 *key = new u8[key_size];
u8 *value = new u8[value_size];
int actual_key_size = (int)fread(key, 1, key_size, file_);
int actual_value_size = (int)fread(value, 1, value_size, file_);
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,
// key_size, actual_key_size, value_size, actual_value_size);
file_corrupt = true;
} else {
reader->Read(key, key_size, value, value_size);
items_read_count++;
}
delete [] key;
delete [] value;
}
fclose(file_);
// Done reading.
// Reopen file for append.
// At this point, ftell() will be at the end of the file,
// which happens to be exactly what we want.
file_ = fopen(filename, "ab");
fseek(file_, 0, SEEK_END);
}
}
if (file_corrupt) {
// Restore sanity, start over.
fclose(file_);
unlink(filename);
file_ = fopen(filename, "wb+");
WriteHeader();
}
return items_read_count;
}
void LinearDiskCache::Append(
const u8 *key, int key_size, const u8 *value, int value_size) {
// Should do a check that we don't already have "key"?
fwrite(&key_size, 1, sizeof(key_size), file_);
fwrite(&value_size, 1, sizeof(value_size), file_);
fwrite(key, 1, key_size, file_);
fwrite(value, 1, value_size, file_);
}
void LinearDiskCache::Sync() {
fflush(file_);
}
void LinearDiskCache::Close() {
fclose(file_);
file_ = 0;
num_entries_ = 0;
}
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "LinearDiskCache.h"
static const char ID[4] = {'D', 'C', 'A', 'C'};
const int version = 4888; // TODO: Get from SVN_REV
LinearDiskCache::LinearDiskCache()
: file_(NULL), num_entries_(0) {
}
void LinearDiskCache::WriteHeader() {
fwrite(ID, 4, 1, file_);
fwrite(&version, 4, 1, file_);
}
bool LinearDiskCache::ValidateHeader() {
char header_id[4];
int header_version;
fread(&header_id, 4, 1, file_);
fread(&header_version, 4, 1, file_);
if (memcmp(header_id, ID, 4) != 0)
return false;
if (header_version != version)
return false;
return true;
}
int LinearDiskCache::OpenAndRead(const char *filename, LinearDiskCacheReader *reader) {
int items_read_count = 0;
file_ = fopen(filename, "rb");
int file_size = 0;
if (file_) {
fseek(file_, 0, SEEK_END);
file_size = (int)ftell(file_);
}
bool file_corrupt = false;
if (file_size == 0) {
if (file_)
fclose(file_);
// Reopen for writing.
file_ = fopen(filename, "wb");
// Cache empty, let's initialize a header.
WriteHeader();
num_entries_ = 0;
} else {
// file_ must be != 0 here.
// Back to the start we go.
fseek(file_, 0, SEEK_SET);
// Check that the file is valid
if (!ValidateHeader()) {
// Not valid - delete the file and start over.
fclose(file_);
unlink(filename);
// PanicAlert("LinearDiskCache file header broken.");
file_ = fopen(filename, "wb");
WriteHeader();
num_entries_ = 0;
} else {
// Valid - blow through it.
// We're past the header already thanks to ValidateHeader.
while (!feof(file_)) {
int key_size, value_size;
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_);
if (key_size_size == 0 && value_size_size == 0) {
// I guess feof isn't doing it's job - we're at the end.
break;
}
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,
// key_size, value_size, key_size_size, value_size_size);
file_corrupt = true;
break;
}
u8 *key = new u8[key_size];
u8 *value = new u8[value_size];
int actual_key_size = (int)fread(key, 1, key_size, file_);
int actual_value_size = (int)fread(value, 1, value_size, file_);
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,
// key_size, actual_key_size, value_size, actual_value_size);
file_corrupt = true;
} else {
reader->Read(key, key_size, value, value_size);
items_read_count++;
}
delete [] key;
delete [] value;
}
fclose(file_);
// Done reading.
// Reopen file for append.
// At this point, ftell() will be at the end of the file,
// which happens to be exactly what we want.
file_ = fopen(filename, "ab");
fseek(file_, 0, SEEK_END);
}
}
if (file_corrupt) {
// Restore sanity, start over.
fclose(file_);
unlink(filename);
file_ = fopen(filename, "wb+");
WriteHeader();
}
return items_read_count;
}
void LinearDiskCache::Append(
const u8 *key, int key_size, const u8 *value, int value_size) {
// Should do a check that we don't already have "key"?
fwrite(&key_size, 1, sizeof(key_size), file_);
fwrite(&value_size, 1, sizeof(value_size), file_);
fwrite(key, 1, key_size, file_);
fwrite(value, 1, value_size, file_);
}
void LinearDiskCache::Sync() {
fflush(file_);
}
void LinearDiskCache::Close() {
fclose(file_);
file_ = 0;
num_entries_ = 0;
}

View File

@ -1,67 +1,67 @@
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _LINEAR_DISKCACHE
#define _LINEAR_DISKCACHE
#include "Common.h"
#include <stdlib.h>
#include <stdio.h>
// On disk format:
// uint32 'DCAC'
// uint32 version; // svn_rev
// uint32 key_length;
// uint32 value_length;
// .... key;
// .... value;
class LinearDiskCacheReader {
public:
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.
// No random read functionality, all reading is done in OpenAndRead.
// Keys and values can contain any characters, including \0.
//
// Suitable for caching generated shader bytecode between executions.
// Not tuned for extreme performance but should be reasonably fast.
// Does not support keys or values larger than 2GB, which should be reasonable.
// Keys must have non-zero length; values can have zero length.
class LinearDiskCache {
public:
LinearDiskCache();
// Returns the number of items read from the cache.
int OpenAndRead(const char *filename, LinearDiskCacheReader *reader);
void Close();
void Sync();
// Appends a key-value pair to the store.
void Append(const u8 *key, int key_size, const u8 *value, int value_size);
private:
void WriteHeader();
bool ValidateHeader();
FILE *file_;
int num_entries_;
};
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _LINEAR_DISKCACHE
#define _LINEAR_DISKCACHE
#include "Common.h"
#include <stdlib.h>
#include <stdio.h>
// On disk format:
// uint32 'DCAC'
// uint32 version; // svn_rev
// uint32 key_length;
// uint32 value_length;
// .... key;
// .... value;
class LinearDiskCacheReader {
public:
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.
// No random read functionality, all reading is done in OpenAndRead.
// Keys and values can contain any characters, including \0.
//
// Suitable for caching generated shader bytecode between executions.
// Not tuned for extreme performance but should be reasonably fast.
// Does not support keys or values larger than 2GB, which should be reasonable.
// Keys must have non-zero length; values can have zero length.
class LinearDiskCache {
public:
LinearDiskCache();
// Returns the number of items read from the cache.
int OpenAndRead(const char *filename, LinearDiskCacheReader *reader);
void Close();
void Sync();
// Appends a key-value pair to the store.
void Append(const u8 *key, int key_size, const u8 *value, int value_size);
private:
void WriteHeader();
bool ValidateHeader();
FILE *file_;
int num_entries_;
};
#endif // _LINEAR_DISKCACHE

View File

@ -1,253 +1,253 @@
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
// 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 "Common.h"
#include "Timer.h"
namespace OpenCL
{
#if defined(HAVE_OPENCL) && HAVE_OPENCL
cl_device_id device_id = NULL;
cl_context g_context = NULL;
cl_command_queue g_cmdq = NULL;
#endif
bool g_bInitialized = false;
bool Initialize()
{
if(g_bInitialized)
return true;
#if defined(HAVE_OPENCL) && HAVE_OPENCL
if(g_context)
return false;
int err; // error code returned from api calls
// Connect to a compute device
cl_uint numPlatforms;
cl_platform_id platform = NULL;
err = clGetPlatformIDs(0, NULL, &numPlatforms);
if (err != CL_SUCCESS)
{
HandleCLError(err, "clGetPlatformIDs failed.");
return false;
}
if (0 < numPlatforms)
{
cl_platform_id* platforms = new cl_platform_id[numPlatforms];
err = clGetPlatformIDs(numPlatforms, platforms, NULL);
if (err != CL_SUCCESS)
{
HandleCLError(err, "clGetPlatformIDs failed.");
return false;
}
char pbuf[100];
err = clGetPlatformInfo(platforms[0], CL_PLATFORM_VENDOR, sizeof(pbuf), pbuf, NULL);
if (err != CL_SUCCESS)
{
HandleCLError(err, "clGetPlatformInfo failed.");
return false;
}
platform = platforms[0];
delete[] platforms;
}
else
{
PanicAlert("No OpenCL platform found.");
return false;
}
cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0};
cl_context_properties* cprops = (NULL == platform) ? NULL : cps;
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);
if (err != CL_SUCCESS)
{
HandleCLError(err, "Failed to create a device group!");
return false;
}
// Create a compute context
g_context = clCreateContext(cprops, 1, &device_id, NULL, NULL, &err);
if (!g_context)
{
HandleCLError(err, "Failed to create a compute context!");
return false;
}
// Create a command commands
g_cmdq = clCreateCommandQueue(g_context, device_id, 0, &err);
if (!g_cmdq)
{
HandleCLError(err, "Failed to create a command commands!");
return false;
}
NOTICE_LOG(COMMON, "Initialized OpenCL!");
g_bInitialized = true;
return true;
#else
return false;
#endif
}
#if defined(HAVE_OPENCL) && HAVE_OPENCL
cl_context GetContext()
{
return g_context;
}
cl_command_queue GetCommandQueue()
{
return g_cmdq;
}
cl_program CompileProgram(const char *Kernel)
{
u32 compileStart = Common::Timer::GetTimeMs();
int err;
cl_program program;
program = clCreateProgramWithSource(OpenCL::g_context, 1, (const char **) & Kernel, NULL, &err);
if (!program)
{
HandleCLError(err, "Error: Failed to create compute program!");
return NULL;
}
// Build the program executable
err = clBuildProgram(program , 0, NULL, NULL, NULL, NULL);
if(err != CL_SUCCESS) {
char *errors[16384] = {0};
err = clGetProgramBuildInfo(program, OpenCL::device_id, CL_PROGRAM_BUILD_LOG, sizeof(errors),
errors, NULL);
ERROR_LOG(COMMON, "Error log:\n%s\n", errors);
return NULL;
}
NOTICE_LOG(COMMON, "OpenCL CompileProgram took %.3f seconds", (float)(Common::Timer::GetTimeMs() - compileStart) / 1000.0);
return program;
}
cl_kernel CompileKernel(cl_program program, const char *Function)
{
u32 compileStart = Common::Timer::GetTimeMs();
int err;
// Create the compute kernel in the program we wish to run
cl_kernel kernel = clCreateKernel(program, Function, &err);
if (!kernel || err != CL_SUCCESS)
{
HandleCLError(err, "Failed to create compute kernel!");
return NULL;
}
NOTICE_LOG(COMMON, "OpenCL CompileKernel took %.3f seconds", (float)(Common::Timer::GetTimeMs() - compileStart) / 1000.0);
return kernel;
}
#endif
void Destroy()
{
#if defined(HAVE_OPENCL) && HAVE_OPENCL
if(!g_context)
return;
clReleaseCommandQueue(g_cmdq);
clReleaseContext(g_context);
g_context = NULL;
g_cmdq = NULL;
g_bInitialized = false;
#endif
}
void HandleCLError(cl_int error, char* str)
{
#if defined(HAVE_OPENCL) && HAVE_OPENCL
char* name;
switch(error)
{
#define CL_ERROR(x) case (x): name = #x; break
CL_ERROR(CL_SUCCESS);
CL_ERROR(CL_DEVICE_NOT_FOUND);
CL_ERROR(CL_DEVICE_NOT_AVAILABLE);
CL_ERROR(CL_COMPILER_NOT_AVAILABLE);
CL_ERROR(CL_MEM_OBJECT_ALLOCATION_FAILURE);
CL_ERROR(CL_OUT_OF_RESOURCES);
CL_ERROR(CL_OUT_OF_HOST_MEMORY);
CL_ERROR(CL_PROFILING_INFO_NOT_AVAILABLE);
CL_ERROR(CL_MEM_COPY_OVERLAP);
CL_ERROR(CL_IMAGE_FORMAT_MISMATCH);
CL_ERROR(CL_IMAGE_FORMAT_NOT_SUPPORTED);
CL_ERROR(CL_BUILD_PROGRAM_FAILURE);
CL_ERROR(CL_MAP_FAILURE);
CL_ERROR(CL_INVALID_VALUE);
CL_ERROR(CL_INVALID_DEVICE_TYPE);
CL_ERROR(CL_INVALID_PLATFORM);
CL_ERROR(CL_INVALID_DEVICE);
CL_ERROR(CL_INVALID_CONTEXT);
CL_ERROR(CL_INVALID_QUEUE_PROPERTIES);
CL_ERROR(CL_INVALID_COMMAND_QUEUE);
CL_ERROR(CL_INVALID_HOST_PTR);
CL_ERROR(CL_INVALID_MEM_OBJECT);
CL_ERROR(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR);
CL_ERROR(CL_INVALID_IMAGE_SIZE);
CL_ERROR(CL_INVALID_SAMPLER);
CL_ERROR(CL_INVALID_BINARY);
CL_ERROR(CL_INVALID_BUILD_OPTIONS);
CL_ERROR(CL_INVALID_PROGRAM);
CL_ERROR(CL_INVALID_PROGRAM_EXECUTABLE);
CL_ERROR(CL_INVALID_KERNEL_NAME);
CL_ERROR(CL_INVALID_KERNEL_DEFINITION);
CL_ERROR(CL_INVALID_KERNEL);
CL_ERROR(CL_INVALID_ARG_INDEX);
CL_ERROR(CL_INVALID_ARG_VALUE);
CL_ERROR(CL_INVALID_ARG_SIZE);
CL_ERROR(CL_INVALID_KERNEL_ARGS);
CL_ERROR(CL_INVALID_WORK_DIMENSION);
CL_ERROR(CL_INVALID_WORK_GROUP_SIZE);
CL_ERROR(CL_INVALID_WORK_ITEM_SIZE);
CL_ERROR(CL_INVALID_GLOBAL_OFFSET);
CL_ERROR(CL_INVALID_EVENT_WAIT_LIST);
CL_ERROR(CL_INVALID_EVENT);
CL_ERROR(CL_INVALID_OPERATION);
CL_ERROR(CL_INVALID_GL_OBJECT);
CL_ERROR(CL_INVALID_BUFFER_SIZE);
CL_ERROR(CL_INVALID_MIP_LEVEL);
#undef CL_ERROR
default:
name = "Unknown error code";
}
if(!str)
str = "";
ERROR_LOG(COMMON, "OpenCL error: %s %s (%d)", str, name, error);
#endif
}
}
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
// 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 "Common.h"
#include "Timer.h"
namespace OpenCL
{
#if defined(HAVE_OPENCL) && HAVE_OPENCL
cl_device_id device_id = NULL;
cl_context g_context = NULL;
cl_command_queue g_cmdq = NULL;
#endif
bool g_bInitialized = false;
bool Initialize()
{
if(g_bInitialized)
return true;
#if defined(HAVE_OPENCL) && HAVE_OPENCL
if(g_context)
return false;
int err; // error code returned from api calls
// Connect to a compute device
cl_uint numPlatforms;
cl_platform_id platform = NULL;
err = clGetPlatformIDs(0, NULL, &numPlatforms);
if (err != CL_SUCCESS)
{
HandleCLError(err, "clGetPlatformIDs failed.");
return false;
}
if (0 < numPlatforms)
{
cl_platform_id* platforms = new cl_platform_id[numPlatforms];
err = clGetPlatformIDs(numPlatforms, platforms, NULL);
if (err != CL_SUCCESS)
{
HandleCLError(err, "clGetPlatformIDs failed.");
return false;
}
char pbuf[100];
err = clGetPlatformInfo(platforms[0], CL_PLATFORM_VENDOR, sizeof(pbuf), pbuf, NULL);
if (err != CL_SUCCESS)
{
HandleCLError(err, "clGetPlatformInfo failed.");
return false;
}
platform = platforms[0];
delete[] platforms;
}
else
{
PanicAlert("No OpenCL platform found.");
return false;
}
cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0};
cl_context_properties* cprops = (NULL == platform) ? NULL : cps;
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);
if (err != CL_SUCCESS)
{
HandleCLError(err, "Failed to create a device group!");
return false;
}
// Create a compute context
g_context = clCreateContext(cprops, 1, &device_id, NULL, NULL, &err);
if (!g_context)
{
HandleCLError(err, "Failed to create a compute context!");
return false;
}
// Create a command commands
g_cmdq = clCreateCommandQueue(g_context, device_id, 0, &err);
if (!g_cmdq)
{
HandleCLError(err, "Failed to create a command commands!");
return false;
}
NOTICE_LOG(COMMON, "Initialized OpenCL!");
g_bInitialized = true;
return true;
#else
return false;
#endif
}
#if defined(HAVE_OPENCL) && HAVE_OPENCL
cl_context GetContext()
{
return g_context;
}
cl_command_queue GetCommandQueue()
{
return g_cmdq;
}
cl_program CompileProgram(const char *Kernel)
{
u32 compileStart = Common::Timer::GetTimeMs();
int err;
cl_program program;
program = clCreateProgramWithSource(OpenCL::g_context, 1, (const char **) & Kernel, NULL, &err);
if (!program)
{
HandleCLError(err, "Error: Failed to create compute program!");
return NULL;
}
// Build the program executable
err = clBuildProgram(program , 0, NULL, NULL, NULL, NULL);
if(err != CL_SUCCESS) {
char *errors[16384] = {0};
err = clGetProgramBuildInfo(program, OpenCL::device_id, CL_PROGRAM_BUILD_LOG, sizeof(errors),
errors, NULL);
ERROR_LOG(COMMON, "Error log:\n%s\n", errors);
return NULL;
}
NOTICE_LOG(COMMON, "OpenCL CompileProgram took %.3f seconds", (float)(Common::Timer::GetTimeMs() - compileStart) / 1000.0);
return program;
}
cl_kernel CompileKernel(cl_program program, const char *Function)
{
u32 compileStart = Common::Timer::GetTimeMs();
int err;
// Create the compute kernel in the program we wish to run
cl_kernel kernel = clCreateKernel(program, Function, &err);
if (!kernel || err != CL_SUCCESS)
{
HandleCLError(err, "Failed to create compute kernel!");
return NULL;
}
NOTICE_LOG(COMMON, "OpenCL CompileKernel took %.3f seconds", (float)(Common::Timer::GetTimeMs() - compileStart) / 1000.0);
return kernel;
}
#endif
void Destroy()
{
#if defined(HAVE_OPENCL) && HAVE_OPENCL
if(!g_context)
return;
clReleaseCommandQueue(g_cmdq);
clReleaseContext(g_context);
g_context = NULL;
g_cmdq = NULL;
g_bInitialized = false;
#endif
}
void HandleCLError(cl_int error, char* str)
{
#if defined(HAVE_OPENCL) && HAVE_OPENCL
char* name;
switch(error)
{
#define CL_ERROR(x) case (x): name = #x; break
CL_ERROR(CL_SUCCESS);
CL_ERROR(CL_DEVICE_NOT_FOUND);
CL_ERROR(CL_DEVICE_NOT_AVAILABLE);
CL_ERROR(CL_COMPILER_NOT_AVAILABLE);
CL_ERROR(CL_MEM_OBJECT_ALLOCATION_FAILURE);
CL_ERROR(CL_OUT_OF_RESOURCES);
CL_ERROR(CL_OUT_OF_HOST_MEMORY);
CL_ERROR(CL_PROFILING_INFO_NOT_AVAILABLE);
CL_ERROR(CL_MEM_COPY_OVERLAP);
CL_ERROR(CL_IMAGE_FORMAT_MISMATCH);
CL_ERROR(CL_IMAGE_FORMAT_NOT_SUPPORTED);
CL_ERROR(CL_BUILD_PROGRAM_FAILURE);
CL_ERROR(CL_MAP_FAILURE);
CL_ERROR(CL_INVALID_VALUE);
CL_ERROR(CL_INVALID_DEVICE_TYPE);
CL_ERROR(CL_INVALID_PLATFORM);
CL_ERROR(CL_INVALID_DEVICE);
CL_ERROR(CL_INVALID_CONTEXT);
CL_ERROR(CL_INVALID_QUEUE_PROPERTIES);
CL_ERROR(CL_INVALID_COMMAND_QUEUE);
CL_ERROR(CL_INVALID_HOST_PTR);
CL_ERROR(CL_INVALID_MEM_OBJECT);
CL_ERROR(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR);
CL_ERROR(CL_INVALID_IMAGE_SIZE);
CL_ERROR(CL_INVALID_SAMPLER);
CL_ERROR(CL_INVALID_BINARY);
CL_ERROR(CL_INVALID_BUILD_OPTIONS);
CL_ERROR(CL_INVALID_PROGRAM);
CL_ERROR(CL_INVALID_PROGRAM_EXECUTABLE);
CL_ERROR(CL_INVALID_KERNEL_NAME);
CL_ERROR(CL_INVALID_KERNEL_DEFINITION);
CL_ERROR(CL_INVALID_KERNEL);
CL_ERROR(CL_INVALID_ARG_INDEX);
CL_ERROR(CL_INVALID_ARG_VALUE);
CL_ERROR(CL_INVALID_ARG_SIZE);
CL_ERROR(CL_INVALID_KERNEL_ARGS);
CL_ERROR(CL_INVALID_WORK_DIMENSION);
CL_ERROR(CL_INVALID_WORK_GROUP_SIZE);
CL_ERROR(CL_INVALID_WORK_ITEM_SIZE);
CL_ERROR(CL_INVALID_GLOBAL_OFFSET);
CL_ERROR(CL_INVALID_EVENT_WAIT_LIST);
CL_ERROR(CL_INVALID_EVENT);
CL_ERROR(CL_INVALID_OPERATION);
CL_ERROR(CL_INVALID_GL_OBJECT);
CL_ERROR(CL_INVALID_BUFFER_SIZE);
CL_ERROR(CL_INVALID_MIP_LEVEL);
#undef CL_ERROR
default:
name = "Unknown error code";
}
if(!str)
str = "";
ERROR_LOG(COMMON, "OpenCL error: %s %s (%d)", str, name, error);
#endif
}
}

View File

@ -1,70 +1,70 @@
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef __OPENCL_H__
#define __OPENCL_H__
#include "Common.h"
// Change to #if 1 if you want to test OpenCL (and you have it) on Windows
#if 0
#pragma comment(lib, "OpenCL.lib")
#define HAVE_OPENCL 1
#endif
#if defined(HAVE_OPENCL) && HAVE_OPENCL
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif
#else
typedef void *cl_context;
typedef void *cl_command_queue;
typedef void *cl_program;
typedef void *cl_kernel;
typedef void *cl_mem;
typedef void *cl_int;
#endif
namespace OpenCL
{
#if defined(HAVE_OPENCL) && HAVE_OPENCL
extern cl_device_id device_id;
extern cl_context g_context;
extern cl_command_queue g_cmdq;
#endif
bool Initialize();
cl_context GetContext();
cl_command_queue GetCommandQueue();
void Destroy();
cl_program CompileProgram(const char *Kernel);
cl_kernel CompileKernel(cl_program program, const char *Function);
void HandleCLError(cl_int error, char* str = 0);
}
#endif
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef __OPENCL_H__
#define __OPENCL_H__
#include "Common.h"
// Change to #if 1 if you want to test OpenCL (and you have it) on Windows
#if 0
#pragma comment(lib, "OpenCL.lib")
#define HAVE_OPENCL 1
#endif
#if defined(HAVE_OPENCL) && HAVE_OPENCL
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif
#else
typedef void *cl_context;
typedef void *cl_command_queue;
typedef void *cl_program;
typedef void *cl_kernel;
typedef void *cl_mem;
typedef void *cl_int;
#endif
namespace OpenCL
{
#if defined(HAVE_OPENCL) && HAVE_OPENCL
extern cl_device_id device_id;
extern cl_context g_context;
extern cl_command_queue g_cmdq;
#endif
bool Initialize();
cl_context GetContext();
cl_command_queue GetCommandQueue();
void Destroy();
cl_program CompileProgram(const char *Kernel);
cl_kernel CompileKernel(cl_program program, const char *Function);
void HandleCLError(cl_int error, char* str = 0);
}
#endif

View File

@ -1,175 +1,173 @@
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "FileUtil.h"
#include "SysConf.h"
SysConf::SysConf()
: m_IsValid(false)
{
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "FileUtil.h"
#include "SysConf.h"
SysConf::SysConf()
: m_IsValid(false)
{
if (LoadFromFile(File::GetUserPath(F_WIISYSCONF_IDX)))
m_IsValid = true;
}
m_IsValid = true;
}
void SysConf::Reload()
{
if (m_IsValid)
return;
if (LoadFromFile(File::GetUserPath(F_WIISYSCONF_IDX)))
m_IsValid = true;
if (m_IsValid)
return;
if (LoadFromFile(File::GetUserPath(F_WIISYSCONF_IDX)))
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.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef __SYSCONF_MANAGER_h__
#define __SYSCONF_MANAGER_h__
#include <string>
#include <vector>
// This class is meant to edit the values in a given Wii SYSCONF file
// It currently does not add/remove/rearrange sections,
// instead only modifies exiting sections' data
#define SYSCONF_SIZE 0x4000
enum SysconfType
{
Type_BigArray = 1,
Type_SmallArray,
Type_Byte,
Type_Short,
Type_Long,
Type_Unknown,
Type_Bool
};
struct SSysConfHeader
{
char version[4];
u16 numEntries;
};
struct SSysConfEntry
{
u16 offset;
SysconfType type;
u8 nameLength;
char name[32];
u16 dataLength;
u8* data;
template<class T>
T GetData() { return *(T*)data; }
};
class SysConf
{
private:
SSysConfHeader m_Header;
std::string m_Filename;
std::vector<SSysConfEntry> m_Entries;
bool m_IsValid;
public:
SysConf();
~SysConf();
bool IsValid() { return m_IsValid; }
void Reload();
template<class T>
T GetData(const char* sectionName)
{
if (!m_IsValid)
{
PanicAlert("Trying to read from invalid SYSCONF");
return 0;
}
size_t index = 0;
for (; index < m_Entries.size() - 1; index++)
{
if (strcmp(m_Entries.at(index).name, sectionName) == 0)
break;
}
if (index == m_Entries.size() - 1)
{
PanicAlert("Section %s not found in SYSCONF", sectionName);
return 0;
}
return m_Entries.at(index).GetData<T>();
}
template<class T>
bool SetData(const char* sectionName, T newValue)
{
if (!m_IsValid)
return false;
size_t index = 0;
for (; index < m_Entries.size() - 1; index++)
{
if (strcmp(m_Entries.at(index).name, sectionName) == 0)
break;
}
if (index == m_Entries.size() - 1)
{
PanicAlert("Section %s not found in SYSCONF", sectionName);
return false;
}
*(T*)m_Entries.at(index).data = newValue;
return true;
}
bool Save();
bool SaveToFile(const char* filename);
bool LoadFromFile(const char* filename);
private:
bool LoadFromFileInternal(FILE *f);
};
#endif // __SYSCONF_MANAGER_h__
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef __SYSCONF_MANAGER_h__
#define __SYSCONF_MANAGER_h__
#include <string>
#include <vector>
// This class is meant to edit the values in a given Wii SYSCONF file
// It currently does not add/remove/rearrange sections,
// instead only modifies exiting sections' data
#define SYSCONF_SIZE 0x4000
enum SysconfType
{
Type_BigArray = 1,
Type_SmallArray,
Type_Byte,
Type_Short,
Type_Long,
Type_Unknown,
Type_Bool
};
struct SSysConfHeader
{
char version[4];
u16 numEntries;
};
struct SSysConfEntry
{
u16 offset;
SysconfType type;
u8 nameLength;
char name[32];
u16 dataLength;
u8* data;
template<class T>
T GetData() { return *(T*)data; }
};
class SysConf
{
private:
SSysConfHeader m_Header;
std::string m_Filename;
std::vector<SSysConfEntry> m_Entries;
bool m_IsValid;
public:
SysConf();
~SysConf();
bool IsValid() { return m_IsValid; }
void Reload();
template<class T>
T GetData(const char* sectionName)
{
if (!m_IsValid)
{
PanicAlert("Trying to read from invalid SYSCONF");
return 0;
}
size_t index = 0;
for (; index < m_Entries.size() - 1; index++)
{
if (strcmp(m_Entries.at(index).name, sectionName) == 0)
break;
}
if (index == m_Entries.size() - 1)
{
PanicAlert("Section %s not found in SYSCONF", sectionName);
return 0;
}
return m_Entries.at(index).GetData<T>();
}
template<class T>
bool SetData(const char* sectionName, T newValue)
{
if (!m_IsValid)
return false;
size_t index = 0;
for (; index < m_Entries.size() - 1; index++)
{
if (strcmp(m_Entries.at(index).name, sectionName) == 0)
break;
}
if (index == m_Entries.size() - 1)
{
PanicAlert("Section %s not found in SYSCONF", sectionName);
return false;
}
*(T*)m_Entries.at(index).data = newValue;
return true;
}
bool Save();
bool SaveToFile(const char* filename);
bool LoadFromFile(const char* filename);
private:
bool LoadFromFileInternal(FILE *f);
};
#endif // __SYSCONF_MANAGER_h__

View File

@ -44,15 +44,12 @@
#include "cmdline.h"
#include "Thread.h"
#include "PowerPC/PowerPC.h"
#include "PluginManager.h"
#include "ConfigManager.h"
#include "LogManager.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_ShowJitResults(unsigned int address){}
@ -99,7 +96,7 @@ void Host_SysMessage(const char *fmt, ...)
msg[len - 1] = '\n';
msg[len] = '\0';
}
fprintf(stderr, msg);
fprintf(stderr, "%s", msg);
}
void Host_UpdateLeds(int led_bits)
@ -167,6 +164,7 @@ int appleMain(int argc, char *argv[]);
@end
volatile bool running;
int main(int argc, char *argv[])
{
@ -182,9 +180,10 @@ int main(int argc, char *argv[])
NSEvent *event = [[NSEvent alloc] init];
[thread cocoaThreadStart];
running = true;
//cocoa event loop
while(true)
while(running)
{
event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ];
if(cocoaSendEvent(event))
@ -212,7 +211,7 @@ int main(int argc, char* argv[])
{
gengetopt_args_info args_info;
if (cmdline_parser (argc, argv, &args_info) != 0)
if (cmdline_parser(argc, argv, &args_info) != 0)
return(1);
if (args_info.inputs_num < 1)
@ -224,30 +223,29 @@ int main(int argc, char* argv[])
updateMainFrameEvent.Init();
cpu_info.Detect();
LogManager::Init();
EventHandler::Init();
SConfig::Init();
CPluginManager::Init();
CPluginManager::GetInstance().ScanForPlugins();
// check to see if ~/Library/Application Support/Dolphin exists; if not, create it
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)
if (BootManager::BootCore(bootFile)) //no use running the loop when booting fails
{
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);
return(0);