diff --git a/rpcs3/CMakeLists.txt b/rpcs3/CMakeLists.txt index 6139e73436..9bece62c40 100644 --- a/rpcs3/CMakeLists.txt +++ b/rpcs3/CMakeLists.txt @@ -8,6 +8,7 @@ if (CMAKE_COMPILER_IS_GNUCXX) add_definitions(-w) # TODO: remove me add_definitions(-fpermissive) # TODO: remove me add_definitions(-g) # Debugging!! + add_definitions(-msse2) endif() set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules) @@ -59,5 +60,5 @@ ${CMAKE_SOURCE_DIR}/../Utilities/* add_executable(rpcs3 ${RPCS3_SRC}) -target_link_libraries(rpcs3 ${wxWidgets_LIBRARIES} ${OPENAL_LIBRARY} ${GLEW_LIBRARIES} ${OPENGL_LIBRARIES} libavformat.a libavcodec.a libavutil.a libswresample.a libswscale.a ${ZLIB_LIBRARIES}) +target_link_libraries(rpcs3 ${wxWidgets_LIBRARIES} ${OPENAL_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES} libavformat.a libavcodec.a libavutil.a libswresample.a libswscale.a ${ZLIB_LIBRARIES}) diff --git a/rpcs3/Crypto/unedat.cpp b/rpcs3/Crypto/unedat.cpp index 03dddf89ce..65641919cb 100644 --- a/rpcs3/Crypto/unedat.cpp +++ b/rpcs3/Crypto/unedat.cpp @@ -457,7 +457,7 @@ void validate_data(const char* file_name, unsigned char *klicensee, NPD_HEADER * else { // Generate klicensee xor key. - xor(key, klicensee, NP_OMAC_KEY_2, 0x10); + xor_(key, klicensee, NP_OMAC_KEY_2, 0x10); // Hash with generated key and compare with dev_hash. dev_hash_result = cmac_hash_compare(key, 0x10, (unsigned char *)npd, 0x60, npd->dev_hash); @@ -529,7 +529,7 @@ bool extract_data(wxFile *input, wxFile *output, const char* input_file_name, un if((EDAT->flags & SDAT_FLAG) == SDAT_FLAG) { ConLog.Warning("EDAT: SDAT detected!\n"); - xor(key, NPD->dev_hash, SDAT_KEY, 0x10); + xor_(key, NPD->dev_hash, SDAT_KEY, 0x10); } else { @@ -670,4 +670,4 @@ int DecryptEDAT(const std::string& input_file_name, const std::string& output_fi input.Close(); output.Close(); return 0; -} \ No newline at end of file +} diff --git a/rpcs3/Crypto/utils.cpp b/rpcs3/Crypto/utils.cpp index 5df31b17e7..13eb434d89 100644 --- a/rpcs3/Crypto/utils.cpp +++ b/rpcs3/Crypto/utils.cpp @@ -20,7 +20,7 @@ u64 swap64(u64 i) ((i & 0x00ff000000000000) >> 40) | ((i & 0xff00000000000000) >> 56); } -void xor(unsigned char *dest, unsigned char *src1, unsigned char *src2, int size) +void xor_(unsigned char *dest, unsigned char *src1, unsigned char *src2, int size) { int i; for(i = 0; i < size; i++) @@ -744,4 +744,4 @@ int lz_decompress(unsigned char *out, unsigned char *in, unsigned int size) delete[] tmp; return result; -} \ No newline at end of file +} diff --git a/rpcs3/Crypto/utils.h b/rpcs3/Crypto/utils.h index 51bc56eba3..0d9e5eed2c 100644 --- a/rpcs3/Crypto/utils.h +++ b/rpcs3/Crypto/utils.h @@ -6,7 +6,7 @@ u16 swap16(u16 i); u32 swap32(u32 i); u64 swap64(u64 i); -void xor(unsigned char *dest, unsigned char *src1, unsigned char *src2, int size); +void xor_(unsigned char *dest, unsigned char *src1, unsigned char *src2, int size); // Hex string conversion auxiliary functions. u64 hex_to_u64(const char* hex_str); @@ -19,4 +19,4 @@ bool hmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int i bool cmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash); // Reverse-engineered custom Lempel–Ziv–Markov based compression (unknown variant of LZRC). -int lz_decompress(unsigned char *out, unsigned char *in, unsigned int size); \ No newline at end of file +int lz_decompress(unsigned char *out, unsigned char *in, unsigned int size); diff --git a/rpcs3/Emu/SysCalls/Dialogs/Dialog.cpp b/rpcs3/Emu/SysCalls/Dialogs/Dialog.cpp new file mode 100644 index 0000000000..80e37ceb0c --- /dev/null +++ b/rpcs3/Emu/SysCalls/Dialogs/Dialog.cpp @@ -0,0 +1,2 @@ +#include "stdafx.h" +#include "Dialog.h" \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Dialogs/Dialog.h b/rpcs3/Emu/SysCalls/Dialogs/Dialog.h new file mode 100644 index 0000000000..0a4e38e58e --- /dev/null +++ b/rpcs3/Emu/SysCalls/Dialogs/Dialog.h @@ -0,0 +1,8 @@ +#pragma once + +class Dialog +{ +public: + void Show(); + void Close(); +}; diff --git a/rpcs3/Emu/SysCalls/Dialogs/MessageDialog.cpp b/rpcs3/Emu/SysCalls/Dialogs/MessageDialog.cpp new file mode 100644 index 0000000000..2390ca5601 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Dialogs/MessageDialog.cpp @@ -0,0 +1,7 @@ +#include "stdafx.h" +#include "MessageDialog.h" + +MessageDialog::MessageDialog(std::string message, std::string title, int flags, char* icon) +{ + // TODO: Use RSX post-drawing instead of wxWidgets +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Dialogs/MessageDialog.h b/rpcs3/Emu/SysCalls/Dialogs/MessageDialog.h new file mode 100644 index 0000000000..9201122fa1 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Dialogs/MessageDialog.h @@ -0,0 +1,15 @@ +#pragma once +#include "Dialog.h" + +enum MessageDialogFlags +{ + MessageDialog_Button_Enter = 0x1, + MessageDialog_Button_Back = 0x2, + + MessageDialog_Controls_YesNo = 0x4, +}; + +class MessageDialog : public Dialog +{ + MessageDialog(std::string message, std::string title, int flags, char* icon); +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Dialogs/SaveDataList.cpp b/rpcs3/Emu/SysCalls/Dialogs/SaveDataList.cpp new file mode 100644 index 0000000000..b8ffafdda7 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Dialogs/SaveDataList.cpp @@ -0,0 +1,37 @@ +#include "stdafx.h" +#include "SaveDataList.h" + +void SaveDataList::Load(const std::vector& entries) +{ + wxDialog dialog(NULL, wxID_ANY, "test", wxDefaultPosition, wxSize(450, 680)); + + wxPanel *panel = new wxPanel(&dialog, -1); + wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); + wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); + wxListCtrl* list = new wxListCtrl(&dialog, wxID_ANY, wxPoint(10,10), wxSize(400,600)); + + list->InsertColumn(0, "Icon"); + list->InsertColumn(1, "Information"); + wxImageList* pImageList = new wxImageList(320,176); + + for (int i=0; iInsertItem (i, i); + list->SetItemColumnImage (i, 0, i); + list->SetItem (i, 1, wxString::Format("%d",i+1)); + + wxImage img(320, 176, entries[i].iconBuffer); + pImageList->Add(img); + } + list->SetImageList(pImageList, wxIMAGE_LIST_SMALL); + + panel->AddChild(list); + + vbox->Add(panel, 1); + vbox->Add(hbox, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, 10); + + dialog.SetSizer(vbox); + dialog.Centre(); + dialog.ShowModal(); + dialog.Destroy(); +} diff --git a/rpcs3/Emu/SysCalls/Dialogs/SaveDataList.h b/rpcs3/Emu/SysCalls/Dialogs/SaveDataList.h new file mode 100644 index 0000000000..0a9e5db1ef --- /dev/null +++ b/rpcs3/Emu/SysCalls/Dialogs/SaveDataList.h @@ -0,0 +1,9 @@ +#pragma once +#include "Dialog.h" +#include "Emu/SysCalls/Modules/cellSysutil_SaveData.h" + +class SaveDataList : public Dialog +{ +public: + void Load(const std::vector& entries); +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Dialogs/UserList.cpp b/rpcs3/Emu/SysCalls/Dialogs/UserList.cpp new file mode 100644 index 0000000000..4f2fcb076d --- /dev/null +++ b/rpcs3/Emu/SysCalls/Dialogs/UserList.cpp @@ -0,0 +1,2 @@ +#include "stdafx.h" +#include "UserList.h" diff --git a/rpcs3/Emu/SysCalls/Dialogs/UserList.h b/rpcs3/Emu/SysCalls/Dialogs/UserList.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index fa1f85e283..16db0c32d7 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -21,6 +21,9 @@ enum CELL_GCM_ERROR_ADDRESS_OVERWRAP = 0x80210005 }; +// Function declaration +int cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id); + /*------------------------------------------------------------ Memory Mapping ------------------------------------------------------------*/ @@ -44,7 +47,7 @@ int32_t cellGcmUnmapEaIoAddress(u64 ea); int32_t cellGcmUnmapIoAddress(u64 io); int32_t cellGcmUnreserveIoMapSize(u32 size); -//------------------------------------------------------------ +//---------------------------------------------------------------------------- CellGcmConfig current_config; CellGcmContextData current_context; @@ -53,6 +56,113 @@ gcmInfo gcm_info; u32 map_offset_addr = 0; u32 map_offset_pos = 0; +//---------------------------------------------------------------------------- +// Data Retrieval +//---------------------------------------------------------------------------- + +u32 cellGcmGetLabelAddress(u8 index) +{ + cellGcmSys.Log("cellGcmGetLabelAddress(index=%d)", index); + return Memory.RSXCMDMem.GetStartAddr() + 0x10 * index; +} + +u32 cellGcmGetReportDataAddressLocation(u8 location, u32 index) +{ + ConLog.Warning("cellGcmGetReportDataAddressLocation(location=%d, index=%d)", location, index); + return Emu.GetGSManager().GetRender().m_report_main_addr; +} + +u64 cellGcmGetTimeStamp(u32 index) +{ + cellGcmSys.Log("cellGcmGetTimeStamp(index=%d)", index); + return Memory.Read64(Memory.RSXFBMem.GetStartAddr() + index * 0x10); +} + +//---------------------------------------------------------------------------- +// Command Buffer Control +//---------------------------------------------------------------------------- + +u32 cellGcmGetControlRegister() +{ + cellGcmSys.Log("cellGcmGetControlRegister()"); + + return gcm_info.control_addr; +} + +u32 cellGcmGetDefaultCommandWordSize() +{ + cellGcmSys.Warning("cellGcmGetDefaultCommandWordSize()"); + return 0x400; +} + +u32 cellGcmGetDefaultSegmentWordSize() +{ + cellGcmSys.Warning("cellGcmGetDefaultSegmentWordSize()"); + return 0x100; +} + +int cellGcmInitDefaultFifoMode(int mode) +{ + cellGcmSys.Warning("cellGcmInitDefaultFifoMode(mode=%d)", mode); + return CELL_OK; +} + +int cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize) +{ + cellGcmSys.Warning("cellGcmSetDefaultFifoSize(bufferSize=0x%x, segmentSize=0x%x)", bufferSize, segmentSize); + return CELL_OK; +} + +//---------------------------------------------------------------------------- +// Hardware Resource Management +//---------------------------------------------------------------------------- + +int cellGcmBindTile(u8 index) +{ + cellGcmSys.Warning("cellGcmBindTile(index=%d)", index); + + if (index >= RSXThread::m_tiles_count) + { + return CELL_GCM_ERROR_INVALID_VALUE; + } + + auto& tile = Emu.GetGSManager().GetRender().m_tiles[index]; + tile.m_binded = true; + + return CELL_OK; +} + +int cellGcmBindZcull(u8 index) +{ + cellGcmSys.Warning("TODO: cellGcmBindZcull(index=%d)", index); + + return CELL_OK; +} + +int cellGcmGetConfiguration(mem_ptr_t config) +{ + cellGcmSys.Log("cellGcmGetConfiguration(config_addr=0x%x)", config.GetAddr()); + + if (!config.IsGood()) return CELL_EFAULT; + + *config = current_config; + + return CELL_OK; +} + +int cellGcmGetFlipStatus() +{ + return Emu.GetGSManager().GetRender().m_flip_status; +} + +u32 cellGcmGetTiledPitchSize(u32 size) +{ + //TODO + cellGcmSys.Warning("cellGcmGetTiledPitchSize(size=%d)", size); + + return size; +} + int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress) { cellGcmSys.Warning("cellGcmInit(context_addr=0x%x,cmdSize=0x%x,ioSize=0x%x,ioAddress=0x%x)", context_addr, cmdSize, ioSize, ioAddress); @@ -119,13 +229,27 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress) return CELL_OK; } -int cellGcmGetConfiguration(mem_ptr_t config) +int cellGcmResetFlipStatus() { - cellGcmSys.Log("cellGcmGetConfiguration(config_addr=0x%x)", config.GetAddr()); + Emu.GetGSManager().GetRender().m_flip_status = 1; - if(!config.IsGood()) return CELL_EFAULT; + return CELL_OK; +} - *config = current_config; +int cellGcmSetDebugOutputLevel(int level) +{ + cellGcmSys.Warning("cellGcmSetDebugOutputLevel(level=%d)", level); + + switch (level) + { + case CELL_GCM_DEBUG_LEVEL0: + case CELL_GCM_DEBUG_LEVEL1: + case CELL_GCM_DEBUG_LEVEL2: + Emu.GetGSManager().GetRender().m_debug_level = level; + break; + + default: return CELL_EINVAL; + } return CELL_OK; } @@ -151,17 +275,50 @@ int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height return CELL_OK; } -u32 cellGcmGetLabelAddress(u8 index) +int cellGcmSetFlip(mem_ptr_t ctxt, u32 id) { - cellGcmSys.Log("cellGcmGetLabelAddress(index=%d)", index); - return Memory.RSXCMDMem.GetStartAddr() + 0x10 * index; + cellGcmSys.Log("cellGcmSetFlip(ctx=0x%x, id=0x%x)", ctxt.GetAddr(), id); + + int res = cellGcmSetPrepareFlip(ctxt, id); + return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK; } -u32 cellGcmGetControlRegister() +int cellGcmSetFlipHandler(u32 handler_addr) { - cellGcmSys.Log("cellGcmGetControlRegister()"); + cellGcmSys.Warning("cellGcmSetFlipHandler(handler_addr=%d)", handler_addr); + if (handler_addr != 0 && !Memory.IsGoodAddr(handler_addr)) + { + return CELL_EFAULT; + } - return gcm_info.control_addr; + Emu.GetGSManager().GetRender().m_flip_handler.SetAddr(handler_addr); + return CELL_OK; +} + +int cellGcmSetFlipMode(u32 mode) +{ + cellGcmSys.Warning("cellGcmSetFlipMode(mode=%d)", mode); + + switch (mode) + { + case CELL_GCM_DISPLAY_HSYNC: + case CELL_GCM_DISPLAY_VSYNC: + case CELL_GCM_DISPLAY_HSYNC_WITH_NOISE: + Emu.GetGSManager().GetRender().m_flip_mode = mode; + break; + + default: + return CELL_EINVAL; + } + + return CELL_OK; +} + +void cellGcmSetFlipStatus() +{ + cellGcmSys.Warning("cellGcmSetFlipStatus()"); + + Emu.GetGSManager().GetRender().m_flip_status = 0; } int cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id) @@ -182,16 +339,16 @@ int cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id) { ConLog.Warning("bad flip!"); //cellGcmCallback(ctxt.GetAddr(), current + 8 - end); - //copied: - - CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr]; - - const s32 res = ctxt->current - ctxt->begin - ctrl.put; - - if(res > 0) Memory.Copy(ctxt->begin, ctxt->current - res, res); - ctxt->current = ctxt->begin + res; - ctrl.put = res; - ctrl.get = 0; + //copied: + + CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr]; + + const s32 res = ctxt->current - ctxt->begin - ctrl.put; + + if(res > 0) Memory.Copy(ctxt->begin, ctxt->current - res, res); + ctxt->current = ctxt->begin + res; + ctrl.put = res; + ctrl.get = 0; } current = ctxt->current; @@ -208,9 +365,80 @@ int cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id) return id; } -int cellGcmSetFlipCommand(u32 ctx, u32 id) +int cellGcmSetSecondVFrequency(u32 freq) { - return cellGcmSetPrepareFlip(ctx, id); + cellGcmSys.Warning("cellGcmSetSecondVFrequency(level=%d)", freq); + + switch (freq) + { + case CELL_GCM_DISPLAY_FREQUENCY_59_94HZ: + case CELL_GCM_DISPLAY_FREQUENCY_SCANOUT: + case CELL_GCM_DISPLAY_FREQUENCY_DISABLE: + Emu.GetGSManager().GetRender().m_frequency_mode = freq; + break; + + default: return CELL_EINVAL; + } + + return CELL_OK; +} + +int cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 comp, u16 base, u8 bank) +{ + cellGcmSys.Warning("cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)", + index, location, offset, size, pitch, comp, base, bank); + + if (index >= RSXThread::m_tiles_count || base >= 800 || bank >= 4) + { + return CELL_GCM_ERROR_INVALID_VALUE; + } + + if (offset & 0xffff || size & 0xffff || pitch & 0xf) + { + return CELL_GCM_ERROR_INVALID_ALIGNMENT; + } + + if (location >= 2 || (comp != 0 && (comp < 7 || comp > 12))) + { + return CELL_GCM_ERROR_INVALID_ENUM; + } + + if (comp) + { + cellGcmSys.Error("cellGcmSetTileInfo: bad comp! (%d)", comp); + } + + auto& tile = Emu.GetGSManager().GetRender().m_tiles[index]; + tile.m_location = location; + tile.m_offset = offset; + tile.m_size = size; + tile.m_pitch = pitch; + tile.m_comp = comp; + tile.m_base = base; + tile.m_bank = bank; + Memory.WriteData(Emu.GetGSManager().GetRender().m_tiles_addr + sizeof(CellGcmTileInfo)* index, tile.Pack()); + + return CELL_OK; +} + +u32 cellGcmSetUserHandler(u32 handler) +{ + cellGcmSys.Warning("cellGcmSetUserHandler(handler=0x%x)", handler); + return handler; +} + +int cellGcmSetVBlankHandler() +{ + UNIMPLEMENTED_FUNC(cellGcmSys); + return CELL_OK; +} + +int cellGcmSetWaitFlip(mem_ptr_t ctxt) +{ + cellGcmSys.Log("cellGcmSetWaitFlip(ctx=0x%x)", ctxt.GetAddr()); + + GSLockCurrent lock(GS_LOCK_WAIT_FLIP); + return CELL_OK; } int cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart, u32 zFormat, u32 aaFormat, u32 zCullDir, u32 zCullFormat, u32 sFunc, u32 sRef, u32 sMask) @@ -221,138 +449,298 @@ int cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart, return CELL_OK; } -int cellGcmBindZcull(u8 index) +int cellGcmUnbindTile(u8 index) { - cellGcmSys.Warning("TODO: cellGcmBindZcull(index=%d)", index); + cellGcmSys.Warning("cellGcmUnbindTile(index=%d)", index); + + if (index >= RSXThread::m_tiles_count) + { + return CELL_GCM_ERROR_INVALID_VALUE; + } + + auto& tile = Emu.GetGSManager().GetRender().m_tiles[index]; + tile.m_binded = false; return CELL_OK; } +int cellGcmUnbindZcull(u8 index) +{ + cellGcmSys.Warning("cellGcmUnbindZcull(index=%d)", index); + if (index >= 8) + return CELL_EINVAL; + + return CELL_OK; +} + +u32 cellGcmGetTileInfo() +{ + cellGcmSys.Warning("cellGcmGetTileInfo()"); + return Emu.GetGSManager().GetRender().m_tiles_addr; +} + u32 cellGcmGetZcullInfo() { cellGcmSys.Warning("cellGcmGetZcullInfo()"); return Emu.GetGSManager().GetRender().m_zculls_addr; } -int cellGcmGetFlipStatus() +u32 cellGcmGetDisplayInfo() { - return Emu.GetGSManager().GetRender().m_flip_status; + cellGcmSys.Warning("cellGcmGetDisplayInfo() = 0x%x", Emu.GetGSManager().GetRender().m_gcm_buffers_addr); + return Emu.GetGSManager().GetRender().m_gcm_buffers_addr; } -int cellGcmResetFlipStatus() +int cellGcmGetCurrentDisplayBufferId(u32 id_addr) { - Emu.GetGSManager().GetRender().m_flip_status = 1; + cellGcmSys.Warning("cellGcmGetCurrentDisplayBufferId(id_addr=0x%x)", id_addr); - return CELL_OK; -} - -int cellGcmSetFlipMode(u32 mode) -{ - cellGcmSys.Warning("cellGcmSetFlipMode(mode=%d)", mode); - - switch(mode) - { - case CELL_GCM_DISPLAY_HSYNC: - case CELL_GCM_DISPLAY_VSYNC: - case CELL_GCM_DISPLAY_HSYNC_WITH_NOISE: - Emu.GetGSManager().GetRender().m_flip_mode = mode; - break; - - default: - return CELL_EINVAL; - } - - return CELL_OK; -} - -u32 cellGcmGetTiledPitchSize(u32 size) -{ - //TODO - cellGcmSys.Warning("cellGcmGetTiledPitchSize(size=%d)", size); - - return size; -} - -u32 cellGcmSetUserHandler(u32 handler) -{ - cellGcmSys.Warning("cellGcmSetUserHandler(handler=0x%x)", handler); - return handler; -} - -u32 cellGcmGetDefaultCommandWordSize() -{ - cellGcmSys.Warning("cellGcmGetDefaultCommandWordSize()"); - return 0x400; -} - -u32 cellGcmGetDefaultSegmentWordSize() -{ - cellGcmSys.Warning("cellGcmGetDefaultSegmentWordSize()"); - return 0x100; -} - -int cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize) -{ - cellGcmSys.Warning("cellGcmSetDefaultFifoSize(bufferSize=0x%x, segmentSize=0x%x)", bufferSize, segmentSize); - return CELL_OK; -} - -int cellGcmUnbindZcull(u8 index) -{ - cellGcmSys.Warning("cellGcmUnbindZcull(index=%d)", index); - if(index >= 8) - return CELL_EINVAL; - - return CELL_OK; -} - -u64 cellGcmGetTimeStamp(u32 index) -{ - cellGcmSys.Log("cellGcmGetTimeStamp(index=%d)", index); - return Memory.Read64(Memory.RSXFBMem.GetStartAddr() + index * 0x10); -} - -int cellGcmSetFlipHandler(u32 handler_addr) -{ - cellGcmSys.Warning("cellGcmSetFlipHandler(handler_addr=%d)", handler_addr); - if(handler_addr != 0 && !Memory.IsGoodAddr(handler_addr)) + if (!Memory.IsGoodAddr(id_addr)) { return CELL_EFAULT; } - Emu.GetGSManager().GetRender().m_flip_handler.SetAddr(handler_addr); + Memory.Write32(id_addr, Emu.GetGSManager().GetRender().m_gcm_current_buffer); + return CELL_OK; } -s64 cellGcmFunc15() +//---------------------------------------------------------------------------- +// Memory Mapping +//---------------------------------------------------------------------------- + +gcm_offset offsetTable = { 0, 0 }; + +void InitOffsetTable() { - cellGcmSys.Error("cellGcmFunc15()"); - return 0; + offsetTable.io = Memory.Alloc(3072 * sizeof(u16), 1); + for (int i = 0; i<3072; i++) + { + Memory.Write16(offsetTable.io + sizeof(u16)*i, 0xFFFF); + } + + offsetTable.ea = Memory.Alloc(256 * sizeof(u16), 1);//TODO: check flags + for (int i = 0; i<256; i++) + { + Memory.Write16(offsetTable.ea + sizeof(u16)*i, 0xFFFF); + } } -int cellGcmSetFlipCommandWithWaitLabel(u32 ctx, u32 id, u32 label_index, u32 label_value) +int32_t cellGcmAddressToOffset(u64 address, mem32_t offset) { - int res = cellGcmSetPrepareFlip(ctx, id); - Memory.Write32(Memory.RSXCMDMem.GetStartAddr() + 0x10 * label_index, label_value); - return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK; -} + cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.GetAddr()); -int cellGcmSetFlip(mem_ptr_t ctxt, u32 id) -{ - cellGcmSys.Log("cellGcmSetFlip(ctx=0x%x, id=0x%x)", ctxt.GetAddr(), id); + if (address >= 0xD0000000/*not on main memory or local*/) + return CELL_GCM_ERROR_FAILURE; - int res = cellGcmSetPrepareFlip(ctxt, id); - return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK; -} + u32 result; -int cellGcmSetWaitFlip(mem_ptr_t ctxt) -{ - cellGcmSys.Log("cellGcmSetWaitFlip(ctx=0x%x)", ctxt.GetAddr()); + // If address is in range of local memory + if (Memory.RSXFBMem.IsInMyRange(address)) + { + result = address - Memory.RSXFBMem.GetStartAddr(); + } + // else check if the adress (main memory) is mapped in IO + else + { + u16 upper12Bits = Memory.Read16(offsetTable.io + sizeof(u16)*(address >> 20)); - GSLockCurrent lock(GS_LOCK_WAIT_FLIP); + if (upper12Bits != 0xFFFF) + { + result = (((u64)upper12Bits << 20) | (address & (0xFFFFF))); + } + // address is not mapped in IO + else + { + return CELL_GCM_ERROR_FAILURE; + } + } + + offset = result; return CELL_OK; } +uint32_t cellGcmGetMaxIoMapSize() +{ + return Memory.RSXIOMem.GetEndAddr() - Memory.RSXIOMem.GetStartAddr() - Memory.RSXIOMem.GetResevedAmount(); +} + +void cellGcmGetOffsetTable(mem_ptr_t table) +{ + table->io = re(offsetTable.io); + table->ea = re(offsetTable.ea); +} + +int32_t cellGcmIoOffsetToAddress(u32 ioOffset, u64 address) +{ + u64 realAddr; + + realAddr = Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + ioOffset); + + if (!realAddr) + return CELL_GCM_ERROR_FAILURE; + + Memory.Write64(address, realAddr); + + return CELL_OK; +} + +int32_t cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size) +{ + cellGcmSys.Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size); + + if ((ea & 0xFFFFF) || (io & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE; + + //check if the mapping was successfull + if (Memory.RSXIOMem.Map(ea, size, Memory.RSXIOMem.GetStartAddr() + io)) + { + //fill the offset table + for (u32 i = 0; i<(size >> 20); i++) + { + Memory.Write16(offsetTable.io + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i); + Memory.Write16(offsetTable.ea + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i); + } + } + else + { + return CELL_GCM_ERROR_FAILURE; + } + + return CELL_OK; +} + +int32_t cellGcmMapEaIoAddressWithFlags(const u32 ea, const u32 io, const u32 size, const u32 flags) +{ + cellGcmSys.Warning("cellGcmMapEaIoAddressWithFlags(ea=0x%x, io=0x%x, size=0x%x, flags=0x%x)", ea, io, size, flags); + return cellGcmMapEaIoAddress(ea, io, size); // TODO: strict ordering +} + +int32_t cellGcmMapLocalMemory(u64 address, u64 size) +{ + if (!local_size && !local_addr) + { + local_size = 0xf900000; //TODO + local_addr = Memory.RSXFBMem.GetStartAddr(); + Memory.RSXFBMem.AllocAlign(local_size); + Memory.Write32(address, local_addr); + Memory.Write32(size, local_size); + } + else + { + cellGcmSys.Error("RSX local memory already mapped"); + return CELL_GCM_ERROR_FAILURE; + } + + return CELL_OK; +} + +int32_t cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset) +{ + cellGcmSys.Warning("cellGcmMapMainMemory(ea=0x%x,size=0x%x,offset_addr=0x%x)", ea, size, offset.GetAddr()); + + u64 io; + + if ((ea & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE; + + //check if the mapping was successfull + if (io = Memory.RSXIOMem.Map(ea, size, 0)) + { + // convert to offset + io = io - Memory.RSXIOMem.GetStartAddr(); + + //fill the offset table + for (u32 i = 0; i<(size >> 20); i++) + { + Memory.Write16(offsetTable.io + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i); + Memory.Write16(offsetTable.ea + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i); + } + + offset = io; + } + else + { + return CELL_GCM_ERROR_NO_IO_PAGE_TABLE; + } + + Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress; + + return CELL_OK; +} + +int32_t cellGcmReserveIoMapSize(const u32 size) +{ + if (size & 0xFFFFF) + return CELL_GCM_ERROR_INVALID_ALIGNMENT; + + if (size > cellGcmGetMaxIoMapSize()) + return CELL_GCM_ERROR_INVALID_VALUE; + + Memory.RSXIOMem.Reserve(size); + return CELL_OK; +} + +int32_t cellGcmUnmapEaIoAddress(u64 ea) +{ + u32 size; + if (size = Memory.RSXIOMem.UnmapRealAddress(ea)) + { + u64 io; + ea = ea >> 20; + io = Memory.Read16(offsetTable.io + (ea*sizeof(u16))); + + for (u32 i = 0; i> 20; + ea = Memory.Read16(offsetTable.ea + (io*sizeof(u16))); + + for (u32 i = 0; i Memory.RSXIOMem.GetResevedAmount()) + return CELL_GCM_ERROR_INVALID_VALUE; + + Memory.RSXIOMem.Unreserve(size); + return CELL_OK; +} + +//---------------------------------------------------------------------------- +// Cursor +//---------------------------------------------------------------------------- + int cellGcmInitCursor() { UNIMPLEMENTED_FUNC(cellGcmSys); @@ -371,11 +759,6 @@ int cellGcmSetCursorDisable() return CELL_OK; } -int cellGcmSetVBlankHandler() -{ - UNIMPLEMENTED_FUNC(cellGcmSys); - return CELL_OK; -} int cellGcmUpdateCursor() { @@ -395,25 +778,9 @@ int cellGcmSetCursorImageOffset(u32 offset) return CELL_OK; } -u32 cellGcmGetDisplayInfo() -{ - cellGcmSys.Warning("cellGcmGetDisplayInfo() = 0x%x", Emu.GetGSManager().GetRender().m_gcm_buffers_addr); - return Emu.GetGSManager().GetRender().m_gcm_buffers_addr; -} - -int cellGcmGetCurrentDisplayBufferId(u32 id_addr) -{ - cellGcmSys.Warning("cellGcmGetCurrentDisplayBufferId(id_addr=0x%x)", id_addr); - - if(!Memory.IsGoodAddr(id_addr)) - { - return CELL_EFAULT; - } - - Memory.Write32(id_addr, Emu.GetGSManager().GetRender().m_gcm_current_buffer); - - return CELL_OK; -} +//------------------------------------------------------------------------ +// Functions for Maintaining Compatibility +//------------------------------------------------------------------------ void cellGcmSetDefaultCommandBuffer() { @@ -421,11 +788,26 @@ void cellGcmSetDefaultCommandBuffer() Memory.Write32(Emu.GetGSManager().GetRender().m_ctxt_addr, gcm_info.context_addr); } -void cellGcmSetFlipStatus() +//------------------------------------------------------------------------ +// Other +//------------------------------------------------------------------------ + +int cellGcmSetFlipCommand(u32 ctx, u32 id) { - cellGcmSys.Warning("cellGcmSetFlipStatus()"); - - Emu.GetGSManager().GetRender().m_flip_status = 0; + return cellGcmSetPrepareFlip(ctx, id); +} + +s64 cellGcmFunc15() +{ + cellGcmSys.Error("cellGcmFunc15()"); + return 0; +} + +int cellGcmSetFlipCommandWithWaitLabel(u32 ctx, u32 id, u32 label_index, u32 label_value) +{ + int res = cellGcmSetPrepareFlip(ctx, id); + Memory.Write32(Memory.RSXCMDMem.GetStartAddr() + 0x10 * label_index, label_value); + return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK; } int cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 comp, u16 base, u8 bank) @@ -467,411 +849,102 @@ int cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co return CELL_OK; } -int cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 comp, u16 base, u8 bank) -{ - cellGcmSys.Warning("cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)", - index, location, offset, size, pitch, comp, base, bank); - - if(index >= RSXThread::m_tiles_count || base >= 800 || bank >= 4) - { - return CELL_GCM_ERROR_INVALID_VALUE; - } - - if(offset & 0xffff || size & 0xffff || pitch & 0xf) - { - return CELL_GCM_ERROR_INVALID_ALIGNMENT; - } - - if(location >= 2 || (comp != 0 && (comp < 7 || comp > 12))) - { - return CELL_GCM_ERROR_INVALID_ENUM; - } - - if(comp) - { - cellGcmSys.Error("cellGcmSetTileInfo: bad comp! (%d)", comp); - } - - auto& tile = Emu.GetGSManager().GetRender().m_tiles[index]; - tile.m_location = location; - tile.m_offset = offset; - tile.m_size = size; - tile.m_pitch = pitch; - tile.m_comp = comp; - tile.m_base = base; - tile.m_bank = bank; - Memory.WriteData(Emu.GetGSManager().GetRender().m_tiles_addr + sizeof(CellGcmTileInfo) * index, tile.Pack()); - - return CELL_OK; -} - -int cellGcmBindTile(u8 index) -{ - cellGcmSys.Warning("cellGcmBindTile(index=%d)", index); - - if(index >= RSXThread::m_tiles_count) - { - return CELL_GCM_ERROR_INVALID_VALUE; - } - - auto& tile = Emu.GetGSManager().GetRender().m_tiles[index]; - tile.m_binded = true; - - return CELL_OK; -} - -int cellGcmUnbindTile(u8 index) -{ - cellGcmSys.Warning("cellGcmUnbindTile(index=%d)", index); - - if(index >= RSXThread::m_tiles_count) - { - return CELL_GCM_ERROR_INVALID_VALUE; - } - - auto& tile = Emu.GetGSManager().GetRender().m_tiles[index]; - tile.m_binded = false; - - return CELL_OK; -} - -u32 cellGcmGetTileInfo() -{ - cellGcmSys.Warning("cellGcmGetTileInfo()"); - return Emu.GetGSManager().GetRender().m_tiles_addr; -} - -int cellGcmInitDefaultFifoMode(int mode) -{ - cellGcmSys.Warning("cellGcmInitDefaultFifoMode(mode=%d)", mode); - return CELL_OK; -} - -u32 cellGcmGetReportDataAddressLocation(u8 location, u32 index) -{ - ConLog.Warning("cellGcmGetReportDataAddressLocation(location=%d, index=%d)", location, index); - return Emu.GetGSManager().GetRender().m_report_main_addr; -} - -int cellGcmSetDebugOutputLevel (int level) -{ - cellGcmSys.Warning("cellGcmSetDebugOutputLevel(level=%d)", level); - - switch (level) - { - case CELL_GCM_DEBUG_LEVEL0: - case CELL_GCM_DEBUG_LEVEL1: - case CELL_GCM_DEBUG_LEVEL2: - Emu.GetGSManager().GetRender().m_debug_level = level; - break; - - default: return CELL_EINVAL; - } - - return CELL_OK; -} - -int cellGcmSetSecondVFrequency (u32 freq) -{ - cellGcmSys.Warning("cellGcmSetSecondVFrequency(level=%d)", freq); - - switch (freq) - { - case CELL_GCM_DISPLAY_FREQUENCY_59_94HZ: - case CELL_GCM_DISPLAY_FREQUENCY_SCANOUT: - case CELL_GCM_DISPLAY_FREQUENCY_DISABLE: - Emu.GetGSManager().GetRender().m_frequency_mode = freq; - break; - - default: return CELL_EINVAL; - } - - return CELL_OK; -} - -/*------------------------------------------------------------ - Memory Mapping -------------------------------------------------------------*/ - -gcm_offset offsetTable = {0, 0}; - -void InitOffsetTable() -{ - offsetTable.io = Memory.Alloc(3072*sizeof(u16), 1); - for(int i=0; i<3072; i++) - { - Memory.Write16(offsetTable.io + sizeof(u16)*i, 0xFFFF); - } - - offsetTable.ea = Memory.Alloc(256*sizeof(u16), 1);//TODO: check flags - for(int i=0; i<256; i++) - { - Memory.Write16(offsetTable.ea + sizeof(u16)*i, 0xFFFF); - } -} - -int32_t cellGcmAddressToOffset(u64 address, mem32_t offset) -{ - cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.GetAddr()); - - if(address >= 0xD0000000/*not on main memory or local*/) - return CELL_GCM_ERROR_FAILURE; - - u32 result; - - // If address is in range of local memory - if(Memory.RSXFBMem.IsInMyRange(address)) - { - result = address - Memory.RSXFBMem.GetStartAddr(); - } - // else check if the adress (main memory) is mapped in IO - else - { - u16 upper12Bits = Memory.Read16(offsetTable.io + sizeof(u16)*(address >> 20)); - - if(upper12Bits != 0xFFFF) - { - result = (((u64)upper12Bits << 20) | (address & (0xFFFFF))); - } - // address is not mapped in IO - else - { - return CELL_GCM_ERROR_FAILURE; - } - } - - offset = result; - return CELL_OK; -} - -uint32_t cellGcmGetMaxIoMapSize() -{ - return Memory.RSXIOMem.GetEndAddr() - Memory.RSXIOMem.GetStartAddr() - Memory.RSXIOMem.GetResevedAmount(); -} - -void cellGcmGetOffsetTable(mem_ptr_t table) -{ - table->io = re(offsetTable.io); - table->ea = re(offsetTable.ea); -} - -int32_t cellGcmIoOffsetToAddress(u32 ioOffset, u64 address) -{ - u64 realAddr; - - realAddr = Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + ioOffset); - - if(!realAddr) - return CELL_GCM_ERROR_FAILURE; - - Memory.Write64(address, realAddr); - - return CELL_OK; -} - -int32_t cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size) -{ - cellGcmSys.Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size); - - if((ea & 0xFFFFF) || (io & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE; - - //check if the mapping was successfull - if(Memory.RSXIOMem.Map(ea, size, Memory.RSXIOMem.GetStartAddr() + io)) - { - //fill the offset table - for(u32 i=0; i<(size >> 20); i++) - { - Memory.Write16(offsetTable.io + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i); - Memory.Write16(offsetTable.ea + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i); - } - } - else - { - return CELL_GCM_ERROR_FAILURE; - } - - return CELL_OK; -} - -int32_t cellGcmMapEaIoAddressWithFlags(const u32 ea, const u32 io, const u32 size, const u32 flags) -{ - cellGcmSys.Warning("cellGcmMapEaIoAddressWithFlags(ea=0x%x, io=0x%x, size=0x%x, flags=0x%x)", ea, io, size, flags); - return cellGcmMapEaIoAddress(ea, io, size); // TODO: strict ordering -} - -int32_t cellGcmMapLocalMemory(u64 address, u64 size) -{ - if(!local_size && !local_addr) - { - local_size = 0xf900000; //TODO - local_addr = Memory.RSXFBMem.GetStartAddr(); - Memory.RSXFBMem.AllocAlign(local_size); - Memory.Write32(address, local_addr); - Memory.Write32(size, local_size); - } - else - { - cellGcmSys.Error("RSX local memory already mapped"); - return CELL_GCM_ERROR_FAILURE; - } - - return CELL_OK; -} - -int32_t cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset) -{ - cellGcmSys.Warning("cellGcmMapMainMemory(ea=0x%x,size=0x%x,offset_addr=0x%x)", ea, size, offset.GetAddr()); - - u64 io; - - if((ea & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE; - - //check if the mapping was successfull - if(io = Memory.RSXIOMem.Map(ea, size, 0)) - { - // convert to offset - io = io - Memory.RSXIOMem.GetStartAddr(); - - //fill the offset table - for(u32 i=0; i<(size >> 20); i++) - { - Memory.Write16(offsetTable.io + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i); - Memory.Write16(offsetTable.ea + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i); - } - - offset = io; - } - else - { - return CELL_GCM_ERROR_NO_IO_PAGE_TABLE; - } - - Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress; - - return CELL_OK; -} - -int32_t cellGcmReserveIoMapSize(const u32 size) -{ - if(size & 0xFFFFF) - return CELL_GCM_ERROR_INVALID_ALIGNMENT; - - if(size > cellGcmGetMaxIoMapSize()) - return CELL_GCM_ERROR_INVALID_VALUE; - - Memory.RSXIOMem.Reserve(size); - return CELL_OK; -} - -int32_t cellGcmUnmapEaIoAddress(u64 ea) -{ - u32 size; - if(size = Memory.RSXIOMem.UnmapRealAddress(ea)) - { - u64 io; - ea = ea >> 20; - io = Memory.Read16(offsetTable.io + (ea*sizeof(u16))); - - for(u32 i=0; i> 20; - ea = Memory.Read16(offsetTable.ea + (io*sizeof(u16))); - - for(u32 i=0; i Memory.RSXIOMem.GetResevedAmount()) - return CELL_GCM_ERROR_INVALID_VALUE; - - Memory.RSXIOMem.Unreserve(size); - return CELL_OK; -} - -//------------------------------------------------------------ +//---------------------------------------------------------------------------- void cellGcmSys_init() { - cellGcmSys.AddFunc(0x055bd74d, cellGcmGetTiledPitchSize); - cellGcmSys.AddFunc(0x06edea9e, cellGcmSetUserHandler); - cellGcmSys.AddFunc(0x15bae46b, cellGcmInit); - cellGcmSys.AddFunc(0x21397818, cellGcmSetFlipCommand); - cellGcmSys.AddFunc(0x3a33c1fd, cellGcmFunc15); - cellGcmSys.AddFunc(0x4ae8d215, cellGcmSetFlipMode); - cellGcmSys.AddFunc(0x5e2ee0f0, cellGcmGetDefaultCommandWordSize); - cellGcmSys.AddFunc(0x72a577ce, cellGcmGetFlipStatus); - cellGcmSys.AddFunc(0x8cdf8c70, cellGcmGetDefaultSegmentWordSize); - cellGcmSys.AddFunc(0x9ba451e4, cellGcmSetDefaultFifoSize); - cellGcmSys.AddFunc(0xa53d12ae, cellGcmSetDisplayBuffer); - cellGcmSys.AddFunc(0xa547adde, cellGcmGetControlRegister); - cellGcmSys.AddFunc(0xb2e761d4, cellGcmResetFlipStatus); - cellGcmSys.AddFunc(0xd8f88e1a, cellGcmSetFlipCommandWithWaitLabel); - cellGcmSys.AddFunc(0xe315a0b2, cellGcmGetConfiguration); - cellGcmSys.AddFunc(0x9dc04436, cellGcmBindZcull); - cellGcmSys.AddFunc(0xd34a420d, cellGcmSetZcull); - cellGcmSys.AddFunc(0xd9a0a879, cellGcmGetZcullInfo); + //------------------------------------------------------------------------ + // Generating Render Commands + //------------------------------------------------------------------------ + + // TODO + + //------------------------------------------------------------------------ + // Data Retrieval + //------------------------------------------------------------------------ + // cellGcmGetCurrentField + cellGcmSys.AddFunc(0xf80196c1, cellGcmGetLabelAddress); + // cellGcmGetNotifyDataAddress + // cellGcmGetReport + // cellGcmGetReportDataAddress + cellGcmSys.AddFunc(0x8572bce2, cellGcmGetReportDataAddressLocation); + // cellGcmGetReportDataLocation cellGcmSys.AddFunc(0x5a41c10f, cellGcmGetTimeStamp); + // cellGcmGetTimeStampLocation + + //------------------------------------------------------------------------ + // Data Transfer and Format Conversion + //------------------------------------------------------------------------ + + // TODO + + //------------------------------------------------------------------------ + // Command Buffer Control + //------------------------------------------------------------------------ + // cellGcmCallbackForSnc + // cellGcmFinish + // cellGcmFlush + cellGcmSys.AddFunc(0xa547adde, cellGcmGetControlRegister); + cellGcmSys.AddFunc(0x5e2ee0f0, cellGcmGetDefaultCommandWordSize); + cellGcmSys.AddFunc(0x8cdf8c70, cellGcmGetDefaultSegmentWordSize); + cellGcmSys.AddFunc(0xcaabd992, cellGcmInitDefaultFifoMode); + // cellGcmReserveMethodSize + // cellGcmResetDefaultCommandBuffer + // cellGcmSetCallCommand + cellGcmSys.AddFunc(0x9ba451e4, cellGcmSetDefaultFifoSize); + // cellGcmSetJumpCommand + // cellGcmSetNopCommand + // cellGcmSetReturnCommand + // cellGcmSetSkipNop + // cellGcmSetupContextData + // cellGcmSetUserCommand + + //------------------------------------------------------------------------ + // Hardware Resource Management + //------------------------------------------------------------------------ + cellGcmSys.AddFunc(0x4524cccd, cellGcmBindTile); + cellGcmSys.AddFunc(0x9dc04436, cellGcmBindZcull); + // cellGcmDumpGraphicsError + cellGcmSys.AddFunc(0xe315a0b2, cellGcmGetConfiguration); + // cellGcmGetDisplayBufferByFlipIndex + cellGcmSys.AddFunc(0x72a577ce, cellGcmGetFlipStatus); + // cellGcmgetLastFlipTime + // cellGcmGetLastSecondVTime + cellGcmSys.AddFunc(0x055bd74d, cellGcmGetTiledPitchSize); + // cellGcmGetVBlankCount + cellGcmSys.AddFunc(0x15bae46b, cellGcmInit); + // cellGcmInitSystemMode + cellGcmSys.AddFunc(0xb2e761d4, cellGcmResetFlipStatus); + cellGcmSys.AddFunc(0x51c9d62b, cellGcmSetDebugOutputLevel); + cellGcmSys.AddFunc(0xa53d12ae, cellGcmSetDisplayBuffer); + cellGcmSys.AddFunc(0xdc09357e, cellGcmSetFlip); + cellGcmSys.AddFunc(0xa41ef7e8, cellGcmSetFlipHandler); + // cellGcmSetFlipImmediate + cellGcmSys.AddFunc(0x4ae8d215, cellGcmSetFlipMode); + cellGcmSys.AddFunc(0xa47c09ff, cellGcmSetFlipStatus); + // cellGcmSetFlipWithWaitLabel + // cellGcmSetGraphicsHandler + cellGcmSys.AddFunc(0x0b4b62d5, cellGcmSetPrepareFlip); + //cellGcmSetQueueHandler + cellGcmSys.AddFunc(0x4d7ce993, cellGcmSetSecondVFrequency); + // cellGcmSetSecondVHandler + cellGcmSys.AddFunc(0xbd100dbc, cellGcmSetTileInfo); + cellGcmSys.AddFunc(0x06edea9e, cellGcmSetUserHandler); + // cellGcmSetVBlankFrequency + cellGcmSys.AddFunc(0xa91b0402, cellGcmSetVBlankHandler); + cellGcmSys.AddFunc(0x983fb9aa, cellGcmSetWaitFlip); + cellGcmSys.AddFunc(0xd34a420d, cellGcmSetZcull); + // cellGcmSortRemapEaIoAddress cellGcmSys.AddFunc(0xd9b7653e, cellGcmUnbindTile); cellGcmSys.AddFunc(0xa75640e8, cellGcmUnbindZcull); - cellGcmSys.AddFunc(0xa41ef7e8, cellGcmSetFlipHandler); - cellGcmSys.AddFunc(0xf80196c1, cellGcmGetLabelAddress); - cellGcmSys.AddFunc(0x107bf3a1, cellGcmInitCursor); - cellGcmSys.AddFunc(0x1a0de550, cellGcmSetCursorPosition); - cellGcmSys.AddFunc(0x69c6cc82, cellGcmSetCursorDisable); - cellGcmSys.AddFunc(0xa91b0402, cellGcmSetVBlankHandler); - cellGcmSys.AddFunc(0xbd2fa0a7, cellGcmUpdateCursor); - cellGcmSys.AddFunc(0xc47d0812, cellGcmSetCursorEnable); - cellGcmSys.AddFunc(0xf9bfdc72, cellGcmSetCursorImageOffset); + cellGcmSys.AddFunc(0x657571f7, cellGcmGetTileInfo); + cellGcmSys.AddFunc(0xd9a0a879, cellGcmGetZcullInfo); cellGcmSys.AddFunc(0x0e6b0dae, cellGcmGetDisplayInfo); cellGcmSys.AddFunc(0x93806525, cellGcmGetCurrentDisplayBufferId); - cellGcmSys.AddFunc(0xbc982946, cellGcmSetDefaultCommandBuffer); - cellGcmSys.AddFunc(0xa47c09ff, cellGcmSetFlipStatus); - cellGcmSys.AddFunc(0xd0b1d189, cellGcmSetTile); - cellGcmSys.AddFunc(0xbd100dbc, cellGcmSetTileInfo); - cellGcmSys.AddFunc(0x4524cccd, cellGcmBindTile); - cellGcmSys.AddFunc(0x0b4b62d5, cellGcmSetPrepareFlip); - cellGcmSys.AddFunc(0x657571f7, cellGcmGetTileInfo); - cellGcmSys.AddFunc(0xcaabd992, cellGcmInitDefaultFifoMode); - cellGcmSys.AddFunc(0x8572bce2, cellGcmGetReportDataAddressLocation); - cellGcmSys.AddFunc(0x51c9d62b, cellGcmSetDebugOutputLevel); - cellGcmSys.AddFunc(0x4d7ce993, cellGcmSetSecondVFrequency); - cellGcmSys.AddFunc(0xdc09357e, cellGcmSetFlip); - cellGcmSys.AddFunc(0x983fb9aa, cellGcmSetWaitFlip); + //------------------------------------------------------------------------ //Memory Mapping + //------------------------------------------------------------------------ cellGcmSys.AddFunc(0x21ac3697, cellGcmAddressToOffset); cellGcmSys.AddFunc(0xfb81c03e, cellGcmGetMaxIoMapSize); cellGcmSys.AddFunc(0x2922aed0, cellGcmGetOffsetTable); @@ -884,6 +957,33 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0xefd00f54, cellGcmUnmapEaIoAddress); cellGcmSys.AddFunc(0xdb23e867, cellGcmUnmapIoAddress); cellGcmSys.AddFunc(0x3b9bd5bd, cellGcmUnreserveIoMapSize); + + //------------------------------------------------------------------------ + // Cursor + //------------------------------------------------------------------------ + cellGcmSys.AddFunc(0x107bf3a1, cellGcmInitCursor); + cellGcmSys.AddFunc(0xc47d0812, cellGcmSetCursorEnable); + cellGcmSys.AddFunc(0x69c6cc82, cellGcmSetCursorDisable); + cellGcmSys.AddFunc(0xf9bfdc72, cellGcmSetCursorImageOffset); + cellGcmSys.AddFunc(0x1a0de550, cellGcmSetCursorPosition); + cellGcmSys.AddFunc(0xbd2fa0a7, cellGcmUpdateCursor); + + //------------------------------------------------------------------------ + // Functions for Maintaining Compatibility + //------------------------------------------------------------------------ + // cellGcmGetCurrentBuffer + // cellGcmSetCurrentBuffer + cellGcmSys.AddFunc(0xbc982946, cellGcmSetDefaultCommandBuffer); + // cellGcmSetDefaultCommandBufferAndSegmentWordSize + // cellGcmSetUserCallback + + //------------------------------------------------------------------------ + // Other + //------------------------------------------------------------------------ + cellGcmSys.AddFunc(0x21397818, cellGcmSetFlipCommand); + cellGcmSys.AddFunc(0x3a33c1fd, cellGcmFunc15); + cellGcmSys.AddFunc(0xd8f88e1a, cellGcmSetFlipCommandWithWaitLabel); + cellGcmSys.AddFunc(0xd0b1d189, cellGcmSetTile); } void cellGcmSys_Load() diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.cpp index e885856e4c..8f4ab520cd 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.cpp @@ -23,17 +23,18 @@ public: if (sortOrder == CELL_SAVEDATA_SORTORDER_DESCENT) { if (sortType == CELL_SAVEDATA_SORTTYPE_MODIFIEDTIME) - return entry1.timestamp >= entry2.timestamp; - else //if (sortType == CELL_SAVEDATA_SORTTYPE_SUBTITLE) + return entry1.st_mtime_ >= entry2.st_mtime_; + if (sortType == CELL_SAVEDATA_SORTTYPE_SUBTITLE) return entry1.subtitle >= entry2.subtitle; } - else //if (sortOrder == CELL_SAVEDATA_SORTORDER_ASCENT) + if (sortOrder == CELL_SAVEDATA_SORTORDER_ASCENT) { if (sortType == CELL_SAVEDATA_SORTTYPE_MODIFIEDTIME) - return entry1.timestamp < entry2.timestamp; - else //if (sortType == CELL_SAVEDATA_SORTTYPE_SUBTITLE) + return entry1.st_mtime_ < entry2.st_mtime_; + if (sortType == CELL_SAVEDATA_SORTTYPE_SUBTITLE) return entry1.subtitle < entry2.subtitle; } + return true; } }; @@ -55,7 +56,7 @@ u64 getSaveDataSize(const std::string& dirName) return totalSize; } -void getSaveDataEntry(std::vector& saveEntries, const std::string& saveDir) +void addSaveDataEntry(std::vector& saveEntries, const std::string& saveDir) { // PSF parameters vfsFile f(saveDir + "/PARAM.SFO"); @@ -75,12 +76,56 @@ void getSaveDataEntry(std::vector& saveEntries, const std::st saveEntry.subtitle = psf.GetString("SUB_TITLE"); saveEntry.details = psf.GetString("DETAIL"); saveEntry.sizeKb = getSaveDataSize(saveDir)/1024; - saveEntry.timestamp = 0; // TODO - saveEntry.iconBuffer = stbi_load(localPath.mb_str(), &width, &height, &actual_components, 3); + saveEntry.st_atime_ = 0; // TODO + saveEntry.st_mtime_ = 0; // TODO + saveEntry.st_ctime_ = 0; // TODO + saveEntry.iconBuf = stbi_load(localPath.mb_str(), &width, &height, &actual_components, 3); + saveEntry.iconBufSize = width * height * 3; + saveEntry.isNew = false; saveEntries.push_back(saveEntry); } +void addNewSaveDataEntry(std::vector& saveEntries, mem_ptr_t newData) +{ + SaveDataListEntry saveEntry; + saveEntry.dirName = (char*)Memory.VirtualToRealAddr(newData->dirName_addr); + saveEntry.title = (char*)Memory.VirtualToRealAddr(newData->icon->title_addr); + saveEntry.subtitle = (char*)Memory.VirtualToRealAddr(newData->icon->title_addr); + saveEntry.iconBuf = Memory.VirtualToRealAddr(newData->icon->iconBuf_addr); + saveEntry.iconBufSize = newData->icon->iconBufSize; + saveEntry.isNew = true; + // TODO: Add information stored in newData->iconPosition. (It's not very relevant) + + saveEntries.push_back(saveEntry); +} + +u32 focusSaveDataEntry(const std::vector& saveEntries, u32 focusPosition) +{ + return 0; +} + +void setSaveDataEntries(std::vector& saveEntries, mem_ptr_t fixedList, u32 fixedListNum) +{ + std::vector::iterator entry = saveEntries.begin(); + while (entry != saveEntries.end()) + { + bool found = false; + for (u32 j=0; jdirName == (char*)fixedList[j].dirName) + { + found = true; + break; + } + } + if (!found) + entry = saveEntries.erase(entry); + else + entry++; + } +} + // Functions int cellSaveDataListSave2(u32 version, mem_ptr_t setList, mem_ptr_t setBuf, @@ -95,7 +140,7 @@ int cellSaveDataListSave2(u32 version, mem_ptr_t setList, m MemoryAllocator result; MemoryAllocator listGet; - MemoryAllocator listSet; + MemoryAllocator listSet; std::string saveBaseDir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current user vfsDir dir(saveBaseDir); @@ -115,14 +160,14 @@ int cellSaveDataListSave2(u32 version, mem_ptr_t setList, m listGet->dirNum++; std::string saveDir = saveBaseDir + (const char*)(entry->name.mb_str()); - getSaveDataEntry(saveEntries, saveDir); + addSaveDataEntry(saveEntries, saveDir); } } // Sort the entries and fill the listGet->dirList array std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder)); - listGet->dirList_addr = setBuf->buf_addr; - CellSaveDataDirList* dirList = (CellSaveDataDirList*)Memory.VirtualToRealAddr(listGet->dirList_addr); + listGet->dirList.SetAddr(setBuf->buf_addr); + CellSaveDataDirList* dirList = (CellSaveDataDirList*)Memory.VirtualToRealAddr(listGet->dirList.GetAddr()); for (u32 i=0; i setList, m funcFile(result.GetAddr(), fileGet.GetAddr(), fileSet.GetAddr()); for (auto& entry : saveEntries) { - delete[] entry.iconBuffer; - entry.iconBuffer = nullptr; + delete[] entry.iconBuf; + entry.iconBuf = nullptr; } return CELL_SAVEDATA_RET_OK; @@ -158,7 +203,7 @@ int cellSaveDataListLoad2(u32 version, mem_ptr_t setList, m MemoryAllocator result; MemoryAllocator listGet; - MemoryAllocator listSet; + MemoryAllocator listSet; std::string saveBaseDir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current user vfsDir dir(saveBaseDir); @@ -178,23 +223,42 @@ int cellSaveDataListLoad2(u32 version, mem_ptr_t setList, m listGet->dirNum++; std::string saveDir = saveBaseDir + (const char*)(entry->name.mb_str()); - getSaveDataEntry(saveEntries, saveDir); + addSaveDataEntry(saveEntries, saveDir); } } // Sort the entries and fill the listGet->dirList array std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder)); - listGet->dirList_addr = setBuf->buf_addr; - CellSaveDataDirList* dirList = (CellSaveDataDirList*)Memory.VirtualToRealAddr(listGet->dirList_addr); + listGet->dirList.SetAddr(setBuf->buf_addr); + CellSaveDataDirList* dirList = (CellSaveDataDirList*)Memory.VirtualToRealAddr(listGet->dirList.GetAddr()); for (u32 i=0; iresult < 0) { + ConLog.Error("cellSaveDataListLoad2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + return CELL_SAVEDATA_ERROR_CBRESULT; + } + if (!listSet->fixedList.IsGood()) { + return CELL_SAVEDATA_ERROR_PARAM; + } + setSaveDataEntries(saveEntries, (u32)listSet->fixedList.GetAddr(), listSet->fixedListNum); + u32 focusIndex = focusSaveDataEntry(saveEntries, listSet->focusPosition); MemoryAllocator statGet; MemoryAllocator statSet; + + // TODO: Display the dialog here + ConLog.Warning("cellSaveDataListLoad2:"); + + statGet->isNewData = CELL_SAVEDATA_ISNEWDATA_NO; // You can *never* load new data + //statGet->dir = + + + funcStat(result.GetAddr(), statGet.GetAddr(), statSet.GetAddr()); MemoryAllocator fileGet; @@ -202,8 +266,8 @@ int cellSaveDataListLoad2(u32 version, mem_ptr_t setList, m funcFile(result.GetAddr(), fileGet.GetAddr(), fileSet.GetAddr()); for (auto& entry : saveEntries) { - delete[] entry.iconBuffer; - entry.iconBuffer = nullptr; + delete[] entry.iconBuf; + entry.iconBuf = nullptr; } return CELL_SAVEDATA_RET_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.h b/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.h index 16cf91ca72..0ebcc172f9 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.h @@ -19,6 +19,19 @@ enum CELL_SAVEDATA_ERROR_NOTSUPPORTED = 0x8002b40c, }; +// Callback return codes +enum +{ + CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM = 2, + CELL_SAVEDATA_CBRESULT_OK_LAST = 1, + CELL_SAVEDATA_CBRESULT_OK_NEXT = 0, + CELL_SAVEDATA_CBRESULT_ERR_NOSPACE = -1, + CELL_SAVEDATA_CBRESULT_ERR_FAILURE = -2, + CELL_SAVEDATA_CBRESULT_ERR_BROKEN = -3, + CELL_SAVEDATA_CBRESULT_ERR_NODATA = -4, + CELL_SAVEDATA_CBRESULT_ERR_INVALID = -5, +}; + // Constants enum { @@ -46,6 +59,18 @@ enum // CellSaveDataSortOrder CELL_SAVEDATA_SORTORDER_DESCENT = 0, CELL_SAVEDATA_SORTORDER_ASCENT = 1, + + // CellSaveDataIsNewData + CELL_SAVEDATA_ISNEWDATA_NO = 0, + CELL_SAVEDATA_ISNEWDATA_YES = 1, + + // CellSaveDataFocusPosition + CELL_SAVEDATA_FOCUSPOS_DIRNAME = 0, + CELL_SAVEDATA_FOCUSPOS_LISTHEAD = 1, + CELL_SAVEDATA_FOCUSPOS_LISTTAIL = 2, + CELL_SAVEDATA_FOCUSPOS_LATEST = 3, + CELL_SAVEDATA_FOCUSPOS_OLDEST = 4, + CELL_SAVEDATA_FOCUSPOS_NEWDATA = 5, }; @@ -77,7 +102,7 @@ struct CellSaveDataListNewData { be_t iconPosition; be_t dirName_addr; // char* - be_t icon_addr; // CellSaveDataNewDataIcon* + mem_beptr_t icon; }; struct CellSaveDataDirList @@ -90,7 +115,7 @@ struct CellSaveDataListGet { be_t dirNum; be_t dirListNum; - be_t dirList_addr; // CellSaveDataDirList* + mem_beptr_t dirList; }; struct CellSaveDataListSet @@ -98,14 +123,15 @@ struct CellSaveDataListSet be_t focusPosition; be_t focusDirName_addr; // char* be_t fixedListNum; - be_t fixedList_addr; // CellSaveDataDirList* - be_t newData_addr; // CellSaveDataListNewData* + mem_beptr_t fixedList; + mem_beptr_t newData; + be_t reserved_addr; // void* }; struct CellSaveDataFixedSet { be_t dirName_addr; // char* - be_t newIcon_addr; // CellSaveDataNewDataIcon* + mem_beptr_t newIcon; be_t option; }; @@ -151,7 +177,7 @@ struct CellSaveDataStatGet be_t sysSizeKB; be_t fileNum; be_t fileListNum; - be_t fileList_addr; // CellSaveDataFileStat* + mem_beptr_t fileList; }; struct CellSaveDataAutoIndicator @@ -165,9 +191,9 @@ struct CellSaveDataAutoIndicator struct CellSaveDataStatSet { - be_t setParam_addr; // CellSaveDataSystemFileParam* + mem_beptr_t setParam; be_t reCreateMode; - be_t indicator_addr; // CellSaveDataAutoIndicator* + mem_beptr_t indicator; }; struct CellSaveDataFileGet @@ -223,8 +249,12 @@ struct SaveDataListEntry std::string subtitle; std::string details; u32 sizeKb; - u64 timestamp; - void* iconBuffer; + s64 st_atime_; + s64 st_mtime_; + s64 st_ctime_; + void* iconBuf; + u32 iconBufSize; + bool isNew; }; diff --git a/rpcs3/cmake_modules/FindGLEW.cmake b/rpcs3/cmake_modules/FindGLEW.cmake new file mode 100644 index 0000000000..c703bf1aa3 --- /dev/null +++ b/rpcs3/cmake_modules/FindGLEW.cmake @@ -0,0 +1,47 @@ +# +# Try to find GLEW library and include path. +# Once done this will define +# +# GLEW_FOUND +# GLEW_INCLUDE_PATH +# GLEW_LIBRARY +# + +IF (WIN32) + FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h + $ENV{PROGRAMFILES}/GLEW/include + ${PROJECT_SOURCE_DIR}/src/nvgl/glew/include + DOC "The directory where GL/glew.h resides") + FIND_LIBRARY( GLEW_LIBRARY + NAMES glew GLEW glew32 glew32s + PATHS + $ENV{PROGRAMFILES}/GLEW/lib + ${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin + ${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib + DOC "The GLEW library") +ELSE (WIN32) + FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h + /usr/include + /usr/local/include + /sw/include + /opt/local/include + DOC "The directory where GL/glew.h resides") + FIND_LIBRARY( GLEW_LIBRARY + NAMES GLEW glew + PATHS + /usr/lib64 + /usr/lib + /usr/local/lib64 + /usr/local/lib + /sw/lib + /opt/local/lib + DOC "The GLEW library") +ENDIF (WIN32) + +IF (GLEW_INCLUDE_PATH) + SET( GLEW_FOUND 1 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise") +ELSE (GLEW_INCLUDE_PATH) + SET( GLEW_FOUND 0 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise") +ENDIF (GLEW_INCLUDE_PATH) + +MARK_AS_ADVANCED( GLEW_FOUND ) \ No newline at end of file