mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
Fixed conflicts
This commit is contained in:
commit
8bd0ee875c
@ -50,10 +50,10 @@ class be_t
|
||||
|
||||
public:
|
||||
typedef T type;
|
||||
|
||||
be_t()
|
||||
{
|
||||
}
|
||||
#ifdef __GNUG__
|
||||
be_t() noexcept = default
|
||||
#endif
|
||||
be_t(){}
|
||||
|
||||
be_t(const T& value)
|
||||
{
|
||||
|
@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(__GNUG__)
|
||||
#include <math.h>
|
||||
#define _fpclass(x) fpclassify(x)
|
||||
#include <cmath>
|
||||
#define _fpclass(x) std::fpclassify(x)
|
||||
#define __forceinline __attribute__((always_inline))
|
||||
#define _byteswap_ushort(x) __builtin_bswap16(x)
|
||||
#define _byteswap_ulong(x) __builtin_bswap32(x)
|
||||
@ -10,4 +10,10 @@
|
||||
#define Sleep(x) usleep(x * 1000)
|
||||
#define mkdir(x) mkdir(x, 0777)
|
||||
#define INFINITE 0xFFFFFFFF
|
||||
#define _CRT_ALIGN(x) __attribute__((aligned(x)))
|
||||
#define InterlockedCompareExchange(ptr,new_val,old_val) __sync_val_compare_and_swap(ptr,old_val,new_val)
|
||||
#define InterlockedCompareExchange64(ptr,new_val,old_val) __sync_val_compare_and_swap(ptr,old_val,new_val)
|
||||
#define _aligned_malloc(size,alignment) aligned_alloc(alignment,size)
|
||||
#define _aligned_free(pointer) free(pointer)
|
||||
#define DWORD int64_t
|
||||
#endif
|
||||
|
@ -96,7 +96,11 @@ public:
|
||||
m_cur_id = s_first_id;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename T
|
||||
#ifdef __GNUG__
|
||||
= char
|
||||
#endif
|
||||
>
|
||||
ID_TYPE GetNewID(const std::string& name = "", T* data = nullptr, const u32 attr = 0)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
@ -155,4 +159,4 @@ public:
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -95,4 +95,4 @@ public:
|
||||
|
||||
wxDialog::Close(force);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -6,9 +6,9 @@ __forceinline void SM_Sleep()
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
__forceinline DWORD SM_GetCurrentThreadId()
|
||||
__forceinline size_t SM_GetCurrentThreadId()
|
||||
{
|
||||
return GetCurrentThreadId();
|
||||
return std::this_thread::get_id().hash();
|
||||
}
|
||||
|
||||
__forceinline u32 SM_GetCurrentCPUThreadId()
|
||||
@ -23,4 +23,4 @@ __forceinline u32 SM_GetCurrentCPUThreadId()
|
||||
__forceinline be_t<u32> SM_GetCurrentCPUThreadIdBE()
|
||||
{
|
||||
return SM_GetCurrentCPUThreadId();
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
extern void SM_Sleep();
|
||||
extern DWORD SM_GetCurrentThreadId();
|
||||
extern size_t SM_GetCurrentThreadId();
|
||||
extern u32 SM_GetCurrentCPUThreadId();
|
||||
extern be_t<u32> SM_GetCurrentCPUThreadIdBE();
|
||||
|
||||
@ -20,13 +20,12 @@ enum SMutexResult
|
||||
template
|
||||
<
|
||||
typename T,
|
||||
u32 free_value = 0,
|
||||
u32 dead_value = ~0,
|
||||
void (wait)() = SM_Sleep
|
||||
u64 free_value = 0,
|
||||
u64 dead_value = ~0,
|
||||
void (*wait)() = SM_Sleep
|
||||
>
|
||||
class SMutexBase
|
||||
{
|
||||
static_assert(sizeof(T) == 4, "Invalid SMutexBase typename");
|
||||
std::atomic<T> owner;
|
||||
|
||||
public:
|
||||
@ -157,16 +156,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef SMutexBase<DWORD>
|
||||
typedef SMutexBase<size_t>
|
||||
SMutexGeneral;
|
||||
typedef SMutexBase<u32>
|
||||
SMutex;
|
||||
typedef SMutexBase<be_t<u32>>
|
||||
SMutexBE;
|
||||
|
||||
typedef SMutexLockerBase<DWORD, SM_GetCurrentThreadId>
|
||||
typedef SMutexLockerBase<size_t, SM_GetCurrentThreadId>
|
||||
SMutexGeneralLocker;
|
||||
typedef SMutexLockerBase<u32, SM_GetCurrentCPUThreadId>
|
||||
SMutexLocker;
|
||||
typedef SMutexLockerBase<be_t<u32>, SM_GetCurrentCPUThreadIdBE>
|
||||
SMutexBELocker;
|
||||
SMutexBELocker;
|
||||
|
@ -1,7 +1,12 @@
|
||||
#include "stdafx.h"
|
||||
#include "Thread.h"
|
||||
|
||||
__declspec(thread) NamedThreadBase* g_tls_this_thread = nullptr;
|
||||
#ifdef _WIN32
|
||||
__declspec(thread)
|
||||
#else
|
||||
thread_local
|
||||
#endif
|
||||
NamedThreadBase* g_tls_this_thread = nullptr;
|
||||
|
||||
NamedThreadBase* GetCurrentNamedThread()
|
||||
{
|
||||
@ -125,7 +130,7 @@ void thread::start(std::function<void()> func)
|
||||
catch(...)
|
||||
{
|
||||
ConLog.Error("Crash :(");
|
||||
terminate();
|
||||
std::terminate();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -143,4 +148,4 @@ void thread::join()
|
||||
bool thread::joinable() const
|
||||
{
|
||||
return m_thr.joinable();
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ class StepThread : public ThreadBase
|
||||
volatile bool m_exit;
|
||||
|
||||
protected:
|
||||
StepThread(const wxString& name = "Unknown StepThread")
|
||||
StepThread(const std::string& name = "Unknown StepThread")
|
||||
: ThreadBase(true, name)
|
||||
, m_exit(false)
|
||||
{
|
||||
|
@ -104,14 +104,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scetool", "scetool", "{AB33
|
||||
scetool\zlib.h = scetool\zlib.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "unpkg", "unpkg", "{9F2D2094-BA46-4456-8C45-FD9EC108F1EE}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
unpkg\oddkeys.h = unpkg\oddkeys.h
|
||||
unpkg\ps3_common.h = unpkg\ps3_common.h
|
||||
unpkg\unpkg.c = unpkg\unpkg.c
|
||||
unpkg\unpkg.h = unpkg\unpkg.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ribbon", "wxWidgets\build\msw\wx_vc10_ribbon.vcxproj", "{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stc", "wxWidgets\build\msw\wx_vc10_stc.vcxproj", "{23E1C437-A951-5943-8639-A17F3CF2E606}"
|
||||
|
@ -3,15 +3,21 @@ cmake_minimum_required(VERSION 2.8)
|
||||
project(rpcs3)
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
add_definitions(-std=gnu++11)
|
||||
add_definitions(-D__WXGTK__)
|
||||
#add_definitions(-Wfatal-errors)
|
||||
add_definitions(-w) # TODO: remove me
|
||||
add_definitions(-DwxUSE_UNICODE=0)
|
||||
add_definitions(-fpermissive) # TODO: remove me
|
||||
add_definitions(-std=gnu++11)
|
||||
#add_definitions(-D__WXGTK__)
|
||||
#add_definitions(-Wfatal-errors)
|
||||
add_definitions(-w) # TODO: remove me
|
||||
add_definitions(-fpermissive) # TODO: remove me
|
||||
endif()
|
||||
|
||||
find_package(wxWidgets)
|
||||
SET(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/../bin")
|
||||
|
||||
add_definitions(-DGL_GLEXT_PROTOTYPES)
|
||||
add_definitions(-DGLX_GLXEXT_PROTOTYPES)
|
||||
|
||||
find_package(wxWidgets COMPONENTS core base net aui gl REQUIRED)
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
|
||||
include("${wxWidgets_USE_FILE}")
|
||||
|
||||
@ -27,11 +33,15 @@ ${CMAKE_SOURCE_DIR}/..
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
RPCS3_SRC
|
||||
${CMAKE_SOURCE_DIR}/rpcs3.cpp
|
||||
${CMAKE_SOURCE_DIR}/AppConnector.cpp
|
||||
${CMAKE_SOURCE_DIR}/Ini.cpp
|
||||
${CMAKE_SOURCE_DIR}/Emu/*
|
||||
${CMAKE_SOURCE_DIR}/Gui/*
|
||||
${CMAKE_SOURCE_DIR}/Loader/*
|
||||
${CMAKE_SOURCE_DIR}/../Utilities/*
|
||||
${CMAKE_SOURCE_DIR}/../scetool/scetool.cpp
|
||||
)
|
||||
|
||||
add_executable(rpcs3 ${RPCS3_SRC})
|
||||
target_link_libraries(rpcs3 ${wxWidgets_LIBRARIES})
|
||||
target_link_libraries(rpcs3 ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${ZLIB_LIBRARIES})
|
||||
|
@ -21,7 +21,7 @@ struct reservation_struct
|
||||
|
||||
extern reservation_struct reservation;
|
||||
|
||||
enum CPUThreadType
|
||||
enum CPUThreadType :unsigned char
|
||||
{
|
||||
CPU_THREAD_PPU,
|
||||
CPU_THREAD_SPU,
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "CPUThread.h"
|
||||
class CPUThread;
|
||||
enum CPUThreadType : unsigned char;
|
||||
|
||||
class CPUThreadManager
|
||||
{
|
||||
@ -24,4 +25,4 @@ public:
|
||||
|
||||
void Exec();
|
||||
void Task();
|
||||
};
|
||||
};
|
||||
|
@ -158,7 +158,7 @@ struct DMAC
|
||||
u32 queue_pos;
|
||||
u32 proxy_pos;
|
||||
long queue_lock;
|
||||
long proxy_lock;
|
||||
volatile std::atomic<int> proxy_lock;
|
||||
|
||||
bool ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size)
|
||||
{
|
||||
@ -193,7 +193,7 @@ struct DMAC
|
||||
return MFC_PPU_DMA_QUEUE_FULL;
|
||||
}
|
||||
|
||||
/* while (_InterlockedExchange(&proxy_lock, 1));
|
||||
/* while (std::atomic_exchange(&proxy_lock, 1));
|
||||
_mm_lfence();
|
||||
DMAC_Proxy& p = proxy[proxy_pos];
|
||||
p.cmd = cmd;
|
||||
@ -212,7 +212,7 @@ struct DMAC
|
||||
|
||||
void ClearCmd()
|
||||
{
|
||||
while (_InterlockedExchange(&proxy_lock, 1));
|
||||
while (std::atomic_exchange(&proxy_lock, 1));
|
||||
_mm_lfence();
|
||||
memcpy(proxy, proxy + 1, --proxy_pos * sizeof(DMAC_Proxy));
|
||||
_mm_sfence();
|
||||
@ -298,4 +298,4 @@ struct MFC
|
||||
MFC_QStatus.SetValue(mask);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if 0
|
||||
#include "stdafx.h"
|
||||
#include "PPCThreadManager.h"
|
||||
#include "PPUThread.h"
|
||||
@ -33,7 +34,7 @@ PPCThread& PPCThreadManager::AddThread(PPCThreadType type)
|
||||
default: assert(0);
|
||||
}
|
||||
|
||||
new_thread->SetId(Emu.GetIdManager().GetNewID(wxString::Format("%s Thread", name), new_thread));
|
||||
new_thread->SetId(Emu.GetIdManager().GetNewID(wxString::Format("%s Thread", name).ToStdString(), new_thread));
|
||||
|
||||
m_threads.Add(new_thread);
|
||||
wxGetApp().SendDbgCommand(DID_CREATE_THREAD, new_thread);
|
||||
@ -106,3 +107,4 @@ void PPCThreadManager::Exec()
|
||||
m_threads[i].Exec();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -3,9 +3,9 @@
|
||||
|
||||
enum PPCThreadType
|
||||
{
|
||||
PPC_THREAD_PPU,
|
||||
PPC_THREAD_SPU,
|
||||
PPC_THREAD_RAW_SPU
|
||||
PPC_THREAD_PPU,
|
||||
PPC_THREAD_SPU,
|
||||
PPC_THREAD_RAW_SPU
|
||||
};
|
||||
|
||||
class PPCThreadManager
|
||||
@ -17,7 +17,7 @@ class PPCThreadManager
|
||||
std::mutex m_mtx_thread;
|
||||
wxSemaphore m_sem_task;
|
||||
Stack<u32> m_delete_threads;
|
||||
u32 m_raw_spu_num;
|
||||
u32 m_raw_spu_num;
|
||||
|
||||
public:
|
||||
PPCThreadManager();
|
||||
|
@ -97,7 +97,7 @@ private:
|
||||
const int fpc = _fpclass(v);
|
||||
#ifdef __GNUG__
|
||||
if(fpc == FP_SUBNORMAL)
|
||||
return signbit(v) ? -0.0f : 0.0f;
|
||||
return std::signbit(v) ? -0.0f : 0.0f;
|
||||
#else
|
||||
if(fpc & _FPCLASS_ND) return -0.0f;
|
||||
if(fpc & _FPCLASS_PD) return 0.0f;
|
||||
@ -3364,7 +3364,7 @@ private:
|
||||
#ifdef _MSC_VER
|
||||
if(_fpclass(CPU.FPR[frb]) >= _FPCLASS_NZ)
|
||||
#else
|
||||
if(_fpclass(CPU.FPR[frb]) == FP_ZERO || signbit(CPU.FPR[frb]) == 0)
|
||||
if(_fpclass(CPU.FPR[frb]) == FP_ZERO || std::signbit(CPU.FPR[frb]) == 0)
|
||||
#endif
|
||||
{
|
||||
res = static_cast<float>(1.0 / CPU.FPR[frb]);
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "Emu/Cell/PPCThread.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "rpcs3.h"
|
||||
#include <cmath>
|
||||
|
||||
enum
|
||||
{
|
||||
@ -373,10 +374,10 @@ struct PPCdouble
|
||||
switch (fpc)
|
||||
{
|
||||
case FP_NAN: return FPR_QNAN;
|
||||
case FP_INFINITE: return signbit(_double) ? FPR_NINF : FPR_PINF;
|
||||
case FP_SUBNORMAL: return signbit(_double) ? FPR_ND : FPR_PD;
|
||||
case FP_ZERO: return signbit(_double) ? FPR_NZ : FPR_PZ;
|
||||
default: return signbit(_double) ? FPR_NN : FPR_PN;
|
||||
case FP_INFINITE: return std::signbit(_double) ? FPR_NINF : FPR_PINF;
|
||||
case FP_SUBNORMAL: return std::signbit(_double) ? FPR_ND : FPR_PD;
|
||||
case FP_ZERO: return std::signbit(_double) ? FPR_NZ : FPR_PZ;
|
||||
default: return std::signbit(_double) ? FPR_NN : FPR_PN;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -44,6 +44,10 @@ void DbgConsole::Task()
|
||||
if(!m_dbg_buffer.HasNewPacket())
|
||||
{
|
||||
Sleep(1);
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -26,9 +26,9 @@ bool EventManager::RegisterKey(EventQueue* data, u64 key)
|
||||
|
||||
if (key_map.find(key) != key_map.end()) return false;
|
||||
|
||||
for (auto& v = key_map.begin(); v != key_map.end(); ++v)
|
||||
for (auto& v : key_map)
|
||||
{
|
||||
if (v->second == data) return false;
|
||||
if (v.second == data) return false;
|
||||
}
|
||||
|
||||
key_map[key] = data;
|
||||
@ -79,4 +79,4 @@ bool EventManager::SendEvent(u64 key, u64 source, u64 d1, u64 d2, u64 d3)
|
||||
|
||||
eq->events.push(source, d1, d2, d3);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "vfsLocalDir.h"
|
||||
#include <direct.h>
|
||||
|
||||
vfsLocalDir::vfsLocalDir(vfsDevice* device) : vfsDirBase(device)
|
||||
{
|
||||
@ -50,4 +49,4 @@ bool vfsLocalDir::Rename(const wxString& from, const wxString& to)
|
||||
bool vfsLocalDir::Remove(const wxString& path)
|
||||
{
|
||||
return wxRmdir(path);
|
||||
}
|
||||
}
|
||||
|
@ -75,27 +75,27 @@ enum
|
||||
|
||||
struct CellGcmControl
|
||||
{
|
||||
u32 put;
|
||||
u32 get;
|
||||
u32 ref;
|
||||
be_t<u32> put;
|
||||
be_t<u32> get;
|
||||
be_t<u32> ref;
|
||||
};
|
||||
|
||||
struct CellGcmConfig
|
||||
{
|
||||
u32 localAddress;
|
||||
u32 ioAddress;
|
||||
u32 localSize;
|
||||
u32 ioSize;
|
||||
u32 memoryFrequency;
|
||||
u32 coreFrequency;
|
||||
be_t<u32> localAddress;
|
||||
be_t<u32> ioAddress;
|
||||
be_t<u32> localSize;
|
||||
be_t<u32> ioSize;
|
||||
be_t<u32> memoryFrequency;
|
||||
be_t<u32> coreFrequency;
|
||||
};
|
||||
|
||||
struct CellGcmContextData
|
||||
{
|
||||
u32 begin;
|
||||
u32 end;
|
||||
u32 current;
|
||||
u32 callback;
|
||||
be_t<u32> begin;
|
||||
be_t<u32> end;
|
||||
be_t<u32> current;
|
||||
be_t<u32> callback;
|
||||
};
|
||||
|
||||
struct gcmInfo
|
||||
@ -147,10 +147,10 @@ struct CellGcmZcullInfo
|
||||
|
||||
struct CellGcmTileInfo
|
||||
{
|
||||
u32 tile;
|
||||
u32 limit;
|
||||
u32 pitch;
|
||||
u32 format;
|
||||
be_t<u32> tile;
|
||||
be_t<u32> limit;
|
||||
be_t<u32> pitch;
|
||||
be_t<u32> format;
|
||||
};
|
||||
|
||||
struct GcmZcullInfo
|
||||
@ -194,10 +194,10 @@ struct GcmTileInfo
|
||||
{
|
||||
CellGcmTileInfo ret;
|
||||
|
||||
re(ret.tile, (m_location + 1) | (m_bank << 4) | ((m_offset / 0x10000) << 16) | (m_location << 31));
|
||||
re(ret.limit, ((m_offset + m_size - 1) / 0x10000) << 16 | (m_location << 31));
|
||||
re(ret.pitch, (m_pitch / 0x100) << 8);
|
||||
re(ret.format, m_base | ((m_base + ((m_size - 1) / 0x10000)) << 13) | (m_comp << 26) | (1 << 30));
|
||||
ret.tile = (m_location + 1) | (m_bank << 4) | ((m_offset / 0x10000) << 16) | (m_location << 31);
|
||||
ret.limit = ((m_offset + m_size - 1) / 0x10000) << 16 | (m_location << 31);
|
||||
ret.pitch = (m_pitch / 0x100) << 8;
|
||||
ret.format = m_base | ((m_base + ((m_size - 1) / 0x10000)) << 13) | (m_comp << 26) | (1 << 30);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1198,6 +1198,7 @@ static const wxString GetMethodName(const u32 id)
|
||||
{ NV4097_SET_TRANSFORM_CONSTANT_LOAD , "SetTransformConstantLoad" } ,
|
||||
{ NV4097_SET_FREQUENCY_DIVIDER_OPERATION , "SetFrequencyDividerOperation" } ,
|
||||
{ NV4097_INVALIDATE_L2 , "InvalidateL2" } ,
|
||||
{ NV4097_SET_TRANSFORM_BRANCH_BITS, "SetTransformBranchBits" } ,
|
||||
};
|
||||
|
||||
for(u32 i = 0; i < WXSIZEOF(METHOD_NAME_LIST); ++i)
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "GLGSRender.h"
|
||||
#include "Emu/Cell/PPCInstrTable.h"
|
||||
#include "Gui/RSXDebugger.h"
|
||||
#include "OpenGL.h"
|
||||
|
||||
#define CMD_DEBUG 0
|
||||
#define DUMP_VERTEX_DATA 0
|
||||
@ -647,8 +648,13 @@ void GLGSRender::OnInitThread()
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
#ifdef _WIN32
|
||||
glSwapInterval(Ini.GSVSyncEnable.GetValue() ? 1 : 0);
|
||||
|
||||
#else
|
||||
if (GLXDrawable drawable = glXGetCurrentDrawable()){
|
||||
glXSwapIntervalEXT(glXGetCurrentDisplay(), drawable, Ini.GSVSyncEnable.GetValue() ? 1 : 0);
|
||||
}
|
||||
#endif
|
||||
glGenTextures(1, &g_depth_tex);
|
||||
glGenTextures(1, &g_flip_tex);
|
||||
}
|
||||
@ -964,7 +970,7 @@ void GLGSRender::ExecCMD()
|
||||
if(m_set_depth_bounds)
|
||||
{
|
||||
//ConLog.Warning("glDepthBounds(%f, %f)", m_depth_bounds_min, m_depth_bounds_max);
|
||||
glDepthBounds(m_depth_bounds_min, m_depth_bounds_max);
|
||||
glDepthBoundsEXT(m_depth_bounds_min, m_depth_bounds_max);
|
||||
checkForGlError("glDepthBounds");
|
||||
}
|
||||
|
||||
|
@ -175,10 +175,10 @@ public:
|
||||
default: ConLog.Error("Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, is_swizzled ? "swizzled" : "linear", tex.GetFormat() & 0x40); break;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.Getmipmap() - 1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.Getmipmap() > 1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.GetMipmap() - 1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.GetMipmap() > 1);
|
||||
|
||||
if(format != 0x81 && format != 0x94)
|
||||
if(format != CELL_GCM_TEXTURE_B8 && format != CELL_GCM_TEXTURE_X16)
|
||||
{
|
||||
u8 remap_a = tex.GetRemap() & 0x3;
|
||||
u8 remap_r = (tex.GetRemap() >> 2) & 0x3;
|
||||
@ -245,7 +245,7 @@ public:
|
||||
|
||||
//Unbind();
|
||||
|
||||
if(is_swizzled && format == 0x85)
|
||||
if(is_swizzled && format == CELL_GCM_TEXTURE_A8R8G8B8)
|
||||
{
|
||||
free(unswizzledPixels);
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ OPENGL_PROC(PFNGLPROGRAMUNIFORM1FPROC, ProgramUniform1f);
|
||||
OPENGL_PROC(PFNGLPROGRAMUNIFORM4FPROC, ProgramUniform4f);
|
||||
OPENGL_PROC(PFNGLUNIFORMMATRIX4FVPROC, UniformMatrix4fv);
|
||||
OPENGL_PROC(PFNGLUSEPROGRAMPROC, UseProgram);
|
||||
OPENGL_PROC2(PFNGLDEPTHBOUNDSEXTPROC, DepthBounds, glDepthBoundsEXT);
|
||||
OPENGL_PROC2(PFNGLDEPTHBOUNDSEXTPROC, DepthBoundsEXT, glDepthBoundsEXT);
|
||||
OPENGL_PROC(PFNGLSTENCILOPSEPARATEPROC, StencilOpSeparate);
|
||||
OPENGL_PROC(PFNGLSTENCILFUNCSEPARATEPROC, StencilFuncSeparate);
|
||||
OPENGL_PROC(PFNGLSTENCILMASKSEPARATEPROC, StencilMaskSeparate);
|
||||
|
@ -3,18 +3,22 @@
|
||||
|
||||
void InitProcTable()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#define OPENGL_PROC(p, n) OPENGL_PROC2(p, n, gl##n)
|
||||
#define OPENGL_PROC2(p, n, tn) /*if(!gl##n)*/ if(!(gl##n = (p)wglGetProcAddress(#tn))) ConLog.Error("OpenGL: initialization of " #tn " failed.")
|
||||
#include "GLProcTable.tbl"
|
||||
#undef OPENGL_PROC
|
||||
#undef OPENGL_PROC2
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#define OPENGL_PROC(p, n) p gl##n = nullptr
|
||||
#define OPENGL_PROC2(p, n, tn) OPENGL_PROC(p, n)
|
||||
#include "GLProcTable.tbl"
|
||||
#undef OPENGL_PROC
|
||||
#undef OPENGL_PROC2
|
||||
#endif
|
||||
|
||||
OpenGL::OpenGL()
|
||||
{
|
||||
@ -29,18 +33,22 @@ OpenGL::~OpenGL()
|
||||
|
||||
void OpenGL::Init()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#define OPENGL_PROC(p, n) OPENGL_PROC2(p, n, gl##n)
|
||||
#define OPENGL_PROC2(p, n, tn) if(!(n = (p)wglGetProcAddress(#tn))) ConLog.Error("OpenGL: initialization of " #tn " failed.")
|
||||
#include "GLProcTable.tbl"
|
||||
#undef OPENGL_PROC
|
||||
#undef OPENGL_PROC2
|
||||
#endif
|
||||
}
|
||||
|
||||
void OpenGL::Close()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#define OPENGL_PROC(p, n) n = nullptr
|
||||
#define OPENGL_PROC2(p, n, tn) OPENGL_PROC(p, n)
|
||||
#include "GLProcTable.tbl"
|
||||
#undef OPENGL_PROC
|
||||
#undef OPENGL_PROC2
|
||||
#endif
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef BOOL (WINAPI* PFNWGLSWAPINTERVALEXTPROC) (int interval);
|
||||
#endif
|
||||
|
||||
#define OPENGL_PROC(p, n) extern p gl##n
|
||||
#define OPENGL_PROC2(p, n, tn) OPENGL_PROC(p, n)
|
||||
@ -12,6 +11,11 @@ typedef BOOL (WINAPI* PFNWGLSWAPINTERVALEXTPROC) (int interval);
|
||||
#undef OPENGL_PROC
|
||||
#undef OPENGL_PROC2
|
||||
|
||||
#else
|
||||
#include <GL/glx.h>
|
||||
#include <GL/glxext.h>
|
||||
#endif
|
||||
|
||||
void InitProcTable();
|
||||
|
||||
struct OpenGL
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "GL/GLGSRender.h"
|
||||
|
||||
BEGIN_EVENT_TABLE(GSFrame, wxFrame)
|
||||
EVT_PAINT(GSFrame::OnPaint)
|
||||
EVT_PAINT(GSFrame::OnPaint)
|
||||
EVT_SIZE(GSFrame::OnSize)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
@ -45,4 +45,4 @@ u8 GSManager::GetState()
|
||||
u8 GSManager::GetColorSpace()
|
||||
{
|
||||
return CELL_VIDEO_OUT_COLOR_SPACE_RGB;
|
||||
}
|
||||
}
|
||||
|
@ -78,4 +78,4 @@ void GSFrame::SetSize(int width, int height)
|
||||
|
||||
GSLockCurrent::GSLockCurrent(GSLockType type) : GSLock(Emu.GetGSManager().GetRender(), type)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "RSXThread.h"
|
||||
#include "RSXTexture.h"
|
||||
|
||||
RSXTexture::RSXTexture()
|
||||
{
|
||||
@ -70,7 +70,7 @@ u8 RSXTexture::GetFormat() const
|
||||
return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 8) & 0xff);
|
||||
}
|
||||
|
||||
u16 RSXTexture::Getmipmap() const
|
||||
u16 RSXTexture::GetMipmap() const
|
||||
{
|
||||
return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 16) & 0xffff);
|
||||
}
|
||||
@ -199,4 +199,4 @@ void RSXTexture::SetControl3(u16 depth, u32 pitch)
|
||||
{
|
||||
m_depth = depth;
|
||||
m_pitch = pitch;
|
||||
}
|
||||
}
|
||||
|
62
rpcs3/Emu/GS/RSXTexture.h
Normal file
62
rpcs3/Emu/GS/RSXTexture.h
Normal file
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
class RSXTexture
|
||||
{
|
||||
u8 m_index;
|
||||
|
||||
public:
|
||||
u32 m_pitch;
|
||||
u16 m_depth;
|
||||
|
||||
public:
|
||||
RSXTexture();
|
||||
RSXTexture(u8 index);
|
||||
void Init();
|
||||
|
||||
// Offset
|
||||
u32 GetOffset() const;
|
||||
|
||||
// Format
|
||||
u8 GetLocation() const;
|
||||
bool isCubemap() const;
|
||||
u8 GetBorderType() const;
|
||||
u8 GetDimension() const;
|
||||
u8 GetFormat() const;
|
||||
u16 GetMipmap() const;
|
||||
|
||||
// Address
|
||||
u8 GetWrapS() const;
|
||||
u8 GetWrapT() const;
|
||||
u8 GetWrapR() const;
|
||||
u8 GetUnsignedRemap() const;
|
||||
u8 GetZfunc() const;
|
||||
u8 GetGamma() const;
|
||||
u8 GetAnisoBias() const;
|
||||
u8 GetSignedRemap() const;
|
||||
|
||||
// Control0
|
||||
bool IsEnabled() const;
|
||||
u16 GetMinLOD() const;
|
||||
u16 GetMaxLOD() const;
|
||||
u8 GetMaxAniso() const;
|
||||
bool IsAlphaKillEnabled() const;
|
||||
|
||||
// Control1
|
||||
u32 GetRemap() const;
|
||||
|
||||
// Filter
|
||||
u16 GetBias() const;
|
||||
u8 GetMinFilter() const;
|
||||
u8 GetMagFilter() const;
|
||||
u8 GetConvolutionFilter() const;
|
||||
bool isASigned() const;
|
||||
bool isRSigned() const;
|
||||
bool isGSigned() const;
|
||||
bool isBSigned() const;
|
||||
|
||||
// Image Rect
|
||||
u16 GetWidth() const;
|
||||
u16 GetHeight() const;
|
||||
|
||||
void SetControl3(u16 depth, u32 pitch);
|
||||
};
|
@ -1,7 +1,8 @@
|
||||
#include "stdafx.h"
|
||||
#include "RSXThread.h"
|
||||
#include "Emu/SysCalls/lv2/SC_Time.h"
|
||||
|
||||
#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count) : Memory.Read32(Memory.RSXIOMem.GetStartAddr() + re(m_ctrl->get) + (4*(x+1))))
|
||||
#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count) : Memory.Read32(Memory.RSXIOMem.GetStartAddr() + m_ctrl->get + (4*(x+1))))
|
||||
|
||||
u32 methodRegisters[0xffff];
|
||||
|
||||
@ -207,7 +208,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
|
||||
break;
|
||||
|
||||
case NV406E_SET_REFERENCE:
|
||||
m_ctrl->ref = re32(ARGS(0));
|
||||
m_ctrl->ref = ARGS(0);
|
||||
break;
|
||||
|
||||
case_16(NV4097_SET_TEXTURE_OFFSET, 0x20):
|
||||
@ -1195,8 +1196,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
|
||||
switch(type)
|
||||
{
|
||||
case 1:
|
||||
data = std::chrono::steady_clock::now().time_since_epoch().count();
|
||||
data *= 1000000;
|
||||
data = get_system_time();
|
||||
data *= 1000; // Microseconds to nanoseconds
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1509,7 +1510,7 @@ void RSXThread::Task()
|
||||
{
|
||||
u32 addr = cmd & ~(CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT);
|
||||
//ConLog.Warning("rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", addr, m_ioAddress + get, cmd, get, put);
|
||||
re(m_ctrl->get, addr);
|
||||
m_ctrl->get = addr;
|
||||
continue;
|
||||
}
|
||||
if(cmd & CELL_GCM_METHOD_FLAG_CALL)
|
||||
@ -1518,7 +1519,7 @@ void RSXThread::Task()
|
||||
u32 offs = cmd & ~CELL_GCM_METHOD_FLAG_CALL;
|
||||
u32 addr = Memory.RSXIOMem.GetStartAddr() + offs;
|
||||
//ConLog.Warning("rsx call(0x%x) #0x%x - 0x%x - 0x%x", offs, addr, cmd, get);
|
||||
m_ctrl->get = re32(offs);
|
||||
m_ctrl->get = offs;
|
||||
continue;
|
||||
}
|
||||
if(cmd == CELL_GCM_METHOD_FLAG_RETURN)
|
||||
@ -1526,7 +1527,7 @@ void RSXThread::Task()
|
||||
//ConLog.Warning("rsx return!");
|
||||
u32 get = m_call_stack.Pop();
|
||||
//ConLog.Warning("rsx return(0x%x)", get);
|
||||
m_ctrl->get = re32(get);
|
||||
m_ctrl->get = get;
|
||||
continue;
|
||||
}
|
||||
if(cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
|
||||
@ -1537,7 +1538,7 @@ void RSXThread::Task()
|
||||
|
||||
if(cmd == 0)
|
||||
{
|
||||
ConLog.Warning("null cmd: addr=0x%x, put=0x%x, get=0x%x", Memory.RSXIOMem.GetStartAddr() + get, re(m_ctrl->put), get);
|
||||
ConLog.Warning("null cmd: addr=0x%x, put=0x%x, get=0x%x", Memory.RSXIOMem.GetStartAddr() + get, m_ctrl->put, get);
|
||||
Emu.Pause();
|
||||
continue;
|
||||
}
|
||||
@ -1550,7 +1551,7 @@ void RSXThread::Task()
|
||||
mem32_ptr_t args(Memory.RSXIOMem.GetStartAddr() + get + 4);
|
||||
DoCmd(cmd, cmd & 0x3ffff, args, count);
|
||||
|
||||
re(m_ctrl->get, get + (count + 1) * 4);
|
||||
m_ctrl->get = get + (count + 1) * 4;
|
||||
//memset(Memory.GetMemFromAddr(p.m_ioAddress + get), 0, (count + 1) * 4);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "GCM.h"
|
||||
#include "RSXTexture.h"
|
||||
#include "RSXVertexProgram.h"
|
||||
#include "RSXFragmentProgram.h"
|
||||
#include "Emu/SysCalls/Callback.h"
|
||||
@ -15,67 +16,6 @@ enum Method
|
||||
extern u32 methodRegisters[0xffff];
|
||||
u32 GetAddress(u32 offset, u8 location);
|
||||
|
||||
class RSXTexture
|
||||
{
|
||||
u8 m_index;
|
||||
|
||||
public:
|
||||
u32 m_pitch;
|
||||
u16 m_depth;
|
||||
|
||||
public:
|
||||
RSXTexture();
|
||||
RSXTexture(u8 index);
|
||||
void Init();
|
||||
|
||||
// Offset
|
||||
u32 GetOffset() const;
|
||||
|
||||
// Format
|
||||
u8 GetLocation() const;
|
||||
bool isCubemap() const;
|
||||
u8 GetBorderType() const;
|
||||
u8 GetDimension() const;
|
||||
u8 GetFormat() const;
|
||||
u16 Getmipmap() const;
|
||||
|
||||
// Address
|
||||
u8 GetWrapS() const;
|
||||
u8 GetWrapT() const;
|
||||
u8 GetWrapR() const;
|
||||
u8 GetUnsignedRemap() const;
|
||||
u8 GetZfunc() const;
|
||||
u8 GetGamma() const;
|
||||
u8 GetAnisoBias() const;
|
||||
u8 GetSignedRemap() const;
|
||||
|
||||
// Control0
|
||||
bool IsEnabled() const;
|
||||
u16 GetMinLOD() const;
|
||||
u16 GetMaxLOD() const;
|
||||
u8 GetMaxAniso() const;
|
||||
bool IsAlphaKillEnabled() const;
|
||||
|
||||
// Control1
|
||||
u32 GetRemap() const;
|
||||
|
||||
// Filter
|
||||
u16 GetBias() const;
|
||||
u8 GetMinFilter() const;
|
||||
u8 GetMagFilter() const;
|
||||
u8 GetConvolutionFilter() const;
|
||||
bool isASigned() const;
|
||||
bool isRSigned() const;
|
||||
bool isGSigned() const;
|
||||
bool isBSigned() const;
|
||||
|
||||
// Image Rect
|
||||
u16 GetWidth() const;
|
||||
u16 GetHeight() const;
|
||||
|
||||
void SetControl3(u16 depth, u32 pitch);
|
||||
};
|
||||
|
||||
struct RSXVertexData
|
||||
{
|
||||
u32 frequency;
|
||||
|
@ -75,7 +75,7 @@ enum CellVideoOutPortType
|
||||
|
||||
enum CellVideoOutDisplayAspect
|
||||
{
|
||||
CELL_VIDEO_OUT_ASPECT_AUTO,
|
||||
CELL_VIDEO_OUT_ASPECT_AUTO,
|
||||
CELL_VIDEO_OUT_ASPECT_4_3,
|
||||
CELL_VIDEO_OUT_ASPECT_16_9,
|
||||
};
|
||||
|
@ -482,7 +482,7 @@ public:
|
||||
|
||||
int OpenDir(const wxString& name)
|
||||
{
|
||||
ConLog.Warning("OpenDir(%s)", name.mb_str());
|
||||
ConLog.Warning("OpenDir(%s)", name.wx_str());
|
||||
u64 entry_block;
|
||||
if(!SearchEntry(name, entry_block))
|
||||
return -1;
|
||||
@ -769,7 +769,7 @@ public:
|
||||
|
||||
if(entry.type == vfsHDD_Entry_Dir && name != "." && name != "..")
|
||||
{
|
||||
ConLog.Warning("removing sub folder '%s'", name.mb_str());
|
||||
ConLog.Warning("removing sub folder '%s'", name.wx_str());
|
||||
RemoveBlocksDir(entry.data_block);
|
||||
}
|
||||
else if(entry.type == vfsHDD_Entry_File)
|
||||
@ -869,4 +869,4 @@ public:
|
||||
{
|
||||
return m_file.GetSize();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "MemoryBlock.h"
|
||||
#include <vector>
|
||||
|
||||
enum MemoryType
|
||||
{
|
||||
|
@ -557,36 +557,40 @@ struct CellAdecM4AacInfo
|
||||
be_t<u32> pad1; // TODO: check alignment
|
||||
|
||||
union {
|
||||
struct { struct
|
||||
{
|
||||
be_t<u32> copyrightIdPresent;
|
||||
char copyrightId[9];
|
||||
be_t<u32> originalCopy;
|
||||
be_t<u32> home;
|
||||
be_t<u32> bitstreamType;
|
||||
be_t<u32> bitrate;
|
||||
be_t<u32> numberOfProgramConfigElements;
|
||||
be_t<u32> bufferFullness;
|
||||
} adif; };
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
be_t<u32> copyrightIdPresent;
|
||||
char copyrightId[9];
|
||||
be_t<u32> originalCopy;
|
||||
be_t<u32> home;
|
||||
be_t<u32> bitstreamType;
|
||||
be_t<u32> bitrate;
|
||||
be_t<u32> numberOfProgramConfigElements;
|
||||
be_t<u32> bufferFullness;
|
||||
} adif;
|
||||
};
|
||||
|
||||
struct { struct
|
||||
{
|
||||
be_t<u32> id;
|
||||
be_t<u32> layer;
|
||||
be_t<u32> protectionAbsent;
|
||||
be_t<u32> profile;
|
||||
be_t<u32> samplingFreqIndex;
|
||||
be_t<u32> privateBit;
|
||||
be_t<u32> channelConfiguration;
|
||||
be_t<u32> originalCopy;
|
||||
be_t<u32> home;
|
||||
be_t<u32> copyrightIdBit;
|
||||
be_t<u32> copyrightIdStart;
|
||||
be_t<u32> frameLength;
|
||||
be_t<u32> bufferFullness;
|
||||
be_t<u32> numberOfRawDataBlocks;
|
||||
be_t<u32> crcCheck;
|
||||
} adts; };
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
be_t<u32> id;
|
||||
be_t<u32> layer;
|
||||
be_t<u32> protectionAbsent;
|
||||
be_t<u32> profile;
|
||||
be_t<u32> samplingFreqIndex;
|
||||
be_t<u32> privateBit;
|
||||
be_t<u32> channelConfiguration;
|
||||
be_t<u32> originalCopy;
|
||||
be_t<u32> home;
|
||||
be_t<u32> copyrightIdBit;
|
||||
be_t<u32> copyrightIdStart;
|
||||
be_t<u32> frameLength;
|
||||
be_t<u32> bufferFullness;
|
||||
be_t<u32> numberOfRawDataBlocks;
|
||||
be_t<u32> crcCheck;
|
||||
} adts;
|
||||
};
|
||||
} bsi;
|
||||
|
||||
be_t<u32> pad2; // TODO: check alignment
|
||||
@ -980,4 +984,4 @@ struct CellAdecMpmcInfo
|
||||
be_t<u32> multiCodecMode;
|
||||
be_t<u32> lfePresent;
|
||||
be_t<u32> channelCoufiguration;
|
||||
};
|
||||
};
|
||||
|
@ -219,20 +219,7 @@ struct CellDmuxResource2
|
||||
be_t<u32> memSize;
|
||||
be_t<u32> ppuThreadPriority;
|
||||
be_t<u32> ppuThreadStackSize;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
be_t<u32> noex_spuThreadPriority;
|
||||
be_t<u32> noex_numOfSpus;
|
||||
};
|
||||
struct
|
||||
{
|
||||
be_t<u32> ex_spurs_addr;
|
||||
u8 ex_priority[8];
|
||||
be_t<u32> ex_maxContention;
|
||||
};
|
||||
};
|
||||
be_t<u32> shit[4];
|
||||
};
|
||||
|
||||
typedef mem_func_ptr_t<void (*)(u32 demuxerHandle, mem_ptr_t<CellDmuxMsg> demuxerMsg, u32 cbArg_addr)> CellDmuxCbMsg;
|
||||
@ -267,8 +254,8 @@ struct CellDmuxEsAttr
|
||||
|
||||
struct CellDmuxEsResource
|
||||
{
|
||||
be_t<u32> memAddr;
|
||||
be_t<u32> memSize;
|
||||
be_t<u32> memAddr;
|
||||
be_t<u32> memSize;
|
||||
};
|
||||
|
||||
struct CellDmuxAuInfo
|
||||
@ -276,7 +263,7 @@ struct CellDmuxAuInfo
|
||||
be_t<u32> auAddr;
|
||||
be_t<u32> auSize;
|
||||
be_t<u32> auMaxSize;
|
||||
be_t<u64> userData;
|
||||
be_t<u64> userData;
|
||||
be_t<u32> ptsUpper;
|
||||
be_t<u32> ptsLower;
|
||||
be_t<u32> dtsUpper;
|
||||
@ -682,4 +669,4 @@ public:
|
||||
last_addr = a128(memAddr);
|
||||
last_size = 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -292,7 +292,7 @@ int cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, u32 dirName_addr)
|
||||
}
|
||||
|
||||
std::string errorMsg = wxString::Format("%s\nSpace needed: %d KB\nDirectory name: %s",
|
||||
wxString(errorName).wx_str(), errNeedSizeKB, wxString(dirName).wx_str());
|
||||
wxString(errorName).wx_str(), errNeedSizeKB, wxString(dirName).wx_str()).ToStdString();
|
||||
wxMessageBox(errorMsg, wxGetApp().GetAppName(), wxICON_ERROR | wxOK);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -70,12 +70,12 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
|
||||
|
||||
map_offset_addr = 0;
|
||||
map_offset_pos = 0;
|
||||
current_config.ioSize = re32(ioSize);
|
||||
current_config.ioAddress = re32(ioAddress);
|
||||
current_config.localSize = re32(local_size);
|
||||
current_config.localAddress = re32(local_addr);
|
||||
current_config.memoryFrequency = re32(650000000);
|
||||
current_config.coreFrequency = re32(500000000);
|
||||
current_config.ioSize = ioSize;
|
||||
current_config.ioAddress = ioAddress;
|
||||
current_config.localSize = local_size;
|
||||
current_config.localAddress = local_addr;
|
||||
current_config.memoryFrequency = 650000000;
|
||||
current_config.coreFrequency = 500000000;
|
||||
|
||||
InitOffsetTable();
|
||||
Memory.RSXCMDMem.AllocAlign(cmdSize);
|
||||
@ -84,10 +84,10 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
|
||||
|
||||
u32 ctx_begin = ioAddress/* + 0x1000*/;
|
||||
u32 ctx_size = 0x6ffc;
|
||||
current_context.begin = re(ctx_begin);
|
||||
current_context.end = re(ctx_begin + ctx_size);
|
||||
current_context.begin = ctx_begin;
|
||||
current_context.end = ctx_begin + ctx_size;
|
||||
current_context.current = current_context.begin;
|
||||
current_context.callback = re32(Emu.GetRSXCallback() - 4);
|
||||
current_context.callback = Emu.GetRSXCallback() - 4;
|
||||
|
||||
gcm_info.context_addr = Memory.MainMem.AllocAlign(0x1000);
|
||||
gcm_info.control_addr = gcm_info.context_addr + 0x40;
|
||||
@ -169,8 +169,8 @@ int cellGcmSetPrepareFlip(mem_ptr_t<CellGcmContextData> ctxt, u32 id)
|
||||
|
||||
GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH); // could stall on exit
|
||||
|
||||
u32 current = re(ctxt->current);
|
||||
u32 end = re(ctxt->end);
|
||||
u32 current = ctxt->current;
|
||||
u32 end = ctxt->end;
|
||||
|
||||
if(current + 8 >= end)
|
||||
{
|
||||
@ -178,15 +178,15 @@ int cellGcmSetPrepareFlip(mem_ptr_t<CellGcmContextData> ctxt, u32 id)
|
||||
cellGcmCallback(ctxt.GetAddr(), current + 8 - end);
|
||||
}
|
||||
|
||||
current = re(ctxt->current);
|
||||
current = ctxt->current;
|
||||
Memory.Write32(current, 0x3fead | (1 << 18));
|
||||
Memory.Write32(current + 4, id);
|
||||
re(ctxt->current, current + 8);
|
||||
ctxt->current += 8;
|
||||
|
||||
if(ctxt.GetAddr() == gcm_info.context_addr)
|
||||
{
|
||||
CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr];
|
||||
re(ctrl.put, re(ctrl.put) + 8);
|
||||
ctrl.put += 8;
|
||||
}
|
||||
|
||||
return id;
|
||||
@ -416,7 +416,8 @@ int cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co
|
||||
{
|
||||
cellGcmSys.Warning("cellGcmSetTile(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)",
|
||||
index, location, offset, size, pitch, comp, base, bank);
|
||||
//copied form cellGcmSetTileInfo
|
||||
|
||||
// Copied form cellGcmSetTileInfo
|
||||
if(index >= RSXThread::m_tiles_count || base >= 800 || bank >= 4)
|
||||
{
|
||||
return CELL_GCM_ERROR_INVALID_VALUE;
|
||||
@ -434,7 +435,7 @@ int cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co
|
||||
|
||||
if(comp)
|
||||
{
|
||||
cellGcmSys.Error("cellGcmSetTileInfo: bad comp! (%d)", comp);
|
||||
cellGcmSys.Error("cellGcmSetTile: bad comp! (%d)", comp);
|
||||
}
|
||||
|
||||
auto& tile = Emu.GetGSManager().GetRender().m_tiles[index];
|
||||
|
@ -44,7 +44,7 @@ int cellPngDecOpen(u32 mainHandle, mem32_t subHandle, mem_ptr_t<CellPngDecSrc> s
|
||||
|
||||
// Get size of file
|
||||
MemoryAllocator<CellFsStat> sb; // Alloc a CellFsStat struct
|
||||
ret = cellFsFstat(current_subHandle->fd, sb);
|
||||
ret = cellFsFstat(current_subHandle->fd, sb.GetAddr());
|
||||
if(ret != CELL_OK) return ret;
|
||||
current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size
|
||||
break;
|
||||
|
@ -728,9 +728,9 @@ int cellRescSetBufferAddress(mem32_t colorBuffers, mem32_t vertexArray, mem32_t
|
||||
if(!colorBuffers.IsGood() || !vertexArray.IsGood() || !fragmentShader.IsGood())
|
||||
return CELL_RESC_ERROR_BAD_ARGUMENT;
|
||||
if(colorBuffers.GetAddr() % COLOR_BUFFER_ALIGNMENT ||
|
||||
vertexArray.GetAddr() % VERTEX_BUFFER_ALIGNMENT ||
|
||||
fragmentShader.GetAddr() % FRAGMENT_SHADER_ALIGNMENT)
|
||||
return CELL_RESC_ERROR_BAD_ALIGNMENT;
|
||||
vertexArray.GetAddr() % VERTEX_BUFFER_ALIGNMENT ||
|
||||
fragmentShader.GetAddr() % FRAGMENT_SHADER_ALIGNMENT)
|
||||
return CELL_RESC_ERROR_BAD_ALIGNMENT;
|
||||
|
||||
s_rescInternalInstance->m_colorBuffersEA_addr = colorBuffers.GetAddr();
|
||||
s_rescInternalInstance->m_vertexArrayEA_addr = vertexArray.GetAddr();
|
||||
@ -813,4 +813,4 @@ void cellResc_init()
|
||||
void cellResc_unload()
|
||||
{
|
||||
s_rescInternalInstance->m_bInitialized = false;
|
||||
}
|
||||
}
|
||||
|
@ -25,13 +25,11 @@ enum
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct CellSyncMutex {
|
||||
union {
|
||||
struct {
|
||||
be_t<u16> m_freed;
|
||||
be_t<u16> m_order;
|
||||
be_t<u16> m_freed;
|
||||
be_t<u16> m_order;
|
||||
volatile u32& m_data(){
|
||||
return *reinterpret_cast<u32*>(this);
|
||||
};
|
||||
volatile u32 m_data;
|
||||
};
|
||||
/*
|
||||
(???) Initialize: set zeros
|
||||
(???) Lock: increase m_order and wait until m_freed == old m_order
|
||||
@ -61,7 +59,7 @@ int cellSyncMutexInitialize(mem_ptr_t<CellSyncMutex> mutex)
|
||||
{
|
||||
reservation.clear();
|
||||
}
|
||||
mutex->m_data = 0;
|
||||
mutex->m_data() = 0;
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
@ -167,4 +165,4 @@ void cellSync_init()
|
||||
cellSync.AddFunc(0x1bb675c2, cellSyncMutexLock);
|
||||
cellSync.AddFunc(0xd06918c4, cellSyncMutexTryLock);
|
||||
cellSync.AddFunc(0x91f2b7b0, cellSyncMutexUnlock);
|
||||
}
|
||||
}
|
||||
|
@ -1010,4 +1010,4 @@ void cellSysutil_init()
|
||||
cellSysutil.AddFunc(0x1e7bff94, cellSysCacheMount);
|
||||
cellSysutil.AddFunc(0x744c1544, cellSysCacheClear);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if 0
|
||||
#include "stdafx.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
@ -5,8 +6,9 @@
|
||||
#include "sceNp.h"
|
||||
|
||||
void sceNp_init();
|
||||
Module sceNp(0x0016, sceNpTrophy_init);
|
||||
Module sceNp(0x0016, sceNp_init);
|
||||
|
||||
void sceNpTrophy_init()
|
||||
void sceNp_init()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
@ -129,8 +129,8 @@ int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
std::atomic<u32> g_FsAioReadID = 0;
|
||||
std::atomic<u32> g_FsAioReadCur = 0;
|
||||
std::atomic<u32> g_FsAioReadID( 0 );
|
||||
std::atomic<u32> g_FsAioReadCur( 0 );
|
||||
bool aio_init = false;
|
||||
|
||||
void fsAioRead(u32 fd, mem_ptr_t<CellFsAio> aio, int xid, mem_func_ptr_t<void (*)(mem_ptr_t<CellFsAio> xaio, int error, int xid, u64 size)> func)
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "Modules.h"
|
||||
|
||||
#define RESULT(x) SC_ARGS_1 = (x)
|
||||
|
||||
|
@ -3,6 +3,13 @@
|
||||
#include "Modules.h"
|
||||
#include "SC_FUNC.h"
|
||||
|
||||
namespace detail{
|
||||
template<> bool CheckId(u32 id, ID*& _id,const std::string &name)
|
||||
{
|
||||
return Emu.GetIdManager().CheckID(id) && (_id = &Emu.GetIdManager().GetID(id))->m_name == name;
|
||||
}
|
||||
}
|
||||
|
||||
void default_syscall();
|
||||
static func_caller *null_func = bind_func(default_syscall);
|
||||
|
||||
@ -358,4 +365,4 @@ void SysCalls::DoSyscall(u32 code)
|
||||
//TODO: remove this
|
||||
declCPU();
|
||||
RESULT(DoFunc(code));
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,20 @@
|
||||
|
||||
#define declCPU PPUThread& CPU = GetCurrentPPUThread
|
||||
|
||||
class SysCallBase;
|
||||
|
||||
namespace detail{
|
||||
template<typename T> bool CheckId(u32 id, T*& data,const std::string &name)
|
||||
{
|
||||
ID* id_data;
|
||||
if(!CheckId(id, id_data,name)) return false;
|
||||
data = id_data->m_data->get<T>();
|
||||
return true;
|
||||
}
|
||||
|
||||
template<> bool CheckId<ID>(u32 id, ID*& _id,const std::string &name);
|
||||
}
|
||||
|
||||
class SysCallBase //Module
|
||||
{
|
||||
private:
|
||||
@ -94,18 +108,7 @@ public:
|
||||
|
||||
template<typename T> bool CheckId(u32 id, T*& data)
|
||||
{
|
||||
ID* id_data;
|
||||
|
||||
if(!CheckId(id, id_data)) return false;
|
||||
|
||||
data = id_data->m_data->get<T>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<> bool CheckId(u32 id, ID*& _id)
|
||||
{
|
||||
return Emu.GetIdManager().CheckID(id) && (_id = &Emu.GetIdManager().GetID(id))->m_name == GetName();
|
||||
return detail::CheckId(id,data,GetName());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -386,4 +386,4 @@ int sys_event_port_send(u32 eport_id, u64 data1, u64 data2, u64 data3)
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
@ -350,9 +350,18 @@ int cellFsUnlink(u32 path_addr)
|
||||
const wxString& ps3_path = Memory.ReadString(path_addr);
|
||||
sys_fs.Warning("cellFsUnlink(path=\"%s\")", ps3_path.wx_str());
|
||||
|
||||
//wxString localPath;
|
||||
//Emu.GetVFS().GetDevice(ps3_path, localPath);
|
||||
//wxRemoveFile(localPath);
|
||||
if (ps3_path.empty())
|
||||
return CELL_EFAULT;
|
||||
|
||||
if (Emu.GetVFS().ExistsDir(ps3_path))
|
||||
return CELL_EISDIR;
|
||||
|
||||
if (!Emu.GetVFS().ExistsFile(ps3_path))
|
||||
return CELL_ENOENT;
|
||||
|
||||
if (!Emu.GetVFS().RemoveFile(ps3_path))
|
||||
return CELL_EACCES;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -12,13 +12,13 @@ int cellGcmCallback(u32 context_addr, u32 count)
|
||||
CellGcmContextData& ctx = (CellGcmContextData&)Memory[context_addr];
|
||||
CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr];
|
||||
|
||||
const s32 res = re(ctx.current) - re(ctx.begin) - re(ctrl.put);
|
||||
const s32 res = ctx.current - ctx.begin - ctrl.put;
|
||||
|
||||
if(res > 0) memcpy(&Memory[re(ctx.begin)], &Memory[re(ctx.current) - res], res);
|
||||
if(res > 0) memcpy(&Memory[ctx.begin], &Memory[ctx.current - res], res);
|
||||
|
||||
ctx.current = re(re(ctx.begin) + res);
|
||||
ctx.current = ctx.begin + res;
|
||||
|
||||
ctrl.put = re(res);
|
||||
ctrl.put = res;
|
||||
ctrl.get = 0;
|
||||
|
||||
return CELL_OK;
|
||||
|
@ -84,21 +84,21 @@ int sys_lwcond_signal(mem_ptr_t<sys_lwcond_t> lwcond)
|
||||
mem_ptr_t<sys_lwmutex_t> mutex(lwcond->lwmutex);
|
||||
be_t<u32> tid = GetCurrentPPUThread().GetId();
|
||||
|
||||
bool was_locked = (mutex->owner.GetOwner() == tid);
|
||||
bool was_locked = (mutex->mutex.GetOwner() == tid);
|
||||
|
||||
if (be_t<u32> target = (mutex->attribute.ToBE() == se32(SYS_SYNC_PRIORITY) ? sq->pop_prio() : sq->pop()))
|
||||
{
|
||||
if (!was_locked)
|
||||
{
|
||||
mutex->owner.lock(tid);
|
||||
mutex->mutex.lock(tid);
|
||||
mutex->recursive_count = 1;
|
||||
mutex->owner.unlock(tid, target);
|
||||
mutex->mutex.unlock(tid, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
mutex->recursive_count = 1;
|
||||
mutex->owner.unlock(tid, target);
|
||||
mutex->owner.lock(tid);
|
||||
mutex->mutex.unlock(tid, target);
|
||||
mutex->mutex.lock(tid);
|
||||
mutex->recursive_count = 1;
|
||||
}
|
||||
}
|
||||
@ -129,21 +129,21 @@ int sys_lwcond_signal_all(mem_ptr_t<sys_lwcond_t> lwcond)
|
||||
mem_ptr_t<sys_lwmutex_t> mutex(lwcond->lwmutex);
|
||||
be_t<u32> tid = GetCurrentPPUThread().GetId();
|
||||
|
||||
bool was_locked = (mutex->owner.GetOwner() == tid);
|
||||
bool was_locked = (mutex->mutex.GetOwner() == tid);
|
||||
|
||||
while (be_t<u32> target = (mutex->attribute.ToBE() == se32(SYS_SYNC_PRIORITY) ? sq->pop_prio() : sq->pop()))
|
||||
{
|
||||
if (!was_locked)
|
||||
{
|
||||
mutex->owner.lock(tid);
|
||||
mutex->mutex.lock(tid);
|
||||
mutex->recursive_count = 1;
|
||||
mutex->owner.unlock(tid, target);
|
||||
mutex->mutex.unlock(tid, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
mutex->recursive_count = 1;
|
||||
mutex->owner.unlock(tid, target);
|
||||
mutex->owner.lock(tid);
|
||||
mutex->mutex.unlock(tid, target);
|
||||
mutex->mutex.lock(tid);
|
||||
mutex->recursive_count = 1;
|
||||
}
|
||||
}
|
||||
@ -184,21 +184,21 @@ int sys_lwcond_signal_to(mem_ptr_t<sys_lwcond_t> lwcond, u32 ppu_thread_id)
|
||||
mem_ptr_t<sys_lwmutex_t> mutex(lwcond->lwmutex);
|
||||
be_t<u32> tid = GetCurrentPPUThread().GetId();
|
||||
|
||||
bool was_locked = (mutex->owner.GetOwner() == tid);
|
||||
bool was_locked = (mutex->mutex.GetOwner() == tid);
|
||||
|
||||
be_t<u32> target = ppu_thread_id;
|
||||
{
|
||||
if (!was_locked)
|
||||
{
|
||||
mutex->owner.lock(tid);
|
||||
mutex->mutex.lock(tid);
|
||||
mutex->recursive_count = 1;
|
||||
mutex->owner.unlock(tid, target);
|
||||
mutex->mutex.unlock(tid, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
mutex->recursive_count = 1;
|
||||
mutex->owner.unlock(tid, target);
|
||||
mutex->owner.lock(tid);
|
||||
mutex->mutex.unlock(tid, target);
|
||||
mutex->mutex.lock(tid);
|
||||
mutex->recursive_count = 1;
|
||||
}
|
||||
}
|
||||
@ -230,7 +230,7 @@ int sys_lwcond_wait(mem_ptr_t<sys_lwcond_t> lwcond, u64 timeout)
|
||||
u32 tid_le = GetCurrentPPUThread().GetId();
|
||||
be_t<u32> tid = tid_le;
|
||||
|
||||
if (mutex->owner.GetOwner() != tid)
|
||||
if (mutex->mutex.GetOwner() != tid)
|
||||
{
|
||||
return CELL_EPERM; // caller must own this lwmutex
|
||||
}
|
||||
@ -238,7 +238,7 @@ int sys_lwcond_wait(mem_ptr_t<sys_lwcond_t> lwcond, u64 timeout)
|
||||
sq->push(tid_le);
|
||||
|
||||
mutex->recursive_count = 0;
|
||||
mutex->owner.unlock(tid);
|
||||
mutex->mutex.unlock(tid);
|
||||
|
||||
u32 counter = 0;
|
||||
const u32 max_counter = timeout ? (timeout / 1000) : ~0;
|
||||
@ -249,7 +249,7 @@ int sys_lwcond_wait(mem_ptr_t<sys_lwcond_t> lwcond, u64 timeout)
|
||||
case SMR_OK: mutex->unlock(tid); break;
|
||||
case SMR_SIGNAL: return CELL_OK;
|
||||
} */
|
||||
if (mutex->owner.GetOwner() == tid)
|
||||
if (mutex->mutex.GetOwner() == tid)
|
||||
{
|
||||
_mm_mfence();
|
||||
mutex->recursive_count = 1;
|
||||
|
@ -28,8 +28,8 @@ int sys_lwmutex_create(mem_ptr_t<sys_lwmutex_t> lwmutex, mem_ptr_t<sys_lwmutex_a
|
||||
}
|
||||
|
||||
lwmutex->attribute = attr->attr_protocol | attr->attr_recursive;
|
||||
lwmutex->all_info = 0;
|
||||
lwmutex->owner.initialize();
|
||||
lwmutex->all_info() = 0;
|
||||
lwmutex->mutex.initialize();
|
||||
//lwmutex->waiter = lwmutex->owner.GetOwner();
|
||||
lwmutex->pad = 0;
|
||||
lwmutex->recursive_count = 0;
|
||||
@ -53,10 +53,10 @@ int sys_lwmutex_destroy(mem_ptr_t<sys_lwmutex_t> lwmutex)
|
||||
if (!Emu.GetIdManager().CheckID(sq_id)) return CELL_ESRCH;
|
||||
|
||||
// try to make it unable to lock
|
||||
switch (int res = lwmutex->trylock(lwmutex->owner.GetDeadValue()))
|
||||
switch (int res = lwmutex->trylock(lwmutex->mutex.GetDeadValue()))
|
||||
{
|
||||
case CELL_OK:
|
||||
lwmutex->all_info = 0;
|
||||
lwmutex->all_info() = 0;
|
||||
lwmutex->attribute = 0;
|
||||
lwmutex->sleep_queue = 0;
|
||||
Emu.GetIdManager().RemoveID(sq_id);
|
||||
@ -71,7 +71,7 @@ int sys_lwmutex_lock(mem_ptr_t<sys_lwmutex_t> lwmutex, u64 timeout)
|
||||
if (!lwmutex.IsGood()) return CELL_EFAULT;
|
||||
|
||||
//ConLog.Write("*** lock mutex (addr=0x%x, attr=0x%x, Nrec=%d, owner=%d, waiter=%d)",
|
||||
//lwmutex.GetAddr(), (u32)lwmutex->attribute, (u32)lwmutex->recursive_count, lwmutex->owner.GetOwner(), (u32)lwmutex->waiter);
|
||||
//lwmutex.GetAddr(), (u32)lwmutex->attribute, (u32)lwmutex->recursive_count, lwmutex->vars.parts.owner.GetOwner(), (u32)lwmutex->waiter);
|
||||
|
||||
return lwmutex->lock(GetCurrentPPUThread().GetId(), timeout ? ((timeout < 1000) ? 1 : (timeout / 1000)) : 0);
|
||||
}
|
||||
@ -92,7 +92,7 @@ int sys_lwmutex_unlock(mem_ptr_t<sys_lwmutex_t> lwmutex)
|
||||
if (!lwmutex.IsGood()) return CELL_EFAULT;
|
||||
|
||||
//ConLog.Write("*** unlocking mutex (addr=0x%x, attr=0x%x, Nrec=%d, owner=%d, waiter=%d)",
|
||||
//lwmutex.GetAddr(), (u32)lwmutex->attribute, (u32)lwmutex->recursive_count, (u32)lwmutex->owner.GetOwner(), (u32)lwmutex->waiter);
|
||||
//lwmutex.GetAddr(), (u32)lwmutex->attribute, (u32)lwmutex->recursive_count, (u32)lwmutex->vars.parts.owner.GetOwner(), (u32)lwmutex->waiter);
|
||||
|
||||
return lwmutex->unlock(GetCurrentPPUThread().GetId());
|
||||
}
|
||||
@ -207,7 +207,7 @@ int sys_lwmutex_t::trylock(be_t<u32> tid)
|
||||
{
|
||||
if (!attribute.ToBE()) return CELL_EINVAL;
|
||||
|
||||
if (tid == owner.GetOwner())
|
||||
if (tid == mutex.GetOwner())
|
||||
{
|
||||
if (attribute.ToBE() & se32(SYS_SYNC_RECURSIVE))
|
||||
{
|
||||
@ -221,7 +221,7 @@ int sys_lwmutex_t::trylock(be_t<u32> tid)
|
||||
}
|
||||
}
|
||||
|
||||
switch (owner.trylock(tid))
|
||||
switch (mutex.trylock(tid))
|
||||
{
|
||||
case SMR_OK: recursive_count = 1; return CELL_OK;
|
||||
case SMR_FAILED: return CELL_EBUSY;
|
||||
@ -231,7 +231,7 @@ int sys_lwmutex_t::trylock(be_t<u32> tid)
|
||||
|
||||
int sys_lwmutex_t::unlock(be_t<u32> tid)
|
||||
{
|
||||
if (tid != owner.GetOwner())
|
||||
if (tid != mutex.GetOwner())
|
||||
{
|
||||
return CELL_EPERM;
|
||||
}
|
||||
@ -250,8 +250,8 @@ int sys_lwmutex_t::unlock(be_t<u32> tid)
|
||||
target = attribute.ToBE() & se32(SYS_SYNC_FIFO) ? sq->pop() : sq->pop_prio();
|
||||
case se32(SYS_SYNC_RETRY): break;
|
||||
}
|
||||
if (target) owner.unlock(tid, target);
|
||||
else owner.unlock(tid);
|
||||
if (target) mutex.unlock(tid, target);
|
||||
else mutex.unlock(tid);
|
||||
}
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -276,7 +276,7 @@ int sys_lwmutex_t::lock(be_t<u32> tid, u64 timeout)
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch (owner.lock(tid, timeout))
|
||||
switch (mutex.lock(tid, timeout))
|
||||
{
|
||||
case SMR_OK:
|
||||
sq->invalidate(tid);
|
||||
@ -289,4 +289,4 @@ int sys_lwmutex_t::lock(be_t<u32> tid, u64 timeout)
|
||||
default:
|
||||
sq->invalidate(tid); return CELL_EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,18 +65,9 @@ struct SleepQueue
|
||||
|
||||
struct sys_lwmutex_t
|
||||
{
|
||||
union // sys_lwmutex_variable_t
|
||||
{
|
||||
struct // sys_lwmutex_lock_info_t
|
||||
{
|
||||
/* volatile */ SMutexBase<be_t<u32>, 0xffffffff, 0> owner;
|
||||
/* volatile */ be_t<u32> waiter; // not used
|
||||
};
|
||||
struct
|
||||
{
|
||||
/* volatile */ be_t<u64> all_info;
|
||||
};
|
||||
};
|
||||
/* volatile */ SMutexBase<be_t<u32>, 0xffffffff, 0> mutex;
|
||||
/* volatile */ be_t<u32> waiter; // not used
|
||||
u64 &all_info(){return *(reinterpret_cast<u64*>(this));}
|
||||
be_t<u32> attribute;
|
||||
be_t<u32> recursive_count;
|
||||
be_t<u32> sleep_queue;
|
||||
@ -85,4 +76,4 @@ struct sys_lwmutex_t
|
||||
int trylock(be_t<u32> tid);
|
||||
int unlock(be_t<u32> tid);
|
||||
int lock(be_t<u32> tid, u64 timeout);
|
||||
};
|
||||
};
|
||||
|
@ -20,29 +20,29 @@ enum CELL_PAD_ERROR_CODE
|
||||
|
||||
struct CellPadData
|
||||
{
|
||||
s32 len;
|
||||
u16 button[CELL_PAD_MAX_CODES];
|
||||
be_t<s32> len;
|
||||
be_t<u16> button[CELL_PAD_MAX_CODES];
|
||||
};
|
||||
|
||||
struct CellPadInfo
|
||||
{
|
||||
u32 max_connect;
|
||||
u32 now_connect;
|
||||
u32 system_info;
|
||||
u16 vendor_id[CELL_MAX_PADS];
|
||||
u16 product_id[CELL_MAX_PADS];
|
||||
u8 status[CELL_MAX_PADS];
|
||||
be_t<u32> max_connect;
|
||||
be_t<u32> now_connect;
|
||||
be_t<u32> system_info;
|
||||
be_t<u16> vendor_id[CELL_MAX_PADS];
|
||||
be_t<u16> product_id[CELL_MAX_PADS];
|
||||
u8 status[CELL_MAX_PADS];
|
||||
};
|
||||
|
||||
struct CellPadInfo2
|
||||
{
|
||||
u32 max_connect;
|
||||
u32 now_connect;
|
||||
u32 system_info;
|
||||
u32 port_status[CELL_PAD_MAX_PORT_NUM];
|
||||
u32 port_setting[CELL_PAD_MAX_PORT_NUM];
|
||||
u32 device_capability[CELL_PAD_MAX_PORT_NUM];
|
||||
u32 device_type[CELL_PAD_MAX_PORT_NUM];
|
||||
be_t<u32> max_connect;
|
||||
be_t<u32> now_connect;
|
||||
be_t<u32> system_info;
|
||||
be_t<u32> port_status[CELL_PAD_MAX_PORT_NUM];
|
||||
be_t<u32> port_setting[CELL_PAD_MAX_PORT_NUM];
|
||||
be_t<u32> device_capability[CELL_PAD_MAX_PORT_NUM];
|
||||
be_t<u32> device_type[CELL_PAD_MAX_PORT_NUM];
|
||||
};
|
||||
|
||||
int cellPadInit(u32 max_connect)
|
||||
@ -130,29 +130,29 @@ int cellPadGetData(u32 port_no, u32 data_addr)
|
||||
*res = 0;
|
||||
}
|
||||
|
||||
data.len = re(len);
|
||||
data.button[CELL_PAD_BTN_OFFSET_DIGITAL1] = re(d1);
|
||||
data.button[CELL_PAD_BTN_OFFSET_DIGITAL2] = re(d2);
|
||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] = re(rx);
|
||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] = re(ry);
|
||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] = re(lx);
|
||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y] = re(ly);
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_RIGHT] = re(pad.m_press_right);
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_LEFT] = re(pad.m_press_left);
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_UP] = re(pad.m_press_up);
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_DOWN] = re(pad.m_press_down);
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_TRIANGLE] = re(pad.m_press_triangle);
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_CIRCLE] = re(pad.m_press_circle);
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_CROSS] = re(pad.m_press_cross);
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_SQUARE] = re(pad.m_press_square);
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_L1] = re(pad.m_press_L1);
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_L2] = re(pad.m_press_L2);
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_R1] = re(pad.m_press_R1);
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_R2] = re(pad.m_press_R2);
|
||||
data.button[CELL_PAD_BTN_OFFSET_SENSOR_X] = re(pad.m_sensor_x);
|
||||
data.button[CELL_PAD_BTN_OFFSET_SENSOR_Y] = re(pad.m_sensor_y);
|
||||
data.button[CELL_PAD_BTN_OFFSET_SENSOR_Z] = re(pad.m_sensor_z);
|
||||
data.button[CELL_PAD_BTN_OFFSET_SENSOR_G] = re(pad.m_sensor_g);
|
||||
data.len = len;
|
||||
data.button[CELL_PAD_BTN_OFFSET_DIGITAL1] = d1;
|
||||
data.button[CELL_PAD_BTN_OFFSET_DIGITAL2] = d2;
|
||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] = rx;
|
||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] = ry;
|
||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] = lx;
|
||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y] = ly;
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_RIGHT] = pad.m_press_right;
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_LEFT] = pad.m_press_left;
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_UP] = pad.m_press_up;
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_DOWN] = pad.m_press_down;
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_TRIANGLE] = pad.m_press_triangle;
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_CIRCLE] = pad.m_press_circle;
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_CROSS] = pad.m_press_cross;
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_SQUARE] = pad.m_press_square;
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_L1] = pad.m_press_L1;
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_L2] = pad.m_press_L2;
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_R1] = pad.m_press_R1;
|
||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_R2] = pad.m_press_R2;
|
||||
data.button[CELL_PAD_BTN_OFFSET_SENSOR_X] = pad.m_sensor_x;
|
||||
data.button[CELL_PAD_BTN_OFFSET_SENSOR_Y] = pad.m_sensor_y;
|
||||
data.button[CELL_PAD_BTN_OFFSET_SENSOR_Z] = pad.m_sensor_z;
|
||||
data.button[CELL_PAD_BTN_OFFSET_SENSOR_G] = pad.m_sensor_g;
|
||||
|
||||
Memory.WriteData(data_addr, data);
|
||||
|
||||
@ -184,9 +184,9 @@ int cellPadGetInfo(u32 info_addr)
|
||||
memset(&info, 0, sizeof(CellPadInfo));
|
||||
|
||||
const PadInfo& rinfo = Emu.GetPadManager().GetInfo();
|
||||
info.max_connect = re(rinfo.max_connect);
|
||||
info.now_connect = re(rinfo.now_connect);
|
||||
info.system_info = re(rinfo.system_info);
|
||||
info.max_connect = rinfo.max_connect;
|
||||
info.now_connect = rinfo.now_connect;
|
||||
info.system_info = rinfo.system_info;
|
||||
|
||||
const Array<Pad>& pads = Emu.GetPadManager().GetPads();
|
||||
|
||||
@ -194,9 +194,9 @@ int cellPadGetInfo(u32 info_addr)
|
||||
{
|
||||
if(i >= pads.GetCount()) break;
|
||||
|
||||
re(info.status[i], pads[i].m_port_status);
|
||||
info.product_id[i] = const_se_t<u16, 0x0268>::value;
|
||||
info.vendor_id[i] = const_se_t<u16, 0x054C>::value;
|
||||
info.status[i] = pads[i].m_port_status;
|
||||
info.product_id[i] = 0x0268;
|
||||
info.vendor_id[i] = 0x054C;
|
||||
}
|
||||
|
||||
Memory.WriteData(info_addr, info);
|
||||
@ -213,19 +213,19 @@ int cellPadGetInfo2(u32 info_addr)
|
||||
memset(&info, 0, sizeof(CellPadInfo2));
|
||||
|
||||
const PadInfo& rinfo = Emu.GetPadManager().GetInfo();
|
||||
info.max_connect = re(rinfo.max_connect);
|
||||
info.now_connect = re(rinfo.now_connect);
|
||||
info.system_info = re(rinfo.system_info);
|
||||
info.max_connect = rinfo.max_connect;
|
||||
info.now_connect = rinfo.now_connect;
|
||||
info.system_info = rinfo.system_info;
|
||||
|
||||
const Array<Pad>& pads = Emu.GetPadManager().GetPads();
|
||||
|
||||
for(u32 i=0; i<CELL_PAD_MAX_PORT_NUM; ++i)
|
||||
{
|
||||
if(i >= pads.GetCount()) break;
|
||||
info.port_status[i] = re(pads[i].m_port_status);
|
||||
info.port_setting[i] = re(pads[i].m_port_setting);
|
||||
info.device_capability[i] = re(pads[i].m_device_capability);
|
||||
info.device_type[i] = re(pads[i].m_device_type);
|
||||
info.port_status[i] = pads[i].m_port_status;
|
||||
info.port_setting[i] = pads[i].m_port_setting;
|
||||
info.device_capability[i] = pads[i].m_device_capability;
|
||||
info.device_type[i] = pads[i].m_device_type;
|
||||
}
|
||||
|
||||
Memory.WriteData(info_addr, info);
|
||||
|
@ -7,23 +7,14 @@
|
||||
* */
|
||||
#include "stdafx.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include <sys/timeb.h>
|
||||
#include "SC_Time.h"
|
||||
|
||||
SysCallBase sys_time("sys_time");
|
||||
|
||||
//static const u64 timebase_frequency = 79800000;
|
||||
extern int cellSysutilGetSystemParamInt(int id, mem32_t value);
|
||||
|
||||
int sys_time_get_timezone(mem32_t timezone, mem32_t summertime)
|
||||
{
|
||||
int ret;
|
||||
ret = cellSysutilGetSystemParamInt(0x0116, timezone); //0x0116 = CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE
|
||||
if (ret != CELL_OK) return ret;
|
||||
ret = cellSysutilGetSystemParamInt(0x0117, summertime); //0x0117 = CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE
|
||||
if (ret != CELL_OK) return ret;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
// Auxiliary functions
|
||||
u64 get_time()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
@ -39,12 +30,24 @@ u64 get_time()
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns some relative time in microseconds, don't change this fact
|
||||
u64 get_system_time()
|
||||
{
|
||||
// returns some relative time in microseconds, don't change this fact
|
||||
return get_time() / 10;
|
||||
}
|
||||
|
||||
|
||||
// Functions
|
||||
int sys_time_get_timezone(mem32_t timezone, mem32_t summertime)
|
||||
{
|
||||
int ret;
|
||||
ret = cellSysutilGetSystemParamInt(0x0116, timezone); //0x0116 = CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE
|
||||
if (ret != CELL_OK) return ret;
|
||||
ret = cellSysutilGetSystemParamInt(0x0117, summertime); //0x0117 = CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE
|
||||
if (ret != CELL_OK) return ret;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_time_get_current_time(u32 sec_addr, u32 nsec_addr)
|
||||
{
|
||||
sys_time.Log("sys_time_get_current_time(sec_addr=0x%x, nsec_addr=0x%x)", sec_addr, nsec_addr);
|
||||
|
4
rpcs3/Emu/SysCalls/lv2/SC_Time.h
Normal file
4
rpcs3/Emu/SysCalls/lv2/SC_Time.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
u64 get_time();
|
||||
u64 get_system_time();
|
@ -1,3 +1,4 @@
|
||||
#if 0
|
||||
#include "stdafx.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
|
||||
@ -19,3 +20,4 @@ int sys_raw_spu_create(u32 id_addr, u32 attr_addr)
|
||||
Memory.Write32(id_addr, Emu.GetIdManager().GetNewID("raw_spu"));
|
||||
return CELL_OK;
|
||||
}
|
||||
#endif
|
||||
|
@ -28,6 +28,7 @@ Emulator::Emulator()
|
||||
, m_dbg_console(nullptr)
|
||||
, m_rsx_callback(0)
|
||||
, m_ppu_callback_thr(0)
|
||||
, m_event_manager(new EventManager())
|
||||
{
|
||||
}
|
||||
|
||||
@ -190,8 +191,8 @@ void Emulator::Load()
|
||||
|
||||
if(IsSelf(m_path.ToStdString()))
|
||||
{
|
||||
std::string self_path = m_path;
|
||||
std::string elf_path = wxFileName(m_path).GetPath().c_str();
|
||||
std::string self_path = m_path.ToStdString();
|
||||
std::string elf_path = wxFileName(m_path).GetPath().ToStdString();
|
||||
|
||||
if(wxFileName(m_path).GetFullName().CmpNoCase("EBOOT.BIN") == 0)
|
||||
{
|
||||
|
@ -12,8 +12,9 @@
|
||||
#include "Emu/DbgConsole.h"
|
||||
#include "Loader/Loader.h"
|
||||
#include "SysCalls/Callback.h"
|
||||
#include "SysCalls/Modules.h"
|
||||
#include "event.h"
|
||||
|
||||
class EventManager;
|
||||
extern void UnloadModules();
|
||||
|
||||
struct EmuInfo
|
||||
{
|
||||
@ -90,7 +91,7 @@ class Emulator
|
||||
AudioManager m_audio_manager;
|
||||
CallbackManager m_callback_manager;
|
||||
CPUThread* m_ppu_callback_thr;
|
||||
EventManager m_event_manager;
|
||||
std::unique_ptr<EventManager> m_event_manager;
|
||||
|
||||
VFS m_vfs;
|
||||
|
||||
@ -120,7 +121,7 @@ public:
|
||||
Array<u64>& GetBreakPoints() { return m_break_points; }
|
||||
Array<u64>& GetMarkedPoints() { return m_marked_points; }
|
||||
CPUThread& GetCallbackThread() { return *m_ppu_callback_thr; }
|
||||
EventManager& GetEventManager() { return m_event_manager; }
|
||||
EventManager& GetEventManager() { return *m_event_manager; }
|
||||
|
||||
void AddModuleInit(ModuleInitializer* m)
|
||||
{
|
||||
@ -164,4 +165,4 @@ public:
|
||||
__forceinline bool IsReady() const { return m_status == Ready; }
|
||||
};
|
||||
|
||||
extern Emulator Emu;
|
||||
extern Emulator Emu;
|
||||
|
@ -47,7 +47,7 @@ AboutDialog::AboutDialog(wxWindow *parent)
|
||||
wxBoxSizer* s_panel_credits(new wxBoxSizer(wxHORIZONTAL));
|
||||
wxStaticText* t_section1 = new wxStaticText(this, wxID_ANY, "\nDevelopers:\n\nDH\nAlexAltea\nHykem\nOil", wxDefaultPosition, wxSize(156,160));
|
||||
wxStaticText* t_section2 = new wxStaticText(this, wxID_ANY, "\nThanks:\n\nBlackDaemon", wxDefaultPosition, wxSize(156,160));
|
||||
wxStaticText* t_section3 = new wxStaticText(this, wxID_ANY, "\nExternal code:\n\n - SELF Decrypter based on scetool (C) 2011-2013 by naehrwert\n - PKG Installer based on ps3pkgtool (C) 2011-2013 by avtolstoy and PKG Finalize (C) by geohot", wxDefaultPosition, wxSize(156,160));
|
||||
wxStaticText* t_section3 = new wxStaticText(this, wxID_ANY, "\nExternal code:\n\n - SELF Decrypter based on scetool (C) 2011-2013 by naehrwert", wxDefaultPosition, wxSize(156,160));
|
||||
|
||||
s_panel_credits->AddSpacer(12);
|
||||
s_panel_credits->Add(t_section1);
|
||||
|
@ -127,8 +127,10 @@ CompilerELF::CompilerELF(wxWindow* parent)
|
||||
" b exit, 0, 0\n"
|
||||
);
|
||||
|
||||
#ifdef _WIN32
|
||||
::SendMessage((HWND)hex_list->GetHWND(), WM_VSCROLL, SB_BOTTOM, 0);
|
||||
::SendMessage((HWND)asm_list->GetHWND(), WM_VSCROLL, SB_BOTTOM, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
CompilerELF::~CompilerELF()
|
||||
@ -318,6 +320,7 @@ void CompilerELF::OnScroll(wxScrollWinEvent& event)
|
||||
dst = hex_list;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if(!m_disable_scroll && src && dst && event.GetOrientation() == wxVERTICAL)
|
||||
{
|
||||
s64 kind = -1;
|
||||
@ -364,6 +367,7 @@ void CompilerELF::OnScroll(wxScrollWinEvent& event)
|
||||
m_disable_scroll = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
@ -268,7 +268,9 @@ void LogFrame::Task()
|
||||
m_log.SetColumnWidth(0, -1); // crashes on exit
|
||||
m_log.SetColumnWidth(1, -1);
|
||||
|
||||
#ifdef _WIN32
|
||||
::SendMessage((HWND)m_log.GetHWND(), WM_VSCROLL, SB_BOTTOM, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
LogBuffer.Flush();
|
||||
|
@ -167,7 +167,7 @@ void InterpreterDisAsmFrame::OnKeyDown(wxKeyEvent& event)
|
||||
{
|
||||
if(event.GetKeyCode() == WXK_SPACE)
|
||||
{
|
||||
wxCommandEvent ce;
|
||||
wxCommandEvent ce;
|
||||
DoStep(ce);
|
||||
return;
|
||||
}
|
||||
@ -222,7 +222,7 @@ void InterpreterDisAsmFrame::OnResize(wxSizeEvent& event)
|
||||
|
||||
void InterpreterDisAsmFrame::DoUpdate()
|
||||
{
|
||||
wxCommandEvent ce;
|
||||
wxCommandEvent ce;
|
||||
Show_PC(ce);
|
||||
WriteRegs();
|
||||
WriteCallStack();
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "RSXDebugger.h"
|
||||
|
||||
#include "git-version.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Ini.h"
|
||||
#include "Emu/GS/sysutil_video.h"
|
||||
#include "Gui/VHDDManager.h"
|
||||
@ -13,7 +12,7 @@
|
||||
#include "Gui/AboutDialog.h"
|
||||
#include <wx/dynlib.h>
|
||||
|
||||
#include "unpkg/unpkg.c"
|
||||
#include "Loader/PKG.h"
|
||||
|
||||
BEGIN_EVENT_TABLE(MainFrame, FrameBase)
|
||||
EVT_CLOSE(MainFrame::OnQuit)
|
||||
@ -81,45 +80,50 @@ MainFrame::MainFrame()
|
||||
wxMenuBar& menubar(*new wxMenuBar());
|
||||
|
||||
wxMenu& menu_boot(*new wxMenu());
|
||||
wxMenu& menu_sys(*new wxMenu());
|
||||
wxMenu& menu_conf(*new wxMenu());
|
||||
wxMenu& menu_tools(*new wxMenu());
|
||||
wxMenu& menu_help(*new wxMenu());
|
||||
|
||||
menubar.Append(&menu_boot, "Boot");
|
||||
menubar.Append(&menu_sys, "System");
|
||||
menubar.Append(&menu_conf, "Config");
|
||||
menubar.Append(&menu_tools, "Tools");
|
||||
menubar.Append(&menu_help, "Help");
|
||||
|
||||
menu_boot.Append(id_boot_game, "Boot game");
|
||||
menu_boot.Append(id_install_pkg, "Install PKG");
|
||||
menu_boot.AppendSeparator();
|
||||
menu_boot.Append(id_boot_elf, "Boot (S)ELF");
|
||||
|
||||
wxMenu& menu_sys(*new wxMenu());
|
||||
menubar.Append(&menu_sys, "System");
|
||||
menu_sys.Append(id_sys_pause, "Pause")->Enable(false);
|
||||
menu_sys.Append(id_sys_stop, "Stop\tCtrl + S")->Enable(false);
|
||||
menu_sys.AppendSeparator();
|
||||
menu_sys.Append(id_sys_send_open_menu, "Send open system menu cmd")->Enable(false);
|
||||
menu_sys.Append(id_sys_send_exit, "Send exit cmd")->Enable(false);
|
||||
|
||||
wxMenu& menu_conf(*new wxMenu());
|
||||
menubar.Append(&menu_conf, "Config");
|
||||
menu_conf.Append(id_config_emu, "Settings");
|
||||
menu_conf.Append(id_config_pad, "PAD Settings");
|
||||
menu_conf.AppendSeparator();
|
||||
menu_conf.Append(id_config_vfs_manager, "Virtual File System Manager");
|
||||
menu_conf.Append(id_config_vhdd_manager, "Virtual HDD Manager");
|
||||
|
||||
wxMenu& menu_tools(*new wxMenu());
|
||||
menubar.Append(&menu_tools, "Tools");
|
||||
menu_tools.Append(id_tools_compiler, "ELF Compiler");
|
||||
menu_tools.Append(id_tools_memory_viewer, "Memory Viewer");
|
||||
menu_tools.Append(id_tools_rsx_debugger, "RSX Debugger");
|
||||
|
||||
wxMenu& menu_help(*new wxMenu());
|
||||
menubar.Append(&menu_help, "Help");
|
||||
menu_help.Append(id_help_about, "About...");
|
||||
|
||||
SetMenuBar(&menubar);
|
||||
|
||||
// Panels
|
||||
m_game_viewer = new GameViewer(this);
|
||||
m_debugger_frame = new DebuggerPanel(this);
|
||||
ConLogFrame = new LogFrame(this);
|
||||
|
||||
AddPane(m_game_viewer, "Game List", wxAUI_DOCK_BOTTOM);
|
||||
AddPane(ConLogFrame, "Log", wxAUI_DOCK_BOTTOM);
|
||||
AddPane(m_debugger_frame, "Debugger", wxAUI_DOCK_RIGHT);
|
||||
|
||||
// Events
|
||||
Connect( id_boot_game, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootGame) );
|
||||
Connect( id_install_pkg, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::InstallPkg) );
|
||||
Connect( id_boot_elf, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootElf) );
|
||||
@ -221,43 +225,21 @@ void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event))
|
||||
return;
|
||||
}
|
||||
|
||||
ConLog.Write("PKG: extracting...");
|
||||
|
||||
Emu.Stop();
|
||||
|
||||
wxString fileName = ctrl.GetPath();
|
||||
if (!pkg_unpack(static_cast<const char*>(fileName)))
|
||||
ConLog.Error("Could not unpack PKG!");
|
||||
else ConLog.Success("PKG: extract done.");
|
||||
|
||||
if (!wxRemoveFile(ctrl.GetPath()+".dec"))
|
||||
ConLog.Warning("Could not delete the decoded DEC file");
|
||||
|
||||
pkg_header *header;
|
||||
pkg_info(static_cast<const char*>(fileName), &header);
|
||||
|
||||
wxString titleID_full (header->title_id);
|
||||
wxString titleID = titleID_full.SubString(7, 15);
|
||||
|
||||
wxString mainDir = wxGetCwd();
|
||||
wxString gamePath = "\\dev_hdd0\\game\\";
|
||||
|
||||
wxString pkgDir = mainDir + gamePath + titleID;
|
||||
|
||||
// Save the title ID.
|
||||
Emu.SetTitleID(titleID);
|
||||
|
||||
//Refresh game list
|
||||
m_game_viewer->Refresh();
|
||||
|
||||
if(Emu.BootGame(pkgDir.ToStdString()))
|
||||
// Open and install PKG file
|
||||
std::string filePath = ctrl.GetPath().ToStdString();
|
||||
wxFile pkg_f(filePath, wxFile::read); // TODO: Use VFS to install PKG files
|
||||
|
||||
if (pkg_f.IsOpened())
|
||||
{
|
||||
ConLog.Success("Game: boot done.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ConLog.Error("Ps3 executable not found in folder (%s)", pkgDir.wx_str());
|
||||
PKGLoader pkg(pkg_f);
|
||||
pkg.Install("/dev_hdd0/game/");
|
||||
pkg.Close();
|
||||
}
|
||||
|
||||
// Refresh game list
|
||||
m_game_viewer->Refresh();
|
||||
}
|
||||
|
||||
void MainFrame::BootElf(wxCommandEvent& WXUNUSED(event))
|
||||
|
@ -1,9 +1,13 @@
|
||||
#pragma once
|
||||
#include "GameViewer.h"
|
||||
|
||||
#include "Gui/Debugger.h"
|
||||
#include "Gui/GameViewer.h"
|
||||
|
||||
#include <wx/aui/aui.h>
|
||||
|
||||
class MainFrame : public FrameBase
|
||||
{
|
||||
DebuggerPanel* m_debugger_frame;
|
||||
GameViewer* m_game_viewer;
|
||||
wxAuiManager m_aui_mgr;
|
||||
AppConnector m_app_connector;
|
||||
|
@ -25,7 +25,7 @@ MemoryViewerPanel::MemoryViewerPanel(wxWindow* parent)
|
||||
|
||||
wxStaticBoxSizer& s_tools_mem_bytes = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Bytes");
|
||||
sc_bytes = new wxSpinCtrl(this, wxID_ANY, "16", wxDefaultPosition, wxSize(44,-1));
|
||||
sc_bytes->SetRange(1, 16);
|
||||
sc_bytes->SetRange(1, 16);
|
||||
s_tools_mem_bytes.Add(sc_bytes);
|
||||
|
||||
wxStaticBoxSizer& s_tools_mem_buttons = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Control");
|
||||
@ -52,7 +52,7 @@ MemoryViewerPanel::MemoryViewerPanel(wxWindow* parent)
|
||||
s_tools_img_size.Add(new wxStaticText(this, wxID_ANY, " x "));
|
||||
s_tools_img_size.Add(sc_img_size_y);
|
||||
|
||||
sc_img_size_x->SetRange(1, 8192);
|
||||
sc_img_size_x->SetRange(1, 8192);
|
||||
sc_img_size_y->SetRange(1, 8192);
|
||||
|
||||
wxStaticBoxSizer& s_tools_img_mode = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Mode");
|
||||
|
@ -322,7 +322,7 @@ void RSXDebugger::GoToGet(wxCommandEvent& event)
|
||||
{
|
||||
if (!RSXReady()) return;
|
||||
CellGcmControl* ctrl = (CellGcmControl*)&Memory[Emu.GetGSManager().GetRender().m_ctrlAddress];
|
||||
m_addr = Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + re(ctrl->get));
|
||||
m_addr = Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + ctrl->get);
|
||||
t_addr->SetValue(wxString::Format("%08x", m_addr));
|
||||
UpdateInformation();
|
||||
event.Skip();
|
||||
@ -332,7 +332,7 @@ void RSXDebugger::GoToPut(wxCommandEvent& event)
|
||||
{
|
||||
if (!RSXReady()) return;
|
||||
CellGcmControl* ctrl = (CellGcmControl*)&Memory[Emu.GetGSManager().GetRender().m_ctrlAddress];
|
||||
m_addr = Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + re(ctrl->put));
|
||||
m_addr = Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + ctrl->put);
|
||||
t_addr->SetValue(wxString::Format("%08x", m_addr));
|
||||
UpdateInformation();
|
||||
event.Skip();
|
||||
@ -546,7 +546,7 @@ void RSXDebugger::GetTexture()
|
||||
m_list_texture->SetItem(i, 3, wxString::Format("%dD", render.m_textures[i].GetDimension()));
|
||||
m_list_texture->SetItem(i, 4, render.m_textures[i].IsEnabled() ? "True" : "False");
|
||||
m_list_texture->SetItem(i, 5, wxString::Format("0x%x", render.m_textures[i].GetFormat()));
|
||||
m_list_texture->SetItem(i, 6, wxString::Format("0x%x", render.m_textures[i].Getmipmap()));
|
||||
m_list_texture->SetItem(i, 6, wxString::Format("0x%x", render.m_textures[i].GetMipmap()));
|
||||
m_list_texture->SetItem(i, 7, wxString::Format("0x%x", render.m_textures[i].m_pitch));
|
||||
m_list_texture->SetItem(i, 8, wxString::Format("%dx%d",
|
||||
render.m_textures[i].GetWidth(),
|
||||
@ -569,7 +569,7 @@ void RSXDebugger::GetSettings()
|
||||
|
||||
LIST_SETTINGS_ADD("Alpha func", !(render.m_set_alpha_func) ? "(none)" : wxString::Format("0x%x (%s)",
|
||||
render.m_alpha_func,
|
||||
ParseGCMEnum(render.m_alpha_func, CELL_GCM_ENUM).wx_str()));
|
||||
ParseGCMEnum(render.m_alpha_func, CELL_GCM_ENUM)));
|
||||
LIST_SETTINGS_ADD("Blend color", !(render.m_set_blend_color) ? "(none)" : wxString::Format("R:%d, G:%d, B:%d, A:%d",
|
||||
render.m_blend_color_r,
|
||||
render.m_blend_color_g,
|
||||
@ -589,10 +589,10 @@ void RSXDebugger::GetSettings()
|
||||
LIST_SETTINGS_ADD("Depth bounds", wxString::Format("Min:%f, Max:%f", render.m_depth_bounds_min, render.m_depth_bounds_max));
|
||||
LIST_SETTINGS_ADD("Depth func", !(render.m_set_depth_func) ? "(none)" : wxString::Format("0x%x (%s)",
|
||||
render.m_depth_func,
|
||||
ParseGCMEnum(render.m_depth_func, CELL_GCM_ENUM).wx_str()));
|
||||
ParseGCMEnum(render.m_depth_func, CELL_GCM_ENUM)));
|
||||
LIST_SETTINGS_ADD("Draw mode", wxString::Format("%d (%s)",
|
||||
render.m_draw_mode,
|
||||
ParseGCMEnum(render.m_draw_mode, CELL_GCM_PRIMITIVE_ENUM).wx_str()));
|
||||
ParseGCMEnum(render.m_draw_mode, CELL_GCM_PRIMITIVE_ENUM)));
|
||||
LIST_SETTINGS_ADD("Scissor", wxString::Format("X:%d, Y:%d, W:%d, H:%d",
|
||||
render.m_scissor_x,
|
||||
render.m_scissor_y,
|
||||
@ -600,7 +600,7 @@ void RSXDebugger::GetSettings()
|
||||
render.m_scissor_h));
|
||||
LIST_SETTINGS_ADD("Stencil func", !(render.m_set_stencil_func) ? "(none)" : wxString::Format("0x%x (%s)",
|
||||
render.m_stencil_func,
|
||||
ParseGCMEnum(render.m_stencil_func, CELL_GCM_ENUM).wx_str()));
|
||||
ParseGCMEnum(render.m_stencil_func, CELL_GCM_ENUM)));
|
||||
LIST_SETTINGS_ADD("Surface Pitch A", wxString::Format("0x%x", render.m_surface_pitch_a));
|
||||
LIST_SETTINGS_ADD("Surface Pitch B", wxString::Format("0x%x", render.m_surface_pitch_b));
|
||||
LIST_SETTINGS_ADD("Surface Pitch C", wxString::Format("0x%x", render.m_surface_pitch_c));
|
||||
@ -690,7 +690,7 @@ void RSXDebugger::OnSelectTexture(wxListEvent& event)
|
||||
UpdateInformation();
|
||||
}
|
||||
|
||||
wxString RSXDebugger::ParseGCMEnum(u32 value, u32 type)
|
||||
const char* RSXDebugger::ParseGCMEnum(u32 value, u32 type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ public:
|
||||
virtual void SetPrograms(wxListEvent& event);
|
||||
virtual void OnSelectTexture(wxListEvent& event);
|
||||
|
||||
wxString ParseGCMEnum(u32 value, u32 type);
|
||||
const char* ParseGCMEnum(u32 value, u32 type);
|
||||
wxString DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioAddr);
|
||||
|
||||
|
||||
|
@ -58,7 +58,7 @@ VFSEntrySettingsDialog::VFSEntrySettingsDialog(wxWindow* parent, VFSManagerEntry
|
||||
m_tctrl_mount->SetValue(m_entry.mount);
|
||||
m_ch_type->SetSelection(m_entry.device);
|
||||
|
||||
wxCommandEvent ce;
|
||||
wxCommandEvent ce;
|
||||
OnSelectType(ce);
|
||||
}
|
||||
|
||||
|
@ -347,10 +347,10 @@ VHDDSetInfoDialog::VHDDSetInfoDialog(wxWindow* parent) : wxDialog(parent, wxID_A
|
||||
m_ch_type->Append("MB");
|
||||
m_ch_type->Append("GB");
|
||||
|
||||
m_spin_size->SetRange(1, 0x7fffffff);
|
||||
m_spin_size->SetRange(1, 0x7fffffff);
|
||||
m_spin_size->SetValue(64);
|
||||
m_ch_type->SetSelection(3);
|
||||
m_spin_block_size->SetRange(64, 0x7fffffff);
|
||||
m_spin_block_size->SetRange(64, 0x7fffffff);
|
||||
m_spin_block_size->SetValue(2048);
|
||||
Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(VHDDSetInfoDialog::OnOk));
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
#include "stdafx.h"
|
||||
#include "Ini.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <wx/msw/iniconf.h>
|
||||
#endif
|
||||
|
||||
Inis Ini;
|
||||
|
||||
@ -148,9 +150,13 @@ static wxString WindowInfoToString(const WindowInfo wind)
|
||||
//Ini
|
||||
Ini::Ini()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
m_Config = new wxIniConfig( wxEmptyString, wxEmptyString,
|
||||
wxGetCwd() + "\\rpcs3.ini",
|
||||
wxEmptyString, wxCONFIG_USE_LOCAL_FILE );
|
||||
#else
|
||||
m_Config = new wxConfig("rpcs3");
|
||||
#endif
|
||||
}
|
||||
|
||||
void Ini::Save(wxString key, int value)
|
||||
@ -211,4 +217,4 @@ wxString Ini::Load(wxString key, const wxString& def_value)
|
||||
WindowInfo Ini::Load(wxString key, const WindowInfo& def_value)
|
||||
{
|
||||
return StringToWindowInfo(m_Config->Read(key, WindowInfoToString(def_value)));
|
||||
}
|
||||
}
|
||||
|
@ -200,9 +200,9 @@ public:
|
||||
PadHandlerR3.Load(static_cast<int>('C'));
|
||||
PadHandlerL3.Load(static_cast<int>('Z'));
|
||||
PadHandlerSelect.Load(0);
|
||||
PadHandlerSquare.Load(static_cast<int>('L'));
|
||||
PadHandlerSquare.Load(static_cast<int>('J'));
|
||||
PadHandlerCross.Load(static_cast<int>('K'));
|
||||
PadHandlerCircle.Load(static_cast<int>('J'));
|
||||
PadHandlerCircle.Load(static_cast<int>('L'));
|
||||
PadHandlerTriangle.Load(static_cast<int>('I'));
|
||||
PadHandlerR1.Load(static_cast<int>('3'));
|
||||
PadHandlerL1.Load(static_cast<int>('1'));
|
||||
|
248
rpcs3/Loader/PKG.cpp
Normal file
248
rpcs3/Loader/PKG.cpp
Normal file
@ -0,0 +1,248 @@
|
||||
#include "stdafx.h"
|
||||
#include "PKG.h"
|
||||
#include "scetool/aes.h"
|
||||
#include "scetool/sha1.h"
|
||||
|
||||
#include <wx/progdlg.h>
|
||||
|
||||
PKGLoader::PKGLoader(wxFile& f) : pkg_f(f)
|
||||
{
|
||||
}
|
||||
|
||||
bool PKGLoader::Install(std::string dest, bool show)
|
||||
{
|
||||
// Initial checks
|
||||
if (!pkg_f.IsOpened())
|
||||
return false;
|
||||
|
||||
dest = wxGetCwd() + dest;
|
||||
if (!dest.empty() && dest.back() != '/')
|
||||
dest += '/';
|
||||
|
||||
if(!LoadHeader(show))
|
||||
return false;
|
||||
|
||||
std::string titleID = std::string(m_header.title_id).substr(7, 9);
|
||||
std::string decryptedFile = wxGetCwd().ToStdString() + "/dev_hdd1/" + titleID + ".dec";
|
||||
|
||||
if (wxDirExists(dest+titleID)) {
|
||||
wxMessageDialog d_overwrite(NULL, "Another installation was found. Do you want to overwrite it?", "PKG Decrypter / Installer", wxYES_NO|wxCENTRE);
|
||||
if (d_overwrite.ShowModal() != wxID_YES) {
|
||||
ConLog.Error("PKG Loader: Another installation found in: %s", wxString(titleID).wx_str());
|
||||
return false;
|
||||
}
|
||||
// TODO: Remove the following two lines and remove the folder dest+titleID
|
||||
ConLog.Error("PKG Loader: Another installation found in: %s", wxString(titleID).wx_str());
|
||||
return false;
|
||||
}
|
||||
if (!wxMkdir(dest+titleID)) {
|
||||
ConLog.Error("PKG Loader: Could not make the installation directory: %s", wxString(titleID).wx_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Decrypt the PKG file
|
||||
wxFile out;
|
||||
out.Create(decryptedFile, true);
|
||||
Decrypt(out);
|
||||
out.Close();
|
||||
|
||||
// Unpack the decrypted file
|
||||
wxFile dec(decryptedFile, wxFile::read);
|
||||
LoadEntries(dec);
|
||||
wxProgressDialog pdlg("PKG Decrypter / Installer", "Please wait, unpacking...", m_entries.size(), 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL);
|
||||
|
||||
for (const PKGEntry& entry : m_entries)
|
||||
{
|
||||
UnpackEntry(dec, entry, dest+titleID+'/');
|
||||
pdlg.Update(pdlg.GetValue() + 1);
|
||||
}
|
||||
pdlg.Update(m_entries.size());
|
||||
|
||||
// Delete decrypted file
|
||||
dec.Close();
|
||||
wxRemoveFile(decryptedFile);
|
||||
ConLog.Write("PKG Loader: Package successfully installed in: /dev_hdd0/game/%s", wxString(titleID.c_str()).wx_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PKGLoader::Close()
|
||||
{
|
||||
return pkg_f.Close();
|
||||
}
|
||||
|
||||
bool PKGLoader::LoadHeader(bool show)
|
||||
{
|
||||
pkg_f.Seek(0);
|
||||
if (pkg_f.Read(&m_header, sizeof(PKGHeader)) != sizeof(PKGHeader)) {
|
||||
ConLog.Error("PKG Loader: Package file is too short!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CheckHeader())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PKGLoader::CheckHeader()
|
||||
{
|
||||
if (m_header.pkg_magic != 0x7F504B47) {
|
||||
ConLog.Error("PKG Loader: Not a package file!");
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (m_header.pkg_type)
|
||||
{
|
||||
case PKG_RELEASE_TYPE_DEBUG: break;
|
||||
case PKG_RELEASE_TYPE_RELEASE: break;
|
||||
default:
|
||||
ConLog.Error("PKG Loader: Unknown PKG type!");
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (m_header.pkg_platform)
|
||||
{
|
||||
case PKG_PLATFORM_TYPE_PS3: break;
|
||||
case PKG_PLATFORM_TYPE_PSP: break;
|
||||
default:
|
||||
ConLog.Error("PKG Loader: Unknown PKG type!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_header.header_size != PKG_HEADER_SIZE) {
|
||||
ConLog.Error("PKG Loader: Wrong header size!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_header.pkg_size != pkg_f.Length()) {
|
||||
ConLog.Error("PKG Loader: File size mismatch.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_header.data_size + m_header.data_offset + 0x60 != pkg_f.Length()) {
|
||||
ConLog.Error("PKG Loader: Data size mismatch.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PKGLoader::LoadEntries(wxFile& dec)
|
||||
{
|
||||
m_entries.resize(m_header.file_count);
|
||||
|
||||
dec.Seek(0);
|
||||
dec.Read(&m_entries[0], sizeof(PKGEntry) * m_header.file_count);
|
||||
|
||||
if (m_entries[0].name_offset / sizeof(PKGEntry) != m_header.file_count) {
|
||||
ConLog.Error("PKG Loader: Entries are damaged!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PKGLoader::UnpackEntry(wxFile& dec, const PKGEntry& entry, std::string dir)
|
||||
{
|
||||
u8 buf[BUF_SIZE];
|
||||
|
||||
dec.Seek(entry.name_offset);
|
||||
dec.Read(buf, entry.name_size);
|
||||
buf[entry.name_size] = 0;
|
||||
|
||||
switch (entry.type & (0xff))
|
||||
{
|
||||
case PKG_FILE_ENTRY_NPDRM:
|
||||
case PKG_FILE_ENTRY_NPDRMEDAT:
|
||||
case PKG_FILE_ENTRY_SDAT:
|
||||
case PKG_FILE_ENTRY_REGULAR:
|
||||
{
|
||||
wxFile out;
|
||||
out.Create(dir + buf);
|
||||
dec.Seek(entry.file_offset);
|
||||
|
||||
for (u64 size = 0; size < entry.file_size; ) {
|
||||
size += dec.Read(buf, BUF_SIZE);
|
||||
if (size > entry.file_size)
|
||||
out.Write(buf, BUF_SIZE - (size - entry.file_size));
|
||||
else
|
||||
out.Write(buf, BUF_SIZE);
|
||||
}
|
||||
out.Close();
|
||||
}
|
||||
break;
|
||||
|
||||
case PKG_FILE_ENTRY_FOLDER:
|
||||
wxMkdir(dir + buf);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PKGLoader::Decrypt(wxFile& out)
|
||||
{
|
||||
aes_context c;
|
||||
u8 iv[HASH_LEN];
|
||||
u8 buf[BUF_SIZE];
|
||||
u8 ctr[BUF_SIZE];
|
||||
|
||||
// Debug key
|
||||
u8 key[0x40];
|
||||
memset(key, 0, 0x40);
|
||||
memcpy(key+0x00, &m_header.qa_digest[0], 8); // &data[0x60]
|
||||
memcpy(key+0x08, &m_header.qa_digest[0], 8); // &data[0x60]
|
||||
memcpy(key+0x10, &m_header.qa_digest[8], 8); // &data[0x68]
|
||||
memcpy(key+0x18, &m_header.qa_digest[8], 8); // &data[0x68]
|
||||
|
||||
pkg_f.Seek(m_header.data_offset);
|
||||
u32 parts = (m_header.data_size + BUF_SIZE - 1) / BUF_SIZE;
|
||||
|
||||
wxProgressDialog pdlg("PKG Decrypter / Installer", "Please wait, decrypting...", parts, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL);
|
||||
|
||||
memcpy(iv, m_header.klicensee, sizeof(iv));
|
||||
aes_setkey_enc(&c, PKG_AES_KEY, 128);
|
||||
|
||||
for (u32 i=0; i<parts; i++)
|
||||
{
|
||||
memset(buf, 0, sizeof(buf));
|
||||
u32 length = pkg_f.Read(buf, BUF_SIZE);
|
||||
u32 bits = (length + HASH_LEN - 1) / HASH_LEN;
|
||||
|
||||
if (m_header.pkg_type == PKG_RELEASE_TYPE_DEBUG)
|
||||
{
|
||||
for (u32 j=0; j<bits; j++)
|
||||
{
|
||||
u8 hash[0x14];
|
||||
sha1(key, 0x40, hash);
|
||||
*(u64*)&buf[j*HASH_LEN + 0] ^= *(u64*)&hash[0];
|
||||
*(u64*)&buf[j*HASH_LEN + 8] ^= *(u64*)&hash[8];
|
||||
*(be_t<u64>*)&key[0x38] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_header.pkg_type == PKG_RELEASE_TYPE_RELEASE)
|
||||
{
|
||||
for (u32 j=0; j<bits; j++)
|
||||
{
|
||||
aes_crypt_ecb(&c, AES_ENCRYPT, iv, ctr+j*HASH_LEN);
|
||||
|
||||
be_t<u64> hi = *(be_t<u64>*)&iv[0];
|
||||
be_t<u64> lo = *(be_t<u64>*)&iv[8] + 1;
|
||||
|
||||
if (lo == 0)
|
||||
hi += 1;
|
||||
|
||||
*(be_t<u64>*)&iv[0] = hi;
|
||||
*(be_t<u64>*)&iv[8] = lo;
|
||||
}
|
||||
|
||||
for (u32 j=0; j<length; j++) {
|
||||
buf[j] ^= ctr[j];
|
||||
}
|
||||
}
|
||||
|
||||
out.Write(buf, length);
|
||||
pdlg.Update(i);
|
||||
}
|
||||
pdlg.Update(parts);
|
||||
}
|
76
rpcs3/Loader/PKG.h
Normal file
76
rpcs3/Loader/PKG.h
Normal file
@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
#include "Loader.h"
|
||||
|
||||
// Constants
|
||||
#define PKG_HEADER_SIZE 0xC0 //sizeof(pkg_header) + sizeof(pkg_unk_checksum)
|
||||
#define PKG_RELEASE_TYPE_RELEASE 0x8000
|
||||
#define PKG_RELEASE_TYPE_DEBUG 0x0000
|
||||
#define PKG_PLATFORM_TYPE_PS3 0x0001
|
||||
#define PKG_PLATFORM_TYPE_PSP 0x0002
|
||||
|
||||
#define PKG_FILE_ENTRY_NPDRM 0x0001
|
||||
#define PKG_FILE_ENTRY_NPDRMEDAT 0x0002
|
||||
#define PKG_FILE_ENTRY_REGULAR 0x0003
|
||||
#define PKG_FILE_ENTRY_FOLDER 0x0004
|
||||
#define PKG_FILE_ENTRY_SDAT 0x0009
|
||||
#define PKG_FILE_ENTRY_OVERWRITE 0x80000000
|
||||
|
||||
#define HASH_LEN 16
|
||||
#define BUF_SIZE 4096
|
||||
|
||||
// Key
|
||||
static const u8 PKG_AES_KEY[16] = {
|
||||
0x2e, 0x7b, 0x71, 0xd7,
|
||||
0xc9, 0xc9, 0xa1, 0x4e,
|
||||
0xa3, 0x22, 0x1f, 0x18,
|
||||
0x88, 0x28, 0xb8, 0xf8
|
||||
};
|
||||
|
||||
// Structs
|
||||
struct PKGHeader
|
||||
{
|
||||
be_t<u32> pkg_magic; // Magic (0x7f504b47)
|
||||
be_t<u16> pkg_type; // Release type (Retail:0x8000, Debug:0x0000)
|
||||
be_t<u16> pkg_platform; // Platform type (PS3:0x0001, PSP:0x0002)
|
||||
be_t<u32> header_size; // Header size (0xc0)
|
||||
be_t<u32> unk1; // Some PKG version maybe?
|
||||
be_t<u32> meta_size; // Size of metadata (block after header & hashes)
|
||||
be_t<u32> file_count; // Number of files
|
||||
be_t<u64> pkg_size; // PKG size in bytes
|
||||
be_t<u64> data_offset; // Encrypted data offset
|
||||
be_t<u64> data_size; // Encrypted data size in bytes
|
||||
char title_id[48]; // Title ID
|
||||
u8 qa_digest[16]; // This should be the hash of "files + attribs"
|
||||
u8 klicensee[16]; // Nonce
|
||||
};
|
||||
|
||||
struct PKGEntry
|
||||
{
|
||||
be_t<u32> name_offset; // File name offset
|
||||
be_t<u32> name_size; // File name size
|
||||
be_t<u64> file_offset; // File offset
|
||||
be_t<u64> file_size; // File size
|
||||
be_t<u32> type; // File type
|
||||
be_t<u32> pad; // Padding (zeros)
|
||||
};
|
||||
|
||||
class PKGLoader
|
||||
{
|
||||
wxFile& pkg_f;
|
||||
PKGHeader m_header;
|
||||
std::vector<PKGEntry> m_entries;
|
||||
|
||||
virtual void Decrypt(wxFile& out);
|
||||
|
||||
public:
|
||||
PKGLoader(wxFile& f);
|
||||
virtual bool Install(std::string dest, bool show = false);
|
||||
|
||||
virtual bool LoadHeader(bool show = false);
|
||||
virtual bool CheckHeader();
|
||||
|
||||
virtual bool LoadEntries(wxFile& dec);
|
||||
virtual bool UnpackEntry(wxFile& dec, const PKGEntry& entry, std::string dir);
|
||||
|
||||
virtual bool Close();
|
||||
};
|
@ -2,8 +2,10 @@
|
||||
#include "rpcs3.h"
|
||||
#include "Ini.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <wx/msw/wrapwin.h>
|
||||
#include "Gui/CompilerELF.h"
|
||||
#endif
|
||||
|
||||
const wxEventType wxEVT_DBG_COMMAND = wxNewEventType();
|
||||
|
||||
@ -22,15 +24,7 @@ bool Rpcs3App::OnInit()
|
||||
SetTopWindow(m_MainFrame);
|
||||
Emu.Init();
|
||||
|
||||
// (new CompilerELF(m_MainFrame))->Show();
|
||||
m_debugger_frame = new DebuggerPanel(m_MainFrame);
|
||||
ConLogFrame = new LogFrame(m_MainFrame);
|
||||
|
||||
m_MainFrame->AddPane(ConLogFrame, "Log", wxAUI_DOCK_BOTTOM);
|
||||
m_MainFrame->AddPane(m_debugger_frame, "Debugger", wxAUI_DOCK_RIGHT);
|
||||
//ConLogFrame->Show();
|
||||
m_MainFrame->Show();
|
||||
|
||||
m_MainFrame->DoSettings(true);
|
||||
|
||||
return true;
|
||||
|
@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "Gui/MainFrame.h"
|
||||
#include "Gui/Debugger.h"
|
||||
|
||||
template<typename T> T min(const T a, const T b) { return a < b ? a : b; }
|
||||
template<typename T> T max(const T a, const T b) { return a > b ? a : b; }
|
||||
@ -55,7 +53,6 @@ class Rpcs3App : public wxApp
|
||||
{
|
||||
public:
|
||||
MainFrame* m_MainFrame;
|
||||
DebuggerPanel* m_debugger_frame;
|
||||
|
||||
virtual bool OnInit();
|
||||
virtual void Exit();
|
||||
@ -68,4 +65,4 @@ DECLARE_APP(Rpcs3App)
|
||||
//extern CPUThread& GetCPU(const u8 core);
|
||||
|
||||
extern Rpcs3App* TheApp;
|
||||
static const u64 PS3_CLK = 3200000000;
|
||||
static const u64 PS3_CLK = 3200000000;
|
||||
|
@ -324,6 +324,7 @@
|
||||
<ClCompile Include="Loader\ELF32.cpp" />
|
||||
<ClCompile Include="Loader\ELF64.cpp" />
|
||||
<ClCompile Include="Loader\Loader.cpp" />
|
||||
<ClCompile Include="Loader\PKG.cpp" />
|
||||
<ClCompile Include="Loader\PSF.cpp" />
|
||||
<ClCompile Include="Loader\SELF.cpp" />
|
||||
<ClCompile Include="Loader\TRP.cpp" />
|
||||
|
@ -415,6 +415,9 @@
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellAdec.cpp">
|
||||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Loader\PKG.cpp">
|
||||
<Filter>Loader</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="rpcs3.rc" />
|
||||
|
@ -3,19 +3,33 @@
|
||||
#define NOMINMAX
|
||||
|
||||
#ifndef QT_UI
|
||||
#ifdef _WIN32
|
||||
#include <wx/msw/setup.h>
|
||||
#include <wx/wx.h>
|
||||
#endif
|
||||
#include <wx/config.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/propdlg.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/filefn.h>
|
||||
#include <wx/dcclient.h>
|
||||
|
||||
#include <wx/wfstream.h>
|
||||
#include <wx/dir.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/datetime.h>
|
||||
#include <wx/filepicker.h>
|
||||
#include <wx/menu.h>
|
||||
#include <wx/menuitem.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include "wx/gauge.h"
|
||||
#include <wx/stattext.h>
|
||||
#include "wx/scrolbar.h"
|
||||
#include "wx/frame.h"
|
||||
#include <wx/combobox.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include "wx/app.h"
|
||||
|
||||
#include <wx/wxprec.h>
|
||||
#endif
|
||||
@ -199,12 +213,15 @@ enum Status
|
||||
|
||||
#include "AppConnector.h"
|
||||
|
||||
#include "Emu/SysCalls/Callback.h"
|
||||
#include "Ini.h"
|
||||
#include "Gui/FrameBase.h"
|
||||
#include "Gui/ConLog.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
#include "Emu/SysCalls/Modules.h"
|
||||
|
||||
|
||||
#include "Emu/FS/vfsDirBase.h"
|
||||
#include "Emu/FS/vfsFileBase.h"
|
||||
|
@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
u8 retail_pkg_aes_key[] = {0x2E,0x7B,0x71,0xD7,0xC9,0xC9,0xA1,0x4E,0xA3,0x22,0x1F,0x18,0x88,0x28,0xB8,0xF8};
|
||||
|
||||
u8 npdrm_keypair_e[] = {
|
||||
0xA1,0xC0,0x13,0xAB,0xCE,0x98,0xA7,0xE3,0xDC,0x69,0x92,0x3B,0x07,0xC0,0x28,0x5F,
|
||||
0x75,0x54,0xC5,0x12,0xB0,0xB0,0xA9,0x6F,0x24,0x52,0x40,0xF2,0xFD,0x43,0x3A,0xF2,
|
||||
0x3F,0x4E,0xFE,0xC6,0xC1,0x83,0xEA,0x37,0x8D,0x1B,0xEC,0xB0,0x9D,0x88,0xDB,0x32,
|
||||
0x8F,0x2C,0x86,0x37,0xB7,0xAC,0x72,0x05,0x9B,0x15,0x56,0xB0,0xD9,0x5B,0x5B,0xE0};
|
||||
|
||||
u8 npdrm_keypair_d[] = {
|
||||
0x87,0xC7,0x4F,0xFE,0x66,0x93,0x0B,0xAA,0xA1,0x6F,0x86,0x40,0x91,0xC5,0x66,0xFB,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x08,0x28,0xB5,0x8F,0xAC,0xF9,0xDE,0xC8,0xD7,0x0D,0xFE,0xF0,0xF3,0x76,0x63,0xAE,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
|
||||
u8 npdrm_omac_key1[] = {0x72,0xF9,0x90,0x78,0x8F,0x9C,0xFF,0x74,0x57,0x25,0xF0,0x8E,0x4C,0x12,0x83,0x87};
|
||||
u8 npdrm_omac_key2[] = {0x6B,0xA5,0x29,0x76,0xEF,0xDA,0x16,0xEF,0x3C,0x33,0x9F,0xB2,0x97,0x1E,0x25,0x6B};
|
||||
u8 npdrm_omac_key3[] = {0x9B,0x51,0x5F,0xEA,0xCF,0x75,0x06,0x49,0x81,0xAA,0x60,0x4D,0x91,0xA5,0x4E,0x97};
|
@ -1,106 +0,0 @@
|
||||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
typedef struct {
|
||||
u32 magic;
|
||||
u32 debugFlag;
|
||||
u32 infoOffset;
|
||||
u32 unknown1;
|
||||
u32 headSize;
|
||||
u32 itemCount;
|
||||
u64 packageSize;
|
||||
u64 dataOffset;
|
||||
u64 dataSize;
|
||||
} pkg_header2;
|
||||
|
||||
u64 get_u64(void* vd) {
|
||||
u8 *d = (u8*)vd;
|
||||
return ((u64)d[0]<<56) | ((u64)d[1]<<48) | ((u64)d[2]<<40) | ((u64)d[3]<<32) | (d[4]<<24) | (d[5]<<16) | (d[6]<<8) | d[7];
|
||||
}
|
||||
|
||||
void set_u64(void* vd, u64 v) {
|
||||
u8 *d = (u8*)vd;
|
||||
d[0] = v>>56;
|
||||
d[1] = v>>48;
|
||||
d[2] = v>>40;
|
||||
d[3] = v>>32;
|
||||
d[4] = v>>24;
|
||||
d[5] = v>>16;
|
||||
d[6] = v>>8;
|
||||
d[7] = v>>0;
|
||||
}
|
||||
|
||||
void set_u32(void* vd, u32 v) {
|
||||
u8 *d = (u8*)vd;
|
||||
d[0] = v>>24;
|
||||
d[1] = v>>16;
|
||||
d[2] = v>>8;
|
||||
d[3] = v>>0;
|
||||
}
|
||||
|
||||
void set_u16(void* vd, u16 v) {
|
||||
u8 *d = (u8*)vd;
|
||||
d[0] = v>>8;
|
||||
d[1] = v>>0;
|
||||
}
|
||||
|
||||
u32 get_u32(void* vd) {
|
||||
u8 *d = (u8*)vd;
|
||||
return (d[0]<<24) | (d[1]<<16) | (d[2]<<8) | d[3];
|
||||
}
|
||||
|
||||
float get_float(u8* d) {
|
||||
float ret;
|
||||
u32 inter = (d[0]<<24) | (d[1]<<16) | (d[2]<<8) | d[3];
|
||||
memcpy(&ret, &inter, 4);
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 get_u16(void* vd) {
|
||||
u8 *d = (u8*)vd;
|
||||
return (d[0]<<8) | d[1];
|
||||
}
|
||||
|
||||
void hexdump(u8* d, int l) {
|
||||
int i;
|
||||
for(i=0;i<l;i++) {
|
||||
if(i!=0 && (i%16)==0) ConLog.Write("\n");
|
||||
ConLog.Write("%2.2X ", d[i]);
|
||||
}
|
||||
ConLog.Write("\n");
|
||||
}
|
||||
|
||||
|
||||
void hexdump_nl(u8* d, int l) {
|
||||
int i;
|
||||
for(i=0;i<l;i++) {
|
||||
ConLog.Write("%2.2X ", d[i]);
|
||||
}
|
||||
ConLog.Write("\n");
|
||||
}
|
||||
|
||||
void hexdump_ns(u8* d, int l) {
|
||||
int i;
|
||||
for(i=0;i<l;i++) {
|
||||
ConLog.Write("%2.2X", d[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void hexdump_c(u8* d, int l) {
|
||||
int i;
|
||||
for(i=0;i<l;i++) {
|
||||
ConLog.Write("0x%2.2X", d[i]);
|
||||
if(i!=(l-1)) {
|
||||
ConLog.Write(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hexdump_32(u8* d, int l) {
|
||||
int i;
|
||||
for(i=0;i<l;i+=4) {
|
||||
if(i!=0 && (i%16)==0) printf("\n");
|
||||
ConLog.Write("%8X ", get_u32(d+i));
|
||||
}
|
||||
ConLog.Write("\n");
|
||||
}
|
435
unpkg/unpkg.c
435
unpkg/unpkg.c
@ -1,435 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 Andrey Tolstoy <avtolstoy@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "unpkg.h"
|
||||
#include "ps3_common.h"
|
||||
#include "oddkeys.h"
|
||||
|
||||
#include <wx/progdlg.h> //in a *.c file ?
|
||||
|
||||
static void hash_tostring(char *str, u8 *hash, u32 len)
|
||||
{
|
||||
u8 *p;
|
||||
memset(str, 0, 2*len+1);
|
||||
for (p = hash; p-hash < len; p++)
|
||||
{
|
||||
str += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void *pkg_open(const char *fname)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
f = fopen(fname, "rb");
|
||||
if (f == NULL)
|
||||
{
|
||||
ConLog.Error ("UnPkg: Could not open package file!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
static int pkg_sanity_check(FILE *f, FILE *g, pkg_header **h_ptr, const char *fname)
|
||||
{
|
||||
pkg_header *header = (pkg_header*)malloc(sizeof(pkg_header));
|
||||
u64 tmp;
|
||||
|
||||
if (!fread(header, sizeof(pkg_header), 1, f))
|
||||
{
|
||||
ConLog.Error("UnPkg: Package file is too short!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// some sanity checks
|
||||
|
||||
if (ntohl(header->magic) != PKG_MAGIC)
|
||||
{
|
||||
ConLog.Error("UnPkg: Not a package file!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (ntohl(header->rel_type) >> 16 & (0xffff))
|
||||
{
|
||||
case PKG_RELEASE_TYPE_DEBUG:
|
||||
{
|
||||
ConLog.Warning ("UnPkg: Debug PKG detected.");
|
||||
wxProgressDialog pdlg ("PKG Decrypter / Installer", "Please wait, recrypting...", 0, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL);
|
||||
|
||||
u8* data;
|
||||
u8 sha_key[0x40];
|
||||
int i;
|
||||
f= fopen(fname, "rb");
|
||||
_fseeki64(f, 0, SEEK_END);
|
||||
int nlen = _ftelli64(f);
|
||||
_fseeki64(f, 0, SEEK_SET);
|
||||
data = (u8*)malloc(nlen);
|
||||
fread(data, 1, nlen, f);
|
||||
fclose(f);
|
||||
|
||||
pkg_header2 *header = (pkg_header2 *)data;
|
||||
int data_offset = get_u64(&(header->dataOffset));
|
||||
int data_size = get_u64(&(header->dataSize));
|
||||
|
||||
// decrypt debug
|
||||
u8 sha_crap[0x40];
|
||||
memset(sha_crap, 0, 0x40);
|
||||
memcpy(sha_crap, &data[0x60], 8);
|
||||
memcpy(sha_crap+0x8, &data[0x60], 8);
|
||||
memcpy(sha_crap+0x10, &data[0x68], 8);
|
||||
memcpy(sha_crap+0x18, &data[0x68], 8);
|
||||
|
||||
int dptr;
|
||||
for(dptr = data_offset; dptr < (data_offset+data_size); dptr+=0x10) {
|
||||
u8 hash[0x14];
|
||||
sha1(sha_crap, 0x40, hash);
|
||||
for(i=0;i<0x10;i++) data[dptr+i] ^= hash[i];
|
||||
|
||||
set_u64(sha_crap+0x38, get_u64(sha_crap+0x38)+1);
|
||||
}
|
||||
|
||||
// recrypt retail
|
||||
u8 pkg_key[0x10];
|
||||
memcpy(pkg_key, &data[0x70], 0x10);
|
||||
|
||||
//AES_KEY aes_key;
|
||||
aes_context aes_key;
|
||||
aes_setkey_enc(&aes_key, retail_pkg_aes_key, 128);
|
||||
|
||||
size_t num=0; u8 ecount_buf[0x10]; memset(ecount_buf, 0, 0x10);
|
||||
aes_crypt_ctr(&aes_key, data_size, &num, pkg_key, ecount_buf, &data[data_offset], &data[data_offset]);
|
||||
|
||||
// write back
|
||||
g = fopen(fname, "wb");
|
||||
data[4] = 0x80; // set finalize flag
|
||||
memset(&data[(data_offset+data_size)], 0, 0x60);
|
||||
|
||||
// add hash
|
||||
sha1(data, nlen-0x20, &data[nlen-0x20]);
|
||||
|
||||
fwrite(data, 1, nlen, g);
|
||||
//fclose(g); // not close the file for continuing
|
||||
|
||||
_fseeki64(g, 0, SEEK_END);
|
||||
tmp = _ftelli64(g);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case PKG_RELEASE_TYPE_RELEASE:
|
||||
{
|
||||
ConLog.Warning ("UnPkg: Retail PKG detected.");
|
||||
_fseeki64(f, 0, SEEK_END);
|
||||
tmp = _ftelli64(f);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ConLog.Error("UnPkg: Unknown release type.");
|
||||
return 1;
|
||||
|
||||
|
||||
}
|
||||
switch (ntohl(header->rel_type) & (0xffff))
|
||||
{
|
||||
case PKG_PLATFORM_TYPE_PS3:
|
||||
case PKG_PLATFORM_TYPE_PSP:
|
||||
break;
|
||||
|
||||
default:
|
||||
ConLog.Error("UnPkg: Unknown platform type.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ntohl(header->header_size) != PKG_HEADER_SIZE)
|
||||
{
|
||||
ConLog.Error("UnPkg: Wrong header size: ");
|
||||
return 1;
|
||||
}
|
||||
|
||||
//fseek(g, 0, SEEK_END);
|
||||
//tmp = ftell(g);
|
||||
if (ntohll(header->pkg_size) != tmp)
|
||||
{
|
||||
ConLog.Error("UnPkg: File size mismatch.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
tmp -= ntohll(header->data_offset) + 0x60;
|
||||
if (ntohll(header->data_size) != tmp)
|
||||
{
|
||||
ConLog.Error("UnPkg: Data size mismatch.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (h_ptr != NULL)
|
||||
{
|
||||
(*h_ptr) = (pkg_header*) malloc(sizeof(pkg_header));
|
||||
memcpy(h_ptr, &header, sizeof(pkg_header*));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_pkg_header(pkg_header *header)
|
||||
{
|
||||
char qa[33], kl[33];
|
||||
|
||||
if (header == NULL)
|
||||
return;
|
||||
|
||||
hash_tostring(qa, header->qa_digest, sizeof(header->qa_digest));
|
||||
hash_tostring(kl, header->klicensee, sizeof(header->klicensee));
|
||||
|
||||
ConLog.Write("Magic: 0x%x", ntohl(header->magic));
|
||||
ConLog.Write("Release Type: 0x%x", ntohl(header->rel_type) >> 16 & (0xffff));
|
||||
ConLog.Write("Platform Type: 0x%x", ntohl(header->rel_type) & (0xffff));
|
||||
ConLog.Write("Header size: 0x%x", ntohl(header->header_size));
|
||||
ConLog.Write("Unk1: 0x%x", ntohl(header->unk1));
|
||||
ConLog.Write("Metadata size: 0x%x", ntohl(header->meta_size));
|
||||
ConLog.Write("File count: %u", ntohl(header->file_count));
|
||||
ConLog.Write("Pkg size: %llu", ntohll(header->pkg_size));
|
||||
ConLog.Write("Data offset: 0x%llx", ntohll(header->data_offset));
|
||||
ConLog.Write("Data size: 0x%llu", ntohll(header->data_size));
|
||||
ConLog.Write("TitleID: %s", wxString(header->title_id, 48).wx_str());
|
||||
ConLog.Write("QA Digest: %s", wxString(qa, 33).wx_str());
|
||||
ConLog.Write("KLicensee: %s", wxString(kl, 33).wx_str());
|
||||
}
|
||||
|
||||
static void *pkg_info(const char *fname, pkg_header **h_ptr)
|
||||
{
|
||||
FILE *f;
|
||||
pkg_header *header;
|
||||
|
||||
f = (FILE*) pkg_open(fname);
|
||||
if (f == NULL)
|
||||
return NULL;
|
||||
|
||||
if (pkg_sanity_check(f, NULL, &header, fname))
|
||||
return NULL;
|
||||
|
||||
print_pkg_header(header);
|
||||
|
||||
if (h_ptr != NULL)
|
||||
{
|
||||
(*h_ptr) = header;
|
||||
}
|
||||
else
|
||||
{
|
||||
free(header);
|
||||
}
|
||||
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
static void pkg_crypt(const u8 *key, const u8 *kl, FILE *f,
|
||||
u64 len, FILE *out)
|
||||
{
|
||||
aes_context c;
|
||||
u32 parts, bits;
|
||||
u32 i, j;
|
||||
u8 iv[HASH_LEN];
|
||||
u8 buf[BUF_SIZE];
|
||||
u8 ctr[BUF_SIZE];
|
||||
u8 out_buf[BUF_SIZE];
|
||||
u32 l;
|
||||
u64 hi, lo;
|
||||
|
||||
int max = len / BUF_SIZE;
|
||||
wxProgressDialog pdlg("PKG Decrypter / Installer", "Please wait, decrypting...", max, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL);
|
||||
|
||||
parts = len / BUF_SIZE;
|
||||
if (len % BUF_SIZE != 0)
|
||||
parts++;
|
||||
|
||||
memcpy(iv, kl, sizeof(iv));
|
||||
aes_setkey_enc(&c, key, 128);
|
||||
|
||||
for (i = 0; i<parts; i++)
|
||||
{
|
||||
l = fread(buf, 1, BUF_SIZE, f);
|
||||
bits = l / HASH_LEN;
|
||||
if (bits % HASH_LEN != 0)
|
||||
bits++;
|
||||
|
||||
for (j = 0; j<bits; j++)
|
||||
{
|
||||
aes_crypt_ecb(&c, AES_ENCRYPT, iv, ctr+j*HASH_LEN);
|
||||
|
||||
hi = unpack64(iv);
|
||||
lo = unpack64(iv+8) + 1;
|
||||
if (lo == 0)
|
||||
hi++;
|
||||
pack64(iv, hi);
|
||||
pack64(iv + 8, lo);
|
||||
}
|
||||
|
||||
|
||||
memset(out_buf, 0, sizeof(out_buf));
|
||||
for (j=0; j<l; j++)
|
||||
{
|
||||
out_buf[j] = buf[j] ^ ctr[j];
|
||||
}
|
||||
|
||||
fwrite(out_buf, 1, l, out);
|
||||
pdlg.Update(i);
|
||||
}
|
||||
pdlg.Update(max);
|
||||
}
|
||||
|
||||
static bool pkg_unpack_file(pkg_file_entry *fentry, FILE *dec)
|
||||
{
|
||||
FILE *out = NULL;
|
||||
u64 size;
|
||||
u32 tmp;
|
||||
u8 buf[BUF_SIZE];
|
||||
|
||||
_fseeki64(dec, fentry->name_offset, SEEK_SET);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
fread(buf, fentry->name_size, 1, dec);
|
||||
|
||||
switch (fentry->type & (0xffff))
|
||||
{
|
||||
case PKG_FILE_ENTRY_NPDRM:
|
||||
case PKG_FILE_ENTRY_NPDRMEDAT:
|
||||
case PKG_FILE_ENTRY_SDAT:
|
||||
case PKG_FILE_ENTRY_REGULAR:
|
||||
out = fopen((char *)buf, "wb");
|
||||
_fseeki64(dec, fentry->file_offset, SEEK_SET);
|
||||
for (size = 0; size < fentry->file_size; )
|
||||
{
|
||||
size += fread(buf, sizeof(u8), BUF_SIZE, dec);
|
||||
if (size > fentry->file_size)
|
||||
tmp = size - fentry->file_size;
|
||||
else
|
||||
tmp = 0;
|
||||
|
||||
fwrite(buf, sizeof(u8), BUF_SIZE - tmp, out);
|
||||
}
|
||||
|
||||
fclose(out);
|
||||
break;
|
||||
|
||||
case PKG_FILE_ENTRY_FOLDER:
|
||||
mkdir ((char *)buf);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void pkg_unpack_data(u32 file_count, FILE *dec)
|
||||
{
|
||||
int max = file_count;
|
||||
wxProgressDialog pdlg ("PKG Decrypter / Installer", "Please wait, unpacking...", max, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL);
|
||||
|
||||
u32 i;
|
||||
pkg_file_entry *file_table = NULL;
|
||||
|
||||
_fseeki64(dec, 0, SEEK_SET);
|
||||
|
||||
file_table = (pkg_file_entry *)malloc(sizeof(pkg_file_entry)*file_count);
|
||||
i = fread(file_table, sizeof(pkg_file_entry), file_count, dec);
|
||||
|
||||
if (ntohl(file_table->name_offset) / sizeof(pkg_file_entry) != file_count)
|
||||
{
|
||||
ConLog.Error("UnPkg: ERROR. Impossiburu!");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i<file_count; i++)
|
||||
{
|
||||
(file_table+i)->name_offset = ntohl((file_table+i)->name_offset);
|
||||
(file_table+i)->name_size = ntohl((file_table+i)->name_size);
|
||||
(file_table+i)->file_offset = ntohll((file_table+i)->file_offset);
|
||||
(file_table+i)->file_size = ntohll((file_table+i)->file_size);
|
||||
(file_table+i)->type = ntohl((file_table+i)->type);
|
||||
|
||||
if(pkg_unpack_file(file_table+i, dec)) pdlg.Update(i);
|
||||
}
|
||||
|
||||
free(file_table);
|
||||
pdlg.Update(max);
|
||||
}
|
||||
|
||||
bool pkg_unpack(const char *fname)
|
||||
{
|
||||
FILE *f, *dec;
|
||||
char *dec_fname;
|
||||
pkg_header *header;
|
||||
struct stat sb;
|
||||
|
||||
f = (FILE*) pkg_info(fname, &header);
|
||||
|
||||
if (f == NULL)
|
||||
return false;
|
||||
|
||||
// Save the main dir.
|
||||
wxString mainDir = wxGetCwd();
|
||||
|
||||
// Set the working directory.
|
||||
wxSetWorkingDirectory(wxGetCwd() + "\\dev_hdd0\\game\\");
|
||||
|
||||
std::string gamePath = "\\dev_hdd0\\game\\";
|
||||
|
||||
// Get the PKG title ID from the header and format it (should match TITLE ID from PARAM.SFO).
|
||||
std::string titleID_full (header->title_id);
|
||||
std::string titleID = titleID_full.substr(7, 9);
|
||||
std::string pkgDir = mainDir + gamePath + titleID;
|
||||
|
||||
_fseeki64(f, ntohll(header->data_offset), SEEK_SET);
|
||||
|
||||
dec_fname = (char*)malloc(strlen(fname)+4);
|
||||
memset(dec_fname, 0, strlen(fname)+4);
|
||||
sprintf(dec_fname, "%s.dec", fname);
|
||||
|
||||
dec = fopen(dec_fname, "wb+");
|
||||
if (dec == NULL)
|
||||
{
|
||||
ConLog.Error("UnPkg: Could not create temp file for decrypted data.");
|
||||
free(header);
|
||||
return false;
|
||||
}
|
||||
unlink(dec_fname);
|
||||
|
||||
pkg_crypt(PKG_AES_KEY, header->klicensee, f, ntohll(header->data_size),
|
||||
dec);
|
||||
_fseeki64(dec, 0, SEEK_SET);
|
||||
|
||||
fclose(f);
|
||||
|
||||
if (stat(header->title_id, &sb) != 0)
|
||||
{
|
||||
if (mkdir(titleID.c_str()) < 0)
|
||||
{
|
||||
ConLog.Error("UnPkg: Could not mkdir.");
|
||||
ConLog.Error("UnPkg: Possibly, folder already exists in dev_hdd0\\game : %s", wxString(titleID).wx_str());
|
||||
wxSetWorkingDirectory(mainDir);
|
||||
free(header);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
chdir(titleID.c_str());
|
||||
|
||||
pkg_unpack_data(ntohl(header->file_count), dec);
|
||||
fclose(dec);
|
||||
|
||||
wxSetWorkingDirectory(mainDir);
|
||||
return true;
|
||||
}
|
180
unpkg/unpkg.h
180
unpkg/unpkg.h
@ -1,180 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 Andrey Tolstoy <avtolstoy@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UNPKG_H_
|
||||
#define UNPKG_H_
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "scetool/aes.h"
|
||||
#include "scetool/sha1.h"
|
||||
|
||||
#ifdef __GNUG__
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#define ntohll(x) (((u64) ntohl (x) << 32) | (u64) ntohl (x >> 32) )
|
||||
#define htonll(x) (((u64) htonl (x) << 32) | (u64) htonl (x >> 32) )
|
||||
#define conv_ntohl(x) { x = ntohl(x); }
|
||||
#define conv_ntohll(x) { x = ntohll(x); }
|
||||
#define conv_htonl(x) { x = htonl(x); }
|
||||
#define conv_htonll(x) { x = htonll(x); }
|
||||
|
||||
#define unpack32(x) ((u32) ((u32)*(x) << 24 | \
|
||||
(u32)*(x+1) << 16 | \
|
||||
(u32)*(x+2) << 8 | \
|
||||
(u32)*(x+3) << 0))
|
||||
|
||||
#define unpack64(x) ((u64)unpack32(x) << 32 | (u64)unpack32(x+4))
|
||||
|
||||
#define pack32(x, p) \
|
||||
{ \
|
||||
*(x) = (u8)(p >> 24); \
|
||||
*((x)+1) = (u8)(p >> 16); \
|
||||
*((x)+2) = (u8)(p >> 8); \
|
||||
*((x)+3) = (u8)(p >> 0); \
|
||||
}
|
||||
|
||||
#define pack64(x, p) { pack32((x + 4), p); pack32((x), p >> 32); }
|
||||
|
||||
#define HASH_LEN 16
|
||||
#define BUF_SIZE 4096
|
||||
|
||||
typedef struct {
|
||||
u32 magic; // magic 0x7f504b47
|
||||
u32 rel_type; // release type
|
||||
u32 header_size; // 0xc0
|
||||
u32 unk1; //some pkg version maybe
|
||||
u32 meta_size; //size of metadata (block after header & hashes)
|
||||
u32 file_count; // number of files
|
||||
u64 pkg_size; // pkg size in bytes
|
||||
u64 data_offset; // encrypted data offset
|
||||
u64 data_size; // encrypted data size in bytes
|
||||
char title_id[48]; // title id
|
||||
u8 qa_digest[16]; // this should be the hash of "files + attribs"
|
||||
u8 klicensee[16]; // nonce
|
||||
} pkg_header;
|
||||
|
||||
typedef struct {
|
||||
u8 hash1[16];
|
||||
u8 hash2[16];
|
||||
u8 hash3[16];
|
||||
u8 hash4[16];
|
||||
} pkg_unk_checksum;
|
||||
|
||||
/*
|
||||
is it in meta or sfo?
|
||||
# CATEGORY : HG
|
||||
# BOOTABLE : YES
|
||||
# VERSION : 01.00
|
||||
# APP_VER : 01.00
|
||||
# PS3_SYSTEM_VER : 03.0000
|
||||
*/
|
||||
|
||||
/* meta hell structure */
|
||||
typedef struct {
|
||||
u32 unk1;
|
||||
u32 unk2;
|
||||
u32 drm_type;
|
||||
u32 unk3;
|
||||
|
||||
u32 unk4;
|
||||
u32 unk5;
|
||||
u32 unk6;
|
||||
u32 unk7;
|
||||
|
||||
u32 unk8;
|
||||
u32 unk9;
|
||||
u32 unk10;
|
||||
u32 unk11;
|
||||
|
||||
u32 data_size;
|
||||
u32 unk12;
|
||||
u32 unk13;
|
||||
u32 packager;
|
||||
|
||||
u8 unk14[64];
|
||||
} pkg_meta;
|
||||
|
||||
typedef struct {
|
||||
u32 name_offset; // file name offset
|
||||
u32 name_size; // file name size
|
||||
u64 file_offset; // file offset
|
||||
u64 file_size; // file size
|
||||
u32 type; // file type
|
||||
/*
|
||||
0x80000003 - regular file
|
||||
0x80000001 - npdrm
|
||||
0x80000004 - folder
|
||||
0x80000009 - sdat ?
|
||||
0x80000002 - npdrm.edat ?
|
||||
*/
|
||||
u32 pad; // padding (zeros)
|
||||
} pkg_file_entry;
|
||||
|
||||
typedef struct {
|
||||
pkg_file_entry fe;
|
||||
char *name;
|
||||
char *path;
|
||||
} file_table_tr;
|
||||
|
||||
#define PKG_MAGIC 0x7f504b47 // \x7fPKG
|
||||
#define PKG_HEADER_SIZE sizeof(pkg_header) + sizeof(pkg_unk_checksum)
|
||||
#define PKG_RELEASE_TYPE_RELEASE 0x8000
|
||||
#define PKG_RELEASE_TYPE_DEBUG 0x0000
|
||||
#define PKG_PLATFORM_TYPE_PS3 0x0001
|
||||
#define PKG_PLATFORM_TYPE_PSP 0x0002
|
||||
|
||||
#define PKG_FILE_ENTRY_OVERWRITE 0x80000000
|
||||
#define PKG_FILE_ENTRY_NPDRM 0x0001
|
||||
#define PKG_FILE_ENTRY_NPDRMEDAT 0x0002 // npdrm.edat
|
||||
#define PKG_FILE_ENTRY_REGULAR 0x0003
|
||||
#define PKG_FILE_ENTRY_FOLDER 0x0004
|
||||
#define PKG_FILE_ENTRY_SDAT 0x0009 // .sdat ?
|
||||
|
||||
static const u8 PKG_AES_KEY[16] = {
|
||||
0x2e, 0x7b, 0x71, 0xd7,
|
||||
0xc9, 0xc9, 0xa1, 0x4e,
|
||||
0xa3, 0x22, 0x1f, 0x18,
|
||||
0x88, 0x28, 0xb8, 0xf8
|
||||
};
|
||||
|
||||
static void hash_tostring(char *str, u8 *hash, u32 len);
|
||||
|
||||
static void *pkg_open(const char *fname);
|
||||
|
||||
static int pkg_sanity_check(FILE *f, FILE *g, pkg_header **h_ptr, const char *fname);
|
||||
|
||||
static void print_pkg_header(pkg_header *header);
|
||||
|
||||
static void *pkg_info(const char *fname, pkg_header **h_ptr);
|
||||
|
||||
static void pkg_crypt(const u8 *key, const u8 *kl, FILE *f,
|
||||
u64 len, FILE *out);
|
||||
|
||||
bool pkg_unpack(const char *fname);
|
||||
|
||||
static void pkg_unpack_data(u32 file_count, FILE *dec);
|
||||
|
||||
static bool pkg_unpack_file(pkg_file_entry *fentry, FILE *dec);;
|
||||
|
||||
static int pkg_pack_data(file_table_tr *ftr, pkg_file_entry *table,
|
||||
int file_count, sha1_context *ctx, FILE *out);
|
||||
|
||||
|
||||
static void *pkg_pack_create_filetable(file_table_tr *tr, int file_count,
|
||||
char **n_table, u32 *n_table_len);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user