mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-05-26 14:32:57 +00:00
okay managed to do it, anyways hacky code land :3
mainly rewrote a bit of the soundengine, made files now load without being mean and uh yeah it works
This commit is contained in:
parent
256a809750
commit
ca84ac0512
|
|
@ -82,8 +82,8 @@ const char* SoundEngine::m_szStreamFileA[eStream_Max] = {"calm1",
|
|||
"ward",
|
||||
"where_are_we_now"};
|
||||
#ifdef __linux__
|
||||
char SoundEngine::m_szSoundPath[] = {"Sound/"};
|
||||
char SoundEngine::m_szMusicPath[] = {"music/"};
|
||||
char SoundEngine::m_szSoundPath[] = {"Common/Sound/"};
|
||||
char SoundEngine::m_szMusicPath[] = {"Common/"};
|
||||
char SoundEngine::m_szRedistName[] = {"redist64"};
|
||||
#endif
|
||||
|
||||
|
|
@ -190,168 +190,144 @@ void SoundEngine::init(Options* pOptions) {
|
|||
void SoundEngine::destroy() { ma_engine_uninit(&m_engine); }
|
||||
void SoundEngine::play(int iSound, float x, float y, float z, float volume,
|
||||
float pitch) {
|
||||
char szSoundName[256] = "Sound/Minecraft/";
|
||||
if (iSound == -1) return;
|
||||
|
||||
if (iSound == -1) {
|
||||
app.DebugPrintf(6, "PlaySound with sound of -1 !!!!!!!!!!!!!!!\n");
|
||||
return;
|
||||
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] = '/';
|
||||
}
|
||||
wcstombs(szSoundName + 16, wchSoundNames[iSound],
|
||||
sizeof(szSoundName) - 16 - 1);
|
||||
szSoundName[sizeof(szSoundName) - 1] = '\0';
|
||||
|
||||
char finalPath[256];
|
||||
// YES I KNOW SOUNDNAMES.CPP EXISTS.
|
||||
const char* extensions[] = {".ogg", ".wav", ".mp3"};
|
||||
size_t extCount = sizeof(extensions) / sizeof(extensions[0]);
|
||||
const char* roots[] = {"Sound/Minecraft/",
|
||||
"build/Minecraft.Client/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;
|
||||
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;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
for (size_t extIdx = 0; extIdx < extCount; extIdx++) {
|
||||
char basePlusExt[256];
|
||||
sprintf_s(basePlusExt, "%s%s", szSoundName, extensions[extIdx]);
|
||||
|
||||
DWORD attr = GetFileAttributesA(basePlusExt);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES &&
|
||||
!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
sprintf_s(finalPath, "%s", basePlusExt);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
int count = 0;
|
||||
|
||||
for (size_t extIdx = 0; extIdx < extCount; extIdx++) {
|
||||
for (size_t i = 1; i < 32; i++) {
|
||||
char numberedPath[256];
|
||||
sprintf_s(numberedPath, "%s%d%s", szSoundName, i,
|
||||
extensions[extIdx]);
|
||||
|
||||
DWORD attr = GetFileAttributesA(numberedPath);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES &&
|
||||
!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
count = i;
|
||||
}
|
||||
if (maxVariant > 0) {
|
||||
int chosen = (rand() % maxVariant) + 1;
|
||||
snprintf(finalPath, sizeof(finalPath), "%s%s%d%s", root,
|
||||
szIdentifier, chosen, ext);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
int chosen = (rand() % count) + 1;
|
||||
for (size_t extIdx = 0; extIdx < extCount; extIdx++) {
|
||||
char numberedPath[256];
|
||||
sprintf_s(numberedPath, "%s%d%s", szSoundName, chosen,
|
||||
extensions[extIdx]);
|
||||
|
||||
DWORD attr = GetFileAttributesA(numberedPath);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES &&
|
||||
!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
sprintf_s(finalPath, "%s", numberedPath);
|
||||
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) {
|
||||
sprintf_s(finalPath, "%s%d.ogg", szSoundName, chosen);
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) return;
|
||||
|
||||
MiniAudioSound* s = new MiniAudioSound();
|
||||
memset(&s->info, 0, sizeof(AUDIO_INFO));
|
||||
|
||||
s->info.x = x;
|
||||
s->info.y = y;
|
||||
s->info.z = z;
|
||||
|
||||
s->info.volume = volume;
|
||||
s->info.pitch = pitch;
|
||||
s->info.bIs3D = true;
|
||||
s->info.bUseSoundsPitchVal = false;
|
||||
s->info.iSound = iSound + eSFX_MAX;
|
||||
|
||||
if (ma_sound_init_from_file(&m_engine, finalPath, MA_SOUND_FLAG_ASYNC,
|
||||
nullptr, nullptr, &s->sound) != MA_SUCCESS) {
|
||||
app.DebugPrintf("Failed to load sound ID : %i from %S\n", iSound,
|
||||
wchSoundNames[iSound]);
|
||||
nullptr, nullptr, &s->sound) == MA_SUCCESS) {
|
||||
ma_sound_set_spatialization_enabled(&s->sound, MA_TRUE);
|
||||
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 {
|
||||
delete s;
|
||||
return;
|
||||
}
|
||||
|
||||
ma_sound_set_spatialization_enabled(&s->sound, MA_TRUE);
|
||||
ma_sound_set_min_distance(&s->sound, SFX_3D_MIN_DISTANCE);
|
||||
ma_sound_set_max_distance(&s->sound, SFX_3D_MAX_DISTANCE);
|
||||
ma_sound_set_rolloff(&s->sound, SFX_3D_ROLLOFF);
|
||||
|
||||
float finalVolume = volume * m_MasterEffectsVolume * SFX_VOLUME_MULTIPLIER;
|
||||
if (finalVolume > SFX_MAX_GAIN) finalVolume = SFX_MAX_GAIN;
|
||||
|
||||
ma_sound_set_volume(&s->sound, finalVolume);
|
||||
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);
|
||||
}
|
||||
|
||||
void SoundEngine::playUI(int iSound, float volume, float pitch) {
|
||||
char szSoundName[256];
|
||||
wstring name;
|
||||
|
||||
char szIdentifier[256];
|
||||
if (iSound >= eSFX_MAX) {
|
||||
strcpy(szSoundName, "Sound/Minecraft/");
|
||||
name = wchSoundNames[iSound];
|
||||
wcstombs(szIdentifier, wchSoundNames[iSound], 255);
|
||||
} else {
|
||||
strcpy(szSoundName, "Sound/Minecraft/UI/");
|
||||
name = wchUISoundNames[iSound];
|
||||
wcstombs(szIdentifier, wchUISoundNames[iSound], 255);
|
||||
}
|
||||
wcstombs(szSoundName + strlen(szSoundName), name.c_str(),
|
||||
sizeof(szSoundName) - strlen(szSoundName) - 1);
|
||||
char finalPath[256];
|
||||
|
||||
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"};
|
||||
size_t extCount = sizeof(extensions) / sizeof(extensions[0]);
|
||||
const char* roots[] = {"Sound/Minecraft/UI/", "Sound/Minecraft/",
|
||||
"build/Minecraft.Client/Sound/Minecraft/UI/",
|
||||
"build/Minecraft.Client/Sound/Minecraft/",
|
||||
"Common/Sound/Minecraft/UI/"};
|
||||
|
||||
char finalPath[512] = {0};
|
||||
bool found = false;
|
||||
|
||||
for (size_t extIdx = 0; extIdx < extCount; extIdx++) {
|
||||
char basePlusExt[256];
|
||||
sprintf_s(basePlusExt, "%s%s", szSoundName, extensions[extIdx]);
|
||||
|
||||
DWORD attr = GetFileAttributesA(basePlusExt);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES &&
|
||||
!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
sprintf_s(finalPath, "%s", basePlusExt);
|
||||
found = true;
|
||||
break;
|
||||
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.volume = volume;
|
||||
s->info.pitch = pitch;
|
||||
s->info.bIs3D = false;
|
||||
s->info.bUseSoundsPitchVal = true;
|
||||
|
||||
if (ma_sound_init_from_file(&m_engine, finalPath, MA_SOUND_FLAG_ASYNC,
|
||||
nullptr, nullptr, &s->sound) != MA_SUCCESS) {
|
||||
nullptr, nullptr, &s->sound) == MA_SUCCESS) {
|
||||
ma_sound_set_spatialization_enabled(&s->sound, MA_FALSE);
|
||||
ma_sound_set_volume(&s->sound, volume * m_MasterEffectsVolume);
|
||||
ma_sound_set_pitch(&s->sound, pitch);
|
||||
ma_sound_start(&s->sound);
|
||||
m_activeSounds.push_back(s);
|
||||
} else {
|
||||
delete s;
|
||||
app.DebugPrintf("ma_sound_init_from_file failed: %s\n", finalPath);
|
||||
return;
|
||||
}
|
||||
|
||||
ma_sound_set_spatialization_enabled(&s->sound, MA_FALSE);
|
||||
|
||||
float finalVolume = volume * m_MasterEffectsVolume;
|
||||
if (finalVolume > 1.0f) finalVolume = 1.0f;
|
||||
printf("UI Sound volume set to %f\nEffects volume: %f\n", finalVolume,
|
||||
m_MasterEffectsVolume);
|
||||
|
||||
ma_sound_set_volume(&s->sound, finalVolume);
|
||||
ma_sound_set_pitch(&s->sound, pitch);
|
||||
|
||||
ma_sound_start(&s->sound);
|
||||
|
||||
m_activeSounds.push_back(s);
|
||||
}
|
||||
|
||||
int SoundEngine::getMusicID(int iDomain) {
|
||||
|
|
@ -507,142 +483,102 @@ void SoundEngine::playMusicTick() {
|
|||
|
||||
switch (m_StreamState) {
|
||||
case eMusicStreamState_Idle:
|
||||
|
||||
// start a stream playing
|
||||
if (m_iMusicDelay > 0) {
|
||||
m_iMusicDelay--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_musicStreamActive) {
|
||||
app.DebugPrintf(
|
||||
"WARNING: m_musicStreamActive already true in Idle state, "
|
||||
"resetting to Playing\n");
|
||||
m_StreamState = eMusicStreamState_Playing;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_musicID != -1) {
|
||||
// start playing it
|
||||
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"};
|
||||
|
||||
strcpy((char*)m_szStreamName, m_szMusicPath);
|
||||
// are we using a mash-up pack?
|
||||
// if(pMinecraft && !pMinecraft->skins->isUsingDefaultSkin() &&
|
||||
// pMinecraft->skins->getSelected()->hasAudio())
|
||||
bool found = false;
|
||||
m_szStreamName[0] = '\0';
|
||||
|
||||
// DLC Mashup pack check
|
||||
if (Minecraft::GetInstance()
|
||||
->skins->getSelected()
|
||||
->hasAudio()) {
|
||||
// It's a mash-up - need to use the DLC path for the music
|
||||
TexturePack* pTexPack =
|
||||
Minecraft::GetInstance()->skins->getSelected();
|
||||
DLCTexturePack* pDLCTexPack = (DLCTexturePack*)pTexPack;
|
||||
DLCPack* pack = pDLCTexPack->getDLCInfoParentPack();
|
||||
DLCPack* pack =
|
||||
((DLCTexturePack*)pTexPack)->getDLCInfoParentPack();
|
||||
DLCAudioFile* dlcAudioFile = (DLCAudioFile*)pack->getFile(
|
||||
DLCManager::e_DLCType_Audio, 0);
|
||||
|
||||
app.DebugPrintf("Mashup pack \n");
|
||||
|
||||
// build the name
|
||||
|
||||
// if the music ID is beyond the end of the texture pack
|
||||
// music files, then it's a CD
|
||||
if (m_musicID < m_iStream_CD_1) {
|
||||
SetIsPlayingStreamingGameMusic(true);
|
||||
SetIsPlayingStreamingCDMusic(false);
|
||||
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);
|
||||
|
||||
string strFile =
|
||||
std::string strFile =
|
||||
"TPACK:\\Data\\" + string(szName) + ".wav";
|
||||
|
||||
std::string mountedPath =
|
||||
StorageManager.GetMountedPath(strFile);
|
||||
strcpy(m_szStreamName, mountedPath.c_str());
|
||||
} else {
|
||||
SetIsPlayingStreamingGameMusic(false);
|
||||
SetIsPlayingStreamingCDMusic(true);
|
||||
m_MusicType = eMusicType_CD;
|
||||
m_StreamingAudioInfo.bIs3D = true;
|
||||
|
||||
// Need to adjust to index into the cds in the game's
|
||||
// m_szStreamFileA
|
||||
strcat((char*)m_szStreamName, "cds/");
|
||||
strcat((char*)m_szStreamName,
|
||||
m_szStreamFileA[m_musicID - m_iStream_CD_1 +
|
||||
eStream_CD_1]);
|
||||
strcat((char*)m_szStreamName, ".wav");
|
||||
if (access(m_szStreamName, F_OK) != -1) found = true;
|
||||
}
|
||||
} else {
|
||||
if (m_musicID < m_iStream_CD_1) {
|
||||
SetIsPlayingStreamingGameMusic(true);
|
||||
SetIsPlayingStreamingCDMusic(false);
|
||||
m_MusicType = eMusicType_Game;
|
||||
m_StreamingAudioInfo.bIs3D = false;
|
||||
// build the name
|
||||
strcat((char*)m_szStreamName, "music/");
|
||||
} else {
|
||||
SetIsPlayingStreamingGameMusic(false);
|
||||
SetIsPlayingStreamingCDMusic(true);
|
||||
m_MusicType = eMusicType_CD;
|
||||
m_StreamingAudioInfo.bIs3D = true;
|
||||
// build the name
|
||||
strcat((char*)m_szStreamName, "cds/");
|
||||
}
|
||||
strcat((char*)m_szStreamName, m_szStreamFileA[m_musicID]);
|
||||
strcat((char*)m_szStreamName, ".wav");
|
||||
}
|
||||
|
||||
FILE* pFile = nullptr;
|
||||
pFile = fopen(reinterpret_cast<char*>(m_szStreamName), "rb");
|
||||
if (pFile) {
|
||||
fclose(pFile);
|
||||
} else {
|
||||
const char* extensions[] = {".ogg", ".mp3", ".wav"};
|
||||
size_t extCount =
|
||||
sizeof(extensions) / sizeof(extensions[0]);
|
||||
bool found = false;
|
||||
// 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/", "./"};
|
||||
|
||||
char* dotPos =
|
||||
strrchr(reinterpret_cast<char*>(m_szStreamName), '.');
|
||||
if (dotPos != nullptr &&
|
||||
(dotPos - reinterpret_cast<char*>(m_szStreamName)) <
|
||||
250) {
|
||||
for (size_t i = 0; i < extCount; i++) {
|
||||
strncpy(dotPos, extensions[i], 5);
|
||||
app.DebugPrintf("Checking %s\n", m_szStreamName);
|
||||
pFile = fopen(
|
||||
reinterpret_cast<char*>(m_szStreamName), "rb");
|
||||
if (pFile) {
|
||||
fclose(pFile);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (dotPos != nullptr) {
|
||||
strncpy(dotPos, ".wav", 5);
|
||||
}
|
||||
app.DebugPrintf(
|
||||
"WARNING: No audio file found for music ID %d "
|
||||
"(tried .ogg, .mp3, .wav)\n",
|
||||
m_musicID);
|
||||
return;
|
||||
if (found) break;
|
||||
}
|
||||
}
|
||||
|
||||
app.DebugPrintf("Starting streaming - %s\n", m_szStreamName);
|
||||
m_openStreamThread = new C4JThread(OpenStreamThreadProc, this,
|
||||
"OpenStreamThreadProc");
|
||||
m_openStreamThread->Run();
|
||||
m_StreamState = eMusicStreamState_Opening;
|
||||
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
|
||||
m_iMusicDelay = 20 * 60;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -651,64 +587,30 @@ void SoundEngine::playMusicTick() {
|
|||
delete m_openStreamThread;
|
||||
m_openStreamThread = nullptr;
|
||||
|
||||
app.DebugPrintf(
|
||||
"OpenStreamThreadProc finished. m_musicStreamActive=%d\n",
|
||||
m_musicStreamActive);
|
||||
|
||||
if (!m_musicStreamActive) {
|
||||
const char* currentExt =
|
||||
strrchr(reinterpret_cast<char*>(m_szStreamName), '.');
|
||||
if (currentExt && _stricmp(currentExt, ".wav") == 0) {
|
||||
const bool isCD = (m_musicID >= m_iStream_CD_1);
|
||||
const char* folder = isCD ? "cds/" : "music/";
|
||||
|
||||
int n =
|
||||
sprintf_s(reinterpret_cast<char*>(m_szStreamName),
|
||||
512, "%s%s%s.wav", m_szMusicPath, folder,
|
||||
m_szStreamFileA[m_musicID]);
|
||||
|
||||
if (n > 0) {
|
||||
FILE* pFile = fopen(
|
||||
reinterpret_cast<char*>(m_szStreamName), "rb");
|
||||
if (pFile) {
|
||||
fclose(pFile);
|
||||
|
||||
m_openStreamThread =
|
||||
new C4JThread(OpenStreamThreadProc, this,
|
||||
"OpenStreamThreadProc");
|
||||
m_openStreamThread->Run();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_StreamState = eMusicStreamState_Idle;
|
||||
break;
|
||||
}
|
||||
|
||||
ma_sound_set_spatialization_enabled(
|
||||
&m_musicStream,
|
||||
m_StreamingAudioInfo.bIs3D ? MA_TRUE : MA_FALSE);
|
||||
if (m_StreamingAudioInfo.bIs3D) {
|
||||
ma_sound_set_spatialization_enabled(&m_musicStream,
|
||||
MA_TRUE);
|
||||
ma_sound_set_position(
|
||||
&m_musicStream, m_StreamingAudioInfo.x,
|
||||
m_StreamingAudioInfo.y, m_StreamingAudioInfo.z);
|
||||
} else {
|
||||
ma_sound_set_spatialization_enabled(&m_musicStream,
|
||||
MA_FALSE);
|
||||
}
|
||||
|
||||
ma_sound_set_pitch(&m_musicStream, m_StreamingAudioInfo.pitch);
|
||||
|
||||
float finalVolume =
|
||||
m_StreamingAudioInfo.volume * getMasterMusicVolume();
|
||||
|
||||
ma_sound_set_volume(&m_musicStream, finalVolume);
|
||||
ma_result startResult = ma_sound_start(&m_musicStream);
|
||||
app.DebugPrintf("ma_sound_start result: %d\n", startResult);
|
||||
ma_sound_set_volume(
|
||||
&m_musicStream,
|
||||
m_StreamingAudioInfo.volume * getMasterMusicVolume());
|
||||
ma_sound_start(&m_musicStream);
|
||||
|
||||
m_StreamState = eMusicStreamState_Playing;
|
||||
}
|
||||
break;
|
||||
|
||||
case eMusicStreamState_OpeningCancel:
|
||||
if (!m_openStreamThread->isRunning()) {
|
||||
delete m_openStreamThread;
|
||||
|
|
@ -716,200 +618,130 @@ void SoundEngine::playMusicTick() {
|
|||
m_StreamState = eMusicStreamState_Stop;
|
||||
}
|
||||
break;
|
||||
|
||||
case eMusicStreamState_Stop:
|
||||
if (m_musicStreamActive) {
|
||||
ma_sound_stop(&m_musicStream);
|
||||
ma_sound_uninit(&m_musicStream);
|
||||
m_musicStreamActive = false;
|
||||
}
|
||||
|
||||
SetIsPlayingStreamingCDMusic(false);
|
||||
SetIsPlayingStreamingGameMusic(false);
|
||||
|
||||
m_StreamState = eMusicStreamState_Idle;
|
||||
break;
|
||||
case eMusicStreamState_Stopping:
|
||||
break;
|
||||
case eMusicStreamState_Play:
|
||||
break;
|
||||
case eMusicStreamState_Playing: {
|
||||
static int frameCount = 0;
|
||||
if (frameCount++ % 60 == 0) {
|
||||
if (m_musicStreamActive) {
|
||||
bool isPlaying = ma_sound_is_playing(&m_musicStream);
|
||||
float vol = ma_sound_get_volume(&m_musicStream);
|
||||
bool isAtEnd = ma_sound_at_end(&m_musicStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case eMusicStreamState_Playing:
|
||||
if (GetIsPlayingStreamingGameMusic()) {
|
||||
{
|
||||
bool playerInEnd = false;
|
||||
bool playerInNether = false;
|
||||
Minecraft* pMinecraft = Minecraft::GetInstance();
|
||||
for (unsigned int i = 0; i < MAX_LOCAL_PLAYERS; ++i) {
|
||||
if (pMinecraft->localplayers[i] != nullptr) {
|
||||
if (pMinecraft->localplayers[i]->dimension ==
|
||||
LevelData::DIMENSION_END) {
|
||||
playerInEnd = true;
|
||||
} else if (pMinecraft->localplayers[i]->dimension ==
|
||||
LevelData::DIMENSION_NETHER) {
|
||||
playerInNether = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool playerInEnd = false, playerInNether = false;
|
||||
Minecraft* pMinecraft = Minecraft::GetInstance();
|
||||
|
||||
if (playerInEnd && !GetIsPlayingEndMusic()) {
|
||||
m_StreamState = eMusicStreamState_Stop;
|
||||
|
||||
// Set the end track
|
||||
m_musicID = getMusicID(LevelData::DIMENSION_END);
|
||||
SetIsPlayingEndMusic(true);
|
||||
SetIsPlayingNetherMusic(false);
|
||||
} else if (!playerInEnd && GetIsPlayingEndMusic()) {
|
||||
if (playerInNether) {
|
||||
m_StreamState = eMusicStreamState_Stop;
|
||||
|
||||
// Set the end track
|
||||
m_musicID = getMusicID(LevelData::DIMENSION_NETHER);
|
||||
SetIsPlayingEndMusic(false);
|
||||
SetIsPlayingNetherMusic(true);
|
||||
} else {
|
||||
m_StreamState = eMusicStreamState_Stop;
|
||||
|
||||
// Set the end track
|
||||
m_musicID =
|
||||
getMusicID(LevelData::DIMENSION_OVERWORLD);
|
||||
SetIsPlayingEndMusic(false);
|
||||
SetIsPlayingNetherMusic(false);
|
||||
}
|
||||
} else if (playerInNether && !GetIsPlayingNetherMusic()) {
|
||||
m_StreamState = eMusicStreamState_Stop;
|
||||
// set the Nether track
|
||||
m_musicID = getMusicID(LevelData::DIMENSION_NETHER);
|
||||
SetIsPlayingNetherMusic(true);
|
||||
SetIsPlayingEndMusic(false);
|
||||
} else if (!playerInNether && GetIsPlayingNetherMusic()) {
|
||||
if (playerInEnd) {
|
||||
m_StreamState = eMusicStreamState_Stop;
|
||||
// set the Nether track
|
||||
m_musicID = getMusicID(LevelData::DIMENSION_END);
|
||||
SetIsPlayingNetherMusic(false);
|
||||
SetIsPlayingEndMusic(true);
|
||||
} else {
|
||||
m_StreamState = eMusicStreamState_Stop;
|
||||
// set the Nether track
|
||||
m_musicID =
|
||||
getMusicID(LevelData::DIMENSION_OVERWORLD);
|
||||
SetIsPlayingNetherMusic(false);
|
||||
SetIsPlayingEndMusic(false);
|
||||
}
|
||||
}
|
||||
|
||||
// volume change required?
|
||||
if (m_musicStreamActive) {
|
||||
float finalVolume =
|
||||
m_StreamingAudioInfo.volume * fMusicVol;
|
||||
|
||||
ma_sound_set_volume(&m_musicStream, finalVolume);
|
||||
for (unsigned int i = 0; i < MAX_LOCAL_PLAYERS; ++i) {
|
||||
if (pMinecraft->localplayers[i]) {
|
||||
if (pMinecraft->localplayers[i]->dimension ==
|
||||
LevelData::DIMENSION_END)
|
||||
playerInEnd = true;
|
||||
else if (pMinecraft->localplayers[i]->dimension ==
|
||||
LevelData::DIMENSION_NETHER)
|
||||
playerInNether = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Music disc playing - if it's a 3D stream, then set the
|
||||
// position - we don't have any streaming audio in the world
|
||||
// that moves, so this isn't required unless we have more than
|
||||
// one listener, and are setting the listening position to the
|
||||
// origin and setting a fake position for the sound down the z
|
||||
// axis
|
||||
if (m_StreamingAudioInfo.bIs3D && m_validListenerCount > 1) {
|
||||
int iClosestListener = 0;
|
||||
float fClosestDist = 1e6f;
|
||||
|
||||
for (size_t i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if (m_ListenerA[i].bValid) {
|
||||
float dx = m_StreamingAudioInfo.x -
|
||||
m_ListenerA[i].vPosition.x;
|
||||
float dy = m_StreamingAudioInfo.y -
|
||||
m_ListenerA[i].vPosition.y;
|
||||
float dz = m_StreamingAudioInfo.z -
|
||||
m_ListenerA[i].vPosition.z;
|
||||
float dist = sqrtf(dx * dx + dy * dy + dz * dz);
|
||||
// Handle Dimension Switching
|
||||
bool needsStop = false;
|
||||
if (playerInEnd && !GetIsPlayingEndMusic()) {
|
||||
m_musicID = getMusicID(LevelData::DIMENSION_END);
|
||||
SetIsPlayingEndMusic(true);
|
||||
SetIsPlayingNetherMusic(false);
|
||||
needsStop = true;
|
||||
} else if (!playerInEnd && GetIsPlayingEndMusic()) {
|
||||
m_musicID =
|
||||
playerInNether
|
||||
? getMusicID(LevelData::DIMENSION_NETHER)
|
||||
: getMusicID(LevelData::DIMENSION_OVERWORLD);
|
||||
SetIsPlayingEndMusic(false);
|
||||
SetIsPlayingNetherMusic(playerInNether);
|
||||
needsStop = true;
|
||||
} else if (playerInNether && !GetIsPlayingNetherMusic()) {
|
||||
m_musicID = getMusicID(LevelData::DIMENSION_NETHER);
|
||||
SetIsPlayingNetherMusic(true);
|
||||
SetIsPlayingEndMusic(false);
|
||||
needsStop = true;
|
||||
} else if (!playerInNether && GetIsPlayingNetherMusic()) {
|
||||
m_musicID =
|
||||
playerInEnd
|
||||
? getMusicID(LevelData::DIMENSION_END)
|
||||
: getMusicID(LevelData::DIMENSION_OVERWORLD);
|
||||
SetIsPlayingNetherMusic(false);
|
||||
SetIsPlayingEndMusic(playerInEnd);
|
||||
needsStop = true;
|
||||
}
|
||||
|
||||
if (dist < fClosestDist) {
|
||||
fClosestDist = dist;
|
||||
iClosestListener = i;
|
||||
}
|
||||
if (needsStop) m_StreamState = eMusicStreamState_Stop;
|
||||
|
||||
// volume change required?
|
||||
if (m_musicStreamActive)
|
||||
ma_sound_set_volume(
|
||||
&m_musicStream,
|
||||
m_StreamingAudioInfo.volume * fMusicVol);
|
||||
|
||||
} 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++) {
|
||||
if (m_ListenerA[i].bValid) {
|
||||
float dist = sqrtf(powf(m_StreamingAudioInfo.x -
|
||||
m_ListenerA[i].vPosition.x,
|
||||
2) +
|
||||
powf(m_StreamingAudioInfo.y -
|
||||
m_ListenerA[i].vPosition.y,
|
||||
2) +
|
||||
powf(m_StreamingAudioInfo.z -
|
||||
m_ListenerA[i].vPosition.z,
|
||||
2));
|
||||
if (dist < fClosestDist) {
|
||||
fClosestDist = dist;
|
||||
iClosest = i;
|
||||
}
|
||||
}
|
||||
|
||||
float relX = m_StreamingAudioInfo.x -
|
||||
m_ListenerA[iClosestListener].vPosition.x;
|
||||
float relY = m_StreamingAudioInfo.y -
|
||||
m_ListenerA[iClosestListener].vPosition.y;
|
||||
float relZ = m_StreamingAudioInfo.z -
|
||||
m_ListenerA[iClosestListener].vPosition.z;
|
||||
|
||||
if (m_musicStreamActive) {
|
||||
ma_sound_set_position(&m_musicStream, relX, relY, relZ);
|
||||
}
|
||||
}
|
||||
ma_sound_set_position(
|
||||
&m_musicStream,
|
||||
m_StreamingAudioInfo.x - m_ListenerA[iClosest].vPosition.x,
|
||||
m_StreamingAudioInfo.y - m_ListenerA[iClosest].vPosition.y,
|
||||
m_StreamingAudioInfo.z - m_ListenerA[iClosest].vPosition.z);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case eMusicStreamState_Completed: {
|
||||
// random delay of up to 3 minutes for music
|
||||
m_iMusicDelay = random->nextInt(
|
||||
20 * 60 * 3); // random->nextInt(20 * 60 * 10) + 20 * 60 * 10;
|
||||
// Check if we have a local player in The Nether or in The End, and
|
||||
// play that music if they are
|
||||
Minecraft* pMinecraft = Minecraft::GetInstance();
|
||||
bool playerInEnd = false;
|
||||
bool playerInNether = false;
|
||||
case eMusicStreamState_Completed:
|
||||
m_iMusicDelay = random->nextInt(20 * 60 * 3);
|
||||
|
||||
for (unsigned int i = 0; i < MAX_LOCAL_PLAYERS; i++) {
|
||||
if (pMinecraft->localplayers[i] != nullptr) {
|
||||
if (pMinecraft->localplayers[i]->dimension ==
|
||||
LevelData::DIMENSION_END) {
|
||||
playerInEnd = true;
|
||||
} else if (pMinecraft->localplayers[i]->dimension ==
|
||||
LevelData::DIMENSION_NETHER) {
|
||||
playerInNether = true;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (playerInEnd) {
|
||||
m_musicID = getMusicID(LevelData::DIMENSION_END);
|
||||
SetIsPlayingEndMusic(true);
|
||||
SetIsPlayingNetherMusic(false);
|
||||
} else if (playerInNether) {
|
||||
m_musicID = getMusicID(LevelData::DIMENSION_NETHER);
|
||||
SetIsPlayingNetherMusic(true);
|
||||
SetIsPlayingEndMusic(false);
|
||||
} else {
|
||||
m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD);
|
||||
SetIsPlayingNetherMusic(false);
|
||||
SetIsPlayingEndMusic(false);
|
||||
}
|
||||
|
||||
m_musicID = getMusicID(dim);
|
||||
SetIsPlayingEndMusic(dim == LevelData::DIMENSION_END);
|
||||
SetIsPlayingNetherMusic(dim == LevelData::DIMENSION_NETHER);
|
||||
m_StreamState = eMusicStreamState_Idle;
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
// check the status of the stream - this is for when a track completes
|
||||
// rather than is stopped by the user action
|
||||
|
||||
if (m_musicStreamActive) {
|
||||
if (!ma_sound_is_playing(&m_musicStream) &&
|
||||
ma_sound_at_end(&m_musicStream)) {
|
||||
ma_sound_uninit(&m_musicStream);
|
||||
m_musicStreamActive = false;
|
||||
|
||||
SetIsPlayingStreamingCDMusic(false);
|
||||
SetIsPlayingStreamingGameMusic(false);
|
||||
|
||||
m_StreamState = eMusicStreamState_Completed;
|
||||
}
|
||||
if (m_musicStreamActive && !ma_sound_is_playing(&m_musicStream) &&
|
||||
ma_sound_at_end(&m_musicStream)) {
|
||||
ma_sound_uninit(&m_musicStream);
|
||||
m_musicStreamActive = false;
|
||||
SetIsPlayingStreamingCDMusic(false);
|
||||
SetIsPlayingStreamingGameMusic(false);
|
||||
m_StreamState = eMusicStreamState_Completed;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,12 @@
|
|||
#include "../../Minecraft.World/Util/ArrayWithLength.h"
|
||||
#include "BufferedImage.h"
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifdef _XBOX
|
||||
typedef struct {
|
||||
unsigned int filesz;
|
||||
|
|
@ -28,7 +34,7 @@ BufferedImage::BufferedImage(int width, int height, int type) {
|
|||
data[0] = new int[width * height];
|
||||
|
||||
for (int i = 1; i < 10; i++) {
|
||||
data[i] = NULL;
|
||||
data[i] = nullptr;
|
||||
}
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
|
|
@ -43,136 +49,125 @@ void BufferedImage::ByteFlip4(unsigned int& data) {
|
|||
// the compression method. Compression method 3 is a 32-bit image with only
|
||||
// 24-bits used (ie no alpha channel) whereas method 0 is a full 32-bit image
|
||||
// with a valid alpha channel.
|
||||
|
||||
// 4jcraft: mostly rewrote this function
|
||||
BufferedImage::BufferedImage(const std::wstring& File,
|
||||
bool filenameHasExtension /*=false*/,
|
||||
bool bTitleUpdateTexture /*=false*/,
|
||||
const std::wstring& drive /*=L""*/) {
|
||||
HRESULT hr;
|
||||
std::wstring wDrive;
|
||||
std::wstring filePath;
|
||||
filePath = File;
|
||||
bool filenameHasExtension,
|
||||
bool bTitleUpdateTexture,
|
||||
const std::wstring& drive) {
|
||||
HRESULT hr = -1;
|
||||
std::wstring filePath = File;
|
||||
|
||||
wDrive = drive;
|
||||
if (wDrive.empty()) {
|
||||
#ifdef _XBOX
|
||||
if (bTitleUpdateTexture) {
|
||||
// Make the content package point to to the UPDATE: drive is needed
|
||||
#ifdef _TU_BUILD
|
||||
wDrive = L"UPDATE:\\";
|
||||
#else
|
||||
// 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;
|
||||
|
||||
wDrive = L"GAME:\\res\\TitleUpdate\\";
|
||||
#endif
|
||||
} else {
|
||||
wDrive = L"GAME:\\";
|
||||
// clean the filename
|
||||
std::wstring baseName = filePath;
|
||||
if (!filenameHasExtension) {
|
||||
if (baseName.size() > 4 &&
|
||||
baseName.substr(baseName.size() - 4) == L".png") {
|
||||
baseName = baseName.substr(0, baseName.size() - 4);
|
||||
}
|
||||
#else
|
||||
|
||||
#ifdef __PS3__
|
||||
|
||||
char* pchUsrDir;
|
||||
if (app.GetBootedFromDiscPatch()) {
|
||||
const char* pchTextureName = wstringtofilename(File);
|
||||
pchUsrDir = app.GetBDUsrDirPath(pchTextureName);
|
||||
} else {
|
||||
pchUsrDir = getUsrDirPath();
|
||||
}
|
||||
|
||||
std::wstring wstr(pchUsrDir, pchUsrDir + strlen(pchUsrDir));
|
||||
|
||||
if (bTitleUpdateTexture) {
|
||||
// Make the content package point to to the UPDATE: drive is needed
|
||||
wDrive = wstr + L"\\Common\\res\\TitleUpdate\\";
|
||||
} else {
|
||||
wDrive = wstr + L"/Common/";
|
||||
}
|
||||
#elif __PSVITA__
|
||||
|
||||
/*char *pchUsrDir=getUsrDirPath();
|
||||
|
||||
wstring wstr (pchUsrDir, pchUsrDir+strlen(pchUsrDir));
|
||||
|
||||
if(bTitleUpdateTexture)
|
||||
{
|
||||
// Make the content package point to to the UPDATE: drive is
|
||||
needed wDrive= wstr + L"\\Common\\res\\TitleUpdate\\";
|
||||
}
|
||||
else
|
||||
{
|
||||
wDrive= wstr + L"/Common/";
|
||||
}*/
|
||||
|
||||
if (bTitleUpdateTexture) {
|
||||
// Make the content package point to to the UPDATE: drive is needed
|
||||
wDrive = L"Common\\res\\TitleUpdate\\";
|
||||
} else {
|
||||
wDrive = L"Common/";
|
||||
}
|
||||
#else
|
||||
if (bTitleUpdateTexture) {
|
||||
// Make the content package point to to the UPDATE: drive is needed
|
||||
wDrive = L"Common\\res\\TitleUpdate\\";
|
||||
} else {
|
||||
wDrive = L"Common/";
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int l = 0; l < 10; l++) {
|
||||
data[l] = NULL;
|
||||
}
|
||||
// avoid // mess
|
||||
while (!baseName.empty() && 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..
|
||||
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 = wDrive + L"res" + filePath.substr(0, filePath.length());
|
||||
} else {
|
||||
name = wDrive + L"res" + filePath.substr(0, filePath.length() - 4) +
|
||||
mipMapPath + L".png";
|
||||
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;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
const char* pchTextureName = wstringtofilename(name);
|
||||
for (auto& attempt : searchPaths) {
|
||||
size_t p;
|
||||
while ((p = attempt.find(L"//")) != std::wstring::npos)
|
||||
attempt.replace(p, 2, L"/");
|
||||
|
||||
#ifndef _CONTENT_PACKAGE
|
||||
app.DebugPrintf("\n--- Loading TEXTURE - %s\n\n", pchTextureName);
|
||||
#if defined(__linux__)
|
||||
if (access(wstringtofilename(attempt), F_OK) != -1) {
|
||||
finalPath = attempt;
|
||||
foundOnDisk = true;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
D3DXIMAGE_INFO ImageInfo;
|
||||
ZeroMemory(&ImageInfo, sizeof(D3DXIMAGE_INFO));
|
||||
hr =
|
||||
RenderManager.LoadTextureData(pchTextureName, &ImageInfo, &data[l]);
|
||||
|
||||
if (hr != ERROR_SUCCESS) {
|
||||
// 4J - If we haven't loaded the non-mipmap version then exit the
|
||||
// game
|
||||
if (l == 0) {
|
||||
app.FatalLoadError();
|
||||
if (foundOnDisk) {
|
||||
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);
|
||||
hr = RenderManager.LoadTextureData(ba.data, ba.length,
|
||||
&ImageInfo, &data[l]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (l == 0) {
|
||||
width = ImageInfo.Width;
|
||||
height = ImageInfo.Height;
|
||||
if (hr == ERROR_SUCCESS) {
|
||||
if (l == 0) {
|
||||
width = ImageInfo.Width;
|
||||
height = ImageInfo.Height;
|
||||
}
|
||||
} 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
|
||||
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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BufferedImage::BufferedImage(DLCPack* dlcPack, const std::wstring& File,
|
||||
bool filenameHasExtension /*= false*/) {
|
||||
bool filenameHasExtension) {
|
||||
HRESULT hr;
|
||||
std::wstring filePath = File;
|
||||
std::uint8_t* pbData = NULL;
|
||||
std::uint8_t* pbData = nullptr;
|
||||
std::uint32_t dataBytes = 0;
|
||||
|
||||
for (int l = 0; l < 10; l++) {
|
||||
data[l] = NULL;
|
||||
data[l] = nullptr;
|
||||
}
|
||||
|
||||
for (int l = 0; l < 10; l++) {
|
||||
|
|
@ -199,12 +194,8 @@ BufferedImage::BufferedImage(DLCPack* dlcPack, const std::wstring& File,
|
|||
|
||||
DLCFile* dlcFile = dlcPack->getFile(DLCManager::e_DLCType_All, name);
|
||||
pbData = dlcFile->getData(dataBytes);
|
||||
if (pbData == NULL || dataBytes == 0) {
|
||||
// 4J - If we haven't loaded the non-mipmap version then exit the
|
||||
// game
|
||||
if (l == 0) {
|
||||
app.FatalLoadError();
|
||||
}
|
||||
if (pbData == nullptr || dataBytes == 0) {
|
||||
if (l == 0) app.FatalLoadError();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -214,10 +205,54 @@ BufferedImage::BufferedImage(DLCPack* dlcPack, const std::wstring& File,
|
|||
&data[l]);
|
||||
|
||||
if (hr != ERROR_SUCCESS) {
|
||||
// 4J - If we haven't loaded the non-mipmap version then exit the
|
||||
// game
|
||||
if (l == 0) {
|
||||
app.FatalLoadError();
|
||||
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;
|
||||
}
|
||||
|
|
@ -230,9 +265,8 @@ BufferedImage::BufferedImage(DLCPack* dlcPack, const std::wstring& File,
|
|||
}
|
||||
|
||||
BufferedImage::BufferedImage(std::uint8_t* pbData, std::uint32_t dataBytes) {
|
||||
int iCurrentByte = 0;
|
||||
for (int l = 0; l < 10; l++) {
|
||||
data[l] = NULL;
|
||||
data[l] = nullptr;
|
||||
}
|
||||
|
||||
D3DXIMAGE_INFO ImageInfo;
|
||||
|
|
@ -273,7 +307,7 @@ int* BufferedImage::getData() { return data[0]; }
|
|||
|
||||
int* BufferedImage::getData(int level) { return data[level]; }
|
||||
|
||||
Graphics* BufferedImage::getGraphics() { return NULL; }
|
||||
Graphics* BufferedImage::getGraphics() { return nullptr; }
|
||||
|
||||
// Returns the transparency. Returns either OPAQUE, BITMASK, or TRANSLUCENT.
|
||||
// Specified by:
|
||||
|
|
@ -299,14 +333,15 @@ BufferedImage* BufferedImage::getSubimage(int x, int y, int w, int h) {
|
|||
this->getRGB(x, y, w, h, arrayWrapper, 0, w);
|
||||
|
||||
int level = 1;
|
||||
while (getData(level) != NULL) {
|
||||
// prevent overflow
|
||||
while (level < 10 && getData(level) != nullptr) {
|
||||
int ww = w >> level;
|
||||
int hh = h >> level;
|
||||
int xx = x >> level;
|
||||
int yy = y >> level;
|
||||
img->data[level] = new int[ww * hh];
|
||||
intArray arrayWrapper(img->data[level], ww * hh);
|
||||
this->getRGB(xx, yy, ww, hh, arrayWrapper, 0, ww, level);
|
||||
intArray levelWrapper(img->data[level], ww * hh);
|
||||
this->getRGB(xx, yy, ww, hh, levelWrapper, 0, ww, level);
|
||||
|
||||
++level;
|
||||
}
|
||||
|
|
@ -324,7 +359,8 @@ void BufferedImage::preMultiplyAlpha() {
|
|||
int b = 0;
|
||||
|
||||
int total = width * height;
|
||||
for (unsigned int i = 0; i < total; ++i) {
|
||||
// why was it unsigned??
|
||||
for (int i = 0; i < total; ++i) {
|
||||
cur = curData[i];
|
||||
alpha = (cur >> 24) & 0xff;
|
||||
r = ((cur >> 16) & 0xff) * (float)alpha / 255;
|
||||
|
|
|
|||
|
|
@ -57,33 +57,44 @@ 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) //: parent( NULL )
|
||||
{
|
||||
// #ifndef _CONTENT_PACKAGE
|
||||
// char buf[256];
|
||||
// wcstombs(buf, pathname.c_str(), 256);
|
||||
// printf("File::File - %s\n",buf);
|
||||
// #endif
|
||||
if (pathname.empty())
|
||||
m_abstractPathName = std::wstring(L"");
|
||||
else
|
||||
m_abstractPathName = pathname;
|
||||
File::File(const std::wstring& pathname) {
|
||||
if (pathname.empty()) {
|
||||
m_abstractPathName = L"";
|
||||
return;
|
||||
}
|
||||
// same thing as in bufferedoverflow
|
||||
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
|
||||
// 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);
|
||||
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);
|
||||
std::wstring candidate = exeDirW + pathSeparator + m_abstractPathName;
|
||||
std::wstring candidate =
|
||||
exeDirW + pathSeparator + m_abstractPathName;
|
||||
const char* candNative = wstringtofilename(candidate);
|
||||
if (access(candNative, F_OK) != -1) {
|
||||
m_abstractPathName = candidate;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
project('4jcraft-chucklegrounds', ['cpp', 'c'],
|
||||
project('4jcraft', ['cpp', 'c'],
|
||||
version : '0.1.0',
|
||||
meson_version: '>= 1.7',
|
||||
default_options : [
|
||||
|
|
|
|||
Loading…
Reference in a new issue