mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-15 16:59:18 +01:00
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:
parent
0819740b6a
commit
3a5a7de906
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
@ -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
@ -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 */
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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());
|
|
||||||
}
|
|
||||||
|
@ -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__
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user