diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index f8bd5a75e4..47ac59462b 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -172,7 +172,7 @@ std::pair Compiler::Compile(const std::stri SetPc(m_ir_builder->getInt32(m_state.current_instruction_address)); - m_ir_builder->CreateRet(exit_instr_i32); + m_ir_builder->CreateRet(m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusBlockEnded)); } // If the function has a default exit block then generate code for it @@ -182,8 +182,7 @@ std::pair Compiler::Compile(const std::stri PHINode *exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); exit_instr_list.push_back(exit_instr_i32); - m_ir_builder->CreateRet(exit_instr_i32); - + m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); } // Add incoming values for all exit instr PHI nodes @@ -255,7 +254,7 @@ RecompilationEngine::RecompilationEngine() , m_last_cache_clear_time(std::chrono::high_resolution_clock::now()) , m_compiler(*this, CPUHybridDecoderRecompiler::ExecuteFunction, CPUHybridDecoderRecompiler::ExecuteTillReturn, CPUHybridDecoderRecompiler::PollStatus) { - FunctionCache = (Executable *)memory_helper::reserve_memory(VIRTUAL_INSTRUCTION_COUNT * sizeof(Executable)); + FunctionCache = (ExecutableStorageType *)memory_helper::reserve_memory(VIRTUAL_INSTRUCTION_COUNT * sizeof(ExecutableStorageType)); // Each char can store 8 page status FunctionCachePagesCommited = (char *)malloc(VIRTUAL_INSTRUCTION_COUNT / (8 * PAGE_SIZE)); memset(FunctionCachePagesCommited, 0, VIRTUAL_INSTRUCTION_COUNT / (8 * PAGE_SIZE)); @@ -264,15 +263,15 @@ RecompilationEngine::RecompilationEngine() } RecompilationEngine::~RecompilationEngine() { - m_address_to_function.clear(); + m_executable_storage.clear(); join(); - memory_helper::free_reserved_memory(FunctionCache, VIRTUAL_INSTRUCTION_COUNT * sizeof(Executable)); + memory_helper::free_reserved_memory(FunctionCache, VIRTUAL_INSTRUCTION_COUNT * sizeof(ExecutableStorageType)); free(FunctionCachePagesCommited); } bool RecompilationEngine::isAddressCommited(u32 address) const { - size_t offset = address * sizeof(Executable); + size_t offset = address * sizeof(ExecutableStorageType); size_t page = offset / 4096; // Since bool is stored in char, the char index is page / 8 (or page >> 3) // and we shr the value with the remaining bits (page & 7) @@ -281,7 +280,7 @@ bool RecompilationEngine::isAddressCommited(u32 address) const void RecompilationEngine::commitAddress(u32 address) { - size_t offset = address * sizeof(Executable); + size_t offset = address * sizeof(ExecutableStorageType); size_t page = offset / 4096; memory_helper::commit_page_memory((u8*)FunctionCache + page * 4096, 4096); // Reverse of isAddressCommited : we set the (page & 7)th bit of (page / 8) th char @@ -289,25 +288,22 @@ void RecompilationEngine::commitAddress(u32 address) FunctionCachePagesCommited[page >> 3] |= (1 << (page & 7)); } -const Executable RecompilationEngine::GetCompiledExecutableIfAvailable(u32 address) +const Executable RecompilationEngine::GetCompiledExecutableIfAvailable(u32 address) const { - std::lock_guard lock(m_address_to_function_lock); if (!isAddressCommited(address / 4)) - commitAddress(address / 4); - if (!Ini.LLVMExclusionRange.GetValue()) - return FunctionCache[address / 4]; - std::unordered_map::iterator It = m_address_to_function.find(address); - if (It == m_address_to_function.end()) return nullptr; - u32 id = std::get<3>(It->second); - if (id >= Ini.LLVMMinId.GetValue() && id <= Ini.LLVMMaxId.GetValue()) + u32 id = FunctionCache[address / 4].second; + if (Ini.LLVMExclusionRange.GetValue() && + (id >= Ini.LLVMMinId.GetValue() && id <= Ini.LLVMMaxId.GetValue())) return nullptr; - return std::get<0>(It->second); + return FunctionCache[address / 4].first; } void RecompilationEngine::NotifyBlockStart(u32 address) { { std::lock_guard lock(m_pending_address_start_lock); + if (m_pending_address_start.size() > 10000) + m_pending_address_start.clear(); m_pending_address_start.push_back(address); } @@ -345,14 +341,14 @@ void RecompilationEngine::Task() { if (!m_current_execution_traces.empty()) { for (u32 address : m_current_execution_traces) - work_done_this_iteration |= ProcessExecutionTrace(address); + work_done_this_iteration |= IncreaseHitCounterAndBuild(address); } if (!work_done_this_iteration) { // Wait a few ms for something to happen auto idling_start = std::chrono::high_resolution_clock::now(); std::unique_lock lock(mutex); - cv.wait_for(lock, std::chrono::milliseconds(250)); + cv.wait_for(lock, std::chrono::milliseconds(10)); auto idling_end = std::chrono::high_resolution_clock::now(); idling_time += std::chrono::duration_cast(idling_end - idling_start); } @@ -375,7 +371,7 @@ void RecompilationEngine::Task() { s_the_instance = nullptr; // Can cause deadlock if this is the last instance. Need to fix this. } -bool RecompilationEngine::ProcessExecutionTrace(u32 address) { +bool RecompilationEngine::IncreaseHitCounterAndBuild(u32 address) { auto It = m_block_table.find(address); if (It == m_block_table.end()) It = m_block_table.emplace(address, BlockEntry(address)).first; @@ -465,26 +461,25 @@ void RecompilationEngine::CompileBlock(BlockEntry & block_entry) { if (!AnalyseBlock(block_entry)) return; Log() << "Compile: " << block_entry.ToString() << "\n"; - const std::pair &compileResult = - m_compiler.Compile(fmt::format("fn_0x%08X", block_entry.address), block_entry.address, block_entry.instructionCount); - // If entry doesn't exist, create it (using lock) - std::unordered_map::iterator It = m_address_to_function.find(block_entry.address); - if (It == m_address_to_function.end()) { - std::lock_guard lock(m_address_to_function_lock); - std::get<1>(m_address_to_function[block_entry.address]) = nullptr; + // We create a lock here so that data are properly stored at the end of the function. + /// Lock for accessing compiler + std::mutex local_mutex; + std::unique_lock lock(local_mutex); + + const std::pair &compileResult = + m_compiler.Compile(fmt::format("fn_0x%08X", block_entry.address), block_entry.address, block_entry.instructionCount); + if (!isAddressCommited(block_entry.address / 4)) commitAddress(block_entry.address / 4); - } - std::get<1>(m_address_to_function[block_entry.address]) = std::unique_ptr(compileResult.second); - std::get<0>(m_address_to_function[block_entry.address]) = compileResult.first; - std::get<3>(m_address_to_function[block_entry.address]) = m_currentId; - Log() << "Associating " << (void*)(uint64_t)block_entry.address << " with ID " << m_currentId << "\n"; - m_currentId++; - block_entry.is_compiled = true; - FunctionCache[block_entry.address / 4] = compileResult.first; + m_executable_storage.push_back(std::unique_ptr(compileResult.second)); + Log() << "Associating " << (void*)(uint64_t)block_entry.address << " with ID " << m_currentId << "\n"; + FunctionCache[block_entry.address / 4] = std::make_pair(compileResult.first, m_currentId); + m_currentId++; + block_entry.is_compiled = true; + } } std::shared_ptr RecompilationEngine::GetInstance() { @@ -508,13 +503,21 @@ ppu_recompiler_llvm::CPUHybridDecoderRecompiler::~CPUHybridDecoderRecompiler() { } u32 ppu_recompiler_llvm::CPUHybridDecoderRecompiler::DecodeMemory(const u32 address) { - ExecuteFunction(&m_ppu, 0); + // TODO: exception_ptr doesnt work, should add every possible exception + if (ExecuteFunction(&m_ppu, 0) == ExecutionStatus::ExecutionStatusPropagateException) + { + std::exception_ptr exn = m_ppu.pending_exception; + m_ppu.pending_exception = nullptr; + std::rethrow_exception(exn); + } return 0; } u32 ppu_recompiler_llvm::CPUHybridDecoderRecompiler::ExecuteFunction(PPUThread * ppu_state, u64 context) { auto execution_engine = (CPUHybridDecoderRecompiler *)ppu_state->GetDecoder(); - return ExecuteTillReturn(ppu_state, 0); + if (ExecuteTillReturn(ppu_state, 0) == ExecutionStatus::ExecutionStatusPropagateException) + return ExecutionStatus::ExecutionStatusPropagateException; + return ExecutionStatus::ExecutionStatusReturn; } /// Get the branch type from a branch instruction @@ -544,7 +547,8 @@ static BranchType GetBranchTypeFromInstruction(u32 instruction) u32 ppu_recompiler_llvm::CPUHybridDecoderRecompiler::ExecuteTillReturn(PPUThread * ppu_state, u64 context) { CPUHybridDecoderRecompiler *execution_engine = (CPUHybridDecoderRecompiler *)ppu_state->GetDecoder(); - execution_engine->m_recompilation_engine->NotifyBlockStart(ppu_state->PC); + // A block is a sequence of contiguous address. + bool previousInstContigousAndInterp = false; while (PollStatus(ppu_state) == false) { const Executable executable = execution_engine->m_recompilation_engine->GetCompiledExecutableIfAvailable(ppu_state->PC); @@ -552,14 +556,30 @@ u32 ppu_recompiler_llvm::CPUHybridDecoderRecompiler::ExecuteTillReturn(PPUThread { auto entry = ppu_state->PC; u32 exit = (u32)executable(ppu_state, 0); - if (exit == 0) - return 0; + if (exit == ExecutionStatus::ExecutionStatusReturn) + return ExecutionStatus::ExecutionStatusReturn; + if (exit == ExecutionStatus::ExecutionStatusPropagateException) + return ExecutionStatus::ExecutionStatusPropagateException; execution_engine->m_recompilation_engine->NotifyBlockStart(ppu_state->PC); + previousInstContigousAndInterp = false; continue; } + // if previousInstContigousAndInterp is true, ie previous step was either a compiled block or a branch inst + // that caused a "gap" in instruction flow, we notify a new block. + if (!previousInstContigousAndInterp) + execution_engine->m_recompilation_engine->NotifyBlockStart(ppu_state->PC); u32 instruction = vm::ps3::read32(ppu_state->PC); u32 oldPC = ppu_state->PC; - execution_engine->m_decoder.Decode(instruction); + try + { + execution_engine->m_decoder.Decode(instruction); + } + catch (...) + { + ppu_state->pending_exception = std::current_exception(); + return ExecutionStatus::ExecutionStatusPropagateException; + } + previousInstContigousAndInterp = (oldPC == ppu_state->PC); auto branch_type = ppu_state->PC != oldPC ? GetBranchTypeFromInstruction(instruction) : BranchType::NonBranch; ppu_state->PC += 4; @@ -568,7 +588,10 @@ u32 ppu_recompiler_llvm::CPUHybridDecoderRecompiler::ExecuteTillReturn(PPUThread if (Emu.GetCPUThreadStop() == ppu_state->PC) ppu_state->fast_stop(); return 0; case BranchType::FunctionCall: { - ExecuteFunction(ppu_state, 0); + u32 status = ExecuteFunction(ppu_state, 0); + // TODO: exception_ptr doesnt work, should add every possible exception + if (status == ExecutionStatus::ExecutionStatusPropagateException) + return ExecutionStatus::ExecutionStatusPropagateException; break; } case BranchType::LocalBranch: diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.h b/rpcs3/Emu/Cell/PPULLVMRecompiler.h index 1f9c5f127c..281537badd 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.h +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.h @@ -24,6 +24,13 @@ #endif namespace ppu_recompiler_llvm { + enum ExecutionStatus + { + ExecutionStatusReturn = 0, ///< Block has hit a return, caller can continue execution + ExecutionStatusBlockEnded, ///< Block has been executed but no return was hit, at least another block must be executed before caller can continue + ExecutionStatusPropagateException, ///< an exception was thrown + }; + class Compiler; class RecompilationEngine; class ExecutionEngine; @@ -779,7 +786,7 @@ namespace ppu_recompiler_llvm { * Get the executable for the specified address if a compiled version is * available, otherwise returns nullptr. **/ - const Executable GetCompiledExecutableIfAvailable(u32 address); + const Executable GetCompiledExecutableIfAvailable(u32 address) const; /// Notify the recompilation engine about a newly detected block start. void NotifyBlockStart(u32 address); @@ -848,15 +855,16 @@ namespace ppu_recompiler_llvm { /// Block table std::unordered_map m_block_table; - /// Lock for accessing m_address_to_function. - std::mutex m_address_to_function_lock; - int m_currentId; - // Store pointer to every compiled function/block. - // We need to map every instruction in PS3 Ram so it's a big table - // But a lot of it won't be accessed. Fortunatly virtual memory help here... - Executable *FunctionCache; + /// (function, id). + typedef std::pair ExecutableStorageType; + + /// Virtual memory allocated array. + /// Store pointer to every compiled function/block and a unique Id. + /// We need to map every instruction in PS3 Ram so it's a big table + /// But a lot of it won't be accessed. Fortunatly virtual memory help here... + ExecutableStorageType* FunctionCache; // Bitfield recording page status in FunctionCache reserved memory. char *FunctionCachePagesCommited; @@ -864,10 +872,8 @@ namespace ppu_recompiler_llvm { bool isAddressCommited(u32) const; void commitAddress(u32); - /// (function, module containing function, times hit, id). - typedef std::tuple, u32, u32> ExecutableStorage; - /// Address to ordinal cahce. Key is address. - std::unordered_map m_address_to_function; + /// vector storing all exec engine + std::vector > m_executable_storage; /// The time at which the m_address_to_ordinal cache was last cleared std::chrono::high_resolution_clock::time_point m_last_cache_clear_time; @@ -883,9 +889,9 @@ namespace ppu_recompiler_llvm { RecompilationEngine & operator = (const RecompilationEngine & other) = delete; RecompilationEngine & operator = (RecompilationEngine && other) = delete; - /// Process an execution trace. - /// Returns true if a block was compiled - bool ProcessExecutionTrace(u32); + /// Increase usage counter for block starting at addr and compile it if threshold was reached. + /// Returns true if block was compiled + bool IncreaseHitCounterAndBuild(u32 addr); /** * Analyse block to get useful info (function called, has indirect branch...) diff --git a/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp b/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp index 3c66119ab0..b688d6006c 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp @@ -1752,21 +1752,37 @@ void Compiler::BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) { CreateBranch(CheckBranchCondition(bo, bi), target_i32, lk ? true : false); } + + +static u32 +wrappedExecutePPUFuncByIndex(PPUThread &CPU, u32 index) +{ + try + { + execute_ppu_func_by_index(CPU, index); + return ExecutionStatus::ExecutionStatusBlockEnded; + } + catch (...) + { + CPU.pending_exception = std::current_exception(); + return ExecutionStatus::ExecutionStatusPropagateException; + } +} + void Compiler::HACK(u32 index) { - Call("execute_ppu_func_by_index", &execute_ppu_func_by_index, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt32(index & EIF_USE_BRANCH ? index : index & ~EIF_PERFORM_BLR)); + llvm::Value *status = Call("wrappedExecutePPUFuncByIndex", &wrappedExecutePPUFuncByIndex, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt32(index & EIF_USE_BRANCH ? index : index & ~EIF_PERFORM_BLR)); + llvm::BasicBlock *cputhreadexitblock = GetBasicBlockFromAddress(m_state.current_instruction_address, "early_exit"); + llvm::Value *isCPUThreadExit = m_ir_builder->CreateICmpEQ(status, m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusPropagateException)); + llvm::BasicBlock *normal_execution = GetBasicBlockFromAddress(m_state.current_instruction_address, "normal_execution"); + m_ir_builder->CreateCondBr(isCPUThreadExit, cputhreadexitblock, normal_execution); + m_ir_builder->SetInsertPoint(cputhreadexitblock); + m_ir_builder->CreateRet(m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusPropagateException)); + + m_ir_builder->SetInsertPoint(normal_execution); if (index & EIF_PERFORM_BLR || index & EIF_USE_BRANCH) { auto lr_i32 = index & EIF_USE_BRANCH ? GetPc() : m_ir_builder->CreateTrunc(m_ir_builder->CreateAnd(GetLr(), ~0x3ULL), m_ir_builder->getInt32Ty()); CreateBranch(nullptr, lr_i32, false, (index & EIF_USE_BRANCH) == 0); } - // copied from Compiler::SC() - //auto ret_i1 = Call("PollStatus", m_poll_status_function, m_state.args[CompileTaskState::Args::State]); - //auto cmp_i1 = m_ir_builder->CreateICmpEQ(ret_i1, m_ir_builder->getInt1(true)); - //auto then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "then_true"); - //auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "merge_true"); - //m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); - //m_ir_builder->SetInsertPoint(then_bb); - //m_ir_builder->CreateRet(m_ir_builder->getInt32(0xFFFFFFFF)); - //m_ir_builder->SetInsertPoint(merge_bb); } void Compiler::SC(u32 lev) { @@ -1788,7 +1804,7 @@ void Compiler::SC(u32 lev) { auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "merge_true"); m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); m_ir_builder->SetInsertPoint(then_bb); - m_ir_builder->CreateRet(m_ir_builder->getInt32(0xFFFFFFFF)); + m_ir_builder->CreateRet(m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusBlockEnded)); m_ir_builder->SetInsertPoint(merge_bb); } @@ -5199,11 +5215,21 @@ void Compiler::CreateBranch(llvm::Value * cmp_i1, llvm::Value * target_i32, bool } SetPc(target_i32); - Function *fn = m_module->getFunction(fmt::format("function_0x%08X", target_address)); - if (fn) - m_ir_builder->CreateCall2(fn, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0)); - else - Call("execute_unknown_function", nullptr, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0)); +// Function *fn = m_module->getFunction(fmt::format("function_0x%08X", target_address)); + llvm::Value *execStatus; +// if (fn) +// execStatus = m_ir_builder->CreateCall2(fn, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0)); +// else + execStatus = Call("execute_unknown_function", nullptr, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0)); + + llvm::BasicBlock *cputhreadexitblock = GetBasicBlockFromAddress(m_state.current_instruction_address, "early_exit"); + llvm::Value *isCPUThreadExit = m_ir_builder->CreateICmpEQ(execStatus, m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusPropagateException)); + llvm::BasicBlock *normal_execution = GetBasicBlockFromAddress(m_state.current_instruction_address, "normal_execution"); + m_ir_builder->CreateCondBr(isCPUThreadExit, cputhreadexitblock, normal_execution); + m_ir_builder->SetInsertPoint(cputhreadexitblock); + m_ir_builder->CreateRet(m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusPropagateException)); + m_ir_builder->SetInsertPoint(normal_execution); + m_ir_builder->CreateBr(GetBasicBlockFromAddress(m_state.current_instruction_address + 4)); } else { @@ -5221,15 +5247,25 @@ void Compiler::CreateBranch(llvm::Value * cmp_i1, llvm::Value * target_i32, bool SetPc(target_i32); if (target_is_lr && !lk) { // Return from this function - m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); + m_ir_builder->CreateRet(m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusReturn)); } else if (lk) { BasicBlock *next_block = GetBasicBlockFromAddress(m_state.current_instruction_address + 4); - m_ir_builder->CreateCall2(m_execute_unknown_function, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0)); + + llvm::Value *execStatus = m_ir_builder->CreateCall2(m_execute_unknown_function, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0)); + + llvm::BasicBlock *cputhreadexitblock = GetBasicBlockFromAddress(m_state.current_instruction_address, "early_exit"); + llvm::Value *isCPUThreadExit = m_ir_builder->CreateICmpEQ(execStatus, m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusPropagateException)); + llvm::BasicBlock *normal_execution = GetBasicBlockFromAddress(m_state.current_instruction_address, "normal_execution"); + m_ir_builder->CreateCondBr(isCPUThreadExit, cputhreadexitblock, normal_execution); + m_ir_builder->SetInsertPoint(cputhreadexitblock); + m_ir_builder->CreateRet(m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusPropagateException)); + m_ir_builder->SetInsertPoint(normal_execution); + m_ir_builder->CreateBr(next_block); } else { - m_ir_builder->CreateRet(m_ir_builder->getInt32(-1)); + m_ir_builder->CreateRet(m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusBlockEnded)); } } diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 50991b5e94..11a0e1047b 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -536,6 +536,11 @@ public: std::function custom_task; + /// When a thread has met an exception, this variable is used to retro propagate it through stack call. + /// Note that exception_ptr is similar to shared_ptr and doesn't need to be freed, but need a nullptr + /// to be assigned. + std::exception_ptr pending_exception; + public: PPUThread(const std::string& name); virtual ~PPUThread() override; diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index b2f535460c..4829fc0747 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -289,6 +289,9 @@ template std::string FragmentProgramDecompiler::GetSRC(T src) ret += AddConst(); break; + case 3: // ??? Used by a few games, what is it? + LOG_ERROR(RSX, "Src type 3 used, please report this to a developer."); + default: LOG_ERROR(RSX, "Bad src type %d", u32{ src.reg_type }); Emu.Pause(); @@ -315,7 +318,10 @@ std::string FragmentProgramDecompiler::BuildCode() { //main += fmt::format("\tgl_FragColor = %c0;\n", m_ctrl & 0x40 ? 'r' : 'h'); - if (m_ctrl & 0xe) main += m_ctrl & 0x40 ? "\tgl_FragDepth = r1.z;\n" : "\tgl_FragDepth = h2.z;\n"; + if (m_ctrl & 0xe) + { + main += m_ctrl & 0x40 ? "\tgl_FragDepth = r1.z;\n" : "\tgl_FragDepth = h0.z;\n"; + } std::stringstream OS; insertHeader(OS); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp index 83bba40794..d2ed9f30b6 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp @@ -179,8 +179,8 @@ bool D3D12GSRender::LoadProgram() if (m_set_blend_color) { - // glBlendColor(m_blend_color_r, m_blend_color_g, m_blend_color_b, m_blend_color_a); - // checkForGlError("glBlendColor"); + // glBlendColor(m_blend_color_r, m_blend_color_g, m_blend_color_b, m_blend_color_a); + // checkForGlError("glBlendColor"); } switch (m_surface_depth_format) diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index 27c13c7857..366f81cbf1 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -282,6 +282,14 @@ enum CELL_GCM_CONTEXT_DMA_NOTIFY_MAIN_0 = 0x6660420F, }; +// User Clip Values +enum +{ + CELL_GCM_USER_CLIP_PLANE_DISABLE = 0, + CELL_GCM_USER_CLIP_PLANE_ENABLE_LT = 1, + CELL_GCM_USER_CLIP_PLANE_ENABLE_GE = 2, +}; + struct CellGcmControl { atomic_be_t put; @@ -1440,9 +1448,10 @@ static const std::string GetMethodName(const u32 id) { NV4097_SET_TRANSFORM_BRANCH_BITS, "NV4097_SET_TRANSFORM_BRANCH_BITS" } }; - for(auto& s: METHOD_NAME_LIST) { - if(s.id == id) - return "CELL_GCM_" + s.name; + for (auto& s: METHOD_NAME_LIST) + { + if (s.id == id) + return s.name; } return fmt::format("unknown/illegal method [0x%08x]", id); diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 60802dc612..71b1cfe14f 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -188,7 +188,7 @@ void GLTexture::Init(RSXTexture& tex) { for (int j = 0; j < tex.GetWidth(); j++) { - dst[(i*tex.GetWidth()) + j] = src[LinearToSwizzleAddress(j, i, 0, log2width, log2height, 0)]; + dst[(i * tex.GetWidth()) + j] = src[LinearToSwizzleAddress(j, i, 0, log2width, log2height, 0)]; } } } diff --git a/rpcs3/Emu/SysCalls/Modules/cellFont.cpp b/rpcs3/Emu/SysCalls/Modules/cellFont.cpp index bec90b0f2d..296d06b6ec 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFont.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFont.cpp @@ -300,7 +300,7 @@ s32 cellFontGetRenderCharGlyphMetrics(vm::ptr font, u32 code, vm::ptr< s32 cellFontRenderCharGlyphImage(vm::ptr font, u32 code, vm::ptr surface, float x, float y, vm::ptr metrics, vm::ptr transInfo) { - cellFont.Log("cellFontRenderCharGlyphImage(font=*0x%x, code=0x%x, surface=*0x%x, x=%f, y=%f, metrics=*0x%x, trans=*0x%x)", font, code, surface, x, y, metrics, transInfo); + cellFont.Notice("cellFontRenderCharGlyphImage(font=*0x%x, code=0x%x, surface=*0x%x, x=%f, y=%f, metrics=*0x%x, trans=*0x%x)", font, code, surface, x, y, metrics, transInfo); if (!font->renderer_addr) { @@ -374,7 +374,7 @@ s32 cellFontGetEffectSlant(vm::ptr font, vm::ptr slantParam) s32 cellFontGetFontIdCode(vm::ptr font, u32 code, vm::ptr fontId, vm::ptr fontCode) { - cellFont.Todo("cellFontGetFontIdCode(font=*0x%x, code=0x%x, fontId=*0x%x, fontCode=*0x%x)", font, code, fontId, fontCode); + cellFont.Todo("cellFontGetFontIdCode(font=*0x%x, code=%d, fontId=*0x%x, fontCode=*0x%x)", font, code, fontId, fontCode); // TODO: ? return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp index 02a887dce4..3d9f4ee8f9 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp @@ -789,7 +789,6 @@ s32 sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil cellFs.Warning("cellFsSdataOpen: Compressed SDATA files are not supported yet."); return CELL_EFSSPECIFIC; } - // SDATA file is NOT compressed else { @@ -826,7 +825,7 @@ s32 sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil s32 cellFsSdataOpen(PPUThread& ppu, vm::cptr path, s32 flags, vm::ptr fd, vm::cptr arg, u64 size) { - cellFs.Log("cellFsSdataOpen(path=*0x%x, flags=%#o, fd=*0x%x, arg=*0x%x, size=0x%llx)", path, flags, fd, arg, size); + cellFs.Notice("cellFsSdataOpen(path=*0x%x, flags=%#o, fd=*0x%x, arg=*0x%x, size=0x%llx)", path, flags, fd, arg, size); if (flags != CELL_FS_O_RDONLY) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 042c125425..ca3e7e2308 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -122,12 +122,12 @@ s32 cellHddGameCheck(PPUThread& ppu, u32 version, vm::cptr dirName, u32 er // TODO ? - //funcStat(result, get, set); + funcStat(ppu, result, get, set); - //if (result->result != CELL_HDDGAME_CBRESULT_OK && result->result != CELL_HDDGAME_CBRESULT_OK_CANCEL) - //{ - // return CELL_HDDGAME_ERROR_CBRESULT; - //} + if (result->result != CELL_HDDGAME_CBRESULT_OK && result->result != CELL_HDDGAME_CBRESULT_OK_CANCEL) + { + return CELL_HDDGAME_ERROR_CBRESULT; + } // TODO ? diff --git a/rpcs3/Emu/SysCalls/Modules/cellGameExec.cpp b/rpcs3/Emu/SysCalls/Modules/cellGameExec.cpp index 33f7bc9c65..5b23200638 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGameExec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGameExec.cpp @@ -11,9 +11,13 @@ s32 cellGameSetExitParam() throw EXCEPTION(""); } -s32 cellGameGetHomeDataExportPath() +s32 cellGameGetHomeDataExportPath(vm::ptr exportPath) { - throw EXCEPTION(""); + cellGameExec.Warning("cellGameGetHomeDataExportPath(exportPath=0x%x)", exportPath); + + // TODO: PlayStation home is defunct. + + return CELL_GAME_ERROR_NOAPP; } s32 cellGameGetHomePath() diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index c3c3768147..6fc5512ba5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -44,16 +44,20 @@ u32 map_offset_pos = 0; */ u32 gcmGetLocalMemorySize(u32 sdk_version) { - if (sdk_version >= 0x00220000) { + if (sdk_version >= 0x00220000) + { return 0x0F900000; // 249MB } - if (sdk_version >= 0x00200000) { + if (sdk_version >= 0x00200000) + { return 0x0F200000; // 242MB } - if (sdk_version >= 0x00190000) { + if (sdk_version >= 0x00190000) + { return 0x0EA00000; // 234MB } - if (sdk_version >= 0x00180000) { + if (sdk_version >= 0x00180000) + { return 0x0E800000; // 232MB } return 0x0E000000; // 224MB @@ -249,7 +253,7 @@ s32 cellGcmBindTile(u8 index) if (index >= RSXThread::m_tiles_count) { - cellGcmSys.Error("cellGcmBindTile : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmBindTile: CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } @@ -265,7 +269,7 @@ s32 cellGcmBindZcull(u8 index) if (index >= RSXThread::m_zculls_count) { - cellGcmSys.Error("cellGcmBindZcull : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmBindZcull: CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } @@ -324,7 +328,7 @@ s32 _cellGcmInitBody(vm::pptr context, u32 cmdSize, u32 ioSi { cellGcmSys.Warning("_cellGcmInitBody(context=**0x%x, cmdSize=0x%x, ioSize=0x%x, ioAddress=0x%x)", context, cmdSize, ioSize, ioAddress); - if(!local_size && !local_addr) + if (!local_size && !local_addr) { local_size = 0xf900000; // TODO: Get sdk_version in _cellGcmFunc15 and pass it to gcmGetLocalMemorySize local_addr = 0xC0000000; @@ -347,7 +351,7 @@ s32 _cellGcmInitBody(vm::pptr context, u32 cmdSize, u32 ioSi if (gcmMapEaIoAddress(ioAddress, 0, ioSize, false) != CELL_OK) { - cellGcmSys.Error("cellGcmInit : CELL_GCM_ERROR_FAILURE"); + cellGcmSys.Error("cellGcmInit: CELL_GCM_ERROR_FAILURE"); return CELL_GCM_ERROR_FAILURE; } @@ -428,8 +432,9 @@ s32 cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height { cellGcmSys.Log("cellGcmSetDisplayBuffer(id=0x%x,offset=0x%x,pitch=%d,width=%d,height=%d)", id, offset, width ? pitch / width : pitch, width, height); - if (id > 7) { - cellGcmSys.Error("cellGcmSetDisplayBuffer : CELL_EINVAL"); + if (id > 7) + { + cellGcmSys.Error("cellGcmSetDisplayBuffer: CELL_EINVAL"); return CELL_EINVAL; } @@ -440,7 +445,8 @@ s32 cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height buffers[id].width = width; buffers[id].height = height; - if (id + 1 > Emu.GetGSManager().GetRender().m_gcm_buffers_count) { + if (id + 1 > Emu.GetGSManager().GetRender().m_gcm_buffers_count) + { Emu.GetGSManager().GetRender().m_gcm_buffers_count = id + 1; } @@ -486,7 +492,7 @@ s32 cellGcmSetPrepareFlip(PPUThread& ppu, vm::ptr ctxt, u32 if (id > 7) { - cellGcmSys.Error("cellGcmSetPrepareFlip : CELL_GCM_ERROR_FAILURE"); + cellGcmSys.Error("cellGcmSetPrepareFlip: CELL_GCM_ERROR_FAILURE"); return CELL_GCM_ERROR_FAILURE; } @@ -494,7 +500,7 @@ s32 cellGcmSetPrepareFlip(PPUThread& ppu, vm::ptr ctxt, u32 { if (s32 res = ctxt->callback(ppu, ctxt, 8 /* ??? */)) { - cellGcmSys.Error("cellGcmSetPrepareFlip : callback failed (0x%08x)", res); + cellGcmSys.Error("cellGcmSetPrepareFlip: callback failed (0x%08x)", res); return res; } } @@ -547,19 +553,19 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u if (index >= RSXThread::m_tiles_count || base >= 800 || bank >= 4) { - cellGcmSys.Error("cellGcmSetTileInfo : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } if (offset & 0xffff || size & 0xffff || pitch & 0xf) { - cellGcmSys.Error("cellGcmSetTileInfo : CELL_GCM_ERROR_INVALID_ALIGNMENT"); + cellGcmSys.Error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT"); return CELL_GCM_ERROR_INVALID_ALIGNMENT; } if (location >= 2 || (comp != 0 && (comp < 7 || comp > 12))) { - cellGcmSys.Error("cellGcmSetTileInfo : CELL_GCM_ERROR_INVALID_ALIGNMENT"); + cellGcmSys.Error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT"); return CELL_GCM_ERROR_INVALID_ENUM; } @@ -621,7 +627,7 @@ s32 cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart, if (index >= RSXThread::m_zculls_count) { - cellGcmSys.Error("cellGcmSetZcull : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmSetZcull: CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } @@ -648,7 +654,7 @@ s32 cellGcmUnbindTile(u8 index) if (index >= RSXThread::m_tiles_count) { - cellGcmSys.Error("cellGcmUnbindTile : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmUnbindTile: CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } @@ -664,7 +670,7 @@ s32 cellGcmUnbindZcull(u8 index) if (index >= 8) { - cellGcmSys.Error("cellGcmUnbindZcull : CELL_EINVAL"); + cellGcmSys.Error("cellGcmUnbindZcull: CELL_EINVAL"); return CELL_EINVAL; } @@ -736,9 +742,9 @@ u64 cellGcmGetLastFlipTime() return Emu.GetGSManager().GetRender().m_last_flip_time; } -s32 cellGcmGetLastSecondVTime() +u64 cellGcmGetLastSecondVTime() { - UNIMPLEMENTED_FUNC(cellGcmSys); + cellGcmSys.Todo("cellGcmGetLastSecondVTime()"); return CELL_OK; } @@ -769,7 +775,7 @@ s32 cellGcmSetFlipImmediate(u8 id) if (id > 7) { - cellGcmSys.Error("cellGcmSetFlipImmediate : CELL_GCM_ERROR_FAILURE"); + cellGcmSys.Error("cellGcmSetFlipImmediate: CELL_GCM_ERROR_FAILURE"); return CELL_GCM_ERROR_FAILURE; } @@ -894,7 +900,7 @@ s32 gcmMapEaIoAddress(u32 ea, u32 io, u32 size, bool is_strict) } else { - cellGcmSys.Error("cellGcmMapEaIoAddress : CELL_GCM_ERROR_FAILURE"); + cellGcmSys.Error("cellGcmMapEaIoAddress: CELL_GCM_ERROR_FAILURE"); return CELL_GCM_ERROR_FAILURE; } @@ -958,7 +964,7 @@ s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr offset) } else { - cellGcmSys.Error("cellGcmMapMainMemory : CELL_GCM_ERROR_NO_IO_PAGE_TABLE"); + cellGcmSys.Error("cellGcmMapMainMemory: CELL_GCM_ERROR_NO_IO_PAGE_TABLE"); return CELL_GCM_ERROR_NO_IO_PAGE_TABLE; } @@ -973,13 +979,13 @@ s32 cellGcmReserveIoMapSize(u32 size) if (size & 0xFFFFF) { - cellGcmSys.Error("cellGcmReserveIoMapSize : CELL_GCM_ERROR_INVALID_ALIGNMENT"); + cellGcmSys.Error("cellGcmReserveIoMapSize: CELL_GCM_ERROR_INVALID_ALIGNMENT"); return CELL_GCM_ERROR_INVALID_ALIGNMENT; } if (size > cellGcmGetMaxIoMapSize()) { - cellGcmSys.Error("cellGcmReserveIoMapSize : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmReserveIoMapSize: CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } @@ -1041,13 +1047,13 @@ s32 cellGcmUnreserveIoMapSize(u32 size) if (size & 0xFFFFF) { - cellGcmSys.Error("cellGcmReserveIoMapSize : CELL_GCM_ERROR_INVALID_ALIGNMENT"); + cellGcmSys.Error("cellGcmReserveIoMapSize: CELL_GCM_ERROR_INVALID_ALIGNMENT"); return CELL_GCM_ERROR_INVALID_ALIGNMENT; } if (size > RSXIOMem.GetReservedAmount()) { - cellGcmSys.Error("cellGcmReserveIoMapSize : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmReserveIoMapSize: CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } @@ -1136,25 +1142,25 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co index, location, offset, size, pitch, comp, base, bank); // Copied form cellGcmSetTileInfo - if(index >= RSXThread::m_tiles_count || base >= 800 || bank >= 4) + if (index >= RSXThread::m_tiles_count || base >= 800 || bank >= 4) { - cellGcmSys.Error("cellGcmSetTile : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmSetTile: CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } - if(offset & 0xffff || size & 0xffff || pitch & 0xf) + if (offset & 0xffff || size & 0xffff || pitch & 0xf) { - cellGcmSys.Error("cellGcmSetTile : CELL_GCM_ERROR_INVALID_ALIGNMENT"); + cellGcmSys.Error("cellGcmSetTile: CELL_GCM_ERROR_INVALID_ALIGNMENT"); return CELL_GCM_ERROR_INVALID_ALIGNMENT; } - if(location >= 2 || (comp != 0 && (comp < 7 || comp > 12))) + if (location >= 2 || (comp != 0 && (comp < 7 || comp > 12))) { - cellGcmSys.Error("cellGcmSetTile : CELL_GCM_ERROR_INVALID_ENUM"); + cellGcmSys.Error("cellGcmSetTile: CELL_GCM_ERROR_INVALID_ENUM"); return CELL_GCM_ERROR_INVALID_ENUM; } - if(comp) + if (comp) { cellGcmSys.Error("cellGcmSetTile: bad compression mode! (%d)", comp); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp b/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp index 220acc60b9..12a38d26c2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp @@ -12,14 +12,14 @@ extern Module cellL10n; -//translate code id to code name. some codepage may has another name. -//If this makes your compilation fail, try replace the string code with one in "iconv -l" +// Translate code id to code name. some codepage may has another name. +// If this makes your compilation fail, try replace the string code with one in "iconv -l" bool _L10nCodeParse(s32 code, std::string& retCode) { if ((code >= _L10N_CODE_) || (code < 0)) return false; switch (code) { - //I don't know these Unicode Variants is LB or BE. + // I don't know these Unicode Variants is LB or BE. case L10N_UTF8: retCode = "UTF-8"; return true; case L10N_UTF16: retCode = "UTF-16"; return true; case L10N_UTF32: retCode = "UTF-32"; return true; @@ -36,7 +36,7 @@ bool _L10nCodeParse(s32 code, std::string& retCode) case L10N_ISO_8859_9: retCode = "ISO-8859-9"; return true; case L10N_ISO_8859_10: retCode = "ISO-8859-10"; return true; case L10N_ISO_8859_11: retCode = "ISO-8859-11"; return true; - case L10N_ISO_8859_13: retCode = "ISO-8859-13"; return true; //No ISO-8859-12 ha ha. + case L10N_ISO_8859_13: retCode = "ISO-8859-13"; return true; // No ISO-8859-12 ha ha. case L10N_ISO_8859_14: retCode = "ISO-8859-14"; return true; case L10N_ISO_8859_15: retCode = "ISO-8859-15"; return true; case L10N_ISO_8859_16: retCode = "ISO-8859-16"; return true; @@ -48,25 +48,25 @@ bool _L10nCodeParse(s32 code, std::string& retCode) case L10N_CODEPAGE_936: retCode = "CP936"; return true; case L10N_CODEPAGE_949: retCode = "CP949"; return true; case L10N_CODEPAGE_950: retCode = "CP950"; return true; - case L10N_CODEPAGE_1251:retCode = "CP1251"; return true; //CYRL - case L10N_CODEPAGE_1252:retCode = "CP1252"; return true; //ANSI - case L10N_EUC_CN: retCode = "EUC-CN"; return true; //GB2312 + case L10N_CODEPAGE_1251:retCode = "CP1251"; return true; // CYRL + case L10N_CODEPAGE_1252:retCode = "CP1252"; return true; // ANSI + case L10N_EUC_CN: retCode = "EUC-CN"; return true; // GB2312 case L10N_EUC_JP: retCode = "EUC-JP"; return true; case L10N_EUC_KR: retCode = "EUC-KR"; return true; case L10N_ISO_2022_JP: retCode = "ISO-2022-JP"; return true; - case L10N_ARIB: retCode = "ARABIC"; return true; //TODO: think that should be ARABIC. + case L10N_ARIB: retCode = "ARABIC"; return true; // TODO: think that should be ARABIC. case L10N_HZ: retCode = "HZ"; return true; case L10N_GB18030: retCode = "GB18030"; return true; - case L10N_RIS_506: retCode = "SHIFT-JIS"; return true; //MusicShiftJIS, MS_KANJI - //These are only supported with FW 3.10 and above + case L10N_RIS_506: retCode = "SHIFT-JIS"; return true; // MusicShiftJIS, MS_KANJI + // These are only supported with FW 3.10 and above case L10N_CODEPAGE_852: retCode = "CP852"; return true; - case L10N_CODEPAGE_1250:retCode = "CP1250"; return true; //EE + case L10N_CODEPAGE_1250:retCode = "CP1250"; return true; // EE case L10N_CODEPAGE_737: retCode = "CP737"; return true; - case L10N_CODEPAGE_1253:retCode = "CP1253"; return true; //Greek + case L10N_CODEPAGE_1253:retCode = "CP1253"; return true; // Greek case L10N_CODEPAGE_857: retCode = "CP857"; return true; - case L10N_CODEPAGE_1254:retCode = "CP1254"; return true; //Turk + case L10N_CODEPAGE_1254:retCode = "CP1254"; return true; // Turk case L10N_CODEPAGE_775: retCode = "CP775"; return true; - case L10N_CODEPAGE_1257:retCode = "CP1257"; return true; //WINBALTRIM + case L10N_CODEPAGE_1257:retCode = "CP1257"; return true; // WINBALTRIM case L10N_CODEPAGE_855: retCode = "CP855"; return true; case L10N_CODEPAGE_858: retCode = "CP858"; return true; case L10N_CODEPAGE_860: retCode = "CP860"; return true; @@ -77,8 +77,8 @@ bool _L10nCodeParse(s32 code, std::string& retCode) } } -//translate code id to code name. -//If this makes your compilation fail, try replace the string code with one in "iconv -l" +// Translate code id to code name. +// If this makes your compilation fail, try replace the string code with one in "iconv -l" bool _L10nCodeParse(s32 code, u32& retCode) { retCode = 0; @@ -86,10 +86,10 @@ bool _L10nCodeParse(s32 code, u32& retCode) switch (code) { case L10N_UTF8: retCode = 65001; return false; - case L10N_UTF16: retCode = 1200; return false; //1200=LE,1201=BE - case L10N_UTF32: retCode = 12000; return false; //12000=LE,12001=BE - case L10N_UCS2: retCode = 1200; return false; //Not in OEM, but just the same as UTF16 - case L10N_UCS4: retCode = 12000; return false; //Not in OEM, but just the same as UTF32 + case L10N_UTF16: retCode = 1200; return false; // 1200=LE,1201=BE + case L10N_UTF32: retCode = 12000; return false; // 12000=LE,12001=BE + case L10N_UCS2: retCode = 1200; return false; // Not in OEM, but just the same as UTF16 + case L10N_UCS4: retCode = 12000; return false; // Not in OEM, but just the same as UTF32 //All OEM Code Pages are Multi-Byte, not wchar_t,u16,u32. case L10N_ISO_8859_1: retCode = 28591; return true; case L10N_ISO_8859_2: retCode = 28592; return true; @@ -102,7 +102,7 @@ bool _L10nCodeParse(s32 code, u32& retCode) case L10N_ISO_8859_9: retCode = 28599; return true; case L10N_ISO_8859_10: retCode = 28600; return true; case L10N_ISO_8859_11: retCode = 28601; return true; - case L10N_ISO_8859_13: retCode = 28603; return true; //No ISO-8859-12 ha ha. + case L10N_ISO_8859_13: retCode = 28603; return true; // No ISO-8859-12 ha ha. case L10N_ISO_8859_14: retCode = 28604; return true; case L10N_ISO_8859_15: retCode = 28605; return true; case L10N_ISO_8859_16: retCode = 28606; return true; @@ -114,26 +114,26 @@ bool _L10nCodeParse(s32 code, u32& retCode) case L10N_CODEPAGE_936: retCode = 936; return true; case L10N_CODEPAGE_949: retCode = 949; return true; case L10N_CODEPAGE_950: retCode = 950; return true; - case L10N_CODEPAGE_1251:retCode = 1251; return true; //CYRL - case L10N_CODEPAGE_1252:retCode = 1252; return true; //ANSI - case L10N_EUC_CN: retCode = 51936; return true; //GB2312 + case L10N_CODEPAGE_1251:retCode = 1251; return true; // CYRL + case L10N_CODEPAGE_1252:retCode = 1252; return true; // ANSI + case L10N_EUC_CN: retCode = 51936; return true; // GB2312 case L10N_EUC_JP: retCode = 51932; return true; case L10N_EUC_KR: retCode = 51949; return true; case L10N_ISO_2022_JP: retCode = 50222; return true; - //Maybe 708/720/864/1256/10004/20420/28596/ - case L10N_ARIB: retCode = 20420; return true; //TODO: think that should be ARABIC. + // Maybe 708/720/864/1256/10004/20420/28596/ + case L10N_ARIB: retCode = 20420; return true; // TODO: think that should be ARABIC. case L10N_HZ: retCode = 52936; return true; case L10N_GB18030: retCode = 54936; return true; - case L10N_RIS_506: retCode = 932; return true; //MusicShiftJIS, MS_KANJI, TODO: Code page - //These are only supported with FW 3.10 and above + case L10N_RIS_506: retCode = 932; return true; // MusicShiftJIS, MS_KANJI, TODO: Code page + // These are only supported with FW 3.10 and above case L10N_CODEPAGE_852: retCode = 852; return true; - case L10N_CODEPAGE_1250:retCode = 1250; return true; //EE + case L10N_CODEPAGE_1250:retCode = 1250; return true; // EE case L10N_CODEPAGE_737: retCode = 737; return true; - case L10N_CODEPAGE_1253:retCode = 1253; return true; //Greek + case L10N_CODEPAGE_1253:retCode = 1253; return true; // Greek case L10N_CODEPAGE_857: retCode = 857; return true; - case L10N_CODEPAGE_1254:retCode = 1254; return true; //Turk + case L10N_CODEPAGE_1254:retCode = 1254; return true; // Turk case L10N_CODEPAGE_775: retCode = 775; return true; - case L10N_CODEPAGE_1257:retCode = 1257; return true; //WINBALTRIM + case L10N_CODEPAGE_1257:retCode = 1257; return true; // WINBALTRIM case L10N_CODEPAGE_855: retCode = 855; return true; case L10N_CODEPAGE_858: retCode = 858; return true; case L10N_CODEPAGE_860: retCode = 860; return true; @@ -144,10 +144,10 @@ bool _L10nCodeParse(s32 code, u32& retCode) } } -//TODO: check and complete transforms. note: unicode to/from other Unicode Formats is needed. +// TODO: check and complete transforms. note: unicode to/from other Unicode Formats is needed. #ifdef _MSC_VER -//Use code page to transform std::string to std::wstring. +// Use code page to transform std::string to std::wstring. s32 _OEM2Wide(u32 oem_code, const std::string src, std::wstring& dst) { //Such length returned should include the '\0' character. @@ -164,7 +164,7 @@ s32 _OEM2Wide(u32 oem_code, const std::string src, std::wstring& dst) return length - 1; } -//Use Code page to transform std::wstring to std::string. +// Use Code page to transform std::wstring to std::string. s32 _Wide2OEM(u32 oem_code, const std::wstring src, std::string& dst) { //Such length returned should include the '\0' character. @@ -181,7 +181,7 @@ s32 _Wide2OEM(u32 oem_code, const std::wstring src, std::string& dst) return length - 1; } -//Convert Codepage to Codepage (all char*) +// Convert Codepage to Codepage (all char*) std::string _OemToOem(u32 src_code, u32 dst_code, const std::string str) { std::wstring wide; std::string result; @@ -191,8 +191,8 @@ std::string _OemToOem(u32 src_code, u32 dst_code, const std::string str) } /* -//Original piece of code. and this is for windows using with _OEM2Wide,_Wide2OEM,_OemToOem. -//The Char -> Char Execution of this function has already been tested using VS and CJK text with encoding. +// Original piece of code. and this is for windows using with _OEM2Wide,_Wide2OEM,_OemToOem. +// The Char -> Char Execution of this function has already been tested using VS and CJK text with encoding. s32 _L10nConvertStr(s32 src_code, const void *src, size_t * src_len, s32 dst_code, void *dst, size_t * dst_len) { u32 srcCode = 0, dstCode = 0; //OEM code pages @@ -215,8 +215,8 @@ s32 _L10nConvertStr(s32 src_code, const void *src, size_t * src_len, s32 dst_cod return ConversionOK; } -//This is the one used with iconv library for linux/mac. Also char->char. -//I've tested the code with console apps using codeblocks. +// This is the one used with iconv library for linux/mac. Also char->char. +// I've tested the code with console apps using codeblocks. s32 _L10nConvertStr(s32 src_code, const void* src, size_t * src_len, s32 dst_code, void * dst, size_t * dst_len) { std::string srcCode, dstCode; @@ -885,9 +885,14 @@ s32 UTF16toUTF32() throw EXCEPTION(""); } -s32 l10n_convert_str() +s32 l10n_convert_str(s32 cd, vm::cptr src, vm::ptr src_len, vm::ptr dst, vm::ptr dst_len) { - throw EXCEPTION(""); + cellL10n.Warning("l10n_convert_str(cd=%d, src=*0x%x, src_len=*0x%x, dst=*0x%x, dst_len=*0x%x)", cd, src, src_len, dst, dst_len); + + s32 src_code = cd >> 16; + s32 dst_code = cd & 0xffff; + + return L10nConvertStr(src_code, src, src_len, dst_code, dst, dst_len); } s32 EUCJPstoJISs() @@ -990,9 +995,10 @@ s32 MSJISstoUCS2s() throw EXCEPTION(""); } -s32 l10n_get_converter() +s32 l10n_get_converter(u32 src_code, u32 dst_code) { - throw EXCEPTION(""); + cellL10n.Warning("l10n_get_converter(src_code=%d, dst_code=%d)", src_code, dst_code); + return (src_code << 16) | dst_code; } s32 GB18030stoUTF8s() @@ -1157,7 +1163,6 @@ s32 UTF8stoUCS2s() throw EXCEPTION(""); } - Module cellL10n("cellL10n", []() { REG_FUNC(cellL10n, UCS2toEUCJP); diff --git a/rpcs3/Emu/SysCalls/Modules/cellL10n.h b/rpcs3/Emu/SysCalls/Modules/cellL10n.h index 0c8057744f..04c39af03a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellL10n.h +++ b/rpcs3/Emu/SysCalls/Modules/cellL10n.h @@ -15,16 +15,16 @@ enum enum { L10N_STR_UNKNOWN = (1 << 0), - L10N_STR_ASCII = (1 << 1), - L10N_STR_JIS = (1 << 2), - L10N_STR_EUCJP = (1 << 3), - L10N_STR_SJIS = (1 << 4), - L10N_STR_UTF8 = (1 << 5), + L10N_STR_ASCII = (1 << 1), + L10N_STR_JIS = (1 << 2), + L10N_STR_EUCJP = (1 << 3), + L10N_STR_SJIS = (1 << 4), + L10N_STR_UTF8 = (1 << 5), L10N_STR_ILLEGAL = (1 << 16), - L10N_STR_ERROR = (1 << 17), + L10N_STR_ERROR = (1 << 17), }; -//CodePages +// CodePages enum { L10N_UTF8 = 0, L10N_UTF16, diff --git a/rpcs3/Emu/SysCalls/Modules/cellMouse.cpp b/rpcs3/Emu/SysCalls/Modules/cellMouse.cpp index df354a0442..6fa25276ab 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMouse.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMouse.cpp @@ -11,8 +11,16 @@ extern Module sys_io; s32 cellMouseInit(u32 max_connect) { sys_io.Warning("cellMouseInit(max_connect=%d)", max_connect); - if(Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_ALREADY_INITIALIZED; - if(max_connect > 7) return CELL_MOUSE_ERROR_INVALID_PARAMETER; + + if (Emu.GetMouseManager().IsInited()) + { + return CELL_MOUSE_ERROR_ALREADY_INITIALIZED; + } + + if (max_connect > 7) + { + return CELL_MOUSE_ERROR_INVALID_PARAMETER; + } Emu.GetMouseManager().Init(max_connect); return CELL_OK; @@ -22,8 +30,16 @@ s32 cellMouseInit(u32 max_connect) s32 cellMouseClearBuf(u32 port_no) { sys_io.Log("cellMouseClearBuf(port_no=%d)", port_no); - if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; - if(port_no >= Emu.GetMouseManager().GetMice().size()) return CELL_MOUSE_ERROR_INVALID_PARAMETER; + + if (!Emu.GetMouseManager().IsInited()) + { + return CELL_MOUSE_ERROR_UNINITIALIZED; + } + + if (port_no >= Emu.GetMouseManager().GetMice().size()) + { + return CELL_MOUSE_ERROR_INVALID_PARAMETER; + } //? @@ -33,7 +49,12 @@ s32 cellMouseClearBuf(u32 port_no) s32 cellMouseEnd() { sys_io.Log("cellMouseEnd()"); - if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; + + if (!Emu.GetMouseManager().IsInited()) + { + return CELL_MOUSE_ERROR_UNINITIALIZED; + } + Emu.GetMouseManager().Close(); return CELL_OK; } @@ -41,15 +62,19 @@ s32 cellMouseEnd() s32 cellMouseGetInfo(vm::ptr info) { sys_io.Log("cellMouseGetInfo(info=*0x%x)", info); - if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; + + if (!Emu.GetMouseManager().IsInited()) + { + return CELL_MOUSE_ERROR_UNINITIALIZED; + } const MouseInfo& current_info = Emu.GetMouseManager().GetInfo(); info->max_connect = current_info.max_connect; info->now_connect = current_info.now_connect; info->info = current_info.info; - for(u32 i=0; ivendor_id[i] = current_info.vendor_id[i]; - for(u32 i=0; iproduct_id[i] = current_info.product_id[i]; - for(u32 i=0; istatus[i] = current_info.status[i]; + for (u32 i=0; ivendor_id[i] = current_info.vendor_id[i]; + for (u32 i=0; iproduct_id[i] = current_info.product_id[i]; + for (u32 i=0; istatus[i] = current_info.status[i]; return CELL_OK; } @@ -57,8 +82,15 @@ s32 cellMouseGetInfo(vm::ptr info) s32 cellMouseInfoTabletMode(u32 port_no, vm::ptr info) { sys_io.Log("cellMouseInfoTabletMode(port_no=%d, info=*0x%x)", port_no, info); - if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; - if(port_no >= Emu.GetMouseManager().GetMice().size()) return CELL_MOUSE_ERROR_INVALID_PARAMETER; + if (!Emu.GetMouseManager().IsInited()) + { + return CELL_MOUSE_ERROR_UNINITIALIZED; + } + + if (port_no >= Emu.GetMouseManager().GetMice().size()) + { + return CELL_MOUSE_ERROR_INVALID_PARAMETER; + } info->is_supported = 0; // Unimplemented: (0=Tablet mode is not supported) info->mode = 1; // Unimplemented: (1=Mouse mode) @@ -69,8 +101,14 @@ s32 cellMouseInfoTabletMode(u32 port_no, vm::ptr info) s32 cellMouseGetData(u32 port_no, vm::ptr data) { sys_io.Log("cellMouseGetData(port_no=%d, data=*0x%x)", port_no, data); - if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; - if(port_no >= Emu.GetMouseManager().GetMice().size()) return CELL_MOUSE_ERROR_NO_DEVICE; + if (!Emu.GetMouseManager().IsInited()) + { + return CELL_MOUSE_ERROR_UNINITIALIZED; + } + if (port_no >= Emu.GetMouseManager().GetMice().size()) + { + return CELL_MOUSE_ERROR_NO_DEVICE; + } MouseData& current_data = Emu.GetMouseManager().GetData(port_no); data->update = current_data.update; @@ -112,8 +150,8 @@ s32 cellMouseGetTabletDataList(u32 port_no, u32 data_addr) s32 cellMouseGetRawData(u32 port_no, vm::ptr data) { sys_io.Todo("cellMouseGetRawData(port_no=%d, data=*0x%x)", port_no, data); - /*if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; - if(port_no >= Emu.GetMouseManager().GetMice().size()) return CELL_MOUSE_ERROR_NO_DEVICE; + /*if (!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; + if (port_no >= Emu.GetMouseManager().GetMice().size()) return CELL_MOUSE_ERROR_NO_DEVICE; CellMouseRawData& current_rawdata = Emu.GetMouseManager().GetRawData(port_no); data += current_rawdata.len; diff --git a/rpcs3/Emu/SysCalls/Modules/cellMusic.cpp b/rpcs3/Emu/SysCalls/Modules/cellMusic.cpp index ed3b438b2d..bd5993b56c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMusic.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMusic.cpp @@ -1,9 +1,20 @@ #include "stdafx.h" +#include "Emu/System.h" +#include "Emu/IdManager.h" #include "Emu/Memory/Memory.h" +#include "Emu/SysCalls/Callback.h" #include "Emu/SysCalls/Modules.h" +#include "cellMusic.h" + extern Module cellMusic; +struct music2_t +{ + vm::ptr func; + vm::ptr userData; +}; + s32 cellMusicGetSelectionContext() { throw EXCEPTION(""); @@ -99,9 +110,32 @@ s32 cellMusicSelectContents() throw EXCEPTION(""); } -s32 cellMusicInitialize2() +s32 cellMusicInitialize2(s32 mode, s32 spuPriority, vm::ptr func, vm::ptr userData) { - throw EXCEPTION(""); + cellMusic.Todo("cellMusicInitialize2(mode=%d, spuPriority=%d, func=*0x%x, userData=*0x%x)", mode, spuPriority, func, userData); + + if (mode != CELL_MUSIC2_PLAYER_MODE_NORMAL) + { + cellMusic.Todo("Unknown player mode: 0x%x", mode); + return CELL_MUSIC2_ERROR_PARAM; + } + + named_thread_t(WRAP_EXPR("CellMusicInit"), [=]() + { + const auto music = fxm::make_always(); + music->func = func; + music->userData = userData; + + Emu.GetCallbackManager().Register([=](CPUThread& CPU) -> s32 + { + vm::var ret(CPU); + *ret = CELL_OK; + func(static_cast(CPU), CELL_MUSIC2_EVENT_INITIALIZE_RESULT, ret, userData); + return CELL_OK; + }); + }).detach(); + + return CELL_OK; } s32 cellMusicSetVolume() diff --git a/rpcs3/Emu/SysCalls/Modules/cellMusic.h b/rpcs3/Emu/SysCalls/Modules/cellMusic.h new file mode 100644 index 0000000000..7b41d7a2ee --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellMusic.h @@ -0,0 +1,134 @@ +#pragma once + +namespace vm { using namespace ps3; } + +// Error Codes +enum +{ + CELL_MUSIC_OK = 0, + CELL_MUSIC_CANCELED = 1, + CELL_MUSIC_PLAYBACK_FINISHED = 0x8002c101, + CELL_MUSIC_ERROR_PARAM = 0x8002c102, + CELL_MUSIC_ERROR_BUSY = 0x8002c103, + CELL_MUSIC_ERROR_NO_ACTIVE_CONTENT = 0x8002c104, + CELL_MUSIC_ERROR_NO_MATCH_FOUND = 0x8002c105, + CELL_MUSIC_ERROR_INVALID_CONTEXT = 0x8002c106, + CELL_MUSIC_ERROR_PLAYBACK_FAILURE = 0x8002c107, + CELL_MUSIC_ERROR_NO_MORE_CONTENT = 0x8002c108, + CELL_MUSIC_DIALOG_OPEN = 0x8002c109, + CELL_MUSIC_DIALOG_CLOSE = 0x8002c10A, + CELL_MUSIC_ERROR_GENERIC = 0x8002c1FF, + CELL_MUSIC2_OK = CELL_MUSIC_OK, + CELL_MUSIC2_CANCELED = CELL_MUSIC_CANCELED, + CELL_MUSIC2_PLAYBACK_FINISHED = CELL_MUSIC_PLAYBACK_FINISHED, + CELL_MUSIC2_ERROR_PARAM = CELL_MUSIC_ERROR_PARAM, + CELL_MUSIC2_ERROR_BUSY = CELL_MUSIC_ERROR_BUSY, + CELL_MUSIC2_ERROR_NO_ACTIVE_CONTENT = CELL_MUSIC_ERROR_NO_ACTIVE_CONTENT, + CELL_MUSIC2_ERROR_NO_MATCH_FOUND = CELL_MUSIC_ERROR_NO_MATCH_FOUND, + CELL_MUSIC2_ERROR_INVALID_CONTEXT = CELL_MUSIC_ERROR_INVALID_CONTEXT, + CELL_MUSIC2_ERROR_PLAYBACK_FAILURE = CELL_MUSIC_ERROR_PLAYBACK_FAILURE, + CELL_MUSIC2_ERROR_NO_MORE_CONTENT = CELL_MUSIC_ERROR_NO_MORE_CONTENT, + CELL_MUSIC2_DIALOG_OPEN = CELL_MUSIC_DIALOG_OPEN, + CELL_MUSIC2_DIALOG_CLOSE = CELL_MUSIC_DIALOG_CLOSE, + CELL_MUSIC2_ERROR_GENERIC = CELL_MUSIC_ERROR_GENERIC, +}; + +enum +{ + CELL_SYSUTIL_MUSIC_INITIALIZING_FINISHED = 1, + CELL_SYSUTIL_MUSIC_SHUTDOWN_FINISHED = 4, // Was 3 in 1.03, changed to 4 in 1.1 + CELL_SYSUTIL_MUSIC_LOADING_FINISHED = 5, + CELL_SYSUTIL_MUSIC_UNLOADING_FINISHED = 7, + CELL_SYSUTIL_MUSIC_RELEASED = 9, + CELL_SYSUTIL_MUSIC_GRABBED = 11, +}; + +enum +{ + CELL_SYSUTIL_MUSIC2_INITIALIZING_FINISHED = CELL_SYSUTIL_MUSIC_INITIALIZING_FINISHED, + CELL_SYSUTIL_MUSIC2_SHUTDOWN_FINISHED = CELL_SYSUTIL_MUSIC_SHUTDOWN_FINISHED, + CELL_SYSUTIL_MUSIC2_LOADING_FINISHED = CELL_SYSUTIL_MUSIC_LOADING_FINISHED, + CELL_SYSUTIL_MUSIC2_UNLOADING_FINISHED = CELL_SYSUTIL_MUSIC_UNLOADING_FINISHED, + CELL_SYSUTIL_MUSIC2_RELEASED = CELL_SYSUTIL_MUSIC_RELEASED, + CELL_SYSUTIL_MUSIC2_GRABBED = CELL_SYSUTIL_MUSIC_GRABBED, +}; + +enum +{ + CELL_MUSIC_EVENT_STATUS_NOTIFICATION = 0, + CELL_MUSIC_EVENT_INITIALIZE_RESULT = 1, + CELL_MUSIC_EVENT_FINALIZE_RESULT = 2, + CELL_MUSIC_EVENT_SELECT_CONTENTS_RESULT = 3, + CELL_MUSIC_EVENT_SET_PLAYBACK_COMMAND_RESULT = 4, + CELL_MUSIC_EVENT_SET_VOLUME_RESULT = 5, + CELL_MUSIC_EVENT_SET_SELECTION_CONTEXT_RESULT = 6, + CELL_MUSIC_EVENT_UI_NOTIFICATION = 7, +}; + +enum +{ + CELL_MUSIC2_EVENT_STATUS_NOTIFICATION = CELL_MUSIC_EVENT_STATUS_NOTIFICATION, + CELL_MUSIC2_EVENT_INITIALIZE_RESULT = CELL_MUSIC_EVENT_INITIALIZE_RESULT, + CELL_MUSIC2_EVENT_FINALIZE_RESULT = CELL_MUSIC_EVENT_FINALIZE_RESULT, + CELL_MUSIC2_EVENT_SELECT_CONTENTS_RESULT = CELL_MUSIC_EVENT_SELECT_CONTENTS_RESULT, + CELL_MUSIC2_EVENT_SET_PLAYBACK_COMMAND_RESULT = CELL_MUSIC_EVENT_SET_PLAYBACK_COMMAND_RESULT, + CELL_MUSIC2_EVENT_SET_VOLUME_RESULT = CELL_MUSIC_EVENT_SET_VOLUME_RESULT, + CELL_MUSIC2_EVENT_SET_SELECTION_CONTEXT_RESULT = CELL_MUSIC_EVENT_SET_SELECTION_CONTEXT_RESULT, + CELL_MUSIC2_EVENT_UI_NOTIFICATION = CELL_MUSIC_EVENT_UI_NOTIFICATION, +}; + +enum +{ + CELL_MUSIC_PB_CMD_STOP = 0, + CELL_MUSIC_PB_CMD_PLAY = 1, + CELL_MUSIC_PB_CMD_PAUSE = 2, + CELL_MUSIC_PB_CMD_NEXT = 3, + CELL_MUSIC_PB_CMD_PREV = 4, + CELL_MUSIC_PB_CMD_FASTFORWARD = 5, + CELL_MUSIC_PB_CMD_FASTREVERSE = 6, +}; + +enum +{ + CELL_MUSIC2_PB_CMD_STOP = CELL_MUSIC_PB_CMD_STOP, + CELL_MUSIC2_PB_CMD_PLAY = CELL_MUSIC_PB_CMD_PLAY, + CELL_MUSIC2_PB_CMD_PAUSE = CELL_MUSIC_PB_CMD_PAUSE, + CELL_MUSIC2_PB_CMD_NEXT = CELL_MUSIC_PB_CMD_NEXT, + CELL_MUSIC2_PB_CMD_PREV = CELL_MUSIC_PB_CMD_PREV, + CELL_MUSIC2_PB_CMD_FASTFORWARD = CELL_MUSIC_PB_CMD_FASTFORWARD, + CELL_MUSIC2_PB_CMD_FASTREVERSE = CELL_MUSIC_PB_CMD_FASTREVERSE, +}; + +enum +{ + CELL_MUSIC_PB_STATUS_STOP = 0, + CELL_MUSIC_PB_STATUS_PLAY = 1, + CELL_MUSIC_PB_STATUS_PAUSE = 2, + CELL_MUSIC_PB_STATUS_FASTFORWARD = 3, + CELL_MUSIC_PB_STATUS_FASTREVERSE = 4, +}; + +enum +{ + CELL_MUSIC2_PB_STATUS_STOP = CELL_MUSIC_PB_STATUS_STOP, + CELL_MUSIC2_PB_STATUS_PLAY = CELL_MUSIC_PB_STATUS_PLAY, + CELL_MUSIC2_PB_STATUS_PAUSE = CELL_MUSIC_PB_STATUS_PAUSE, + CELL_MUSIC2_PB_STATUS_FASTFORWARD = CELL_MUSIC_PB_STATUS_FASTFORWARD, + CELL_MUSIC2_PB_STATUS_FASTREVERSE = CELL_MUSIC_PB_STATUS_FASTREVERSE, +}; + +enum +{ + CELL_MUSIC_PLAYBACK_MEMORY_CONTAINER_SIZE = 11 * 1024 * 1024, + CELL_MUSIC_PLAYER_MODE_NORMAL = 0, + CELL_MUSIC2_PLAYER_MODE_NORMAL = CELL_MUSIC_PLAYER_MODE_NORMAL, + CELL_MUSIC_SELECTION_CONTEXT_SIZE = 2048, +}; + +using CellMusicCallback = void(u32 event, vm::ptr param, vm::ptr userData); +using CellMusic2Callback = void(u32 event, vm::ptr param, vm::ptr userData); + +struct CellMusicSelectionContext +{ + char data[CELL_MUSIC_SELECTION_CONTEXT_SIZE]; +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp b/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp index a31e2a951c..831a19c846 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp @@ -30,6 +30,17 @@ extern Module cellNetCtl; +std::unique_ptr g_sign_in_dialog; + +SignInDialogInstance::SignInDialogInstance() +{ +} + +void SignInDialogInstance::Close() +{ + //state = signInDialogClose; +} + s32 cellNetCtlInit() { cellNetCtl.Warning("cellNetCtlInit()"); @@ -338,16 +349,21 @@ s32 cellNetCtlNetStartDialogLoadAsync(vm::ptr par { cellNetCtl.Warning("cellNetCtlNetStartDialogLoadAsync(param=*0x%x)", param); - // TODO: Actually sign into PSN or an emulated network similar to PSN + // TODO: Actually sign into PSN or an emulated network similar to PSN (ESN) + // TODO: Properly open the dialog prompt for sign in + sysutilSendSystemCommand(CELL_SYSUTIL_NET_CTL_NETSTART_LOADED, 0); + g_sign_in_dialog->status = CELL_NET_CTL_ERROR_DIALOG_CANCELED; sysutilSendSystemCommand(CELL_SYSUTIL_NET_CTL_NETSTART_FINISHED, 0); - return CELL_OK; + return CELL_NET_CTL_ERROR_NOT_CONNECTED; } s32 cellNetCtlNetStartDialogAbortAsync() { cellNetCtl.Todo("cellNetCtlNetStartDialogAbortAsync()"); + g_sign_in_dialog->status = CELL_NET_CTL_ERROR_DIALOG_ABORTED; + return CELL_OK; } @@ -355,6 +371,7 @@ s32 cellNetCtlNetStartDialogUnloadAsync(vm::ptr { cellNetCtl.Warning("cellNetCtlNetStartDialogUnloadAsync(result=*0x%x)", result); + result->result = g_sign_in_dialog->status; sysutilSendSystemCommand(CELL_SYSUTIL_NET_CTL_NETSTART_UNLOADED, 0); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellNetCtl.h b/rpcs3/Emu/SysCalls/Modules/cellNetCtl.h index 65275e4c62..de60bfe1d4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellNetCtl.h +++ b/rpcs3/Emu/SysCalls/Modules/cellNetCtl.h @@ -261,6 +261,21 @@ struct CellNetCtlNatInfo typedef void(cellNetCtlHandler)(s32 prev_state, s32 new_state, s32 event, s32 error_code, vm::ptr arg); +struct SignInDialogInstance +{ + //std::atomic state; + + s32 status; + + SignInDialogInstance(); + virtual ~SignInDialogInstance() = default; + + virtual void Close(); + + virtual void Create() = 0; + virtual void Destroy() = 0; +}; + inline static const char* InfoCodeToName(s32 code) { switch (code) diff --git a/rpcs3/Emu/SysCalls/Modules/cellPad.cpp b/rpcs3/Emu/SysCalls/Modules/cellPad.cpp index 4ec390e81b..263f6a988f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPad.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPad.cpp @@ -72,12 +72,33 @@ s32 cellPadClearBuf(u32 port_no) s32 cellPadPeriphGetInfo(vm::ptr info) { - sys_io.Warning("cellPadPeriphGetInfo(info=*0x%x)", info); + sys_io.Todo("cellPadPeriphGetInfo(info=*0x%x)", info); + + if (!Emu.GetPadManager().IsInited()) + { + return CELL_PAD_ERROR_UNINITIALIZED; + } + + const PadInfo& rinfo = Emu.GetPadManager().GetInfo(); + + info->max_connect = rinfo.max_connect; + info->now_connect = rinfo.now_connect; + info->system_info = rinfo.system_info; + + std::vector& pads = Emu.GetPadManager().GetPads(); // TODO: Support other types of controllers - for (u32 i = 0; i < info->now_connect; i++) + for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; ++i) { + if (i >= pads.size()) + break; + + info->port_status[i] = pads[i].m_port_status; + info->port_setting[i] = pads[i].m_port_setting; + info->device_capability[i] = pads[i].m_device_capability; + info->device_type[i] = pads[i].m_device_type; info->pclass_type[i] = CELL_PAD_PCLASS_TYPE_STANDARD; + info->pclass_profile[i] = 0x0; } return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSail.cpp b/rpcs3/Emu/SysCalls/Modules/cellSail.cpp index 4ab1497fff..c532f8626c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSail.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSail.cpp @@ -725,11 +725,14 @@ s32 cellSailPlayerSetRendererVideo() s32 cellSailPlayerSetParameter(vm::ptr pSelf, s32 parameterType, u64 param0, u64 param1) { - cellSail.Todo("cellSailPlayerSetParameter(pSelf=*0x%x, parameterType=0x%x, param0=0x%llx, param1=0x%llx)", pSelf, parameterType, param0, param1); + cellSail.Warning("cellSailPlayerSetParameter(pSelf=*0x%x, parameterType=0x%x, param0=0x%llx, param1=0x%llx)", pSelf, parameterType, param0, param1); switch (parameterType) { - default: cellSail.Error("cellSailPlayerSetParameter(): unimplemented parameter %s", ParameterCodeToName(parameterType)); + case CELL_SAIL_PARAMETER_GRAPHICS_ADAPTER_BUFFER_RELEASE_DELAY: pSelf->graphics_adapter_buffer_release_delay = param1; break; // TODO: Stream index + case CELL_SAIL_PARAMETER_CONTROL_PPU_THREAD_STACK_SIZE: pSelf->control_ppu_thread_stack_size = param0; break; + case CELL_SAIL_PARAMETER_ENABLE_APOST_SRC: pSelf->enable_apost_src = param1; break; // TODO: Stream index + default: cellSail.Todo("cellSailPlayerSetParameter(): unimplemented parameter %s", ParameterCodeToName(parameterType)); } return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSail.h b/rpcs3/Emu/SysCalls/Modules/cellSail.h index 1b90452a08..105beac7fb 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSail.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSail.h @@ -1,5 +1,7 @@ #pragma once +#include "cellVpost.h" + namespace vm { using namespace ps3; } // Error Codes @@ -666,8 +668,7 @@ union CellSailEvent { be_t major; be_t minor; - } - u32x2; + } u32x2; be_t value; }; @@ -1193,6 +1194,36 @@ struct CellSailPlayer bool booted; vm::ptr sAdapter; vm::ptr gAdapter; + + // Attributes + be_t control_ppu_thread_priority; + be_t control_ppu_thread_stack_size; + be_t spurs_num_of_spus; + be_t spurs_spu_thread_priority; + be_t spurs_ppu_thread_priority; + b8 spurs_exit_if_no_work; + be_t io_ppu_thread_priority; + be_t io_ppu_thread_stack_size; + be_t dmux_ppu_thread_priority; + be_t dmux_num_of_spus; + be_t dmux_spurs_task_priorities; + be_t adec_ppu_thread_priority; + be_t adec_num_of_spus; + be_t adec_spurs_task_priorities; + b8 enable_apost_src; + be_t vdec_ppu_thread_priority; + be_t vdec_m2v_num_of_spus; + be_t vdec_avc_num_of_spus; + be_t vdec_spurs_task_priorities; + vm::ptr enable_vpost; + be_t vpost_ppu_thread_priority; + be_t vpost_num_of_spus; + be_t vpost_spurs_task_priorities; + be_t graphics_adapter_buffer_release_delay; + be_t video_performance_policy; + b8 av_sync_es_audio; + b8 av_sync_es_video; + CellSailFsRead fs; }; CHECK_MAX_SIZE(CellSailPlayer, 0x100); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp b/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp index 8276422d20..c43c6d55da 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp @@ -29,14 +29,14 @@ using PFuncDone = vm::ptr; enum : u32 { - SAVEDATA_OP_AUTO_SAVE = 0, - SAVEDATA_OP_AUTO_LOAD = 1, + SAVEDATA_OP_AUTO_SAVE = 0, + SAVEDATA_OP_AUTO_LOAD = 1, SAVEDATA_OP_LIST_AUTO_SAVE = 2, SAVEDATA_OP_LIST_AUTO_LOAD = 3, - SAVEDATA_OP_LIST_SAVE = 4, - SAVEDATA_OP_LIST_LOAD = 5, - SAVEDATA_OP_FIXED_SAVE = 6, - SAVEDATA_OP_FIXED_LOAD = 7, + SAVEDATA_OP_LIST_SAVE = 4, + SAVEDATA_OP_LIST_LOAD = 5, + SAVEDATA_OP_FIXED_SAVE = 6, + SAVEDATA_OP_FIXED_LOAD = 7, SAVEDATA_OP_FIXED_DELETE = 14, }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutilAvc2.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutilAvc2.cpp index 3f726b2a4b..57c3661b74 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutilAvc2.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutilAvc2.cpp @@ -1,6 +1,11 @@ #include "stdafx.h" #include "Emu/Memory/Memory.h" #include "Emu/SysCalls/Modules.h" +#include "rpcs3/Ini.h" + +#include "sceNp.h" +#include "sceNp2.h" +#include "cellSysutilAvc2.h" extern Module cellSysutilAvc2; @@ -124,9 +129,21 @@ s32 cellSysutilAvc2GetSpeakerVolumeLevel() throw EXCEPTION(""); } -s32 cellSysutilAvc2IsCameraAttached() +s32 cellSysutilAvc2IsCameraAttached(vm::ptr status) { - throw EXCEPTION(""); + cellSysutilAvc2.Todo("cellSysutilAvc2IsCameraAttached()"); + + if (Ini.Camera.GetValue() == 0) + { + *status = CELL_AVC2_CAMERA_STATUS_DETACHED; + } + else + { + // TODO: We need to check if the camera has been turned on, but this requires further implementation of cellGem/cellCamera. + *status = CELL_AVC2_CAMERA_STATUS_ATTACHED_OFF; + } + + return CELL_OK; } s32 cellSysutilAvc2MicRead() @@ -159,9 +176,51 @@ s32 cellSysutilAvc2GetWindowShowStatus() throw EXCEPTION(""); } -s32 cellSysutilAvc2InitParam() +s32 cellSysutilAvc2InitParam(u16 version, vm::ptr option) { - throw EXCEPTION(""); + cellSysutilAvc2.Warning("cellSysutilAvc2InitParam(version=%d, option=*0x%x)", version, option); + + if (version >= 110) + { + // Notify the user that, a version different from the one, that we know the constants for, is used. + // Other versions shouldn't differ by too much, if at all - they most likely differ in other functions. + if (version != 140) + { + cellSysutilAvc2.Todo("cellSysutilAvc2InitParam(): Older/newer version %d used, might cause problems.", version); + } + + option->avc_init_param_version = version; + + if (option->media_type == CELL_SYSUTIL_AVC2_VOICE_CHAT) + { + option->max_players = 16; + } + else if (option->media_type == CELL_SYSUTIL_AVC2_VIDEO_CHAT) + { + if (option->video_param.frame_mode == CELL_SYSUTIL_AVC2_FRAME_MODE_NORMAL) + { + option->max_players = 6; + } + else if (option->video_param.frame_mode == CELL_SYSUTIL_AVC2_FRAME_MODE_INTRA_ONLY) + { + option->max_players = 16; + } + else + { + cellSysutilAvc2.Error("Unknown frame mode 0x%x", option->video_param.frame_mode); + } + } + else + { + cellSysutilAvc2.Error("Unknown media type 0x%x", option->media_type); + } + } + else + { + cellSysutilAvc2.Error("cellSysutilAvc2InitParam(): Unknown version %d used, please report this to a developer.", version); + } + + return CELL_OK; } s32 cellSysutilAvc2GetWindowSize() diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutilAvc2.h b/rpcs3/Emu/SysCalls/Modules/cellSysutilAvc2.h new file mode 100644 index 0000000000..dc08ffa39b --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutilAvc2.h @@ -0,0 +1,206 @@ +#pragma once + +namespace vm { using namespace ps3; } + +// Error codes +enum +{ + CELL_AVC2_ERROR_UNKNOWN = 0x8002b701, + CELL_AVC2_ERROR_NOT_SUPPORTED = 0x8002b702, + CELL_AVC2_ERROR_NOT_INITIALIZED = 0x8002b703, + CELL_AVC2_ERROR_ALREADY_INITIALIZED = 0x8002b704, + CELL_AVC2_ERROR_INVALID_ARGUMENT = 0x8002b705, + CELL_AVC2_ERROR_OUT_OF_MEMORY = 0x8002b706, + CELL_AVC2_ERROR_ERROR_BAD_ID = 0x8002b707, + CELL_AVC2_ERROR_INVALID_STATUS = 0x8002b70a, + CELL_AVC2_ERROR_TIMEOUT = 0x8002b70b, + CELL_AVC2_ERROR_NO_SESSION = 0x8002b70d, + CELL_AVC2_ERROR_WINDOW_ALREADY_EXISTS = 0x8002b70f, + CELL_AVC2_ERROR_TOO_MANY_WINDOWS = 0x8002b710, + CELL_AVC2_ERROR_TOO_MANY_PEER_WINDOWS = 0x8002b711, + CELL_AVC2_ERROR_WINDOW_NOT_FOUND = 0x8002b712, +}; + +enum +{ + CELL_SYSUTIL_AVC2_VOICE_CHAT = 0x00000001, + CELL_SYSUTIL_AVC2_VIDEO_CHAT = 0x00000010, +}; + +enum +{ + CELL_SYSUTIL_AVC2_VOICE_QUALITY_NORMAL = 0x00000001, +}; + +enum +{ + CELL_SYSUTIL_AVC2_VIDEO_QUALITY_NORMAL = 0x00000001, +}; + +enum +{ + CELL_SYSUTIL_AVC2_FRAME_MODE_NORMAL = 0x00000001, + CELL_SYSUTIL_AVC2_FRAME_MODE_INTRA_ONLY = 0x00000002, +}; + +enum +{ + CELL_SYSUTIL_AVC2_VIRTUAL_COORDINATES = 0x00000001, + CELL_SYSUTIL_AVC2_ABSOLUTE_COORDINATES = 0x00000002, +}; + +enum +{ + CELL_SYSUTIL_AVC2_VIDEO_RESOLUTION_QQVGA = 0x00000001, + CELL_SYSUTIL_AVC2_VIDEO_RESOLUTION_QVGA = 0x00000002, +}; + +enum +{ + CELL_SYSUTIL_AVC2_CHAT_TARGET_MODE_ROOM = 0x00000100, + CELL_SYSUTIL_AVC2_CHAT_TARGET_MODE_TEAM = 0x00000200, + CELL_SYSUTIL_AVC2_CHAT_TARGET_MODE_PRIVATE = 0x00000300, + CELL_SYSUTIL_AVC2_CHAT_TARGET_MODE_DIRECT = 0x00001000, +}; + +enum +{ + CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_DETECT_EVENT_TYPE = 0x00001001, + CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_DETECT_INTERVAL_TIME = 0x00001002, + CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_DETECT_SIGNAL_LEVEL = 0x00001003, + CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_MAX_BITRATE = 0x00001004, + CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_DATA_FEC = 0x00001005, + CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_PACKET_CONTENTION = 0x00001006, + CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_DTX_MODE = 0x00001007, + CELL_SYSUTIL_AVC2_ATTRIBUTE_MIC_STATUS_DETECTION = 0x00001008, + CELL_SYSUTIL_AVC2_ATTRIBUTE_MIC_SETTING_NOTIFICATION = 0x00001009, + CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_MUTING_NOTIFICATION = 0x0000100A, + CELL_SYSUTIL_AVC2_ATTRIBUTE_CAMERA_STATUS_DETECTION = 0x0000100B, +}; + +enum +{ + CELL_SYSUTIL_AVC2_WINDOW_ATTRIBUTE_ALPHA = 0x00002001, + CELL_SYSUTIL_AVC2_WINDOW_ATTRIBUTE_TRANSITION_TYPE = 0x00002002, + CELL_SYSUTIL_AVC2_WINDOW_ATTRIBUTE_TRANSITION_DURATION = 0x00002003, + CELL_SYSUTIL_AVC2_WINDOW_ATTRIBUTE_STRING_VISIBLE = 0x00002004, + CELL_SYSUTIL_AVC2_WINDOW_ATTRIBUTE_ROTATION = 0x00002005, + CELL_SYSUTIL_AVC2_WINDOW_ATTRIBUTE_ZORDER = 0x00002006, + CELL_SYSUTIL_AVC2_WINDOW_ATTRIBUTE_SURFACE = 0x00002007, +}; + +enum +{ + CELL_SYSUTIL_AVC2_TRANSITION_NONE = 0xffffffff, + CELL_SYSUTIL_AVC2_TRANSITION_LINEAR = 0x00000000, + CELL_SYSUTIL_AVC2_TRANSITION_SLOWDOWN = 0x00000001, + CELL_SYSUTIL_AVC2_TRANSITION_FASTUP = 0x00000002, + CELL_SYSUTIL_AVC2_TRANSITION_ANGULAR = 0x00000003, + CELL_SYSUTIL_AVC2_TRANSITION_EXPONENT = 0x00000004, +}; + +enum +{ + CELL_SYSUTIL_AVC2_ZORDER_FORWARD_MOST = 0x00000001, + CELL_SYSUTIL_AVC2_ZORDER_BEHIND_MOST = 0x00000002, +}; + +enum +{ + CELL_AVC2_CAMERA_STATUS_DETACHED = 0, + CELL_AVC2_CAMERA_STATUS_ATTACHED_OFF = 1, + CELL_AVC2_CAMERA_STATUS_ATTACHED_ON = 2, + CELL_AVC2_CAMERA_STATUS_UNKNOWN = 3, +}; + +typedef u32 CellSysutilAvc2AttributeId; +typedef u32 CellSysutilAvc2WindowAttributeId; + +typedef u32 CellSysutilAvc2EventId; +typedef u64 CellSysutilAvc2EventParam; + +using CellSysutilAvc2Callback = void(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, vm::ptr userdata); + +typedef u32 CellSysutilAvc2MediaType; +typedef u32 CellSysutilAvc2VoiceQuality; +typedef u32 CellSysutilAvc2VideoQuality; +typedef u32 CellSysutilAvc2FrameMode; +typedef u32 CellSysutilAvc2VideoResolution; +typedef u32 CellSysutilAvc2CoordinatesForm; + +struct CellSysutilAvc2VoiceInitParam +{ + be_t voice_quality; + be_t max_speakers; + u8 mic_out_stream_sharing; +}; + +struct CellSysutilAvc2VideoInitParam +{ + be_t video_quality; + be_t frame_mode; + be_t max_video_resolution; + be_t max_video_windows; + be_t max_video_framerate; + be_t max_video_bitrate; + CellSysutilAvc2CoordinatesForm coordinates_form; + u8 video_stream_sharing; +}; + +struct CellSysutilAvc2StreamingModeParam +{ + be_t mode; + be_t port; +}; + +struct CellSysutilAvc2InitParam +{ + be_t avc_init_param_version; + be_t max_players; + be_t spu_load_average; + CellSysutilAvc2StreamingModeParam streaming_mode; + be_t media_type; + CellSysutilAvc2VoiceInitParam voice_param; + CellSysutilAvc2VideoInitParam video_param; +}; + +struct CellSysutilAvc2RoomMemberList +{ + vm::ptr member_id; + u8 member_num; +}; + +struct CellSysutilAvc2MemberIpAndPortList +{ + vm::ptr member_id; + vm::ptr dst_addr; // in_addr + vm::ptr dst_port; + be_t my_member_id; + u8 member_num; +}; + +union CellSysutilAvc2AttributeParam +{ + be_t int_param; + be_t float_param; + vm::ptr ptr_param; +}; + +struct CellSysutilAvc2Attribute +{ + be_t attr_id; + CellSysutilAvc2AttributeParam attr_param; +}; + +union CellSysutilAvc2WindowAttributeParam +{ + be_t int_vector[4]; + be_t float_vector[4]; + vm::ptr ptr_vector[4]; +}; + +struct CellSysutilAvc2WindowAttribute +{ + be_t attr_id; + CellSysutilAvc2WindowAttributeParam attr_param; +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutilMisc.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutilMisc.cpp index 7658cbee4c..3800b104a0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutilMisc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutilMisc.cpp @@ -1,12 +1,36 @@ #include "stdafx.h" +#include "Emu/System.h" #include "Emu/Memory/Memory.h" #include "Emu/SysCalls/Modules.h" extern Module cellSysutilMisc; +// License areas +enum +{ + CELL_SYSUTIL_LICENSE_AREA_J = 0, + CELL_SYSUTIL_LICENSE_AREA_A = 1, + CELL_SYSUTIL_LICENSE_AREA_E = 2, + CELL_SYSUTIL_LICENSE_AREA_H = 3, + CELL_SYSUTIL_LICENSE_AREA_K = 4, + CELL_SYSUTIL_LICENSE_AREA_C = 5, + CELL_SYSUTIL_LICENSE_AREA_OTHER = 100, +}; + s32 cellSysutilGetLicenseArea() { - throw EXCEPTION(""); + cellSysutilMisc.Warning("cellSysutilGetLicenseArea()"); + + switch (const char region = Emu.GetTitleID().at(2)) + { + case 'J': return CELL_SYSUTIL_LICENSE_AREA_J; + case 'U': return CELL_SYSUTIL_LICENSE_AREA_A; + case 'E': return CELL_SYSUTIL_LICENSE_AREA_E; + case 'H': return CELL_SYSUTIL_LICENSE_AREA_H; + case 'K': return CELL_SYSUTIL_LICENSE_AREA_K; + case 'A': return CELL_SYSUTIL_LICENSE_AREA_C; + default: cellSysutilMisc.Todo("Unknown license area: %s", Emu.GetTitleID().c_str()); return CELL_SYSUTIL_LICENSE_AREA_OTHER; + } } Module cellSysutilMisc("cellSysutilMisc", []() diff --git a/rpcs3/Emu/SysCalls/Modules/cellVideoOut.cpp b/rpcs3/Emu/SysCalls/Modules/cellVideoOut.cpp index 95c903c8cd..f1e7329f65 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVideoOut.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVideoOut.cpp @@ -51,7 +51,7 @@ s32 cellVideoOutGetResolution(u32 resolutionId, vm::ptr s32 cellVideoOutConfigure(u32 videoOut, vm::ptr config, vm::ptr option, u32 waitForEvent) { - cellSysutil.Warning("cellVideoOutConfigure(videoOut=%d, config=*0x%x, option=*0x%x, waitForEvent=0x%x)", videoOut, config, option, waitForEvent); + cellSysutil.Warning("cellVideoOutConfigure(videoOut=%d, config=*0x%x, option=*0x%x, waitForEvent=%d)", videoOut, config, option, waitForEvent); switch (videoOut) { diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp index 577d9d6204..489d5fa94d 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp @@ -220,7 +220,7 @@ s32 sceNpTrophyRegisterContext(PPUThread& CPU, u32 context, u32 handle, vm::ptr< s32 sceNpTrophyGetRequiredDiskSpace(u32 context, u32 handle, vm::ptr reqspace, u64 options) { - sceNpTrophy.Todo("sceNpTrophyGetRequiredDiskSpace(context=0x%x, handle=0x%x, reqspace*=0x%x, options=0x%llx)", context, handle, reqspace, options); + sceNpTrophy.Todo("sceNpTrophyGetRequiredDiskSpace(context=0x%x, handle=0x%x, reqspace=*0x%x, options=0x%llx)", context, handle, reqspace, options); const auto ctxt = idm::get(context); diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 95ed5477d3..94b59b2ce1 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -145,9 +145,13 @@ s32 console_putc() throw EXCEPTION(""); } -s32 console_write() +s32 console_write(vm::ptr data, u32 len) { - throw EXCEPTION(""); + sysPrxForUser.Warning("console_write(data=*0x%x, len=%d)", data, len); + + LOG_NOTICE(TTY, { data.get_ptr(), len }); + + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/sys_game.cpp b/rpcs3/Emu/SysCalls/Modules/sys_game.cpp index 9f06602f29..aed67378f2 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_game.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_game.cpp @@ -62,10 +62,10 @@ void sys_game_process_exitspawn(vm::cptr path, u32 argv_addr, u32 envp_add } } - //TODO: execute the file in with the args in argv - //and the environment parameters in envp and copy the data - //from data_addr into the adress space of the new process - //then kill the current process + // TODO: execute the file in with the args in argv + // and the environment parameters in envp and copy the data + // from data_addr into the adress space of the new process + // then kill the current process Emu.Pause(); sysPrxForUser.Success("Process finished"); @@ -138,10 +138,10 @@ void sys_game_process_exitspawn2(vm::cptr path, u32 argv_addr, u32 envp_ad } } - //TODO: execute the file in with the args in argv - //and the environment parameters in envp and copy the data - //from data_addr into the adress space of the new process - //then kill the current process + // TODO: execute the file in with the args in argv + // and the environment parameters in envp and copy the data + // from data_addr into the adress space of the new process + // then kill the current process Emu.Pause(); sysPrxForUser.Success("Process finished"); diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index ff2ec5cd0f..38a2e4c3ef 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -59,7 +59,7 @@ const ppu_func_caller g_sc_table[1024] = bind_func(sys_process_get_number_of_object), //12 (0x00C) bind_func(sys_process_get_id), //13 (0x00D) - bind_func(sys_process_is_spu_lock_line_reservation_address), //14 (0x00E) + bind_func(sys_process_is_spu_lock_line_reservation_address), //14 (0x00E) null_func, null_func, null_func, //15-17 UNS @@ -75,7 +75,7 @@ const ppu_func_caller g_sc_table[1024] = null_func,//bind_func(), //27 (0x01B) DBG null_func,//bind_func(_sys_process_get_number_of_object)//28 (0x01C) ROOT bind_func(sys_process_get_id), //29 (0x01D) ROOT - bind_func(_sys_process_get_paramsfo), //30 (0x01E) + bind_func(_sys_process_get_paramsfo), //30 (0x01E) null_func,//bind_func(sys_process_get_ppu_guid), //31 (0x01F) null_func, null_func, null_func, null_func, null_func, null_func, null_func, null_func, null_func, //32-40 UNS @@ -91,7 +91,7 @@ const ppu_func_caller g_sc_table[1024] = bind_func(sys_ppu_thread_get_stack_information), //49 (0x031) null_func,//bind_func(sys_ppu_thread_stop), //50 (0x032) ROOT null_func,//bind_func(sys_ppu_thread_restart), //51 (0x033) ROOT - bind_func(_sys_ppu_thread_create), //52 (0x034) DBG + bind_func(_sys_ppu_thread_create), //52 (0x034) DBG bind_func(sys_ppu_thread_start), //53 (0x035) null_func,//bind_func(sys_ppu_...), //54 (0x036) ROOT null_func,//bind_func(sys_ppu_...), //55 (0x037) ROOT @@ -442,14 +442,14 @@ const ppu_func_caller g_sc_table[1024] = null_func, null_func, null_func, //477-479 UNS - bind_func(sys_prx_load_module), //480 (0x1E0) - bind_func(sys_prx_start_module), //481 (0x1E1) - bind_func(sys_prx_stop_module), //482 (0x1E2) - bind_func(sys_prx_unload_module), //483 (0x1E3) - bind_func(sys_prx_register_module), //484 (0x1E4) + bind_func(sys_prx_load_module), //480 (0x1E0) + bind_func(sys_prx_start_module), //481 (0x1E1) + bind_func(sys_prx_stop_module), //482 (0x1E2) + bind_func(sys_prx_unload_module), //483 (0x1E3) + bind_func(sys_prx_register_module), //484 (0x1E4) bind_func(sys_prx_query_module), //485 (0x1E5) bind_func(sys_prx_register_library), //486 (0x1E6) - bind_func(sys_prx_unregister_library), //487 (0x1E7) + bind_func(sys_prx_unregister_library), //487 (0x1E7) bind_func(sys_prx_link_library), //488 (0x1E8) bind_func(sys_prx_unlink_library), //489 (0x1E9) bind_func(sys_prx_query_library), //490 (0x1EA) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.h b/rpcs3/Emu/SysCalls/lv2/sys_spu.h index 15db193013..1b720448de 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.h @@ -6,20 +6,20 @@ namespace vm { using namespace ps3; } enum : s32 { - SYS_SPU_THREAD_GROUP_TYPE_NORMAL = 0x00, - SYS_SPU_THREAD_GROUP_TYPE_SEQUENTIAL = 0x01, - SYS_SPU_THREAD_GROUP_TYPE_SYSTEM = 0x02, + SYS_SPU_THREAD_GROUP_TYPE_NORMAL = 0x00, + SYS_SPU_THREAD_GROUP_TYPE_SEQUENTIAL = 0x01, + SYS_SPU_THREAD_GROUP_TYPE_SYSTEM = 0x02, SYS_SPU_THREAD_GROUP_TYPE_MEMORY_FROM_CONTAINER = 0x04, - SYS_SPU_THREAD_GROUP_TYPE_NON_CONTEXT = 0x08, + SYS_SPU_THREAD_GROUP_TYPE_NON_CONTEXT = 0x08, SYS_SPU_THREAD_GROUP_TYPE_EXCLUSIVE_NON_CONTEXT = 0x18, SYS_SPU_THREAD_GROUP_TYPE_COOPERATE_WITH_SYSTEM = 0x20, }; enum { - SYS_SPU_THREAD_GROUP_JOIN_GROUP_EXIT = 0x0001, + SYS_SPU_THREAD_GROUP_JOIN_GROUP_EXIT = 0x0001, SYS_SPU_THREAD_GROUP_JOIN_ALL_THREADS_EXIT = 0x0002, - SYS_SPU_THREAD_GROUP_JOIN_TERMINATED = 0x0004 + SYS_SPU_THREAD_GROUP_JOIN_TERMINATED = 0x0004 }; enum diff --git a/rpcs3/Gui/GameViewer.cpp b/rpcs3/Gui/GameViewer.cpp index cada6a51fd..b60d69c75f 100644 --- a/rpcs3/Gui/GameViewer.cpp +++ b/rpcs3/Gui/GameViewer.cpp @@ -42,7 +42,8 @@ class WxDirDeleteTraverser : public wxDirTraverser public: virtual wxDirTraverseResult OnFile(const wxString& filename) override { - if (!wxRemoveFile(filename)){ + if (!wxRemoveFile(filename)) + { LOG_ERROR(HLE, "Couldn't delete File: %s", fmt::ToUTF8(filename).c_str()); } return wxDIR_CONTINUE; @@ -51,7 +52,8 @@ public: { wxDir dir(dirname); dir.Traverse(*this); - if (!wxRmDir(dirname)){ + if (!wxRmDir(dirname)) + { //this get triggered a few times while clearing folders //but if this gets reimplented we should probably warn //if directories can't be removed @@ -120,7 +122,7 @@ void GameViewer::LoadGames() void GameViewer::LoadPSF() { m_game_data.clear(); - for(uint i=0; iAdd(cbox_audio_out, wxSizerFlags().Border(wxALL, 5).Expand()); + // Miscellaneous s_round_hle_log_lvl->Add(cbox_hle_loglvl, wxSizerFlags().Border(wxALL, 5).Expand()); // Networking diff --git a/rpcs3/Gui/SignInDialog.cpp b/rpcs3/Gui/SignInDialog.cpp new file mode 100644 index 0000000000..951b75033f --- /dev/null +++ b/rpcs3/Gui/SignInDialog.cpp @@ -0,0 +1,79 @@ +#include "stdafx_gui.h" +#include "Emu/SysCalls/Modules.h" +#include "Emu/Memory/Memory.h" + +#include "Emu/SysCalls/Modules/cellSysutil.h" +#include "SignInDialog.h" + +// TODO: Make this look and work more reasonably +void SignInDialogFrame::Create() +{ + wxWindow* parent = nullptr; // TODO: align the window better + + m_dialog = std::make_unique(parent, wxID_ANY, "Sign in", wxDefaultPosition, wxDefaultSize); + static const u32 width = 300; + static const u32 height = 98; + + wxNotebook* nb_config = new wxNotebook(m_dialog.get(), wxID_ANY, wxPoint(2, 2), wxSize(width, height)); + wxPanel* p_esn = new wxPanel(nb_config, wxID_ANY); + wxPanel* p_psn = new wxPanel(nb_config, wxID_ANY); + + wxButton* b_signin = new wxButton(p_esn, wxID_OK, "Fake sign in"); + wxButton* b_cancel = new wxButton(p_esn, wxID_CANCEL, "Cancel"); + + nb_config->AddPage(p_esn, wxT("ESN")); + nb_config->AddPage(p_psn, wxT("PSN")); + + wxBoxSizer* s_subpanel_esn = new wxBoxSizer(wxVERTICAL); + wxBoxSizer* s_subpanel_psn = new wxBoxSizer(wxVERTICAL); + + wxStaticText* esn_unimplemented = new wxStaticText(p_esn, wxID_ANY, "ESN support is not ready yet."); + wxStaticText* psn_unimplemented = new wxStaticText(p_psn, wxID_ANY, "PSN support is not yet implemented."); + + // ESN + s_subpanel_esn->Add(esn_unimplemented, wxSizerFlags().Centre()); + s_subpanel_esn->Add(b_signin, wxSizerFlags().Left().Border(5).Expand()); + s_subpanel_esn->Add(b_cancel, wxSizerFlags().Right().Border(5).Expand()); + + // PSN + s_subpanel_psn->Add(psn_unimplemented, wxSizerFlags().Centre()); + + m_dialog->SetSizerAndFit(s_subpanel_esn, false); + m_dialog->SetSizerAndFit(s_subpanel_psn, false); + + m_dialog->SetSize(width + 18, height + 42); + + m_dialog->Centre(wxBOTH); + m_dialog->Show(); + m_dialog->Enable(); + //m_dialog->ShowModal(); + + b_signin->Bind(wxEVT_BUTTON, [&](wxCommandEvent& event) + { + this->status = CELL_OK; + this->m_dialog->Hide(); + this->Close(); + sysutilSendSystemCommand(CELL_SYSUTIL_NET_CTL_NETSTART_FINISHED, 0); + }); + + b_cancel->Bind(wxEVT_BUTTON, [&](wxCommandEvent& event) + { + this->status = CELL_NET_CTL_ERROR_DIALOG_CANCELED; + this->m_dialog->Hide(); + this->Close(); + sysutilSendSystemCommand(CELL_SYSUTIL_NET_CTL_NETSTART_FINISHED, 0); + }); + + m_dialog->Bind(wxEVT_CLOSE_WINDOW, [&](wxCloseEvent& event) + { + this->status = CELL_NET_CTL_ERROR_DIALOG_CANCELED; + this->m_dialog->Hide(); + this->Close(); + sysutilSendSystemCommand(CELL_SYSUTIL_NET_CTL_NETSTART_FINISHED, 0); + }); +} + +void SignInDialogFrame::Destroy() +{ + m_dialog.reset(); +} diff --git a/rpcs3/Gui/SignInDialog.h b/rpcs3/Gui/SignInDialog.h new file mode 100644 index 0000000000..f1808188ae --- /dev/null +++ b/rpcs3/Gui/SignInDialog.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Emu/SysCalls/Modules/cellNetCtl.h" + +class SignInDialogFrame : public SignInDialogInstance +{ + std::unique_ptr m_dialog; + +public: + virtual void Create() override; + virtual void Destroy() override; +}; diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index c5bb69b897..3da301472e 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -613,6 +613,7 @@ + @@ -631,6 +632,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 0040ea3ba1..95534f0105 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1876,5 +1876,11 @@ Emu\CPU\Cell + + Emu\SysCalls\Modules + + + Emu\SysCalls\Modules + \ No newline at end of file diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index b75eae9835..3494f1e499 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -529,6 +529,7 @@ + @@ -579,6 +580,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index c62f7a8098..b97b3b1f86 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -108,6 +108,9 @@ Gui + + Gui + @@ -219,6 +222,9 @@ Gui + + Gui +