mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
commit
fd56797b77
29 changed files with 906 additions and 288 deletions
|
@ -6,6 +6,14 @@
|
|||
#define thread_local __thread
|
||||
#endif
|
||||
|
||||
template<size_t size>
|
||||
void strcpy_trunc(char (&dst)[size], const std::string& src)
|
||||
{
|
||||
const size_t count = (src.size() >= size) ? size - 1 /* truncation */ : src.size();
|
||||
memcpy(dst, src.c_str(), count);
|
||||
dst[count] = 0;
|
||||
}
|
||||
|
||||
#if defined(__GNUG__)
|
||||
#include <cmath>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -4,8 +4,6 @@ template<typename T, u32 SQSize = 666>
|
|||
class SQueue
|
||||
{
|
||||
std::mutex m_mutex;
|
||||
NamedThreadBase* push_waiter;
|
||||
NamedThreadBase* pop_waiter;
|
||||
u32 m_pos;
|
||||
u32 m_count;
|
||||
T m_data[SQSize];
|
||||
|
@ -14,8 +12,6 @@ public:
|
|||
SQueue()
|
||||
: m_pos(0)
|
||||
, m_count(0)
|
||||
, push_waiter(nullptr)
|
||||
, pop_waiter(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -26,9 +22,6 @@ public:
|
|||
|
||||
bool Push(const T& data)
|
||||
{
|
||||
NamedThreadBase* t = GetCurrentNamedThread();
|
||||
push_waiter = t;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (m_count >= SQSize)
|
||||
|
@ -46,11 +39,9 @@ public:
|
|||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
if (m_count >= SQSize) continue;
|
||||
if (pop_waiter && !m_count) pop_waiter->Notify();
|
||||
|
||||
m_data[(m_pos + m_count++) % SQSize] = data;
|
||||
|
||||
push_waiter = nullptr;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -58,9 +49,6 @@ public:
|
|||
|
||||
bool Pop(T& data)
|
||||
{
|
||||
NamedThreadBase* t = GetCurrentNamedThread();
|
||||
pop_waiter = t;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!m_count)
|
||||
|
@ -78,43 +66,44 @@ public:
|
|||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
if (!m_count) continue;
|
||||
if (push_waiter && m_count >= SQSize) push_waiter->Notify();
|
||||
|
||||
data = m_data[m_pos];
|
||||
m_pos = (m_pos + 1) % SQSize;
|
||||
m_count--;
|
||||
|
||||
pop_waiter = nullptr;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
volatile u32 GetCount() // may be thread unsafe
|
||||
u32 GetCount()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
return m_count;
|
||||
}
|
||||
|
||||
u32 GetCountUnsafe()
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
volatile bool IsEmpty() // may be thread unsafe
|
||||
bool IsEmpty()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
return !m_count;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (push_waiter && m_count >= SQSize) push_waiter->Notify();
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
T& Peek(u32 pos = 0)
|
||||
{
|
||||
NamedThreadBase* t = GetCurrentNamedThread();
|
||||
pop_waiter = t;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!m_count)
|
||||
if (m_count <= pos)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
|
@ -127,13 +116,27 @@ public:
|
|||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (m_count)
|
||||
if (m_count > pos)
|
||||
{
|
||||
pop_waiter = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_data[(m_pos + pos) % SQSize];
|
||||
}
|
||||
|
||||
T& PeekIfExist(u32 pos = 0)
|
||||
{
|
||||
static T def_value;
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (m_count <= pos)
|
||||
{
|
||||
return def_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_data[(m_pos + pos) % SQSize];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -257,23 +257,38 @@ struct CellAudioInDeviceConfiguration
|
|||
u8 reserved[31];
|
||||
};
|
||||
|
||||
enum CellBgmPlaybackStatusState
|
||||
enum CellSysutilBgmPlaybackStatusState
|
||||
{
|
||||
CELL_BGMPLAYBACK_STATUS_PLAY = 0,
|
||||
CELL_BGMPLAYBACK_STATUS_STOP = 1
|
||||
CELL_SYSUTIL_BGMPLAYBACK_STATUS_PLAY = 0,
|
||||
CELL_SYSUTIL_BGMPLAYBACK_STATUS_STOP = 1
|
||||
};
|
||||
|
||||
enum CellBgmPlaybackStatusEnabled
|
||||
enum CellSysutilBgmPlaybackStatusEnabled
|
||||
{
|
||||
CELL_BGMPLAYBACK_STATUS_ENABLE = 0,
|
||||
CELL_BGMPLAYBACK_STATUS_DISABLE = 1
|
||||
CELL_SYSUTIL_BGMPLAYBACK_STATUS_ENABLE = 0,
|
||||
CELL_SYSUTIL_BGMPLAYBACK_STATUS_DISABLE = 1
|
||||
};
|
||||
|
||||
struct CellBgmPlaybackStatus
|
||||
struct CellSysutilBgmPlaybackStatus
|
||||
{
|
||||
u8 playbackState;
|
||||
u8 enabled;
|
||||
u8 playerState;
|
||||
u8 enableState;
|
||||
char contentId[16];
|
||||
u8 fadeRatio;
|
||||
u8 currentFadeRatio;
|
||||
char reserved[13];
|
||||
};
|
||||
|
||||
struct CellSysutilBgmPlaybackStatus2
|
||||
{
|
||||
u8 playerState;
|
||||
char reserved[7];
|
||||
};
|
||||
|
||||
struct CellSysutilBgmPlaybackExtraParam
|
||||
{
|
||||
be_t<s32> systemBgmFadeInTime;
|
||||
be_t<s32> systemBgmFadeOutTime;
|
||||
be_t<s32> gameBgmFadeInTime;
|
||||
be_t<s32> gameBgmFadeOutTime;
|
||||
char reserved[8];
|
||||
};
|
||||
|
|
|
@ -115,3 +115,8 @@ bool vfsLocalFile::IsOpened() const
|
|||
{
|
||||
return m_file.IsOpened() && vfsFileBase::IsOpened();
|
||||
}
|
||||
|
||||
bool vfsLocalFile::Exists(const std::string& path)
|
||||
{
|
||||
return rFileExists(path);
|
||||
}
|
|
@ -12,6 +12,7 @@ public:
|
|||
virtual bool Open(const std::string& path, vfsOpenMode mode = vfsRead) override;
|
||||
virtual bool Create(const std::string& path) override;
|
||||
virtual bool Close() override;
|
||||
virtual bool Exists(const std::string& path) override;
|
||||
|
||||
virtual u64 GetSize() override;
|
||||
|
||||
|
|
|
@ -623,6 +623,8 @@ enum
|
|||
NV3089_IMAGE_IN_FORMAT = 0x0000C404,
|
||||
NV3089_IMAGE_IN_OFFSET = 0x0000C408,
|
||||
NV3089_IMAGE_IN = 0x0000C40C,
|
||||
|
||||
GCM_SET_USER_COMMAND = 0x0000EB00,
|
||||
};
|
||||
|
||||
static const std::string GetMethodName(const u32 id)
|
||||
|
|
|
@ -355,8 +355,9 @@ bool GLGSRender::LoadProgram()
|
|||
if(m_fp_buf_num == -1)
|
||||
{
|
||||
LOG_WARNING(RSX, "FP not found in buffer!");
|
||||
m_shader_prog.DecompileAsync(*m_cur_shader_prog);
|
||||
m_shader_prog.Wait();
|
||||
//m_shader_prog.DecompileAsync(*m_cur_shader_prog);
|
||||
//m_shader_prog.Wait();
|
||||
m_shader_prog.Decompile(*m_cur_shader_prog);
|
||||
m_shader_prog.Compile();
|
||||
checkForGlError("m_shader_prog.Compile");
|
||||
|
||||
|
@ -367,8 +368,9 @@ bool GLGSRender::LoadProgram()
|
|||
if(m_vp_buf_num == -1)
|
||||
{
|
||||
LOG_WARNING(RSX, "VP not found in buffer!");
|
||||
m_vertex_prog.DecompileAsync(*m_cur_vertex_prog);
|
||||
m_vertex_prog.Wait();
|
||||
//m_vertex_prog.DecompileAsync(*m_cur_vertex_prog);
|
||||
//m_vertex_prog.Wait();
|
||||
m_vertex_prog.Decompile(*m_cur_vertex_prog);
|
||||
m_vertex_prog.Compile();
|
||||
checkForGlError("m_vertex_prog.Compile");
|
||||
|
||||
|
|
|
@ -251,6 +251,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
|
|||
//if(cmd == 0xfeadffff)
|
||||
{
|
||||
Flip();
|
||||
m_last_flip_time = get_system_time();
|
||||
|
||||
m_gcm_current_buffer = ARGS(0);
|
||||
m_read_buffer = true;
|
||||
|
@ -2311,6 +2312,14 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
|
|||
}
|
||||
break;
|
||||
|
||||
case GCM_SET_USER_COMMAND:
|
||||
{
|
||||
const u32 cause = ARGS(0);
|
||||
m_user_handler.Handle(cause);
|
||||
m_user_handler.Branch(false);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
std::string log = GetMethodName(cmd);
|
||||
|
@ -2366,6 +2375,41 @@ void RSXThread::Task()
|
|||
|
||||
OnInitThread();
|
||||
|
||||
m_last_flip_time = get_system_time();
|
||||
volatile bool is_vblank_stopped = false;
|
||||
|
||||
thread vblank("VBlank thread", [&]()
|
||||
{
|
||||
const u64 start_time = get_system_time();
|
||||
|
||||
m_vblank_count = 0;
|
||||
|
||||
while (!TestDestroy())
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
LOG_WARNING(RSX, "VBlank thread aborted");
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_system_time() - start_time > m_vblank_count * 1000000 / 60)
|
||||
{
|
||||
m_vblank_count++;
|
||||
if (m_vblank_handler)
|
||||
{
|
||||
m_vblank_handler.Handle(1);
|
||||
m_vblank_handler.Branch(false);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
is_vblank_stopped = true;
|
||||
});
|
||||
vblank.detach();
|
||||
|
||||
while(!TestDestroy())
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
|
@ -2457,6 +2501,11 @@ void RSXThread::Task()
|
|||
//memset(Memory.GetMemFromAddr(p.m_ioAddress + get), 0, (count + 1) * 4);
|
||||
}
|
||||
|
||||
while (!is_vblank_stopped)
|
||||
{
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
LOG_NOTICE(RSX, "RSX thread ended");
|
||||
|
||||
OnExitThread();
|
||||
|
|
|
@ -151,7 +151,11 @@ public:
|
|||
std::mutex m_cs_main;
|
||||
SSemaphore m_sem_flush;
|
||||
SSemaphore m_sem_flip;
|
||||
u64 m_last_flip_time;
|
||||
Callback m_flip_handler;
|
||||
Callback m_user_handler;
|
||||
u64 m_vblank_count;
|
||||
Callback m_vblank_handler;
|
||||
|
||||
public:
|
||||
// Dither
|
||||
|
|
|
@ -32,7 +32,7 @@ int adecRawRead(void* opaque, u8* buf, int buf_size)
|
|||
next:
|
||||
if (adec.reader.size < (u32)buf_size /*&& !adec.just_started*/)
|
||||
{
|
||||
while (adec.job.IsEmpty())
|
||||
while (!adec.job.GetCountUnsafe())
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
|
@ -45,6 +45,7 @@ next:
|
|||
switch (adec.job.Peek().type)
|
||||
{
|
||||
case adecEndSeq:
|
||||
case adecClose:
|
||||
{
|
||||
buf_size = adec.reader.size;
|
||||
}
|
||||
|
@ -209,7 +210,7 @@ u32 adecOpen(AudioDecoder* data)
|
|||
break;
|
||||
}
|
||||
|
||||
if (adec.job.IsEmpty() && adec.is_running)
|
||||
if (!adec.job.GetCountUnsafe() && adec.is_running)
|
||||
{
|
||||
Sleep(1);
|
||||
continue;
|
||||
|
@ -255,10 +256,8 @@ u32 adecOpen(AudioDecoder* data)
|
|||
cb.Branch(true); // ???*/
|
||||
adec.adecCb->ExecAsCallback(adec.cbFunc, true, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg);
|
||||
|
||||
avcodec_close(adec.ctx);
|
||||
avformat_close_input(&adec.fmt);
|
||||
|
||||
adec.is_running = false;
|
||||
adec.just_finished = true;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -312,7 +311,14 @@ u32 adecOpen(AudioDecoder* data)
|
|||
dump.Close();
|
||||
}*/
|
||||
|
||||
if (adec.just_started) // deferred initialization
|
||||
if (adec.just_started && adec.just_finished)
|
||||
{
|
||||
avcodec_flush_buffers(adec.ctx);
|
||||
adec.reader.init = true;
|
||||
adec.just_finished = false;
|
||||
adec.just_started = false;
|
||||
}
|
||||
else if (adec.just_started) // deferred initialization
|
||||
{
|
||||
err = avformat_open_input(&adec.fmt, NULL, av_find_input_format("oma"), NULL);
|
||||
if (err)
|
||||
|
@ -353,7 +359,7 @@ u32 adecOpen(AudioDecoder* data)
|
|||
av_dict_set(&opts, "refcounted_frames", "1", 0);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_mutex_avcodec_open2);
|
||||
// not multithread-safe
|
||||
// not multithread-safe (???)
|
||||
err = avcodec_open2(adec.ctx, codec, &opts);
|
||||
}
|
||||
if (err)
|
||||
|
@ -605,7 +611,7 @@ int cellAdecClose(u32 handle)
|
|||
|
||||
adec->job.Push(AdecTask(adecClose));
|
||||
|
||||
while (!adec->is_finished || !adec->frames.IsEmpty())
|
||||
while (!adec->is_finished)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
|
@ -789,13 +795,14 @@ int cellAdecGetPcmItem(u32 handle, mem32_t pcmItem_ptr)
|
|||
return CELL_ADEC_ERROR_FATAL;
|
||||
}
|
||||
|
||||
AdecFrame& af = adec->frames.Peek();
|
||||
|
||||
if (adec->frames.IsEmpty())
|
||||
{
|
||||
Sleep(1); // hack
|
||||
return CELL_ADEC_ERROR_EMPTY;
|
||||
}
|
||||
|
||||
AdecFrame& af = adec->frames.Peek();
|
||||
|
||||
AVFrame* frame = af.data;
|
||||
|
||||
mem_ptr_t<CellAdecPcmItem> pcm(adec->memAddr + adec->memBias);
|
||||
|
|
|
@ -1076,6 +1076,7 @@ public:
|
|||
volatile bool is_running;
|
||||
volatile bool is_finished;
|
||||
bool just_started;
|
||||
bool just_finished;
|
||||
|
||||
AVCodecContext* ctx;
|
||||
AVFormatContext* fmt;
|
||||
|
@ -1127,6 +1128,7 @@ public:
|
|||
, is_running(false)
|
||||
, is_finished(false)
|
||||
, just_started(false)
|
||||
, just_finished(false)
|
||||
, ctx(nullptr)
|
||||
, fmt(nullptr)
|
||||
{
|
||||
|
@ -1156,6 +1158,7 @@ public:
|
|||
|
||||
~AudioDecoder()
|
||||
{
|
||||
// TODO: check finalization
|
||||
if (ctx)
|
||||
{
|
||||
for (u32 i = frames.GetCount() - 1; ~i; i--)
|
||||
|
|
|
@ -71,7 +71,7 @@ u32 dmuxOpen(Demuxer* data)
|
|||
break;
|
||||
}
|
||||
|
||||
if (dmux.job.IsEmpty() && dmux.is_running)
|
||||
if (!dmux.job.GetCountUnsafe() && dmux.is_running)
|
||||
{
|
||||
// default task (demuxing) (if there is no other work)
|
||||
be_t<u32> code;
|
||||
|
@ -145,22 +145,20 @@ u32 dmuxOpen(Demuxer* data)
|
|||
if (esATX[ch])
|
||||
{
|
||||
ElementaryStream& es = *esATX[ch];
|
||||
while (es.isfull())
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
LOG_WARNING(HLE, "esATX[%d] was full, waiting aborted", ch);
|
||||
return;
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
if (es.hasunseen()) // hack, probably useless
|
||||
if (es.isfull())
|
||||
{
|
||||
stream = backup;
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*if (es.hasunseen()) // hack, probably useless
|
||||
{
|
||||
stream = backup;
|
||||
Sleep(1);
|
||||
continue;
|
||||
}*/
|
||||
|
||||
stream.skip(4);
|
||||
len -= 4;
|
||||
|
||||
|
@ -194,14 +192,10 @@ u32 dmuxOpen(Demuxer* data)
|
|||
if (esAVC[ch])
|
||||
{
|
||||
ElementaryStream& es = *esAVC[ch];
|
||||
while (es.isfull())
|
||||
if (es.isfull())
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
LOG_WARNING(HLE, "esAVC[%d] was full, waiting aborted", ch);
|
||||
return;
|
||||
}
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
DemuxerStream backup = stream;
|
||||
|
@ -217,11 +211,12 @@ u32 dmuxOpen(Demuxer* data)
|
|||
|
||||
if (pes.new_au && es.hasdata()) // new AU detected
|
||||
{
|
||||
if (es.hasunseen()) // hack, probably useless
|
||||
/*if (es.hasunseen()) // hack, probably useless
|
||||
{
|
||||
stream = backup;
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
}*/
|
||||
es.finish(stream);
|
||||
// callback
|
||||
mem_ptr_t<CellDmuxEsMsg> esMsg(a128(dmux.memAddr) + (cb_add ^= 16));
|
||||
|
@ -242,6 +237,7 @@ u32 dmuxOpen(Demuxer* data)
|
|||
if (es.isfull())
|
||||
{
|
||||
stream = backup;
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,178 +10,320 @@
|
|||
|
||||
#include "Loader/PSF.h"
|
||||
|
||||
#include "cellGame.h"
|
||||
|
||||
//void cellGame_init();
|
||||
//Module cellGame(0x003e, cellGame_init);
|
||||
extern Module *cellGame = nullptr;
|
||||
|
||||
// Return Codes
|
||||
enum
|
||||
{
|
||||
CELL_GAME_RET_OK = 0,
|
||||
CELL_GAME_RET_CANCEL = 1,
|
||||
CELL_GAME_RET_NONE = 2,
|
||||
CELL_GAME_ERROR_NOTFOUND = 0x8002cb04,
|
||||
CELL_GAME_ERROR_BROKEN = 0x8002cb05,
|
||||
CELL_GAME_ERROR_INTERNAL = 0x8002cb06,
|
||||
CELL_GAME_ERROR_PARAM = 0x8002cb07,
|
||||
CELL_GAME_ERROR_NOAPP = 0x8002cb08,
|
||||
CELL_GAME_ERROR_ACCESS_ERROR = 0x8002cb09,
|
||||
CELL_GAME_ERROR_NOSPACE = 0x8002cb20,
|
||||
CELL_GAME_ERROR_NOTSUPPORTED = 0x8002cb21,
|
||||
CELL_GAME_ERROR_FAILURE = 0x8002cb22,
|
||||
CELL_GAME_ERROR_BUSY = 0x8002cb23,
|
||||
CELL_GAME_ERROR_IN_SHUTDOWN = 0x8002cb24,
|
||||
CELL_GAME_ERROR_INVALID_ID = 0x8002cb25,
|
||||
CELL_GAME_ERROR_EXIST = 0x8002cb26,
|
||||
CELL_GAME_ERROR_NOTPATCH = 0x8002cb27,
|
||||
CELL_GAME_ERROR_INVALID_THEME_FILE = 0x8002cb28,
|
||||
CELL_GAME_ERROR_BOOTPATH = 0x8002cb50,
|
||||
};
|
||||
|
||||
// Definitions
|
||||
enum
|
||||
{
|
||||
CELL_GAME_PATH_MAX = 128,
|
||||
CELL_GAME_DIRNAME_SIZE = 32,
|
||||
CELL_GAME_THEMEFILENAME_SIZE = 48,
|
||||
CELL_GAME_SYSP_TITLE_SIZE = 128,
|
||||
CELL_GAME_SYSP_TITLEID_SIZE = 10,
|
||||
CELL_GAME_SYSP_VERSION_SIZE = 6,
|
||||
CELL_GAME_SYSP_APP_VER_SIZE = 6,
|
||||
|
||||
CELL_GAME_GAMETYPE_DISC = 1,
|
||||
CELL_GAME_GAMETYPE_HDD = 2,
|
||||
|
||||
CELL_GAME_SIZEKB_NOTCALC = -1,
|
||||
|
||||
CELL_GAME_ATTRIBUTE_PATCH = 0x1,
|
||||
CELL_GAME_ATTRIBUTE_APP_HOME = 0x2,
|
||||
CELL_GAME_ATTRIBUTE_DEBUG = 0x4,
|
||||
CELL_GAME_ATTRIBUTE_XMBBUY = 0x8,
|
||||
CELL_GAME_ATTRIBUTE_COMMERCE2_BROWSER = 0x10,
|
||||
CELL_GAME_ATTRIBUTE_INVITE_MESSAGE = 0x20,
|
||||
CELL_GAME_ATTRIBUTE_CUSTOM_DATA_MESSAGE = 0x40,
|
||||
CELL_GAME_ATTRIBUTE_WEB_BROWSER = 0x100,
|
||||
};
|
||||
|
||||
//Parameter IDs of PARAM.SFO
|
||||
enum
|
||||
{
|
||||
//Integers
|
||||
CELL_GAME_PARAMID_PARENTAL_LEVEL = 102,
|
||||
CELL_GAME_PARAMID_RESOLUTION = 103,
|
||||
CELL_GAME_PARAMID_SOUND_FORMAT = 104,
|
||||
|
||||
//Strings
|
||||
CELL_GAME_PARAMID_TITLE = 0,
|
||||
CELL_GAME_PARAMID_TITLE_DEFAULT = 1,
|
||||
CELL_GAME_PARAMID_TITLE_JAPANESE = 2,
|
||||
CELL_GAME_PARAMID_TITLE_ENGLISH = 3,
|
||||
CELL_GAME_PARAMID_TITLE_FRENCH = 4,
|
||||
CELL_GAME_PARAMID_TITLE_SPANISH = 5,
|
||||
CELL_GAME_PARAMID_TITLE_GERMAN = 6,
|
||||
CELL_GAME_PARAMID_TITLE_ITALIAN = 7,
|
||||
CELL_GAME_PARAMID_TITLE_DUTCH = 8,
|
||||
CELL_GAME_PARAMID_TITLE_PORTUGUESE = 9,
|
||||
CELL_GAME_PARAMID_TITLE_RUSSIAN = 10,
|
||||
CELL_GAME_PARAMID_TITLE_KOREAN = 11,
|
||||
CELL_GAME_PARAMID_TITLE_CHINESE_T = 12,
|
||||
CELL_GAME_PARAMID_TITLE_CHINESE_S = 13,
|
||||
CELL_GAME_PARAMID_TITLE_FINNISH = 14,
|
||||
CELL_GAME_PARAMID_TITLE_SWEDISH = 15,
|
||||
CELL_GAME_PARAMID_TITLE_DANISH = 16,
|
||||
CELL_GAME_PARAMID_TITLE_NORWEGIAN = 17,
|
||||
CELL_GAME_PARAMID_TITLE_POLISH = 18,
|
||||
CELL_GAME_PARAMID_TITLE_PORTUGUESE_BRAZIL = 19,
|
||||
CELL_GAME_PARAMID_TITLE_ENGLISH_UK = 20,
|
||||
CELL_GAME_PARAMID_TITLE_ID = 100,
|
||||
CELL_GAME_PARAMID_VERSION = 101,
|
||||
CELL_GAME_PARAMID_APP_VER = 106,
|
||||
};
|
||||
|
||||
//Error dialog types
|
||||
enum
|
||||
{
|
||||
CELL_GAME_ERRDIALOG_BROKEN_GAMEDATA = 0,
|
||||
CELL_GAME_ERRDIALOG_BROKEN_HDDGAME = 1,
|
||||
CELL_GAME_ERRDIALOG_NOSPACE = 2,
|
||||
CELL_GAME_ERRDIALOG_BROKEN_EXIT_GAMEDATA = 100,
|
||||
CELL_GAME_ERRDIALOG_BROKEN_EXIT_HDDGAME = 101,
|
||||
CELL_GAME_ERRDIALOG_NOSPACE_EXIT = 102,
|
||||
};
|
||||
|
||||
struct CellGameContentSize
|
||||
{
|
||||
be_t<s32> hddFreeSizeKB;
|
||||
be_t<s32> sizeKB;
|
||||
be_t<s32> sysSizeKB;
|
||||
};
|
||||
std::string contentInfo = "";
|
||||
std::string usrdir = "";
|
||||
|
||||
int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_t<CellGameContentSize> size, mem_list_ptr_t<u8> dirName)
|
||||
{
|
||||
cellGame->Warning("cellGameBootCheck(type_addr=0x%x, attributes_addr=0x%x, size_addr=0x%x, dirName_addr=0x%x)",
|
||||
type.GetAddr(), attributes.GetAddr(), size.GetAddr(), dirName.GetAddr());
|
||||
|
||||
if (!type.IsGood() || !attributes.IsGood() || !size.IsGood() || !dirName.IsGood())
|
||||
if (!type.IsGood() || !attributes.IsGood() || !size.IsGood() || (dirName.GetAddr() && !dirName.IsGood()))
|
||||
{
|
||||
cellGame->Warning("cellGameBootCheck returns CELL_GAME_ERROR_PARAM. As a result size->hddFreeSizeKB may be 0.");
|
||||
cellGame->Error("cellGameBootCheck(): CELL_GAME_ERROR_PARAM");
|
||||
return CELL_GAME_ERROR_PARAM;
|
||||
}
|
||||
|
||||
// TODO: Only works for HDD games
|
||||
type = CELL_GAME_GAMETYPE_HDD;
|
||||
attributes = 0;
|
||||
size->hddFreeSizeKB = 40000000; //40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run.
|
||||
size->sizeKB = CELL_GAME_SIZEKB_NOTCALC;
|
||||
size->sysSizeKB = 0;
|
||||
// TODO: Use the free space of the computer's HDD where RPCS3 is being run.
|
||||
size->hddFreeSizeKB = 40000000; // 40 GB
|
||||
|
||||
// TODO: Calculate data size for HG and DG games, if necessary.
|
||||
size->sizeKB = CELL_GAME_SIZEKB_NOTCALC;
|
||||
size->sysSizeKB = 0;
|
||||
|
||||
// TODO: Locate the PARAM.SFO. The following path may be wrong.
|
||||
vfsFile f("/app_home/PARAM.SFO");
|
||||
if (!f.IsOpened())
|
||||
{
|
||||
cellGame->Error("cellGameBootCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot open PARAM.SFO)");
|
||||
return CELL_GAME_ERROR_ACCESS_ERROR;
|
||||
}
|
||||
|
||||
PSFLoader psf(f);
|
||||
if(!psf.Load(false))
|
||||
if (!psf.Load(false))
|
||||
{
|
||||
cellGame->Error("cellGameBootCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot read PARAM.SFO)");
|
||||
return CELL_GAME_ERROR_ACCESS_ERROR;
|
||||
}
|
||||
|
||||
std::string category = psf.GetString("CATEGORY");
|
||||
if (category.substr(0, 2) == "DG")
|
||||
{
|
||||
type = CELL_GAME_GAMETYPE_DISC;
|
||||
attributes = 0; // TODO
|
||||
if (dirName.GetAddr()) Memory.WriteString(dirName.GetAddr(), ""); // ???
|
||||
contentInfo = "/dev_bdvd/PS3_GAME";
|
||||
usrdir = "/dev_bdvd/PS3_GAME/USRDIR";
|
||||
}
|
||||
else if (category.substr(0, 2) == "HG")
|
||||
{
|
||||
std::string titleId = psf.GetString("TITLE_ID");
|
||||
type = CELL_GAME_GAMETYPE_HDD;
|
||||
attributes = 0; // TODO
|
||||
if (dirName.GetAddr()) Memory.WriteString(dirName.GetAddr(), titleId);
|
||||
contentInfo = "/dev_hdd0/game/" + titleId;
|
||||
usrdir = "/dev_hdd0/game/" + titleId + "/USRDIR";
|
||||
}
|
||||
else if (category.substr(0, 2) == "GD")
|
||||
{
|
||||
std::string titleId = psf.GetString("TITLE_ID");
|
||||
type = CELL_GAME_GAMETYPE_DISC;
|
||||
attributes = CELL_GAME_ATTRIBUTE_PATCH; // TODO
|
||||
if (dirName.GetAddr()) Memory.WriteString(dirName.GetAddr(), titleId); // ???
|
||||
contentInfo = "/dev_bdvd/PS3_GAME";
|
||||
usrdir = "/dev_bdvd/PS3_GAME/USRDIR";
|
||||
}
|
||||
else
|
||||
{
|
||||
cellGame->Error("cellGameBootCheck(): CELL_GAME_ERROR_FAILURE (unknown CATEGORY)");
|
||||
return CELL_GAME_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return CELL_GAME_RET_OK;
|
||||
}
|
||||
|
||||
int cellGamePatchCheck(mem_ptr_t<CellGameContentSize> size, u32 reserved_addr)
|
||||
{
|
||||
cellGame->Warning("cellGamePatchCheck(size_addr=0x%x, reserved_addr=0x%x)", size.GetAddr(), reserved_addr);
|
||||
|
||||
if (!size.IsGood() || reserved_addr != 0)
|
||||
{
|
||||
cellGame->Error("cellGamePatchCheck(): CELL_GAME_ERROR_PARAM");
|
||||
return CELL_GAME_ERROR_PARAM;
|
||||
}
|
||||
|
||||
// TODO: Use the free space of the computer's HDD where RPCS3 is being run.
|
||||
size->hddFreeSizeKB = 40000000; // 40 GB
|
||||
|
||||
// TODO: Calculate data size for patch data, if necessary.
|
||||
size->sizeKB = CELL_GAME_SIZEKB_NOTCALC;
|
||||
size->sysSizeKB = 0;
|
||||
|
||||
vfsFile f("/app_home/PARAM.SFO");
|
||||
if (!f.IsOpened())
|
||||
{
|
||||
cellGame->Error("cellGamePatchCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot open PARAM.SFO)");
|
||||
return CELL_GAME_ERROR_ACCESS_ERROR;
|
||||
}
|
||||
|
||||
PSFLoader psf(f);
|
||||
if (!psf.Load(false))
|
||||
{
|
||||
cellGame->Error("cellGamePatchCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot read PARAM.SFO)");
|
||||
return CELL_GAME_ERROR_ACCESS_ERROR;
|
||||
}
|
||||
|
||||
std::string category = psf.GetString("CATEGORY");
|
||||
if (category.substr(0, 2) != "GD")
|
||||
{
|
||||
cellGame->Error("cellGamePatchCheck(): CELL_GAME_ERROR_NOTPATCH");
|
||||
return CELL_GAME_ERROR_NOTPATCH;
|
||||
}
|
||||
|
||||
std::string titleId = psf.GetString("TITLE_ID");
|
||||
|
||||
Memory.WriteString(dirName.GetAddr(), titleId);
|
||||
return CELL_OK;
|
||||
contentInfo = "/dev_hdd0/game/" + titleId;
|
||||
usrdir = "/dev_hdd0/game/" + titleId + "/USRDIR";
|
||||
|
||||
return CELL_GAME_RET_OK;
|
||||
}
|
||||
|
||||
int cellGamePatchCheck()
|
||||
int cellGameDataCheck(u32 type, const mem_list_ptr_t<u8> dirName, mem_ptr_t<CellGameContentSize> size)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellGame);
|
||||
return CELL_OK;
|
||||
cellGame->Warning("cellGameDataCheck(type=0x%x, dirName_addr=0x%x, size_addr=0x%x)", type, dirName.GetAddr(), size.GetAddr());
|
||||
|
||||
if ((type - 1) >= 3 || !size.IsGood() || !dirName.IsGood())
|
||||
{
|
||||
cellGame->Error("cellGameDataCheck(): CELL_GAME_ERROR_PARAM");
|
||||
return CELL_GAME_ERROR_PARAM;
|
||||
}
|
||||
|
||||
// TODO: Use the free space of the computer's HDD where RPCS3 is being run.
|
||||
size->hddFreeSizeKB = 40000000; //40 GB
|
||||
|
||||
// TODO: Calculate data size for game data, if necessary.
|
||||
size->sizeKB = CELL_GAME_SIZEKB_NOTCALC;
|
||||
size->sysSizeKB = 0;
|
||||
|
||||
if (type == CELL_GAME_GAMETYPE_DISC)
|
||||
{
|
||||
// TODO: not sure what should be checked there
|
||||
|
||||
if (!Emu.GetVFS().ExistsDir("/dev_bdvd/PS3_GAME"))
|
||||
{
|
||||
cellGame->Warning("cellGameDataCheck(): /dev_bdvd/PS3_GAME not found");
|
||||
return CELL_GAME_RET_NONE;
|
||||
}
|
||||
contentInfo = "/dev_bdvd/PS3_GAME";
|
||||
usrdir = "/dev_bdvd/PS3_GAME/USRDIR";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string dir = "/dev_hdd0/game/" + std::string(dirName.GetString());
|
||||
|
||||
if (!Emu.GetVFS().ExistsDir(dir))
|
||||
{
|
||||
cellGame->Warning("cellGameDataCheck(): '%s' directory not found", dir.c_str());
|
||||
return CELL_GAME_RET_NONE;
|
||||
}
|
||||
contentInfo = dir;
|
||||
usrdir = dir + "/USRDIR";
|
||||
}
|
||||
|
||||
return CELL_GAME_RET_OK;
|
||||
}
|
||||
|
||||
int cellGameDataCheck()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellGame);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellGameContentPermit(mem_list_ptr_t<u8> contentInfoPath, mem_list_ptr_t<u8> usrdirPath)
|
||||
int cellGameContentPermit(mem_list_ptr_t<u8> contentInfoPath, mem_list_ptr_t<u8> usrdirPath)
|
||||
{
|
||||
cellGame->Warning("cellGameContentPermit(contentInfoPath_addr=0x%x, usrdirPath_addr=0x%x)",
|
||||
contentInfoPath.GetAddr(), usrdirPath.GetAddr());
|
||||
|
||||
if (!contentInfoPath.IsGood() || !usrdirPath.IsGood())
|
||||
{
|
||||
cellGame->Error("cellGameContentPermit(): CELL_GAME_ERROR_PARAM");
|
||||
return CELL_GAME_ERROR_PARAM;
|
||||
|
||||
// TODO: Locate the PARAM.SFO. The following path may be wrong.
|
||||
vfsFile f("/app_home/PARAM.SFO");
|
||||
PSFLoader psf(f);
|
||||
if(!psf.Load(false))
|
||||
return CELL_GAME_ERROR_FAILURE;
|
||||
std::string titleId = psf.GetString("TITLE_ID");
|
||||
}
|
||||
|
||||
// TODO: Only works for HDD games
|
||||
Memory.WriteString(contentInfoPath.GetAddr(), "/dev_hdd0/game/"+titleId);
|
||||
Memory.WriteString(usrdirPath.GetAddr(), "/dev_hdd0/game/"+titleId+"/USRDIR");
|
||||
return CELL_OK;
|
||||
if (contentInfo == "" && usrdir == "")
|
||||
{
|
||||
cellGame->Warning("cellGameContentPermit(): CELL_GAME_ERROR_FAILURE (no permission given)");
|
||||
return CELL_GAME_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// TODO: make it better
|
||||
Memory.WriteString(contentInfoPath.GetAddr(), contentInfo);
|
||||
Memory.WriteString(usrdirPath.GetAddr(), usrdir);
|
||||
|
||||
contentInfo = "";
|
||||
usrdir = "";
|
||||
|
||||
return CELL_GAME_RET_OK;
|
||||
}
|
||||
|
||||
int cellGameCreateGameData()
|
||||
int cellGameDataCheckCreate2(u32 version, const mem_list_ptr_t<u8> dirName, u32 errDialog,
|
||||
mem_func_ptr_t<void(*)(mem_ptr_t<CellGameDataCBResult> cbResult, mem_ptr_t<CellGameDataStatGet> get, mem_ptr_t<CellGameDataStatSet> set)> funcStat, u32 container)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellGame);
|
||||
cellGame->Warning("cellGameDataCheckCreate2(version=0x%x, dirName_addr=0x%x, errDialog=0x%x, funcStat_addr=0x%x, container=%d)",
|
||||
version, dirName.GetAddr(), errDialog, funcStat.GetAddr(), container);
|
||||
|
||||
if (version != CELL_GAMEDATA_VERSION_CURRENT || !dirName.IsGood() || errDialog > 1 || !funcStat.IsGood())
|
||||
{
|
||||
cellGame->Error("cellGameDataCheckCreate2(): CELL_GAMEDATA_ERROR_PARAM");
|
||||
return CELL_GAMEDATA_ERROR_PARAM;
|
||||
}
|
||||
|
||||
// TODO: output errors (errDialog)
|
||||
|
||||
const std::string dir = "/dev_hdd0/game/" + std::string(dirName.GetString());
|
||||
|
||||
if (!Emu.GetVFS().ExistsDir(dir))
|
||||
{
|
||||
cellGame->Error("cellGameDataCheckCreate2(): TODO: creating directory '%s'", dir.c_str());
|
||||
// TODO: create data
|
||||
return CELL_GAMEDATA_RET_OK;
|
||||
}
|
||||
|
||||
vfsFile f(dir + "/PARAM.SFO");
|
||||
if (!f.IsOpened())
|
||||
{
|
||||
cellGame->Error("cellGameDataCheckCreate2(): CELL_GAMEDATA_ERROR_BROKEN (cannot open PARAM.SFO)");
|
||||
return CELL_GAMEDATA_ERROR_BROKEN;
|
||||
}
|
||||
|
||||
PSFLoader psf(f);
|
||||
if (!psf.Load(false))
|
||||
{
|
||||
cellGame->Error("cellGameDataCheckCreate2(): CELL_GAMEDATA_ERROR_BROKEN (cannot read PARAM.SFO)");
|
||||
return CELL_GAMEDATA_ERROR_BROKEN;
|
||||
}
|
||||
|
||||
// TODO: use memory container
|
||||
MemoryAllocator<CellGameDataCBResult> cbResult;
|
||||
MemoryAllocator<CellGameDataStatGet> cbGet;
|
||||
MemoryAllocator<CellGameDataStatSet> cbSet;
|
||||
|
||||
memset(cbGet.GetPtr(), 0, sizeof(CellGameDataStatGet));
|
||||
|
||||
// TODO: Use the free space of the computer's HDD where RPCS3 is being run.
|
||||
cbGet->hddFreeSizeKB = 40000000; //40 GB
|
||||
|
||||
cbGet->isNewData = CELL_GAMEDATA_ISNEWDATA_NO;
|
||||
strcpy_trunc(cbGet->contentInfoPath, dir);
|
||||
strcpy_trunc(cbGet->gameDataPath, dir + "/USRDIR");
|
||||
|
||||
// TODO: set correct time
|
||||
cbGet->st_atime_ = 0;
|
||||
cbGet->st_ctime_ = 0;
|
||||
cbGet->st_mtime_ = 0;
|
||||
|
||||
// TODO: calculate data size, if necessary
|
||||
cbGet->sizeKB = CELL_GAMEDATA_SIZEKB_NOTCALC;
|
||||
cbGet->sysSizeKB = 0;
|
||||
|
||||
cbGet->getParam.attribute = CELL_GAMEDATA_ATTR_NORMAL;
|
||||
cbGet->getParam.parentalLevel = psf.GetInteger("PARENTAL_LEVEL");
|
||||
strcpy_trunc(cbGet->getParam.dataVersion, psf.GetString("APP_VER"));
|
||||
strcpy_trunc(cbGet->getParam.titleId, psf.GetString("TITLE_ID"));
|
||||
strcpy_trunc(cbGet->getParam.title, psf.GetString("TITLE"));
|
||||
// TODO: write lang titles
|
||||
|
||||
funcStat(cbResult.GetAddr(), cbGet.GetAddr(), cbSet.GetAddr());
|
||||
|
||||
if (cbSet->setParam.GetAddr())
|
||||
{
|
||||
// TODO: write PARAM.SFO from cbSet
|
||||
cellGame->Error("cellGameDataCheckCreate2(): TODO: writing PARAM.SFO parameters (addr=0x%x)", cbSet->setParam.GetAddr());
|
||||
}
|
||||
|
||||
switch ((s32)cbResult->result)
|
||||
{
|
||||
case CELL_GAMEDATA_CBRESULT_OK_CANCEL:
|
||||
// TODO: do not process game data
|
||||
cellGame->Warning("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_OK_CANCEL");
|
||||
|
||||
case CELL_GAMEDATA_CBRESULT_OK:
|
||||
return CELL_GAMEDATA_RET_OK;
|
||||
|
||||
case CELL_GAMEDATA_CBRESULT_ERR_NOSPACE: // TODO: process errors, error message and needSizeKB result
|
||||
cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NOSPACE");
|
||||
return CELL_GAMEDATA_ERROR_CBRESULT;
|
||||
|
||||
case CELL_GAMEDATA_CBRESULT_ERR_BROKEN:
|
||||
cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_BROKEN");
|
||||
return CELL_GAMEDATA_ERROR_CBRESULT;
|
||||
|
||||
case CELL_GAMEDATA_CBRESULT_ERR_NODATA:
|
||||
cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NODATA");
|
||||
return CELL_GAMEDATA_ERROR_CBRESULT;
|
||||
|
||||
case CELL_GAMEDATA_CBRESULT_ERR_INVALID:
|
||||
cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_INVALID");
|
||||
return CELL_GAMEDATA_ERROR_CBRESULT;
|
||||
|
||||
default:
|
||||
cellGame->Error("cellGameDataCheckCreate2(): callback returned unknown error (code=0x%x)");
|
||||
return CELL_GAMEDATA_ERROR_CBRESULT;
|
||||
}
|
||||
}
|
||||
|
||||
int cellGameDataCheckCreate(u32 version, const mem_list_ptr_t<u8> dirName, u32 errDialog,
|
||||
mem_func_ptr_t<void(*)(mem_ptr_t<CellGameDataCBResult> cbResult, mem_ptr_t<CellGameDataStatGet> get, mem_ptr_t<CellGameDataStatSet> set)> funcStat, u32 container)
|
||||
{
|
||||
// TODO: almost identical, the only difference is that this function will always calculate the size of game data
|
||||
return cellGameDataCheckCreate2(version, dirName, errDialog, funcStat, container);
|
||||
}
|
||||
|
||||
int cellGameCreateGameData(mem_ptr_t<CellGameSetInitParams> init, mem_list_ptr_t<u8> tmp_contentInfoPath, mem_list_ptr_t<u8> tmp_usrdirPath)
|
||||
{
|
||||
cellGame->Error("cellGameCreateGameData(init_addr=0x%x, tmp_contentInfoPath_addr=0x%x, tmp_usrdirPath_addr=0x%x)",
|
||||
init.GetAddr(), tmp_contentInfoPath.GetAddr(), tmp_usrdirPath.GetAddr());
|
||||
|
||||
// TODO: create temporary game directory, set initial PARAM.SFO parameters
|
||||
// cellGameContentPermit should then move files in non-temporary location and return their non-temporary displacement
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -198,7 +340,7 @@ int cellGameGetParamInt(u32 id, mem32_t value)
|
|||
if(!value.IsGood())
|
||||
return CELL_GAME_ERROR_PARAM;
|
||||
|
||||
// TODO: Locate the PARAM.SFO. The following path may be wrong.
|
||||
// TODO: Access through cellGame***Check functions
|
||||
vfsFile f("/app_home/PARAM.SFO");
|
||||
PSFLoader psf(f);
|
||||
if(!psf.Load(false))
|
||||
|
@ -224,7 +366,7 @@ int cellGameGetParamString(u32 id, u32 buf_addr, u32 bufsize)
|
|||
if(!Memory.IsGoodAddr(buf_addr))
|
||||
return CELL_GAME_ERROR_PARAM;
|
||||
|
||||
// TODO: Locate the PARAM.SFO. The following path may be wrong.
|
||||
// TODO: Access through cellGame***Check functions
|
||||
vfsFile f("/app_home/PARAM.SFO");
|
||||
PSFLoader psf(f);
|
||||
if(!psf.Load(false))
|
||||
|
|
202
rpcs3/Emu/SysCalls/Modules/cellGame.h
Normal file
202
rpcs3/Emu/SysCalls/Modules/cellGame.h
Normal file
|
@ -0,0 +1,202 @@
|
|||
#pragma once
|
||||
|
||||
// Return Codes
|
||||
enum
|
||||
{
|
||||
CELL_GAME_RET_OK = 0,
|
||||
CELL_GAME_RET_CANCEL = 1,
|
||||
CELL_GAME_RET_NONE = 2,
|
||||
CELL_GAME_ERROR_NOTFOUND = 0x8002cb04,
|
||||
CELL_GAME_ERROR_BROKEN = 0x8002cb05,
|
||||
CELL_GAME_ERROR_INTERNAL = 0x8002cb06,
|
||||
CELL_GAME_ERROR_PARAM = 0x8002cb07,
|
||||
CELL_GAME_ERROR_NOAPP = 0x8002cb08,
|
||||
CELL_GAME_ERROR_ACCESS_ERROR = 0x8002cb09,
|
||||
CELL_GAME_ERROR_NOSPACE = 0x8002cb20,
|
||||
CELL_GAME_ERROR_NOTSUPPORTED = 0x8002cb21,
|
||||
CELL_GAME_ERROR_FAILURE = 0x8002cb22,
|
||||
CELL_GAME_ERROR_BUSY = 0x8002cb23,
|
||||
CELL_GAME_ERROR_IN_SHUTDOWN = 0x8002cb24,
|
||||
CELL_GAME_ERROR_INVALID_ID = 0x8002cb25,
|
||||
CELL_GAME_ERROR_EXIST = 0x8002cb26,
|
||||
CELL_GAME_ERROR_NOTPATCH = 0x8002cb27,
|
||||
CELL_GAME_ERROR_INVALID_THEME_FILE = 0x8002cb28,
|
||||
CELL_GAME_ERROR_BOOTPATH = 0x8002cb50,
|
||||
};
|
||||
|
||||
// Definitions
|
||||
enum
|
||||
{
|
||||
CELL_GAME_PATH_MAX = 128,
|
||||
CELL_GAME_DIRNAME_SIZE = 32,
|
||||
CELL_GAME_THEMEFILENAME_SIZE = 48,
|
||||
CELL_GAME_SYSP_LANGUAGE_NUM = 20,
|
||||
CELL_GAME_SYSP_TITLE_SIZE = 128,
|
||||
CELL_GAME_SYSP_TITLEID_SIZE = 10,
|
||||
CELL_GAME_SYSP_VERSION_SIZE = 6,
|
||||
CELL_GAME_SYSP_APP_VER_SIZE = 6,
|
||||
|
||||
CELL_GAME_GAMETYPE_DISC = 1,
|
||||
CELL_GAME_GAMETYPE_HDD = 2,
|
||||
|
||||
CELL_GAME_GAMETYPE_GAMEDATA = 3,
|
||||
|
||||
CELL_GAME_SIZEKB_NOTCALC = -1,
|
||||
|
||||
CELL_GAME_ATTRIBUTE_PATCH = 0x1,
|
||||
CELL_GAME_ATTRIBUTE_APP_HOME = 0x2,
|
||||
CELL_GAME_ATTRIBUTE_DEBUG = 0x4,
|
||||
CELL_GAME_ATTRIBUTE_XMBBUY = 0x8,
|
||||
CELL_GAME_ATTRIBUTE_COMMERCE2_BROWSER = 0x10,
|
||||
CELL_GAME_ATTRIBUTE_INVITE_MESSAGE = 0x20,
|
||||
CELL_GAME_ATTRIBUTE_CUSTOM_DATA_MESSAGE = 0x40,
|
||||
CELL_GAME_ATTRIBUTE_WEB_BROWSER = 0x100,
|
||||
};
|
||||
|
||||
//Parameter IDs of PARAM.SFO
|
||||
enum
|
||||
{
|
||||
//Integers
|
||||
CELL_GAME_PARAMID_PARENTAL_LEVEL = 102,
|
||||
CELL_GAME_PARAMID_RESOLUTION = 103,
|
||||
CELL_GAME_PARAMID_SOUND_FORMAT = 104,
|
||||
|
||||
//Strings
|
||||
CELL_GAME_PARAMID_TITLE = 0,
|
||||
CELL_GAME_PARAMID_TITLE_DEFAULT = 1,
|
||||
CELL_GAME_PARAMID_TITLE_JAPANESE = 2,
|
||||
CELL_GAME_PARAMID_TITLE_ENGLISH = 3,
|
||||
CELL_GAME_PARAMID_TITLE_FRENCH = 4,
|
||||
CELL_GAME_PARAMID_TITLE_SPANISH = 5,
|
||||
CELL_GAME_PARAMID_TITLE_GERMAN = 6,
|
||||
CELL_GAME_PARAMID_TITLE_ITALIAN = 7,
|
||||
CELL_GAME_PARAMID_TITLE_DUTCH = 8,
|
||||
CELL_GAME_PARAMID_TITLE_PORTUGUESE = 9,
|
||||
CELL_GAME_PARAMID_TITLE_RUSSIAN = 10,
|
||||
CELL_GAME_PARAMID_TITLE_KOREAN = 11,
|
||||
CELL_GAME_PARAMID_TITLE_CHINESE_T = 12,
|
||||
CELL_GAME_PARAMID_TITLE_CHINESE_S = 13,
|
||||
CELL_GAME_PARAMID_TITLE_FINNISH = 14,
|
||||
CELL_GAME_PARAMID_TITLE_SWEDISH = 15,
|
||||
CELL_GAME_PARAMID_TITLE_DANISH = 16,
|
||||
CELL_GAME_PARAMID_TITLE_NORWEGIAN = 17,
|
||||
CELL_GAME_PARAMID_TITLE_POLISH = 18,
|
||||
CELL_GAME_PARAMID_TITLE_PORTUGUESE_BRAZIL = 19,
|
||||
CELL_GAME_PARAMID_TITLE_ENGLISH_UK = 20,
|
||||
CELL_GAME_PARAMID_TITLE_ID = 100,
|
||||
CELL_GAME_PARAMID_VERSION = 101,
|
||||
CELL_GAME_PARAMID_APP_VER = 106,
|
||||
};
|
||||
|
||||
//Error dialog types
|
||||
enum
|
||||
{
|
||||
CELL_GAME_ERRDIALOG_BROKEN_GAMEDATA = 0,
|
||||
CELL_GAME_ERRDIALOG_BROKEN_HDDGAME = 1,
|
||||
CELL_GAME_ERRDIALOG_NOSPACE = 2,
|
||||
CELL_GAME_ERRDIALOG_BROKEN_EXIT_GAMEDATA = 100,
|
||||
CELL_GAME_ERRDIALOG_BROKEN_EXIT_HDDGAME = 101,
|
||||
CELL_GAME_ERRDIALOG_NOSPACE_EXIT = 102,
|
||||
};
|
||||
|
||||
struct CellGameContentSize
|
||||
{
|
||||
be_t<s32> hddFreeSizeKB;
|
||||
be_t<s32> sizeKB;
|
||||
be_t<s32> sysSizeKB;
|
||||
};
|
||||
|
||||
struct CellGameSetInitParams
|
||||
{
|
||||
char title[CELL_GAME_SYSP_TITLE_SIZE];
|
||||
char titleId[CELL_GAME_SYSP_TITLEID_SIZE];
|
||||
char reserved0[2];
|
||||
char version[CELL_GAME_SYSP_VERSION_SIZE];
|
||||
char reserved1[66];
|
||||
};
|
||||
|
||||
struct CellGameDataCBResult
|
||||
{
|
||||
be_t<s32> result;
|
||||
be_t<s32> errNeedSizeKB;
|
||||
be_t<u32> invalidMsg_addr;
|
||||
be_t<u32> reserved;
|
||||
};
|
||||
|
||||
enum // old consts
|
||||
{
|
||||
CELL_GAMEDATA_CBRESULT_OK_CANCEL = 1,
|
||||
CELL_GAMEDATA_CBRESULT_OK = 0,
|
||||
CELL_GAMEDATA_CBRESULT_ERR_NOSPACE = -1,
|
||||
CELL_GAMEDATA_CBRESULT_ERR_BROKEN = -3,
|
||||
CELL_GAMEDATA_CBRESULT_ERR_NODATA = -4,
|
||||
CELL_GAMEDATA_CBRESULT_ERR_INVALID = -5,
|
||||
|
||||
CELL_GAMEDATA_RET_OK = 0,
|
||||
CELL_GAMEDATA_RET_CANCEL = 1,
|
||||
|
||||
CELL_GAMEDATA_ERROR_CBRESULT = 0x8002b601,
|
||||
CELL_GAMEDATA_ERROR_ACCESS_ERROR = 0x8002b602,
|
||||
CELL_GAMEDATA_ERROR_INTERNAL = 0x8002b603,
|
||||
|
||||
CELL_GAMEDATA_ERROR_PARAM = 0x8002b604,
|
||||
CELL_GAMEDATA_ERROR_NOSPACE = 0x8002b605,
|
||||
CELL_GAMEDATA_ERROR_BROKEN = 0x8002b606,
|
||||
|
||||
CELL_GAMEDATA_ERROR_FAILURE = 0x8002b607,
|
||||
|
||||
CELL_GAMEDATA_ATTR_NORMAL = 0,
|
||||
CELL_GAMEDATA_VERSION_CURRENT = 0,
|
||||
|
||||
CELL_GAMEDATA_INVALIDMSG_MAX = 256,
|
||||
CELL_GAMEDATA_PATH_MAX = 1055,
|
||||
CELL_GAMEDATA_DIRNAME_SIZE = 32,
|
||||
|
||||
CELL_GAMEDATA_SIZEKB_NOTCALC = -1,
|
||||
|
||||
CELL_GAMEDATA_SYSP_LANGUAGE_NUM = 20,
|
||||
CELL_GAMEDATA_SYSP_TITLE_SIZE = 128,
|
||||
CELL_GAMEDATA_SYSP_TITLEID_SIZE = 10,
|
||||
CELL_GAMEDATA_SYSP_VERSION_SIZE = 6,
|
||||
|
||||
CELL_GAMEDATA_ISNEWDATA_NO = 0,
|
||||
CELL_GAMEDATA_ISNEWDATA_YES = 1,
|
||||
|
||||
CELL_GAMEDATA_ERRDIALOG_NONE = 0,
|
||||
CELL_GAMEDATA_ERRDIALOG_ALWAYS = 1,
|
||||
};
|
||||
|
||||
struct CellGameDataSystemFileParam
|
||||
{
|
||||
char title[CELL_GAMEDATA_SYSP_TITLE_SIZE];
|
||||
char titleLang[CELL_GAMEDATA_SYSP_LANGUAGE_NUM][CELL_GAMEDATA_SYSP_TITLE_SIZE];
|
||||
char titleId[CELL_GAMEDATA_SYSP_TITLEID_SIZE];
|
||||
char reserved0[2];
|
||||
char dataVersion[CELL_GAMEDATA_SYSP_VERSION_SIZE];
|
||||
char reserved1[2];
|
||||
be_t<u32> parentalLevel;
|
||||
be_t<u32> attribute;
|
||||
char reserved2[256];
|
||||
};
|
||||
|
||||
struct CellGameDataStatGet
|
||||
{
|
||||
be_t<s32> hddFreeSizeKB;
|
||||
be_t<u32> isNewData;
|
||||
char contentInfoPath[CELL_GAMEDATA_PATH_MAX];
|
||||
char gameDataPath[CELL_GAMEDATA_PATH_MAX];
|
||||
char reserved0[2];
|
||||
be_t<s64> st_atime_;
|
||||
be_t<s64> st_mtime_;
|
||||
be_t<s64> st_ctime_;
|
||||
CellGameDataSystemFileParam getParam;
|
||||
be_t<s32> sizeKB;
|
||||
be_t<s32> sysSizeKB;
|
||||
char reserved1[68];
|
||||
};
|
||||
|
||||
struct CellGameDataStatSet
|
||||
{
|
||||
mem_beptr_t<CellGameDataSystemFileParam> setParam;
|
||||
be_t<u32> reserved;
|
||||
};
|
|
@ -421,18 +421,16 @@ int cellGcmSetFlip(mem_ptr_t<CellGcmContextData> ctxt, u32 id)
|
|||
return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK;
|
||||
}
|
||||
|
||||
int cellGcmSetFlipHandler(u32 handler_addr)
|
||||
void cellGcmSetFlipHandler(u32 handler_addr)
|
||||
{
|
||||
cellGcmSys->Warning("cellGcmSetFlipHandler(handler_addr=%d)", handler_addr);
|
||||
|
||||
if (handler_addr != 0 && !Memory.IsGoodAddr(handler_addr))
|
||||
{
|
||||
cellGcmSys->Error("cellGcmSetFlipHandler : CELL_EFAULT");
|
||||
return CELL_EFAULT;
|
||||
cellGcmSys->Error("cellGcmSetFlipHandler(handler_addr=%d): invalid address", handler_addr);
|
||||
}
|
||||
|
||||
Emu.GetGSManager().GetRender().m_flip_handler.SetAddr(handler_addr);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellGcmSetFlipMode(u32 mode)
|
||||
|
@ -567,16 +565,28 @@ int cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
u32 cellGcmSetUserHandler(u32 handler)
|
||||
void cellGcmSetUserHandler(u32 handler_addr)
|
||||
{
|
||||
cellGcmSys->Warning("cellGcmSetUserHandler(handler=0x%x)", handler);
|
||||
return handler;
|
||||
cellGcmSys->Warning("cellGcmSetUserHandler(handler_addr=0x%x)", handler_addr);
|
||||
|
||||
if (handler_addr != 0 && !Memory.IsGoodAddr(handler_addr))
|
||||
{
|
||||
cellGcmSys->Error("cellGcmSetUserHandler(handler_addr=%d): invalid address", handler_addr);
|
||||
}
|
||||
|
||||
Emu.GetGSManager().GetRender().m_user_handler.SetAddr(handler_addr);
|
||||
}
|
||||
|
||||
int cellGcmSetVBlankHandler()
|
||||
void cellGcmSetVBlankHandler(u32 handler_addr)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellGcmSys);
|
||||
return CELL_OK;
|
||||
cellGcmSys->Warning("cellGcmSetVBlankHandler(handler_addr=0x%x)", handler_addr);
|
||||
|
||||
if (handler_addr != 0 && !Memory.IsGoodAddr(handler_addr))
|
||||
{
|
||||
cellGcmSys->Error("cellGcmSetVBlankHandler(handler_addr=%d): invalid address", handler_addr);
|
||||
}
|
||||
|
||||
Emu.GetGSManager().GetRender().m_vblank_handler.SetAddr(handler_addr);
|
||||
}
|
||||
|
||||
int cellGcmSetWaitFlip(mem_ptr_t<CellGcmContextData> ctxt)
|
||||
|
@ -699,10 +709,11 @@ int cellGcmGetDisplayBufferByFlipIndex()
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellGcmgetLastFlipTime()
|
||||
u64 cellGcmGetLastFlipTime()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellGcmSys);
|
||||
return CELL_OK;
|
||||
cellGcmSys->Log("cellGcmGetLastFlipTime()");
|
||||
|
||||
return Emu.GetGSManager().GetRender().m_last_flip_time;
|
||||
}
|
||||
|
||||
int cellGcmGetLastSecondVTime()
|
||||
|
@ -711,10 +722,11 @@ int cellGcmGetLastSecondVTime()
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellGcmGetVBlankCount()
|
||||
u64 cellGcmGetVBlankCount()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellGcmSys);
|
||||
return CELL_OK;
|
||||
cellGcmSys->Log("cellGcmGetVBlankCount()");
|
||||
|
||||
return Emu.GetGSManager().GetRender().m_vblank_count;
|
||||
}
|
||||
|
||||
int cellGcmInitSystemMode()
|
||||
|
@ -1156,7 +1168,7 @@ void cellGcmSys_init()
|
|||
cellGcmSys->AddFunc(0xe315a0b2, cellGcmGetConfiguration);
|
||||
cellGcmSys->AddFunc(0x371674cf, cellGcmGetDisplayBufferByFlipIndex);
|
||||
cellGcmSys->AddFunc(0x72a577ce, cellGcmGetFlipStatus);
|
||||
cellGcmSys->AddFunc(0x63387071, cellGcmgetLastFlipTime);
|
||||
cellGcmSys->AddFunc(0x63387071, cellGcmGetLastFlipTime);
|
||||
cellGcmSys->AddFunc(0x23ae55a3, cellGcmGetLastSecondVTime);
|
||||
cellGcmSys->AddFunc(0x055bd74d, cellGcmGetTiledPitchSize);
|
||||
cellGcmSys->AddFunc(0x723bbc7e, cellGcmGetVBlankCount);
|
||||
|
|
|
@ -93,6 +93,23 @@ int cellPngDecOpen(u32 mainHandle, mem32_t subHandle, mem_ptr_t<CellPngDecSrc> s
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPngDecExtOpen(u32 mainHandle, mem32_t subHandle, mem_ptr_t<CellPngDecSrc> src, u32 openInfo, mem_ptr_t<CellPngDecCbCtrlStrm> cbCtrlStrm, mem_ptr_t<CellPngDecOpnParam> opnParam)
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecExtOpen(mainHandle=0x%x, subHandle=0x%x, src_addr=0x%x, openInfo=0x%x, cbCtrlStrm_addr=0x%x, opnParam=0x%x)",
|
||||
mainHandle, subHandle.GetAddr(), src.GetAddr(), openInfo, cbCtrlStrm.GetAddr(), opnParam.GetAddr());
|
||||
|
||||
cellPngDec->Warning("*** cbCtrlStrm->cbCtrlStrmFunc_addr=0x%x", cbCtrlStrm->cbCtrlStrmFunc.GetAddr());
|
||||
|
||||
MemoryAllocator<CellPngDecStrmInfo> streamInfo;
|
||||
MemoryAllocator<CellPngDecStrmParam> streamParam;
|
||||
|
||||
int res = cellPngDecOpen(mainHandle, subHandle, src, openInfo);
|
||||
|
||||
if (!res) cbCtrlStrm->cbCtrlStrmFunc(streamInfo.GetAddr(), streamParam.GetAddr(), cbCtrlStrm->cbCtrlStrmArg);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int cellPngDecClose(u32 mainHandle, u32 subHandle)
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecClose(mainHandle=0x%x,subHandle=0x%x)", mainHandle, subHandle);
|
||||
|
@ -112,7 +129,7 @@ int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellPngDecInfo
|
|||
if (!info.IsGood())
|
||||
return CELL_PNGDEC_ERROR_ARG;
|
||||
|
||||
cellPngDec->Warning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%llx)", mainHandle, subHandle, info.GetAddr());
|
||||
cellPngDec->Warning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", mainHandle, subHandle, info.GetAddr());
|
||||
CellPngDecSubHandle* subHandle_data;
|
||||
if(!cellPngDec->CheckId(subHandle, subHandle_data))
|
||||
return CELL_PNGDEC_ERROR_FATAL;
|
||||
|
@ -167,6 +184,14 @@ int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellPngDecInfo
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPngDecExtReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellPngDecInfo> info, mem_ptr_t<CellPngDecExtInfo> extInfo)
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecExtReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x, extInfo_addr=0x%x)",
|
||||
mainHandle, subHandle, info.GetAddr(), extInfo.GetAddr());
|
||||
|
||||
return cellPngDecReadHeader(mainHandle, subHandle, info);
|
||||
}
|
||||
|
||||
int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const mem_ptr_t<CellPngDecDataCtrlParam> dataCtrlParam, mem_ptr_t<CellPngDecDataOutInfo> dataOutInfo)
|
||||
{
|
||||
if (!data.IsGood() || !dataCtrlParam.IsGood() || !dataOutInfo.IsGood())
|
||||
|
@ -292,6 +317,17 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPngDecExtDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const mem_ptr_t<CellPngDecDataCtrlParam> dataCtrlParam,
|
||||
mem_ptr_t<CellPngDecDataOutInfo> dataOutInfo, mem_ptr_t<CellPngDecCbCtrlDisp> cbCtrlDisp, mem_ptr_t<CellPngDecDispParam> dispParam)
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecExtDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x, cbCtrlDisp_addr=0x%x, dispParam=0x%x",
|
||||
mainHandle, subHandle, data.GetAddr(), dataCtrlParam.GetAddr(), dataOutInfo.GetAddr(), cbCtrlDisp.GetAddr(), dispParam.GetAddr());
|
||||
|
||||
if (cbCtrlDisp.GetAddr()) cellPngDec->Warning("*** cbCtrlDisp->cbCtrlDispFunc_addr=0x%x", (u32)cbCtrlDisp->cbCtrlDispFunc_addr);
|
||||
|
||||
return cellPngDecDecodeData(mainHandle, subHandle, data, dataCtrlParam, dataOutInfo);
|
||||
}
|
||||
|
||||
int cellPngDecSetParameter(u32 mainHandle, u32 subHandle, const mem_ptr_t<CellPngDecInParam> inParam, mem_ptr_t<CellPngDecOutParam> outParam)
|
||||
{
|
||||
if (!inParam.IsGood() || !outParam.IsGood())
|
||||
|
@ -333,6 +369,15 @@ int cellPngDecSetParameter(u32 mainHandle, u32 subHandle, const mem_ptr_t<CellPn
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPngDecExtSetParameter(u32 mainHandle, u32 subHandle, const mem_ptr_t<CellPngDecInParam> inParam, mem_ptr_t<CellPngDecOutParam> outParam,
|
||||
mem_ptr_t<CellPngDecExtInParam> extInParam, mem_ptr_t<CellPngDecExtOutParam> extOutParam)
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecExtSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x, extInParam=0x%x, extOutParam=0x%x",
|
||||
mainHandle, subHandle, inParam.GetAddr(), outParam.GetAddr(), extInParam.GetAddr(), extOutParam.GetAddr());
|
||||
|
||||
return cellPngDecSetParameter(mainHandle, subHandle, inParam, outParam);
|
||||
}
|
||||
|
||||
void cellPngDec_init()
|
||||
{
|
||||
cellPngDec->AddFunc(0x157d30c5, cellPngDecCreate);
|
||||
|
@ -343,11 +388,12 @@ void cellPngDec_init()
|
|||
cellPngDec->AddFunc(0x2310f155, cellPngDecDecodeData);
|
||||
cellPngDec->AddFunc(0xe97c9bd4, cellPngDecSetParameter);
|
||||
|
||||
/*cellPngDec->AddFunc(0x48436b2d, cellPngDecExtCreate);
|
||||
cellPngDec->AddFunc(0x0c515302, cellPngDecExtOpen);
|
||||
cellPngDec->AddFunc(0x8b33f863, cellPngDecExtReadHeader);
|
||||
cellPngDec->AddFunc(0x726fc1d0, cellPngDecExtDecodeData);
|
||||
cellPngDec->AddFunc(0x9e9d7d42, cellPngDecExtSetParameter);
|
||||
|
||||
/*cellPngDec->AddFunc(0x48436b2d, cellPngDecExtCreate);
|
||||
cellPngDec->AddFunc(0x7585a275, cellPngDecGetbKGD);
|
||||
cellPngDec->AddFunc(0x7a062d26, cellPngDecGetcHRM);
|
||||
cellPngDec->AddFunc(0xb153629c, cellPngDecGetgAMA);
|
||||
|
|
|
@ -124,3 +124,54 @@ struct CellPngDecMainHandle
|
|||
be_t<u32> threadInParam;
|
||||
be_t<u32> threadOutParam;
|
||||
};
|
||||
|
||||
struct CellPngDecStrmInfo
|
||||
{
|
||||
be_t<u32> decodedStrmSize;
|
||||
};
|
||||
|
||||
struct CellPngDecStrmParam
|
||||
{
|
||||
be_t<u32> strmPtr;
|
||||
be_t<u32> strmSize;
|
||||
};
|
||||
|
||||
struct CellPngDecCbCtrlStrm
|
||||
{
|
||||
mem_func_beptr_t<void(*)(mem_ptr_t<CellPngDecStrmInfo> strmInfo, mem_ptr_t<CellPngDecStrmParam> strmParam, u32 cbCtrlStrmArg)> cbCtrlStrmFunc;
|
||||
be_t<u32> cbCtrlStrmArg;
|
||||
};
|
||||
|
||||
struct CellPngDecCbCtrlDisp
|
||||
{
|
||||
be_t<u32> cbCtrlDispFunc_addr;
|
||||
be_t<u32> cbCtrlDispArg;
|
||||
};
|
||||
|
||||
struct CellPngDecDispParam
|
||||
{
|
||||
be_t<u32> nextOutputImage_addr;
|
||||
};
|
||||
|
||||
struct CellPngDecExtInfo
|
||||
{
|
||||
be_t<u64> reserved;
|
||||
};
|
||||
|
||||
struct CellPngDecExtInParam
|
||||
{
|
||||
be_t<u32> bufferMode; // CellPngDecBufferMode
|
||||
be_t<u32> outputCounts;
|
||||
be_t<u32> spuMode; // CellPngDecSpuMode
|
||||
};
|
||||
|
||||
struct CellPngDecExtOutParam
|
||||
{
|
||||
be_t<u64> outputWidthByte;
|
||||
be_t<u32> outputHeight;
|
||||
};
|
||||
|
||||
struct CellPngDecOpnParam
|
||||
{
|
||||
be_t<u32> selectChunk;
|
||||
};
|
|
@ -88,13 +88,13 @@ CCellRescInternal* s_rescInternalInstance = nullptr;
|
|||
|
||||
// Extern Functions
|
||||
extern int cellGcmSetFlipMode(u32 mode);
|
||||
extern int cellGcmSetFlipHandler(u32 handler_addr);
|
||||
extern s32 cellGcmAddressToOffset(u64 address, mem32_t offset);
|
||||
extern void cellGcmSetFlipHandler(u32 handler_addr);
|
||||
extern int cellGcmAddressToOffset(u64 address, mem32_t offset);
|
||||
extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height);
|
||||
extern int cellGcmSetPrepareFlip(mem_ptr_t<CellGcmContextData> ctx, u32 id);
|
||||
extern int cellGcmSetSecondVFrequency(u32 freq);
|
||||
extern u32 cellGcmGetLabelAddress(u8 index);
|
||||
extern u32 cellGcmSetVBlankHandler(u32 handler);
|
||||
extern void cellGcmSetVBlankHandler(u32 handler);
|
||||
extern u32 cellGcmSetSecondVHandler(u32 handler);
|
||||
extern u32 cellGcmGetTiledPitchSize(u32 size);
|
||||
|
||||
|
@ -1096,19 +1096,16 @@ int cellRescSetBufferAddress(mem32_t colorBuffers, mem32_t vertexArray, mem32_t
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellRescSetFlipHandler(u32 handler_addr)
|
||||
void cellRescSetFlipHandler(u32 handler_addr)
|
||||
{
|
||||
cellResc->Warning("cellRescSetFlipHandler(handler_addr=0x%x)", handler_addr);
|
||||
|
||||
if (handler_addr != 0 && !Memory.IsGoodAddr(handler_addr))
|
||||
{
|
||||
cellResc->Error("cellRescSetFlipHandler : CELL_EFAULT");
|
||||
return CELL_EFAULT;
|
||||
cellResc->Error("cellRescSetFlipHandler(handler_addr=%d): invalid address", handler_addr);
|
||||
}
|
||||
|
||||
Emu.GetGSManager().GetRender().m_flip_handler.SetAddr(handler_addr);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
void cellRescResetFlipStatus()
|
||||
|
@ -1131,10 +1128,11 @@ int cellRescGetRegisterCount()
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellRescGetLastFlipTime()
|
||||
u64 cellRescGetLastFlipTime()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellResc);
|
||||
return CELL_OK;
|
||||
cellResc->Log("cellRescGetLastFlipTime()");
|
||||
|
||||
return Emu.GetGSManager().GetRender().m_last_flip_time;
|
||||
}
|
||||
|
||||
int cellRescSetRegisterCount()
|
||||
|
@ -1143,10 +1141,16 @@ int cellRescSetRegisterCount()
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellRescSetVBlankHandler()
|
||||
void cellRescSetVBlankHandler(u32 handler_addr)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellResc);
|
||||
return CELL_OK;
|
||||
cellResc->Warning("cellRescSetVBlankHandler(handler_addr=0x%x)", handler_addr);
|
||||
|
||||
if (handler_addr != 0 && !Memory.IsGoodAddr(handler_addr))
|
||||
{
|
||||
cellResc->Error("cellRescSetVBlankHandler(handler_addr=%d): invalid address", handler_addr);
|
||||
}
|
||||
|
||||
Emu.GetGSManager().GetRender().m_vblank_handler.SetAddr(handler_addr);
|
||||
}
|
||||
|
||||
u16 FloatToHalf(float val)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "cellSysutil.h"
|
||||
#include "cellSysutil_SaveData.h"
|
||||
#include "cellGame.h"
|
||||
|
||||
#include "Loader/PSF.h"
|
||||
|
||||
|
@ -380,8 +381,11 @@ int cellSysutilUnregisterCallback(int slot)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellMsgDialogOpen2(u32 type, char* msgString, mem_func_ptr_t<CellMsgDialogCallback> callback, mem_ptr_t<void> userData, u32 extParam)
|
||||
int cellMsgDialogOpen2(u32 type, mem_list_ptr_t<u8> msgString, mem_func_ptr_t<CellMsgDialogCallback> callback, mem_ptr_t<void> userData, u32 extParam)
|
||||
{
|
||||
cellSysutil->Warning("cellMsgDialogOpen2(type=0x%x, msgString_addr=0x%x, callback_addr=0x%x, userData=0x%x, extParam=0x%x)",
|
||||
type, msgString.GetAddr(), callback.GetAddr(), userData.GetAddr(), extParam);
|
||||
|
||||
long style = 0;
|
||||
|
||||
if(type & CELL_MSGDIALOG_DIALOG_TYPE_NORMAL)
|
||||
|
@ -402,7 +406,7 @@ int cellMsgDialogOpen2(u32 type, char* msgString, mem_func_ptr_t<CellMsgDialogCa
|
|||
style |= rOK;
|
||||
}
|
||||
|
||||
int res = rMessageBox(std::string(msgString), rGetApp().GetAppName(), style);
|
||||
int res = rMessageBox(std::string(msgString.GetString()), rGetApp().GetAppName(), style);
|
||||
|
||||
u64 status;
|
||||
|
||||
|
@ -919,22 +923,24 @@ int cellHddGameCheck(u32 version, u32 dirName_addr, u32 errDialog, mem_func_ptr_
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
bool bgm_playback_enabled = false;
|
||||
bool bgm_playback_enabled = true;
|
||||
|
||||
int cellSysutilEnableBgmPlayback()
|
||||
{
|
||||
cellSysutil->Warning("cellSysutilEnableBgmPlayback()");
|
||||
|
||||
// TODO
|
||||
bgm_playback_enabled = true;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSysutilEnableBgmPlaybackEx()
|
||||
int cellSysutilEnableBgmPlaybackEx(mem_ptr_t<CellSysutilBgmPlaybackExtraParam> param)
|
||||
{
|
||||
cellSysutil->Warning("cellSysutilEnableBgmPlaybackEx()");
|
||||
cellSysutil->Warning("cellSysutilEnableBgmPlaybackEx(param_addr=0x%x)", param.GetAddr());
|
||||
|
||||
bgm_playback_enabled = true;
|
||||
// TODO
|
||||
bgm_playback_enabled = true;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -943,42 +949,43 @@ int cellSysutilDisableBgmPlayback()
|
|||
{
|
||||
cellSysutil->Warning("cellSysutilDisableBgmPlayback()");
|
||||
|
||||
// TODO
|
||||
bgm_playback_enabled = false;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSysutilDisableBgmPlaybackEx()
|
||||
int cellSysutilDisableBgmPlaybackEx(mem_ptr_t<CellSysutilBgmPlaybackExtraParam> param)
|
||||
{
|
||||
cellSysutil->Warning("cellSysutilDisableBgmPlaybackEx()");
|
||||
|
||||
bgm_playback_enabled = false;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSysutilGetBgmPlaybackStatus(mem_ptr_t<CellBgmPlaybackStatus> status)
|
||||
{
|
||||
cellSysutil->Warning("cellSysutilGetBgmPlaybackStatus(status=0x%x)", status.GetAddr());
|
||||
cellSysutil->Warning("cellSysutilDisableBgmPlaybackEx(param_addr=0x%x)", param.GetAddr());
|
||||
|
||||
// TODO
|
||||
status->playbackState = CELL_BGMPLAYBACK_STATUS_STOP;
|
||||
status->enabled = bgm_playback_enabled ? CELL_BGMPLAYBACK_STATUS_ENABLE : CELL_BGMPLAYBACK_STATUS_DISABLE;
|
||||
status->fadeRatio = 0; // volume ratio
|
||||
bgm_playback_enabled = false;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSysutilGetBgmPlaybackStatus(mem_ptr_t<CellSysutilBgmPlaybackStatus> status)
|
||||
{
|
||||
cellSysutil->Log("cellSysutilGetBgmPlaybackStatus(status_addr=0x%x)", status.GetAddr());
|
||||
|
||||
// TODO
|
||||
status->playerState = CELL_SYSUTIL_BGMPLAYBACK_STATUS_STOP;
|
||||
status->enableState = bgm_playback_enabled ? CELL_SYSUTIL_BGMPLAYBACK_STATUS_ENABLE : CELL_SYSUTIL_BGMPLAYBACK_STATUS_DISABLE;
|
||||
status->currentFadeRatio = 0; // current volume ratio (0%)
|
||||
memset(status->contentId, 0, sizeof(status->contentId));
|
||||
memset(status->reserved, 0, sizeof(status->reserved));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSysutilGetBgmPlaybackStatus2(mem_ptr_t<CellBgmPlaybackStatus> status2)
|
||||
int cellSysutilGetBgmPlaybackStatus2(mem_ptr_t<CellSysutilBgmPlaybackStatus2> status2)
|
||||
{
|
||||
cellSysutil->Warning("cellSysutilGetBgmPlaybackStatus2(status=0x%x)", status2.GetAddr());
|
||||
cellSysutil->Log("cellSysutilGetBgmPlaybackStatus2(status2_addr=0x%x)", status2.GetAddr());
|
||||
|
||||
// TODO
|
||||
status2->playbackState = CELL_BGMPLAYBACK_STATUS_STOP;
|
||||
status2->enabled = bgm_playback_enabled ? CELL_BGMPLAYBACK_STATUS_ENABLE : CELL_BGMPLAYBACK_STATUS_DISABLE;
|
||||
status2->fadeRatio = 0; // volume ratio
|
||||
memset(status2->contentId, 0, sizeof(status2->contentId));
|
||||
status2->playerState = CELL_SYSUTIL_BGMPLAYBACK_STATUS_STOP;
|
||||
memset(status2->reserved, 0, sizeof(status2->reserved));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -991,6 +998,12 @@ int cellWebBrowserEstimate2(mem8_ptr_t _config, mem32_ptr_t memSize)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
extern int cellGameDataCheckCreate2(u32 version, const mem_list_ptr_t<u8> dirName, u32 errDialog,
|
||||
mem_func_ptr_t<void(*)(mem_ptr_t<CellGameDataCBResult> cbResult, mem_ptr_t<CellGameDataStatGet> get, mem_ptr_t<CellGameDataStatSet> set)> funcStat, u32 container);
|
||||
|
||||
extern int cellGameDataCheckCreate(u32 version, const mem_list_ptr_t<u8> dirName, u32 errDialog,
|
||||
mem_func_ptr_t<void(*)(mem_ptr_t<CellGameDataCBResult> cbResult, mem_ptr_t<CellGameDataStatGet> get, mem_ptr_t<CellGameDataStatSet> set)> funcStat, u32 container);
|
||||
|
||||
void cellSysutil_init()
|
||||
{
|
||||
cellSysutil->AddFunc(0x40e895d3, cellSysutilGetSystemParamInt);
|
||||
|
@ -1068,4 +1081,7 @@ void cellSysutil_init()
|
|||
//cellSysutil->AddFunc(0xe7fa820b, cellSaveDataEnableOverlay);
|
||||
|
||||
cellSysutil->AddFunc(0x6d087930, cellWebBrowserEstimate2);
|
||||
|
||||
cellSysutil->AddFunc(0xe7951dee, cellGameDataCheckCreate);
|
||||
cellSysutil->AddFunc(0xc9645c41, cellGameDataCheckCreate2);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ int vdecRead(void* opaque, u8* buf, int buf_size)
|
|||
next:
|
||||
if (vdec.reader.size < (u32)buf_size /*&& !vdec.just_started*/)
|
||||
{
|
||||
while (vdec.job.IsEmpty())
|
||||
while (!vdec.job.GetCountUnsafe())
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
|
@ -44,6 +44,7 @@ next:
|
|||
switch (vdec.job.Peek().type)
|
||||
{
|
||||
case vdecEndSeq:
|
||||
case vdecClose:
|
||||
{
|
||||
buf_size = vdec.reader.size;
|
||||
}
|
||||
|
@ -147,7 +148,7 @@ u32 vdecOpen(VideoDecoder* data)
|
|||
break;
|
||||
}
|
||||
|
||||
if (vdec.job.IsEmpty() && vdec.is_running)
|
||||
if (!vdec.job.GetCountUnsafe() && vdec.is_running)
|
||||
{
|
||||
Sleep(1);
|
||||
continue;
|
||||
|
@ -189,10 +190,8 @@ u32 vdecOpen(VideoDecoder* data)
|
|||
cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg);
|
||||
cb.Branch(true); // ???*/
|
||||
|
||||
avcodec_close(vdec.ctx);
|
||||
avformat_close_input(&vdec.fmt);
|
||||
|
||||
vdec.is_running = false;
|
||||
vdec.just_finished = true;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -244,7 +243,13 @@ u32 vdecOpen(VideoDecoder* data)
|
|||
|
||||
} au(0);
|
||||
|
||||
if (vdec.just_started) // deferred initialization
|
||||
if (vdec.just_started && vdec.just_finished)
|
||||
{
|
||||
avcodec_flush_buffers(vdec.ctx);
|
||||
vdec.just_started = false;
|
||||
vdec.just_finished = false;
|
||||
}
|
||||
else if (vdec.just_started) // deferred initialization
|
||||
{
|
||||
err = avformat_open_input(&vdec.fmt, NULL, av_find_input_format("mpeg"), NULL);
|
||||
if (err)
|
||||
|
@ -285,7 +290,7 @@ u32 vdecOpen(VideoDecoder* data)
|
|||
av_dict_set(&opts, "refcounted_frames", "1", 0);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_mutex_avcodec_open2);
|
||||
// not multithread-safe
|
||||
// not multithread-safe (???)
|
||||
err = avcodec_open2(vdec.ctx, codec, &opts);
|
||||
}
|
||||
if (err)
|
||||
|
@ -294,8 +299,6 @@ u32 vdecOpen(VideoDecoder* data)
|
|||
Emu.Pause();
|
||||
break;
|
||||
}
|
||||
//vdec.ctx->flags |= CODEC_FLAG_TRUNCATED;
|
||||
//vdec.ctx->flags2 |= CODEC_FLAG2_CHUNKS;
|
||||
vdec.just_started = false;
|
||||
}
|
||||
|
||||
|
@ -303,8 +306,9 @@ u32 vdecOpen(VideoDecoder* data)
|
|||
|
||||
while (true)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
if (Emu.IsStopped() || vdec.job.PeekIfExist().type == vdecClose)
|
||||
{
|
||||
vdec.is_finished = true;
|
||||
LOG_WARNING(HLE, "vdecDecodeAu: aborted");
|
||||
return;
|
||||
}
|
||||
|
@ -498,7 +502,7 @@ int cellVdecClose(u32 handle)
|
|||
|
||||
vdec->job.Push(VdecTask(vdecClose));
|
||||
|
||||
while (!vdec->is_finished || !vdec->frames.IsEmpty())
|
||||
while (!vdec->is_finished)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
|
@ -674,14 +678,14 @@ int cellVdecGetPicItem(u32 handle, mem32_t picItem_ptr)
|
|||
return CELL_VDEC_ERROR_FATAL;
|
||||
}
|
||||
|
||||
VdecFrame& vf = vdec->frames.Peek();
|
||||
|
||||
if (vdec->frames.IsEmpty())
|
||||
{
|
||||
Sleep(1);
|
||||
Sleep(1); // hack
|
||||
return CELL_VDEC_ERROR_EMPTY;
|
||||
}
|
||||
|
||||
VdecFrame& vf = vdec->frames.Peek();
|
||||
|
||||
AVFrame& frame = *vf.data;
|
||||
|
||||
mem_ptr_t<CellVdecPicItem> info(vdec->memAddr + vdec->memBias);
|
||||
|
|
|
@ -647,6 +647,7 @@ struct CellVdecMpeg2Info
|
|||
|
||||
enum VdecJobType : u32
|
||||
{
|
||||
vdecInvalid,
|
||||
vdecStartSeq,
|
||||
vdecEndSeq,
|
||||
vdecDecodeAu,
|
||||
|
@ -675,6 +676,7 @@ struct VdecTask
|
|||
}
|
||||
|
||||
VdecTask()
|
||||
: type(vdecInvalid)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -697,6 +699,7 @@ public:
|
|||
volatile bool is_running;
|
||||
volatile bool is_finished;
|
||||
bool just_started;
|
||||
bool just_finished;
|
||||
|
||||
AVCodecContext* ctx;
|
||||
AVFormatContext* fmt;
|
||||
|
@ -735,6 +738,7 @@ public:
|
|||
, is_finished(false)
|
||||
, is_running(false)
|
||||
, just_started(false)
|
||||
, just_finished(false)
|
||||
, ctx(nullptr)
|
||||
, vdecCb(nullptr)
|
||||
{
|
||||
|
@ -764,6 +768,7 @@ public:
|
|||
|
||||
~VideoDecoder()
|
||||
{
|
||||
// TODO: check finalization
|
||||
if (ctx)
|
||||
{
|
||||
for (u32 i = frames.GetCount() - 1; ~i; i--)
|
||||
|
|
|
@ -30,6 +30,12 @@ int sceNpDrmIsAvailable(u32 k_licensee_addr, u32 drm_path_addr)
|
|||
sceNp->Warning("sceNpDrmIsAvailable(k_licensee_addr=0x%x, drm_path_addr=0x%x)", k_licensee_addr, drm_path_addr);
|
||||
|
||||
std::string drm_path = Memory.ReadString(drm_path_addr);
|
||||
if (!Emu.GetVFS().ExistsFile(drm_path))
|
||||
{
|
||||
sceNp->Warning("sceNpDrmIsAvailable(): '%s' not found", drm_path.c_str());
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
|
||||
std::string k_licensee_str;
|
||||
u8 k_licensee[0x10];
|
||||
for(int i = 0; i < 0x10; i++)
|
||||
|
|
|
@ -114,16 +114,16 @@ int sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil
|
|||
int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||
{
|
||||
const std::string& path = Memory.ReadString(path_addr);
|
||||
sys_fs->Warning("cellFsSdataOpen(path=\"%s\", flags=0x%x, fd_addr=0x%x, arg_addr=0x%x, size=0x%llx)",
|
||||
sys_fs->Warning("cellFsSdataOpen(path=\"%s\", flags=0x%x, fd_addr=0x%x, arg_addr=0x%x, size=0x%llx) -> cellFsOpen()",
|
||||
path.c_str(), flags, fd.GetAddr(), arg.GetAddr(), size);
|
||||
|
||||
if (!fd.IsGood() || (!arg.IsGood() && size))
|
||||
/*if (!fd.IsGood() || (!arg.IsGood() && size))
|
||||
return CELL_EFAULT;
|
||||
|
||||
if (flags != CELL_O_RDONLY)
|
||||
return CELL_EINVAL;
|
||||
|
||||
std::string suffix = path.substr(path.length() - 5, 4);
|
||||
std::string suffix = path.substr(path.length() - 5, 5);
|
||||
if (suffix != ".sdat" && suffix != ".SDAT")
|
||||
return CELL_ENOTSDATA;
|
||||
|
||||
|
@ -135,7 +135,9 @@ int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
|||
|
||||
fd = sys_fs->GetNewId(Emu.GetVFS().OpenFile(unpacked_path, vfsRead), flags);
|
||||
|
||||
return CELL_OK;
|
||||
return CELL_OK;*/
|
||||
|
||||
return cellFsOpen(path_addr, flags, fd, arg, size);
|
||||
}
|
||||
|
||||
std::atomic<u32> g_FsAioReadID( 0 );
|
||||
|
|
|
@ -142,8 +142,6 @@ int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64
|
|||
{
|
||||
SMutexLocker lock(ef->m_mutex);
|
||||
|
||||
ef->signal.unlock(tid);
|
||||
|
||||
u64 flags = ef->flags;
|
||||
|
||||
for (u32 i = 0; i < ef->waiters.size(); i++)
|
||||
|
@ -161,6 +159,17 @@ int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64
|
|||
ef->flags = 0;
|
||||
}
|
||||
|
||||
if (u32 target = ef->check())
|
||||
{
|
||||
// if signal, leave both mutexes locked...
|
||||
ef->signal.unlock(tid, target);
|
||||
ef->m_mutex.unlock(tid, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
ef->signal.unlock(tid);
|
||||
}
|
||||
|
||||
if (result.IsGood())
|
||||
{
|
||||
result = flags;
|
||||
|
@ -175,6 +184,7 @@ int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64
|
|||
}
|
||||
}
|
||||
|
||||
ef->signal.unlock(tid);
|
||||
return CELL_ECANCELED;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,6 +116,12 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
|||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (!Emu.GetVFS().ExistsFile(ppath))
|
||||
{
|
||||
sys_fs->Error("\"%s\" not found! flags: 0x%08x", ppath.c_str(), flags);
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
|
||||
vfsFileBase* stream = Emu.GetVFS().OpenFile(ppath, o_mode);
|
||||
|
||||
if(!stream || !stream->IsOpened())
|
||||
|
@ -126,7 +132,7 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
|||
}
|
||||
|
||||
fd = sys_fs->GetNewId(stream, IDFlag_File);
|
||||
LOG_WARNING(HLE, "*** cellFsOpen(path=\"%s\"): fd = %d", path.c_str(), fd.GetValue());
|
||||
LOG_WARNING(HLE, "\"%s\" opened: fd = %d", path.c_str(), fd.GetValue());
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "Emu/Cell/SPUThread.h"
|
||||
#include "Emu/Cell/PPUInstrTable.h"
|
||||
#include "Emu/FS/vfsFile.h"
|
||||
#include "Emu/FS/vfsDeviceLocalFile.h"
|
||||
|
||||
#include "Emu/CPU/CPUThreadManager.h" //gui dependency
|
||||
|
||||
|
@ -163,6 +164,18 @@ void Emulator::Load()
|
|||
{
|
||||
LOG_NOTICE(LOADER, "%s -> %s", m_vfs.m_devices[i]->GetPs3Path().c_str(), m_vfs.m_devices[i]->GetLocalPath().c_str());
|
||||
}
|
||||
// bdvd inserting imitation
|
||||
vfsFile f1("/app_home/dev_bdvd.path");
|
||||
if (f1.IsOpened())
|
||||
{
|
||||
std::string bdvd;
|
||||
bdvd.resize(f1.GetSize());
|
||||
f1.Read(&bdvd[0], bdvd.size());
|
||||
|
||||
// load desired /dev_bdvd/ real directory and remount
|
||||
Emu.GetVFS().Mount("/dev_bdvd/", bdvd, new vfsDeviceLocalFile());
|
||||
LOG_NOTICE(LOADER, "/dev_bdvd/ remounted into %s", bdvd.c_str());
|
||||
}
|
||||
LOG_NOTICE(LOADER, " ");//used to be skip_line
|
||||
|
||||
if(m_elf_path.empty())
|
||||
|
|
|
@ -88,7 +88,7 @@ struct wxWriter : Log::LogListener
|
|||
default:
|
||||
break;
|
||||
}
|
||||
llogcon->AppendText(wxString(msg.mText));
|
||||
llogcon->AppendText(fmt::FromUTF8(msg.mText));
|
||||
}
|
||||
}
|
||||
if (m_log->GetLastPosition() > GUI_BUFFER_MAX_SIZE)
|
||||
|
|
|
@ -339,6 +339,7 @@
|
|||
<ClInclude Include="Emu\SysCalls\Modules\cellAtrac.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellDmux.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellFont.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellGame.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellGifDec.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellJpgDec.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellPamf.h" />
|
||||
|
|
|
@ -1072,5 +1072,8 @@
|
|||
<ClInclude Include="..\Utilities\Log.h">
|
||||
<Filter>Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellGame.h">
|
||||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Add table
Reference in a new issue