Performance optimizations: sound caching, renderer culling, entity and lighting improvements
- Sound engine: cache filesystem probe results to avoid repeated file existence checks; add MA_SOUND_FLAG_DECODE for pre-decoded playback - Level renderer: column-level frustum culling, compact visible chunk lists to skip empty iteration, lightweight second-pass render path, early-out for non-dirty chunks, scaled recheck period at high render distances - Entity: cache shared_from_this() to reduce reference counting overhead in move() and checkInsideTiles() - Level: skip checkLight() when tile light properties unchanged; enable entity locking on all platforms (not just Vita) - LevelChunk: only rescan min height when the minimum column changes; defer lightGap processing - LivingEntity: use raw pointer cast instead of dynamic_pointer_cast; cache friction tile lookup - ServerPlayerGameMode: return whether block was destroyed to avoid redundant tile update packets
This commit is contained in:
@@ -468,65 +468,69 @@ void SoundEngine::play(int iSound, float x, float y, float z, float volume, floa
|
||||
sprintf_s(basePath, "Windows64Media/Sound/%s", (char*)szSoundName);
|
||||
|
||||
char finalPath[256];
|
||||
sprintf_s(finalPath, "%s.wav", basePath);
|
||||
|
||||
const char* extensions[] = { ".ogg", ".wav", ".mp3" };
|
||||
size_t extCount = sizeof(extensions) / sizeof(extensions[0]);
|
||||
bool found = false;
|
||||
|
||||
for (size_t extIdx = 0; extIdx < extCount; extIdx++)
|
||||
// Check path cache first to avoid expensive filesystem probing
|
||||
auto cacheIt = m_soundPathCache.find(iSound);
|
||||
if (cacheIt != m_soundPathCache.end())
|
||||
{
|
||||
char basePlusExt[256];
|
||||
sprintf_s(basePlusExt, "%s%s", basePath, extensions[extIdx]);
|
||||
|
||||
DWORD attr = GetFileAttributesA(basePlusExt);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
sprintf_s(finalPath, "%s", basePlusExt);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
const auto& paths = cacheIt->second;
|
||||
if (paths.empty())
|
||||
return; // previously probed, no files found
|
||||
const std::string& chosen = paths[rand() % paths.size()];
|
||||
sprintf_s(finalPath, "%s", chosen.c_str());
|
||||
}
|
||||
|
||||
if (!found)
|
||||
else
|
||||
{
|
||||
int count = 0;
|
||||
// Cache miss — probe filesystem and store results
|
||||
std::vector<std::string> validPaths;
|
||||
const char* extensions[] = { ".ogg", ".wav", ".mp3" };
|
||||
size_t extCount = sizeof(extensions) / sizeof(extensions[0]);
|
||||
bool found = false;
|
||||
|
||||
// Check base name with each extension (non-numbered)
|
||||
for (size_t extIdx = 0; extIdx < extCount; extIdx++)
|
||||
{
|
||||
for (size_t i = 1; i < 32; i++)
|
||||
char basePlusExt[256];
|
||||
sprintf_s(basePlusExt, "%s%s", basePath, extensions[extIdx]);
|
||||
|
||||
DWORD attr = GetFileAttributesA(basePlusExt);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
char numberedPath[256];
|
||||
sprintf_s(numberedPath, "%s%d%s", basePath, i, extensions[extIdx]);
|
||||
|
||||
DWORD attr = GetFileAttributesA(numberedPath);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
validPaths.push_back(basePlusExt);
|
||||
found = true;
|
||||
break; // non-numbered: only one base file needed
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
// Check numbered variants (e.g. sound1.ogg, sound2.ogg, ...)
|
||||
for (size_t extIdx = 0; extIdx < extCount; extIdx++)
|
||||
{
|
||||
for (int i = 1; i < 32; i++)
|
||||
{
|
||||
count = i;
|
||||
char numberedPath[256];
|
||||
sprintf_s(numberedPath, "%s%d%s", basePath, i, extensions[extIdx]);
|
||||
|
||||
DWORD attr = GetFileAttributesA(numberedPath);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
validPaths.push_back(numberedPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
m_soundPathCache[iSound] = validPaths;
|
||||
|
||||
if (validPaths.empty())
|
||||
{
|
||||
int chosen = (rand() % count) + 1;
|
||||
for (size_t extIdx = 0; extIdx < extCount; extIdx++)
|
||||
{
|
||||
char numberedPath[256];
|
||||
sprintf_s(numberedPath, "%s%d%s", basePath, chosen, extensions[extIdx]);
|
||||
|
||||
DWORD attr = GetFileAttributesA(numberedPath);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
sprintf_s(finalPath, "%s", numberedPath);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
sprintf_s(finalPath, "%s%d.wav", basePath, chosen);
|
||||
}
|
||||
sprintf_s(finalPath, "%s.wav", basePath); // fallback for debug print
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::string& chosen = validPaths[rand() % validPaths.size()];
|
||||
sprintf_s(finalPath, "%s", chosen.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,7 +550,7 @@ void SoundEngine::play(int iSound, float x, float y, float z, float volume, floa
|
||||
if (ma_sound_init_from_file(
|
||||
&m_engine,
|
||||
finalPath,
|
||||
MA_SOUND_FLAG_ASYNC,
|
||||
MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_ASYNC,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&s->sound) != MA_SUCCESS)
|
||||
@@ -602,24 +606,40 @@ void SoundEngine::playUI(int iSound, float volume, float pitch)
|
||||
sprintf_s(basePath, "Windows64Media/Sound/Minecraft/UI/%s", ConvertSoundPathToName(name));
|
||||
|
||||
char finalPath[256];
|
||||
sprintf_s(finalPath, "%s.wav", basePath);
|
||||
|
||||
const char* extensions[] = { ".ogg", ".wav", ".mp3" };
|
||||
size_t count = sizeof(extensions) / sizeof(extensions[0]);
|
||||
bool found = false;
|
||||
for (size_t i = 0; i < count; i++)
|
||||
// Check UI sound path cache first
|
||||
auto cacheIt = m_uiSoundPathCache.find(iSound);
|
||||
if (cacheIt != m_uiSoundPathCache.end())
|
||||
{
|
||||
sprintf_s(finalPath, "%s%s", basePath, extensions[i]);
|
||||
if (FileExists(finalPath))
|
||||
if (cacheIt->second.empty())
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
app.DebugPrintf("No sound file found for UI sound (cached): %s\n", basePath);
|
||||
return;
|
||||
}
|
||||
sprintf_s(finalPath, "%s", cacheIt->second.c_str());
|
||||
}
|
||||
if (!found)
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("No sound file found for UI sound: %s\n", basePath);
|
||||
return;
|
||||
// Cache miss — probe filesystem and store result
|
||||
const char* extensions[] = { ".ogg", ".wav", ".mp3" };
|
||||
size_t count = sizeof(extensions) / sizeof(extensions[0]);
|
||||
bool found = false;
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
sprintf_s(finalPath, "%s%s", basePath, extensions[i]);
|
||||
if (FileExists(finalPath))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
m_uiSoundPathCache[iSound] = ""; // cache negative result
|
||||
app.DebugPrintf("No sound file found for UI sound: %s\n", basePath);
|
||||
return;
|
||||
}
|
||||
m_uiSoundPathCache[iSound] = finalPath;
|
||||
}
|
||||
|
||||
MiniAudioSound* s = new MiniAudioSound();
|
||||
@@ -633,7 +653,7 @@ void SoundEngine::playUI(int iSound, float volume, float pitch)
|
||||
if (ma_sound_init_from_file(
|
||||
&m_engine,
|
||||
finalPath,
|
||||
MA_SOUND_FLAG_ASYNC,
|
||||
MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_ASYNC,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&s->sound) != MA_SUCCESS)
|
||||
|
||||
@@ -5,6 +5,8 @@ using namespace std;
|
||||
#include "..\..\Minecraft.World\SoundTypes.h"
|
||||
|
||||
#include "miniaudio.h"
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
constexpr float SFX_3D_MIN_DISTANCE = 1.0f;
|
||||
constexpr float SFX_3D_MAX_DISTANCE = 16.0f;
|
||||
@@ -187,6 +189,9 @@ private:
|
||||
int m_iStream_CD_1;
|
||||
bool *m_bHeardTrackA;
|
||||
|
||||
std::unordered_map<int, std::vector<std::string>> m_soundPathCache; // play(): sound ID → all valid variant paths
|
||||
std::unordered_map<int, std::string> m_uiSoundPathCache; // playUI(): sound ID → resolved path
|
||||
|
||||
#ifdef __ORBIS__
|
||||
int32_t m_hBGMAudio;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user