mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-05-11 04:07:13 +00:00
cleaned up, less hacky, more silly
This commit is contained in:
parent
ca84ac0512
commit
21fc2166ff
|
|
@ -1,6 +1,6 @@
|
|||
#include "../../Minecraft.World/Platform/stdafx.h"
|
||||
|
||||
#include "SoundEngine.h"
|
||||
#include "PathHelper.h"
|
||||
#include "../Consoles_App.h"
|
||||
#include "../../Minecraft.Client/Player/MultiPlayerLocalPlayer.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.h"
|
||||
|
|
@ -188,69 +188,51 @@ void SoundEngine::init(Options* pOptions) {
|
|||
m_bSystemMusicPlaying = false;
|
||||
}
|
||||
void SoundEngine::destroy() { ma_engine_uninit(&m_engine); }
|
||||
|
||||
void SoundEngine::play(int iSound, float x, float y, float z, float volume,
|
||||
float pitch) {
|
||||
if (iSound == -1) return;
|
||||
char szId[256];
|
||||
wcstombs(szId, wchSoundNames[iSound], 255);
|
||||
for (int i = 0; szId[i]; i++)
|
||||
if (szId[i] == '.') szId[i] = '/';
|
||||
|
||||
char szIdentifier[256];
|
||||
wcstombs(szIdentifier, wchSoundNames[iSound], 255);
|
||||
|
||||
// dot to folder structure (example step.grass -> step/grass)
|
||||
for (int i = 0; szIdentifier[i]; i++) {
|
||||
if (szIdentifier[i] == '.') szIdentifier[i] = '/';
|
||||
}
|
||||
// YES I KNOW SOUNDNAMES.CPP EXISTS.
|
||||
const char* extensions[] = {".ogg", ".wav", ".mp3"};
|
||||
const char* roots[] = {"Sound/Minecraft/",
|
||||
"build/Minecraft.Client/Sound/Minecraft/",
|
||||
"Common/Sound/Minecraft/",
|
||||
std::string base = PathHelper::GetExecutableDirA() + "/";
|
||||
const char* roots[] = {"Sound/Minecraft/", "Common/Sound/Minecraft/",
|
||||
"Common/res/TitleUpdate/res/Sound/Minecraft/"};
|
||||
|
||||
char finalPath[512] = {0};
|
||||
bool found = false;
|
||||
// search for variants (grass1, grass2, etc.)
|
||||
// this is hacky
|
||||
|
||||
for (const char* root : roots) {
|
||||
for (const char* ext : extensions) {
|
||||
int maxVariant = 0;
|
||||
std::string fullRoot = base + root;
|
||||
for (const char* ext : {".ogg", ".wav"}) {
|
||||
int count = 0;
|
||||
for (int i = 1; i <= 16; i++) {
|
||||
char tryPath[512];
|
||||
snprintf(tryPath, sizeof(tryPath), "%s%s%d%s", root,
|
||||
szIdentifier, i, ext);
|
||||
if (access(tryPath, F_OK) != -1)
|
||||
maxVariant = i;
|
||||
char tryP[512];
|
||||
snprintf(tryP, 512, "%s%s%d%s", fullRoot.c_str(), szId, i, ext);
|
||||
if (access(tryP, F_OK) != -1)
|
||||
count = i;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (maxVariant > 0) {
|
||||
int chosen = (rand() % maxVariant) + 1;
|
||||
snprintf(finalPath, sizeof(finalPath), "%s%s%d%s", root,
|
||||
szIdentifier, chosen, ext);
|
||||
if (count > 0) {
|
||||
snprintf(finalPath, 512, "%s%s%d%s", fullRoot.c_str(), szId,
|
||||
(rand() % count) + 1, ext);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
char tryP[512];
|
||||
snprintf(tryP, 512, "%s%s%s", fullRoot.c_str(), szId, ext);
|
||||
if (access(tryP, F_OK) != -1) {
|
||||
strncpy(finalPath, tryP, 511);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
if (!found) {
|
||||
for (const char* root : roots) {
|
||||
for (const char* ext : extensions) {
|
||||
char tryPath[512];
|
||||
snprintf(tryPath, sizeof(tryPath), "%s%s%s", root, szIdentifier,
|
||||
ext);
|
||||
if (access(tryPath, F_OK) != -1) {
|
||||
strncpy(finalPath, tryPath, 511);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) return;
|
||||
|
||||
MiniAudioSound* s = new MiniAudioSound();
|
||||
memset(&s->info, 0, sizeof(AUDIO_INFO));
|
||||
s->info.x = x;
|
||||
|
|
@ -266,43 +248,38 @@ void SoundEngine::play(int iSound, float x, float y, float z, float volume,
|
|||
ma_sound_set_min_distance(&s->sound, 2.0f);
|
||||
ma_sound_set_max_distance(&s->sound, 48.0f);
|
||||
ma_sound_set_volume(&s->sound, volume * m_MasterEffectsVolume);
|
||||
ma_sound_set_pitch(&s->sound, pitch);
|
||||
ma_sound_set_position(&s->sound, x, y, z);
|
||||
ma_sound_start(&s->sound);
|
||||
m_activeSounds.push_back(s);
|
||||
} else {
|
||||
} else
|
||||
delete s;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundEngine::playUI(int iSound, float volume, float pitch) {
|
||||
char szIdentifier[256];
|
||||
if (iSound >= eSFX_MAX) {
|
||||
if (iSound >= eSFX_MAX)
|
||||
wcstombs(szIdentifier, wchSoundNames[iSound], 255);
|
||||
} else {
|
||||
else
|
||||
wcstombs(szIdentifier, wchUISoundNames[iSound], 255);
|
||||
}
|
||||
|
||||
for (int i = 0; szIdentifier[i]; i++) {
|
||||
for (int i = 0; szIdentifier[i]; i++)
|
||||
if (szIdentifier[i] == '.') szIdentifier[i] = '/';
|
||||
}
|
||||
// ui sfx also WHO WHO THAT EWWW
|
||||
const char* extensions[] = {".ogg", ".wav", ".mp3"};
|
||||
const char* roots[] = {"Sound/Minecraft/UI/", "Sound/Minecraft/",
|
||||
"build/Minecraft.Client/Sound/Minecraft/UI/",
|
||||
"build/Minecraft.Client/Sound/Minecraft/",
|
||||
"Common/Sound/Minecraft/UI/"};
|
||||
|
||||
std::string base = PathHelper::GetExecutableDirA() + "/";
|
||||
const char* roots[] = {
|
||||
"Sound/Minecraft/UI/",
|
||||
"Sound/Minecraft/",
|
||||
"Common/Sound/Minecraft/UI/",
|
||||
"Common/Sound/Minecraft/",
|
||||
};
|
||||
char finalPath[512] = {0};
|
||||
bool found = false;
|
||||
|
||||
for (const char* root : roots) {
|
||||
for (const char* ext : extensions) {
|
||||
char tryPath[512];
|
||||
snprintf(tryPath, sizeof(tryPath), "%s%s%s", root, szIdentifier,
|
||||
for (const char* ext : {".ogg", ".wav", ".mp3"}) {
|
||||
char tryP[512];
|
||||
snprintf(tryP, 512, "%s%s%s%s", base.c_str(), root, szIdentifier,
|
||||
ext);
|
||||
if (access(tryPath, F_OK) != -1) {
|
||||
strncpy(finalPath, tryPath, 511);
|
||||
if (access(tryP, F_OK) != -1) {
|
||||
strncpy(finalPath, tryP, 511);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -311,7 +288,6 @@ void SoundEngine::playUI(int iSound, float volume, float pitch) {
|
|||
}
|
||||
|
||||
if (!found) return;
|
||||
|
||||
MiniAudioSound* s = new MiniAudioSound();
|
||||
memset(&s->info, 0, sizeof(AUDIO_INFO));
|
||||
s->info.volume = volume;
|
||||
|
|
@ -325,9 +301,8 @@ void SoundEngine::playUI(int iSound, float volume, float pitch) {
|
|||
ma_sound_set_pitch(&s->sound, pitch);
|
||||
ma_sound_start(&s->sound);
|
||||
m_activeSounds.push_back(s);
|
||||
} else {
|
||||
} else
|
||||
delete s;
|
||||
}
|
||||
}
|
||||
|
||||
int SoundEngine::getMusicID(int iDomain) {
|
||||
|
|
@ -344,9 +319,10 @@ int SoundEngine::getMusicID(int iDomain) {
|
|||
if (pMinecraft->skins->isUsingDefaultSkin()) {
|
||||
switch (iDomain) {
|
||||
case LevelData::DIMENSION_END:
|
||||
// the end isn't random - it has different music depending on
|
||||
// whether the dragon is alive or not, but we've not added the
|
||||
// dead dragon music yet
|
||||
// the end isn't random - it has different music depending
|
||||
// whether the dragon is alive or not, but we've not
|
||||
// added the dead dragon music yet
|
||||
// haha they said wheter
|
||||
return m_iStream_End_Min;
|
||||
case LevelData::DIMENSION_NETHER:
|
||||
return GetRandomishTrack(m_iStream_Nether_Min,
|
||||
|
|
@ -464,7 +440,8 @@ int SoundEngine::OpenStreamThreadProc(void* lpParameter) {
|
|||
|
||||
if (result != MA_SUCCESS) {
|
||||
app.DebugPrintf(
|
||||
"SoundEngine::OpenStreamThreadProc - Failed to open stream: %s\n",
|
||||
"SoundEngine::OpenStreamThreadProc - Failed to open stream: "
|
||||
"%s\n",
|
||||
soundEngine->m_szStreamName);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -476,7 +453,6 @@ int SoundEngine::OpenStreamThreadProc(void* lpParameter) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SoundEngine::playMusicTick() {
|
||||
static float fMusicVol = 0.0f;
|
||||
fMusicVol = getMasterMusicVolume();
|
||||
|
|
@ -487,96 +463,51 @@ void SoundEngine::playMusicTick() {
|
|||
m_iMusicDelay--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_musicStreamActive) {
|
||||
m_StreamState = eMusicStreamState_Playing;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_musicID != -1) {
|
||||
std::string base = PathHelper::GetExecutableDirA() + "/";
|
||||
bool isCD = (m_musicID >= m_iStream_CD_1);
|
||||
const char* folder = isCD ? "cds/" : "music/";
|
||||
const char* trackName = m_szStreamFileA[m_musicID];
|
||||
const char* extensions[] = {".ogg", ".mp3", ".wav"};
|
||||
|
||||
const char* track = m_szStreamFileA[m_musicID];
|
||||
bool found = false;
|
||||
m_szStreamName[0] = '\0';
|
||||
|
||||
// DLC Mashup pack check
|
||||
if (Minecraft::GetInstance()
|
||||
->skins->getSelected()
|
||||
->hasAudio()) {
|
||||
TexturePack* pTexPack =
|
||||
Minecraft::GetInstance()->skins->getSelected();
|
||||
DLCPack* pack =
|
||||
((DLCTexturePack*)pTexPack)->getDLCInfoParentPack();
|
||||
DLCAudioFile* dlcAudioFile = (DLCAudioFile*)pack->getFile(
|
||||
DLCManager::e_DLCType_Audio, 0);
|
||||
const char* roots[] = {"Common/music/", "music/", "./"};
|
||||
|
||||
if (!isCD) {
|
||||
m_MusicType = eMusicType_Game;
|
||||
m_StreamingAudioInfo.bIs3D = false;
|
||||
|
||||
wstring& wstrSoundName =
|
||||
dlcAudioFile->GetSoundName(m_musicID);
|
||||
char szName[255];
|
||||
wcstombs(szName, wstrSoundName.c_str(), 255);
|
||||
|
||||
std::string strFile =
|
||||
"TPACK:\\Data\\" + string(szName) + ".wav";
|
||||
std::string mountedPath =
|
||||
StorageManager.GetMountedPath(strFile);
|
||||
strcpy(m_szStreamName, mountedPath.c_str());
|
||||
|
||||
if (access(m_szStreamName, F_OK) != -1) found = true;
|
||||
}
|
||||
}
|
||||
|
||||
// we're doing this again, daring aren't we
|
||||
if (!found) {
|
||||
const char* roots[] = {
|
||||
"build/Minecraft.Client/Common/music/",
|
||||
"build/Minecraft.Client/music/", "Common/music/",
|
||||
"music/", "./"};
|
||||
|
||||
for (const char* root : roots) {
|
||||
for (const char* ext : extensions) {
|
||||
char cand[512];
|
||||
|
||||
// if only i wrote a function that does EXACTLY
|
||||
// that., nope ctrl c ctrl v it is
|
||||
snprintf(cand, sizeof(cand), "%s%s%s%s", root,
|
||||
folder, trackName, ext);
|
||||
if (access(cand, F_OK) != -1) {
|
||||
strncpy(m_szStreamName, cand, 511);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf(cand, sizeof(cand), "%s%s%s", root,
|
||||
trackName, ext);
|
||||
if (access(cand, F_OK) != -1) {
|
||||
strncpy(m_szStreamName, cand, 511);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
for (const char* r : roots) {
|
||||
for (const char* e : {".ogg", ".mp3", ".wav"}) {
|
||||
char c[512];
|
||||
// try with folder prefix (music/ or cds/)
|
||||
snprintf(c, 512, "%s%s%s%s%s", base.c_str(), r, folder,
|
||||
track, e);
|
||||
if (access(c, F_OK) != -1) {
|
||||
strncpy(m_szStreamName, c, 511);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
// try without folder prefix
|
||||
snprintf(c, 512, "%s%s%s%s", base.c_str(), r, track, e);
|
||||
if (access(c, F_OK) != -1) {
|
||||
strncpy(m_szStreamName, c, 511);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
m_MusicType = isCD ? eMusicType_CD : eMusicType_Game;
|
||||
m_StreamingAudioInfo.bIs3D = isCD;
|
||||
SetIsPlayingStreamingGameMusic(!isCD);
|
||||
SetIsPlayingStreamingCDMusic(isCD);
|
||||
|
||||
m_openStreamThread = new C4JThread(
|
||||
OpenStreamThreadProc, this, "OpenStreamThreadProc");
|
||||
m_openStreamThread->Run();
|
||||
m_StreamState = eMusicStreamState_Opening;
|
||||
} else {
|
||||
// Retry later if missing
|
||||
app.DebugPrintf(
|
||||
"[SoundEngine] oh noes couldn't find music track '%s', "
|
||||
"retrying "
|
||||
"in 1min\n",
|
||||
track);
|
||||
m_iMusicDelay = 20 * 60;
|
||||
}
|
||||
}
|
||||
|
|
@ -686,7 +617,6 @@ void SoundEngine::playMusicTick() {
|
|||
|
||||
} else if (m_StreamingAudioInfo.bIs3D && m_validListenerCount > 1 &&
|
||||
m_musicStreamActive) {
|
||||
// incase we're splitscreen
|
||||
float fClosestDist = 1e6f;
|
||||
int iClosest = 0;
|
||||
for (size_t i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
|
|
@ -716,18 +646,19 @@ void SoundEngine::playMusicTick() {
|
|||
|
||||
case eMusicStreamState_Completed:
|
||||
m_iMusicDelay = random->nextInt(20 * 60 * 3);
|
||||
|
||||
int dim = LevelData::DIMENSION_OVERWORLD;
|
||||
Minecraft* pMc = Minecraft::GetInstance();
|
||||
for (int i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if (pMc->localplayers[i]) {
|
||||
dim = pMc->localplayers[i]->dimension;
|
||||
break;
|
||||
{
|
||||
int dim = LevelData::DIMENSION_OVERWORLD;
|
||||
Minecraft* pMc = Minecraft::GetInstance();
|
||||
for (int i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if (pMc->localplayers[i]) {
|
||||
dim = pMc->localplayers[i]->dimension;
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_musicID = getMusicID(dim);
|
||||
SetIsPlayingEndMusic(dim == LevelData::DIMENSION_END);
|
||||
SetIsPlayingNetherMusic(dim == LevelData::DIMENSION_NETHER);
|
||||
}
|
||||
m_musicID = getMusicID(dim);
|
||||
SetIsPlayingEndMusic(dim == LevelData::DIMENSION_END);
|
||||
SetIsPlayingNetherMusic(dim == LevelData::DIMENSION_NETHER);
|
||||
m_StreamState = eMusicStreamState_Idle;
|
||||
break;
|
||||
}
|
||||
|
|
@ -2134,7 +2065,8 @@ F32 AILCALLBACK custom_falloff_function(HSAMPLE S, F32 distance,
|
|||
}
|
||||
#endif
|
||||
|
||||
// Universal, these functions shouldn't need platform specific implementations
|
||||
// Universal, these functions shouldn't need platform specific
|
||||
// implementations
|
||||
void SoundEngine::updateMusicVolume(float fVal) { m_MasterMusicVolume = fVal; }
|
||||
void SoundEngine::updateSystemMusicPlaying(bool isPlaying) {
|
||||
m_bSystemMusicPlaying = isPlaying;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
#include "../Minecraft.Client/Minecraft.h"
|
||||
#if defined(__linux__)
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <climits>
|
||||
#endif
|
||||
#ifdef _XBOX
|
||||
#include "../Minecraft.Client/Platform/Xbox/GameConfig/Minecraft.spa.h"
|
||||
|
|
@ -4606,18 +4606,22 @@ void CMinecraftApp::loadMediaArchive() {
|
|||
if (!mediapath.empty()) {
|
||||
// (check file.cpp)
|
||||
// try to load the archive relative to the executable
|
||||
// directory first.
|
||||
// directory first.
|
||||
// If that fails, fall back to the current working
|
||||
// directory (original behavior)
|
||||
// if everything fails, may god help you
|
||||
#if defined(__linux__)
|
||||
// THIS CAN USE PATHHELPER.h
|
||||
char exePathBuf[PATH_MAX];
|
||||
ssize_t exeLen = readlink("/proc/self/exe", exePathBuf, sizeof(exePathBuf) - 1);
|
||||
ssize_t exeLen =
|
||||
readlink("/proc/self/exe", exePathBuf, sizeof(exePathBuf) - 1);
|
||||
if (exeLen != -1) {
|
||||
exePathBuf[exeLen] = '\0';
|
||||
std::string exePathStr(exePathBuf);
|
||||
size_t pos = exePathStr.find_last_of('/');
|
||||
std::string exeDir = (pos == std::string::npos) ? std::string(".") : exePathStr.substr(0, pos);
|
||||
std::string exeDir = (pos == std::string::npos)
|
||||
? std::string(".")
|
||||
: exePathStr.substr(0, pos);
|
||||
std::wstring exeDirW = convStringToWstring(exeDir.c_str());
|
||||
std::wstring candidate = exeDirW + File::pathSeparator + mediapath;
|
||||
if (File(candidate).exists()) {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#include "../Platform/stdafx.h"
|
||||
#include "../../Minecraft.World/Util/StringHelpers.h"
|
||||
#include "Textures.h"
|
||||
#include "PathHelper.h"
|
||||
#include "../../Minecraft.World/Util/ArrayWithLength.h"
|
||||
#include "BufferedImage.h"
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
|
@ -58,13 +58,11 @@ BufferedImage::BufferedImage(const std::wstring& File,
|
|||
HRESULT hr = -1;
|
||||
std::wstring filePath = File;
|
||||
|
||||
// turn that \ upside down! (grace ref)
|
||||
for (size_t i = 0; i < filePath.length(); ++i) {
|
||||
if (filePath[i] == L'\\') filePath[i] = L'/';
|
||||
}
|
||||
for (int l = 0; l < 10; l++) data[l] = nullptr;
|
||||
|
||||
// clean the filename
|
||||
std::wstring baseName = filePath;
|
||||
if (!filenameHasExtension) {
|
||||
if (baseName.size() > 4 &&
|
||||
|
|
@ -73,50 +71,36 @@ BufferedImage::BufferedImage(const std::wstring& File,
|
|||
}
|
||||
}
|
||||
|
||||
// avoid // mess
|
||||
while (!baseName.empty() && baseName[0] == L'/')
|
||||
while (!baseName.empty() && (baseName[0] == L'/' || baseName[0] == L'\\'))
|
||||
baseName = baseName.substr(1);
|
||||
if (baseName.find(L"res/") == 0) baseName = baseName.substr(4);
|
||||
|
||||
// bad code alert
|
||||
// loops through stuff on the drives because i don't fucking know what 4j
|
||||
// did with the paths and i don't to break it..
|
||||
std::wstring exeDir = PathHelper::GetExecutableDirW();
|
||||
|
||||
for (int l = 0; l < 10; l++) {
|
||||
std::wstring mipSuffix =
|
||||
(l != 0) ? L"MipMapLevel" + _toString<int>(l + 1) : L"";
|
||||
std::wstring fileName = baseName + mipSuffix + L".png";
|
||||
|
||||
bool foundOnDisk = false;
|
||||
std::wstring finalPath;
|
||||
bool foundOnDisk = false;
|
||||
|
||||
// i tried everything i can think of.
|
||||
std::vector<std::wstring> searchPaths = {
|
||||
L"build/Minecraft.Client/Common/res/TitleUpdate/res/" + fileName,
|
||||
L"build/Minecraft.Client/Common/res/" + fileName,
|
||||
L"build/Minecraft.Client/Common/Media/" + fileName,
|
||||
L"Common/res/TitleUpdate/res/" + fileName,
|
||||
L"Common/res/" + fileName,
|
||||
L"Minecraft.Assets/Common/res/TitleUpdate/res/" + fileName};
|
||||
|
||||
if (!drive.empty()) {
|
||||
std::wstring drivePath = drive;
|
||||
if (drivePath.back() != L'/') drivePath += L'/';
|
||||
searchPaths.push_back(drivePath + fileName);
|
||||
searchPaths.push_back(drivePath + L"res/" + fileName);
|
||||
}
|
||||
exeDir + L"/Common/res/TitleUpdate/res/" + fileName,
|
||||
exeDir + L"/Common/res/" + fileName,
|
||||
exeDir + L"/Common/Media/Graphics/" + fileName,
|
||||
exeDir + L"/Common/Media/font/" + fileName,
|
||||
exeDir + L"/Common/res/font/" + fileName,
|
||||
exeDir + L"/Common/Media/" + fileName};
|
||||
|
||||
for (auto& attempt : searchPaths) {
|
||||
size_t p;
|
||||
while ((p = attempt.find(L"//")) != std::wstring::npos)
|
||||
attempt.replace(p, 2, L"/");
|
||||
|
||||
#if defined(__linux__)
|
||||
if (access(wstringtofilename(attempt), F_OK) != -1) {
|
||||
finalPath = attempt;
|
||||
foundOnDisk = true;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
D3DXIMAGE_INFO ImageInfo;
|
||||
|
|
@ -126,8 +110,6 @@ BufferedImage::BufferedImage(const std::wstring& File,
|
|||
hr = RenderManager.LoadTextureData(wstringtofilename(finalPath),
|
||||
&ImageInfo, &data[l]);
|
||||
} else {
|
||||
// if everything fails just try the archive maybe theres something
|
||||
// in it
|
||||
std::wstring archiveKey = L"res/" + fileName;
|
||||
if (app.hasArchiveFile(archiveKey)) {
|
||||
byteArray ba = app.getArchiveFile(archiveKey);
|
||||
|
|
@ -143,14 +125,9 @@ BufferedImage::BufferedImage(const std::wstring& File,
|
|||
}
|
||||
} else {
|
||||
if (l == 0) {
|
||||
app.DebugPrintf("[Texture Warning] Missing asset: %S\n",
|
||||
fileName.c_str());
|
||||
// We MUST initialize width/height to avoid the program being a
|
||||
// crybaby and crash
|
||||
// safety dummy to prevent crash
|
||||
width = 1;
|
||||
height = 1;
|
||||
// Create a tiny missingno buffer so the rest of the game loads
|
||||
// without crashing up
|
||||
data[0] = new int[1];
|
||||
data[0][0] = 0xFFFF00FF;
|
||||
}
|
||||
|
|
@ -158,37 +135,25 @@ BufferedImage::BufferedImage(const std::wstring& File,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
BufferedImage::BufferedImage(DLCPack* dlcPack, const std::wstring& File,
|
||||
bool filenameHasExtension) {
|
||||
HRESULT hr;
|
||||
std::wstring filePath = File;
|
||||
std::uint8_t* pbData = nullptr;
|
||||
std::uint32_t dataBytes = 0;
|
||||
|
||||
for (int l = 0; l < 10; l++) {
|
||||
data[l] = nullptr;
|
||||
}
|
||||
for (int l = 0; l < 10; l++) data[l] = nullptr;
|
||||
|
||||
for (int l = 0; l < 10; l++) {
|
||||
std::wstring name;
|
||||
std::wstring mipMapPath = L"";
|
||||
if (l != 0) {
|
||||
mipMapPath = L"MipMapLevel" + _toString<int>(l + 1);
|
||||
}
|
||||
if (filenameHasExtension) {
|
||||
name = L"res" + filePath.substr(0, filePath.length());
|
||||
} else {
|
||||
name = L"res" + filePath.substr(0, filePath.length() - 4) +
|
||||
mipMapPath + L".png";
|
||||
}
|
||||
std::wstring mipMapPath =
|
||||
(l != 0) ? L"MipMapLevel" + _toString<int>(l + 1) : L"";
|
||||
name = L"res" + (filenameHasExtension
|
||||
? filePath
|
||||
: filePath.substr(0, filePath.length() - 4) +
|
||||
mipMapPath + L".png");
|
||||
|
||||
if (!dlcPack->doesPackContainFile(DLCManager::e_DLCType_All, name)) {
|
||||
// 4J - If we haven't loaded the non-mipmap version then exit the
|
||||
// game
|
||||
if (l == 0) {
|
||||
app.FatalLoadError();
|
||||
}
|
||||
if (l == 0) app.FatalLoadError();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -200,64 +165,9 @@ BufferedImage::BufferedImage(DLCPack* dlcPack, const std::wstring& File,
|
|||
}
|
||||
|
||||
D3DXIMAGE_INFO ImageInfo;
|
||||
ZeroMemory(&ImageInfo, sizeof(D3DXIMAGE_INFO));
|
||||
hr = RenderManager.LoadTextureData(pbData, dataBytes, &ImageInfo,
|
||||
&data[l]);
|
||||
|
||||
if (hr != ERROR_SUCCESS) {
|
||||
if (l == 0) {
|
||||
std::wstring wname = L"res" +
|
||||
filePath.substr(0, filePath.length() - 4) +
|
||||
L".png";
|
||||
std::vector<std::wstring> candidates;
|
||||
candidates.push_back(wname);
|
||||
if (wname.rfind(L"Common/res/", 0) == 0) {
|
||||
candidates.push_back(
|
||||
wname.substr(std::wstring(L"Common/res/").length()));
|
||||
}
|
||||
candidates.push_back(filePath);
|
||||
if (!filePath.empty() && filePath[0] == L'/')
|
||||
candidates.push_back(filePath.substr(1));
|
||||
|
||||
std::wstring baseName2;
|
||||
size_t posSlash2 = filePath.find_last_of(L"/\\");
|
||||
if (posSlash2 == std::wstring::npos)
|
||||
baseName2 = filePath;
|
||||
else
|
||||
baseName2 = filePath.substr(posSlash2 + 1);
|
||||
// same thing but for the fonts.. i found a way to make this
|
||||
// less horrible but im lazy sorry :/
|
||||
if (!baseName2.empty()) {
|
||||
candidates.insert(candidates.begin(),
|
||||
L"Common/Res/Font/" + baseName2);
|
||||
candidates.push_back(L"font/" + baseName2);
|
||||
candidates.push_back(L"font\\" + baseName2);
|
||||
candidates.push_back(L"res/font/" + baseName2);
|
||||
candidates.push_back(L"Common/res/font/" + baseName2);
|
||||
candidates.push_back(L"Common/Res/Font/" + baseName2);
|
||||
}
|
||||
|
||||
bool loaded = false;
|
||||
for (auto& key : candidates) {
|
||||
if (key.empty()) continue;
|
||||
if (app.hasArchiveFile(key)) {
|
||||
byteArray ba = app.getArchiveFile(key);
|
||||
if (ba.data != nullptr && ba.length > 0) {
|
||||
hr = RenderManager.LoadTextureData(
|
||||
ba.data, ba.length, &ImageInfo, &data[l]);
|
||||
if (hr == ERROR_SUCCESS) {
|
||||
loaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!loaded) app.FatalLoadError();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (l == 0) {
|
||||
if (hr == ERROR_SUCCESS && l == 0) {
|
||||
width = ImageInfo.Width;
|
||||
height = ImageInfo.Height;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ endif
|
|||
|
||||
client = executable('Minecraft.Client',
|
||||
client_sources + platform_sources + localisation[1],
|
||||
include_directories : [include_directories('Platform', 'Platform/Linux/Iggy/include'),stb],
|
||||
include_directories : [include_directories('Platform', 'Platform/Linux/Iggy/include', '../Minecraft.World/Platform'),stb],
|
||||
dependencies : client_dependencies,
|
||||
cpp_args : global_cpp_args + global_cpp_defs + [
|
||||
'-DUNICODE', '-D_UNICODE',
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include "FileFilter.h"
|
||||
#include "../../Level/Storage/McRegionLevelStorageSource.h"
|
||||
#include "File.h"
|
||||
|
||||
#include "PathHelper.h"
|
||||
#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
|
|
@ -57,52 +57,55 @@ File::File(const File& parent, const std::wstring& child) {
|
|||
|
||||
// Creates a new File instance by converting the given pathname string into an
|
||||
// abstract pathname.
|
||||
|
||||
File::File(const std::wstring& pathname) {
|
||||
if (pathname.empty()) {
|
||||
m_abstractPathName = L"";
|
||||
return;
|
||||
}
|
||||
// same thing as in bufferedoverflow
|
||||
std::wstring fixedPath = pathname;
|
||||
|
||||
std::wstring fixedPath = pathname;
|
||||
for (size_t i = 0; i < fixedPath.length(); ++i) {
|
||||
if (fixedPath[i] == L'\\') fixedPath[i] = L'/';
|
||||
}
|
||||
|
||||
size_t dpos;
|
||||
while ((dpos = fixedPath.find(L"//")) != std::wstring::npos)
|
||||
fixedPath.erase(dpos, 1);
|
||||
if (fixedPath.find(L"GAME:/") == 0) fixedPath = fixedPath.substr(6);
|
||||
|
||||
m_abstractPathName = fixedPath;
|
||||
|
||||
#if defined(__linux__)
|
||||
// If this is a relative path and it doesn't exist in the CWD, try to
|
||||
// resolve it relative to the executable directory
|
||||
if (!m_abstractPathName.empty() && m_abstractPathName[0] != L'/') {
|
||||
const char* native = wstringtofilename(m_abstractPathName);
|
||||
if (access(native, F_OK) == -1) {
|
||||
char exePathBuf[PATH_MAX];
|
||||
ssize_t exeLen =
|
||||
readlink("/proc/self/exe", exePathBuf, sizeof(exePathBuf) - 1);
|
||||
if (exeLen != -1) {
|
||||
exePathBuf[exeLen] = '\0';
|
||||
std::string exePathStr(exePathBuf);
|
||||
size_t pos = exePathStr.find_last_of('/');
|
||||
std::string exeDir = (pos == std::string::npos)
|
||||
? std::string(".")
|
||||
: exePathStr.substr(0, pos);
|
||||
std::wstring exeDirW = convStringToWstring(exeDir);
|
||||
std::wstring candidate =
|
||||
exeDirW + pathSeparator + m_abstractPathName;
|
||||
const char* candNative = wstringtofilename(candidate);
|
||||
if (access(candNative, F_OK) != -1) {
|
||||
m_abstractPathName = candidate;
|
||||
}
|
||||
}
|
||||
std::string request = wstringtofilename(m_abstractPathName);
|
||||
while (!request.empty() && request[0] == '/') request.erase(0, 1);
|
||||
if (request.find("res/") == 0) request.erase(0, 4);
|
||||
|
||||
std::string exeDir = PathHelper::GetExecutableDirA();
|
||||
std::string fileName = request;
|
||||
size_t lastSlash = fileName.find_last_of('/');
|
||||
if (lastSlash != std::string::npos)
|
||||
fileName = fileName.substr(lastSlash + 1);
|
||||
|
||||
const char* bases[] = {"/",
|
||||
"/Common/res/TitleUpdate/res/",
|
||||
"/Common/Media/",
|
||||
"/Common/res/",
|
||||
"/Common/",
|
||||
"/Minecraft.Assets/"};
|
||||
|
||||
for (const char* base : bases) {
|
||||
std::string tryFull = exeDir + base + request;
|
||||
std::string tryFile = exeDir + base + fileName;
|
||||
if (access(tryFull.c_str(), F_OK) != -1) {
|
||||
m_abstractPathName = convStringToWstring(tryFull);
|
||||
return;
|
||||
}
|
||||
if (access(tryFile.c_str(), F_OK) != -1) {
|
||||
m_abstractPathName = convStringToWstring(tryFile);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
std::string path = wstringtofilename(m_abstractPathName);
|
||||
std::string finalPath = StorageManager.GetMountedPath(path.c_str());
|
||||
|
|
|
|||
37
Minecraft.World/Platform/PathHelper.h
Normal file
37
Minecraft.World/Platform/PathHelper.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#if defined(__linux__)
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
namespace PathHelper {
|
||||
inline std::wstring GetExecutableDirW() {
|
||||
#if defined(__linux__)
|
||||
char buffer[4096];
|
||||
ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1);
|
||||
if (len != -1) {
|
||||
buffer[len] = '\0';
|
||||
std::string path(buffer);
|
||||
size_t lastSlash = path.find_last_of('/');
|
||||
if (lastSlash != std::string::npos)
|
||||
return std::wstring(path.begin(), path.begin() + lastSlash);
|
||||
}
|
||||
#endif
|
||||
return L".";
|
||||
}
|
||||
|
||||
inline std::string GetExecutableDirA() {
|
||||
#if defined(__linux__)
|
||||
char buffer[4096];
|
||||
ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1);
|
||||
if (len != -1) {
|
||||
buffer[len] = '\0';
|
||||
std::string path(buffer);
|
||||
size_t lastSlash = path.find_last_of('/');
|
||||
if (lastSlash != std::string::npos) return path.substr(0, lastSlash);
|
||||
}
|
||||
#endif
|
||||
return ".";
|
||||
}
|
||||
} // namespace PathHelper
|
||||
Loading…
Reference in a new issue