mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Fixed crash at the end of DS sound playback
* revert to the previous implementation. Made sure sfall only loads a localized resource file with valid name. Some code edits.
This commit is contained in:
@@ -1046,6 +1046,7 @@ sfall_funcX metarule functions
|
||||
- Overrides the name of the script object that was set from **scrname.msg**
|
||||
- The changed name will be reset each time the player leaves the map or reloads the game
|
||||
- Passing an empty string ("") to the `name` argument or omitting it will allow the game to get the name for the object from pro_*.msg files
|
||||
- The function can override the name only once for the same object until reset
|
||||
- __NOTE:__ this function is intended for use in normal game scripts
|
||||
|
||||
|
||||
|
||||
@@ -472,11 +472,16 @@ static void SfallResourceFile() {
|
||||
const char* sfallRes = "sfall.dat";
|
||||
|
||||
WIN32_FIND_DATA findData;
|
||||
HANDLE hFind = FindFirstFile("sfall_??.dat", &findData); // example: sfall_ru.dat, sfall_zh.dat
|
||||
HANDLE hFind = FindFirstFileA("sfall_??.dat", &findData); // example: sfall_ru.dat, sfall_zh.dat
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
if (std::strlen(&findData.cFileName[6]) == 6) {
|
||||
dlog_f("Found a localized sfall resource file: %s\n", DL_MAIN, findData.cFileName);
|
||||
sfallRes = findData.cFileName;
|
||||
break;
|
||||
}
|
||||
} while (FindNextFileA(hFind, &findData));
|
||||
FindClose(hFind);
|
||||
dlog_f("Found a localized sfall resource file: %s\n", DL_MAIN, findData.cFileName);
|
||||
sfallRes = findData.cFileName;
|
||||
}
|
||||
patchFiles.push_back(sfallRes);
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ static void ReadExtraGameMsgFiles() {
|
||||
path += ".msg";
|
||||
fo::MessageList* list = new fo::MessageList();
|
||||
if (fo::func::message_load(list, path.c_str()) == 1) {
|
||||
Message::gExtraGameMsgLists.insert(std::make_pair(0x2000 + number, list));
|
||||
Message::gExtraGameMsgLists.emplace(0x2000 + number, list);
|
||||
} else {
|
||||
delete list;
|
||||
}
|
||||
|
||||
@@ -561,7 +561,7 @@ static void PrepareGlobalScriptsListByMask() {
|
||||
fo::func::debug_printf("\n[SFALL] Script: %s will not be executed. A script with the same name already exists in another directory.", fullPath);
|
||||
continue;
|
||||
}
|
||||
globalScriptFilesList.insert(std::make_pair(baseName, fullPath)); // script files should be sorted in alphabetical order
|
||||
globalScriptFilesList.emplace(std::move(baseName), std::move(fullPath)); // script files should be sorted in alphabetical order
|
||||
}
|
||||
}
|
||||
fo::func::db_free_file_list(&filenames, 0);
|
||||
|
||||
+53
-23
@@ -16,7 +16,6 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
#include <dsound.h>
|
||||
#include <dshow.h>
|
||||
@@ -31,7 +30,8 @@
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
#define SAFERELEASE(a) { if (a) { a->Release(); } }
|
||||
#define WM_APP_DS_NOTIFY 0xA000
|
||||
#define SAFERELEASE(a) { if (a) { a->Release(); } }
|
||||
|
||||
enum SoundType : DWORD {
|
||||
sfx_loop = 0, // sfall
|
||||
@@ -83,7 +83,7 @@ static bool deathSceneSpeech = false;
|
||||
static bool lipsPlaying = false;
|
||||
|
||||
static void FreeSound(sDSSound* sound) {
|
||||
sound->pEvent->SetNotifyWindow(0, WM_APP, 0);
|
||||
sound->pEvent->SetNotifyWindow(0, WM_APP_DS_NOTIFY, 0);
|
||||
SAFERELEASE(sound->pAudio);
|
||||
SAFERELEASE(sound->pEvent);
|
||||
SAFERELEASE(sound->pSeek);
|
||||
@@ -93,8 +93,8 @@ static void FreeSound(sDSSound* sound) {
|
||||
}
|
||||
|
||||
static void WipeSounds() {
|
||||
for (size_t i = 0; i < playingSounds.size(); i++) FreeSound(playingSounds[i]);
|
||||
for (size_t i = 0; i < loopingSounds.size(); i++) FreeSound(loopingSounds[i]);
|
||||
for (auto &sound : playingSounds) FreeSound(sound);
|
||||
for (auto &sound : loopingSounds) FreeSound(sound);
|
||||
playingSounds.clear();
|
||||
loopingSounds.clear();
|
||||
backgroundMusic = nullptr;
|
||||
@@ -105,33 +105,51 @@ static void WipeSounds() {
|
||||
}
|
||||
|
||||
LRESULT CALLBACK SoundWndProc(HWND wnd, UINT msg, WPARAM w, LPARAM l) {
|
||||
if (msg == WM_APP) {
|
||||
if (!(l & 0xA0000000)) return 0;
|
||||
sDSSound* sound = reinterpret_cast<sDSSound*>(l & ~0xA0000000);
|
||||
if (msg == WM_APP_DS_NOTIFY) {
|
||||
long id = l;
|
||||
sDSSound* sound = nullptr;
|
||||
size_t i;
|
||||
if (id & SoundFlags::looping) {
|
||||
for (i = 0; i < loopingSounds.size(); i++) {
|
||||
if (loopingSounds[i]->id == id) {
|
||||
sound = loopingSounds[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < playingSounds.size(); i++) {
|
||||
if (playingSounds[i]->id == id) {
|
||||
sound = playingSounds[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!sound || !sound->pEvent) return 0;
|
||||
|
||||
LONG e = 0;
|
||||
LONG_PTR p1 = 0, p2 = 0;
|
||||
if (!FAILED(sound->pEvent->GetEvent(&e, &p1, &p2, 0))) {
|
||||
bool shouldFree = false;
|
||||
|
||||
while (!FAILED(sound->pEvent->GetEvent(&e, &p1, &p2, 0))) {
|
||||
sound->pEvent->FreeEventParams(e, p1, p2);
|
||||
if (e == EC_COMPLETE) {
|
||||
if (sound->id & SoundFlags::looping) {
|
||||
LONGLONG pos = 0;
|
||||
sound->pSeek->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning);
|
||||
sound->pControl->Run();
|
||||
sound->pEvent->FreeEventParams(e, p1, p2);
|
||||
} else {
|
||||
sound->pEvent->FreeEventParams(e, p1, p2);
|
||||
if (sound->id & SoundFlags::on_stop) { // speech sound playback is completed
|
||||
fo::var::main_death_voiceover_done = 1;
|
||||
fo::var::endgame_subtitle_done = 1;
|
||||
lipsPlaying = false;
|
||||
speechSound = nullptr;
|
||||
}
|
||||
playingSounds.erase(
|
||||
std::find_if(playingSounds.cbegin(), playingSounds.cend(), [&](const sDSSound* snd) { return snd->id == sound->id; })
|
||||
);
|
||||
FreeSound(sound);
|
||||
playingSounds.erase(playingSounds.cbegin() + i);
|
||||
shouldFree = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shouldFree) FreeSound(sound);
|
||||
return 0;
|
||||
}
|
||||
return DefWindowProc(wnd, msg, w, l);
|
||||
@@ -170,22 +188,34 @@ static DWORD GetSpeechPlayingPosition() {
|
||||
return static_cast<DWORD>(pos << 1);
|
||||
}
|
||||
|
||||
void __fastcall PauseSfallSound(sDSSound* sound) {
|
||||
if (sound) sound->pControl->Pause();
|
||||
}
|
||||
//void __fastcall PauseSfallSound(sDSSound* sound) {
|
||||
// if (sound) sound->pControl->Pause();
|
||||
//}
|
||||
|
||||
void __fastcall ResumeSfallSound(sDSSound* sound) {
|
||||
if (sound) sound->pControl->Run();
|
||||
}
|
||||
|
||||
void __stdcall PauseAllSfallSound() {
|
||||
for (sDSSound* sound : loopingSounds) sound->pControl->Pause();
|
||||
for (sDSSound* sound : playingSounds) sound->pControl->Pause();
|
||||
for (sDSSound* sound : loopingSounds) {
|
||||
sound->pEvent->SetNotifyFlags(AM_MEDIAEVENT_NONOTIFY);
|
||||
sound->pControl->Pause();
|
||||
}
|
||||
for (sDSSound* sound : playingSounds) {
|
||||
sound->pEvent->SetNotifyFlags(AM_MEDIAEVENT_NONOTIFY);
|
||||
sound->pControl->Pause();
|
||||
}
|
||||
}
|
||||
|
||||
void __stdcall ResumeAllSfallSound() {
|
||||
for (sDSSound* sound : loopingSounds) sound->pControl->Run();
|
||||
for (sDSSound* sound : playingSounds) sound->pControl->Run();
|
||||
for (sDSSound* sound : loopingSounds) {
|
||||
sound->pEvent->SetNotifyFlags(0);
|
||||
sound->pControl->Run();
|
||||
}
|
||||
for (sDSSound* sound : playingSounds) {
|
||||
sound->pEvent->SetNotifyFlags(0);
|
||||
sound->pControl->Run();
|
||||
}
|
||||
}
|
||||
|
||||
long Sound::CalculateVolumeDB(long masterVolume, long passVolume) {
|
||||
@@ -301,7 +331,7 @@ static sDSSound* PlayingSound(const wchar_t* pathFile, SoundMode mode, long adju
|
||||
break;
|
||||
}
|
||||
|
||||
sound->pEvent->SetNotifyWindow((OAHWND)soundwindow, WM_APP, ((unsigned long)sound | 0xA0000000));
|
||||
sound->pEvent->SetNotifyWindow((OAHWND)soundwindow, WM_APP_DS_NOTIFY, (LONG_PTR)sound->id);
|
||||
sound->pControl->Run();
|
||||
|
||||
if (isLoop) {
|
||||
|
||||
@@ -562,7 +562,7 @@ bool Worldmap::LoadData(HANDLE file) {
|
||||
ReadFile(file, &mID, 4, &sizeRead, 0);
|
||||
ReadFile(file, &elevData, sizeof(levelRest), &sizeRead, 0);
|
||||
if (sizeRead != sizeof(levelRest)) return true;
|
||||
mapRestInfo.insert(std::make_pair(mID, elevData));
|
||||
mapRestInfo.emplace(mID, elevData);
|
||||
}
|
||||
if (count && !restMap) {
|
||||
HookCall(0x42E57A, critter_can_obj_dude_rest_hook);
|
||||
@@ -637,7 +637,7 @@ void Worldmap::SetRestMapLevel(int mapId, long elev, bool canRest) {
|
||||
elev++;
|
||||
}
|
||||
elevData.level[elev] = canRest;
|
||||
mapRestInfo.insert(std::make_pair(mapId, elevData));
|
||||
mapRestInfo.emplace(mapId, elevData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user