mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge remote-tracking branch 'origin/master' into Mp4_branch
This commit is contained in:
commit
54f812c867
10 changed files with 130 additions and 37 deletions
|
@ -48,6 +48,15 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|||
if (NOT MOBILE_DEVICE)
|
||||
set(USE_FFMPEG ON)
|
||||
endif()
|
||||
if (NOT ARM)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_M_X64")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_M_X64")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_M_IX86")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_M_IX86")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
|
|
|
@ -450,6 +450,31 @@ void WriteReplaceInstruction(u32 address, u64 hash, int size) {
|
|||
}
|
||||
}
|
||||
|
||||
void RestoreReplacedInstruction(u32 address) {
|
||||
const u32 curInstr = Memory::Read_U32(address);
|
||||
if (MIPS_IS_REPLACEMENT(curInstr)) {
|
||||
Memory::Write_U32(replacedInstructions[address], address);
|
||||
}
|
||||
INFO_LOG(HLE, "Restored replaced func at %08x", address);
|
||||
replacedInstructions.erase(address);
|
||||
}
|
||||
|
||||
void RestoreReplacedInstructions(u32 startAddr, u32 endAddr) {
|
||||
const auto start = replacedInstructions.lower_bound(startAddr);
|
||||
const auto end = replacedInstructions.upper_bound(endAddr);
|
||||
int restored = 0;
|
||||
for (auto it = start; it != end; ++it) {
|
||||
const u32 addr = it->first;
|
||||
const u32 curInstr = Memory::Read_U32(addr);
|
||||
if (MIPS_IS_REPLACEMENT(curInstr)) {
|
||||
Memory::Write_U32(it->second, addr);
|
||||
++restored;
|
||||
}
|
||||
}
|
||||
INFO_LOG(HLE, "Restored %d replaced funcs between %08x-%08x", restored, startAddr, endAddr);
|
||||
replacedInstructions.erase(start, end);
|
||||
}
|
||||
|
||||
bool GetReplacedOpAt(u32 address, u32 *op) {
|
||||
u32 instr = Memory::Read_Opcode_JIT(address).encoding;
|
||||
if (MIPS_IS_REPLACEMENT(instr)) {
|
||||
|
|
|
@ -58,4 +58,6 @@ int GetReplacementFuncIndex(u64 hash, int funcSize);
|
|||
const ReplacementTableEntry *GetReplacementFunc(int index);
|
||||
|
||||
void WriteReplaceInstruction(u32 address, u64 hash, int size);
|
||||
void RestoreReplacedInstruction(u32 address);
|
||||
void RestoreReplacedInstructions(u32 startAddr, u32 endAddr);
|
||||
bool GetReplacedOpAt(u32 address, u32 *op);
|
||||
|
|
|
@ -959,10 +959,11 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro
|
|||
SectionID textSection = reader.GetSectionByName(".text");
|
||||
|
||||
if (textSection != -1) {
|
||||
u32 textStart = reader.GetSectionAddr(textSection);
|
||||
module->textStart = reader.GetSectionAddr(textSection);
|
||||
u32 textSize = reader.GetSectionSize(textSection);
|
||||
module->textEnd = module->textStart + textSize;
|
||||
|
||||
module->nm.text_addr = textStart;
|
||||
module->nm.text_addr = module->textStart;
|
||||
// TODO: This value appears to be wrong. In one example, the PSP has a value > 0x1000 bigger.
|
||||
module->nm.text_size = textSize;
|
||||
// TODO: It seems like the data size excludes the text size, which kinda makes sense?
|
||||
|
@ -970,11 +971,11 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro
|
|||
|
||||
#if !defined(MOBILE_DEVICE)
|
||||
bool gotSymbols = reader.LoadSymbols();
|
||||
MIPSAnalyst::ScanForFunctions(textStart, textStart + textSize, !gotSymbols);
|
||||
MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols);
|
||||
#else
|
||||
if (g_Config.bFuncHashMap) {
|
||||
bool gotSymbols = reader.LoadSymbols();
|
||||
MIPSAnalyst::ScanForFunctions(textStart, textStart + textSize, !gotSymbols);
|
||||
MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1127,15 +1128,15 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro
|
|||
}
|
||||
|
||||
if (textSection == -1) {
|
||||
u32 textStart = reader.GetVaddr();
|
||||
u32 textEnd = firstImportStubAddr - 4;
|
||||
module->textStart = reader.GetVaddr();
|
||||
module->textEnd = firstImportStubAddr - 4;
|
||||
#if !defined(MOBILE_DEVICE)
|
||||
bool gotSymbols = reader.LoadSymbols();
|
||||
MIPSAnalyst::ScanForFunctions(textStart, textEnd, !gotSymbols);
|
||||
MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols);
|
||||
#else
|
||||
if (g_Config.bFuncHashMap) {
|
||||
bool gotSymbols = reader.LoadSymbols();
|
||||
MIPSAnalyst::ScanForFunctions(textStart, textEnd, !gotSymbols);
|
||||
MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "Core/MemMap.h"
|
||||
#include "Core/Reporting.h"
|
||||
|
||||
static const int ID3 = 0x49443300;
|
||||
|
||||
#ifdef USE_FFMPEG
|
||||
#ifndef PRId64
|
||||
#define PRId64 "%llu"
|
||||
|
@ -241,11 +243,8 @@ int sceMp3Decode(u32 mp3, u32 outPcmPtr) {
|
|||
fclose(file);
|
||||
}
|
||||
#endif
|
||||
// 2 bytes per channel and we have frame.channels in mp3 source
|
||||
// learn japanese v0.9 frame.channels = 0
|
||||
if (frame.channels == 0)
|
||||
frame.channels = 2;
|
||||
ctx->mp3SumDecodedSamples += bytesdecoded / (2 * frame.channels);
|
||||
// 2 bytes per channel and we use ctx->mp3Channels here
|
||||
ctx->mp3SumDecodedSamples += bytesdecoded / (2 * ctx->mp3Channels);
|
||||
|
||||
return bytesdecoded;
|
||||
}
|
||||
|
@ -340,9 +339,6 @@ u32 sceMp3ReserveMp3Handle(u32 mp3Addr) {
|
|||
ctx->mp3DecodedBytes = 0;
|
||||
ctx->mp3SumDecodedSamples = 0;
|
||||
ctx->mp3LoopNum = -1;
|
||||
ctx->mp3Channels = 2;
|
||||
ctx->mp3Bitrate = 128;
|
||||
ctx->mp3SamplingRate = 44100;
|
||||
|
||||
if (mp3Map.find(mp3Addr) != mp3Map.end()) {
|
||||
delete mp3Map[mp3Addr];
|
||||
|
@ -427,6 +423,72 @@ int __Mp3InitContext(Mp3Context *ctx) {
|
|||
#endif
|
||||
}
|
||||
|
||||
int __CalculateMp3Channels(int bitval) {
|
||||
if (bitval == 0 || bitval == 1 || bitval == 2) { // Stereo / Joint Stereo / Dual Channel.
|
||||
return 2;
|
||||
} else if (bitval == 3) { // Mono.
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int __CalculateMp3SampleRates(int bitval, int mp3version) {
|
||||
if (mp3version == 3) { // MPEG Version 1
|
||||
int valuemapping[] = { 44100, 48000, 32000, -1 };
|
||||
return valuemapping[bitval];
|
||||
} else if (mp3version == 2) { // MPEG Version 2
|
||||
int valuemapping[] = { 22050, 24000, 16000, -1 };
|
||||
return valuemapping[bitval];
|
||||
} else if (mp3version == 0) { // MPEG Version 2.5
|
||||
int valuemapping[] = { 11025, 12000, 8000, -1 };
|
||||
return valuemapping[bitval];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int __CalculateMp3Bitrates(int bitval, int mp3version, int mp3layer) {
|
||||
if (mp3version == 3) { // MPEG Version 1
|
||||
if (mp3layer == 3) { // Layer I
|
||||
int valuemapping[] = { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1 };
|
||||
return valuemapping[bitval];
|
||||
} else if (mp3layer == 2) { // Layer II
|
||||
int valuemapping[] = { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1 };
|
||||
return valuemapping[bitval];
|
||||
} else if (mp3layer == 1) { // Layer III
|
||||
int valuemapping[] = { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1 };
|
||||
return valuemapping[bitval];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else if (mp3version == 2 || mp3version == 0) { // MPEG Version 2 or 2.5
|
||||
if (mp3layer == 3) { // Layer I
|
||||
int valuemapping[] = { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1 };
|
||||
return valuemapping[bitval];
|
||||
} else if (mp3layer == 1 || mp3layer == 2) { // Layer II or III
|
||||
int valuemapping[] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1 };
|
||||
return valuemapping[bitval];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int __ParseMp3Header(Mp3Context *ctx) {
|
||||
int header = bswap32(Memory::Read_U32(ctx->mp3Buf));
|
||||
// ID3 tag , can be seen in Hanayaka Nari Wa ga Ichizoku.
|
||||
if ((header & 0xFFFFFF00) == ID3) {
|
||||
int size = bswap32(Memory::Read_U32(ctx->mp3Buf + ctx->mp3StreamStart + 6));
|
||||
// Highest bit of each byte has to be ignored (format: 0x7F7F7F7F)
|
||||
size = (size & 0x7F) | ((size & 0x7F00) >> 1) | ((size & 0x7F0000) >> 2) | ((size & 0x7F000000) >> 3);
|
||||
header = bswap32(Memory::Read_U32(ctx->mp3Buf + ctx->mp3StreamStart + 10 + size));
|
||||
}
|
||||
return header;
|
||||
}
|
||||
|
||||
int sceMp3Init(u32 mp3) {
|
||||
DEBUG_LOG(ME, "sceMp3Init(%08x)", mp3);
|
||||
|
||||
|
@ -436,22 +498,20 @@ int sceMp3Init(u32 mp3) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Read in the header and swap the endian
|
||||
int header = bswap32(Memory::Read_U32(ctx->mp3Buf));
|
||||
// Parse the Mp3 header
|
||||
int header = __ParseMp3Header(ctx);
|
||||
int layer = (header >> 17) & 0x3;
|
||||
ctx->mp3Version = ((header >> 19) & 0x3);
|
||||
ctx->mp3SamplingRate = __CalculateMp3SampleRates((header >> 10) & 0x3, ctx->mp3Version);
|
||||
ctx->mp3Channels = __CalculateMp3Channels((header >> 6) & 0x3);
|
||||
ctx->mp3Bitrate = __CalculateMp3Bitrates((header >> 12) & 0xF, ctx->mp3Version, layer);
|
||||
|
||||
INFO_LOG(ME, "sceMp3Init(): channels=%i, samplerate=%ikHz, bitrate=%ikbps", ctx->mp3Channels, ctx->mp3SamplingRate, ctx->mp3Bitrate);
|
||||
|
||||
#ifdef USE_FFMPEG
|
||||
int ret = __Mp3InitContext(ctx);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
// Let's just grab this info from FFMPEG, it seems more reliable than the code above.
|
||||
|
||||
ctx->mp3SamplingRate = ctx->decoder_context->sample_rate;
|
||||
ctx->mp3Channels = ctx->decoder_context->channels;
|
||||
ctx->mp3Bitrate = ctx->decoder_context->bit_rate / 1000;
|
||||
INFO_LOG(ME, "sceMp3Init(): channels=%i, samplerate=%ikHz, bitrate=%ikbps", ctx->mp3Channels, ctx->mp3SamplingRate, ctx->mp3Bitrate);
|
||||
|
||||
return ret;
|
||||
av_dump_format(ctx->avformat_context, 0, "mp3", 0);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -559,6 +559,8 @@ skip:
|
|||
}
|
||||
}
|
||||
|
||||
RestoreReplacedInstructions(startAddr, endAddr);
|
||||
|
||||
// TODO: Also wipe them from hash->function map
|
||||
}
|
||||
|
||||
|
|
|
@ -1581,12 +1581,6 @@ void GLES_GPU::ExecuteOpInternal(u32 op, u32 diff) {
|
|||
#endif
|
||||
|
||||
case GE_CMD_TEXLEVEL:
|
||||
#ifndef MOBILE_DEVICE
|
||||
if (data == 1)
|
||||
WARN_LOG_REPORT_ONCE(texLevel1, G3D, "Unsupported texture level bias settings: %06x", data)
|
||||
else if (data != 0)
|
||||
WARN_LOG_REPORT_ONCE(texLevel2, G3D, "Unsupported texture level bias settings: %06x", data);
|
||||
#endif
|
||||
if (diff)
|
||||
gstate_c.textureChanged = true;
|
||||
break;
|
||||
|
|
|
@ -489,8 +489,8 @@ void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
|
|||
// Enforce no mip filtering, for safety.
|
||||
minFilt &= 1; // no mipmaps yet
|
||||
} else {
|
||||
// TODO: Is this a signed value? Which direction?
|
||||
float lodBias = 0.0; // -(float)((gstate.texlevel >> 16) & 0xFF) / 16.0f;
|
||||
// Texture lod bias should be signed.
|
||||
float lodBias = (float)(int)(s8)((gstate.texlevel >> 16) & 0xFF) / 16.0f;
|
||||
if (force || entry.lodBias != lodBias) {
|
||||
#ifndef USING_GLES2
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, lodBias);
|
||||
|
|
|
@ -119,7 +119,7 @@ namespace WindowsRawInput {
|
|||
}
|
||||
|
||||
if (g_Config.bEscapeExitsEmulator && raw->data.keyboard.VKey == VK_ESCAPE) {
|
||||
DestroyWindow(MainWindow::GetHWND());
|
||||
PostMessage(MainWindow::GetHWND(), WM_CLOSE, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1316,7 +1316,7 @@ namespace MainWindow
|
|||
break;
|
||||
|
||||
case ID_FILE_EXIT:
|
||||
DestroyWindow(hWnd);
|
||||
PostMessage(hwndMain, WM_CLOSE, 0, 0);
|
||||
break;
|
||||
|
||||
case ID_DEBUG_RUNONLOAD:
|
||||
|
|
Loading…
Add table
Reference in a new issue