mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added support for ACM audio file playback to soundplay script function
(with volume control, #331) Added a volume control to reduce the volume for play_sfall_sound. Added descriptions and constant defines to documents. Some code optimization. Updated version number.
This commit is contained in:
+8
-8
@@ -1,5 +1,5 @@
|
||||
;sfall configuration settings
|
||||
;v4.2.7
|
||||
;v4.2.8
|
||||
|
||||
[Main]
|
||||
;Change to 1 if you want to use command line args to tell sfall to use another ini file.
|
||||
@@ -44,7 +44,7 @@ SpeedMulti9=900
|
||||
;The initial speed at game startup
|
||||
SpeedMultiInitial=100
|
||||
|
||||
;Set to 1 to also affect the playback speed of mve video files without an audio track
|
||||
;Set to 1 to also affect the playback speed of MVE video files without an audio track
|
||||
AffectPlayback=0
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
@@ -84,8 +84,8 @@ GPUBlt=0
|
||||
;Requires DX9 graphics mode and v2.0 pixel shader support (see GPUBlt option)
|
||||
Use32BitHeadGraphics=0
|
||||
|
||||
;Set to 1 to automatically search for alternative avi video files when Fallout tries to play the game movies
|
||||
;Set to 2 to force avi videos to fit the screen width
|
||||
;Set to 1 to automatically search for alternative AVI video files when Fallout tries to play the game movies
|
||||
;Set to 2 to force AVI videos to fit the screen width
|
||||
;Requires DX9 graphics mode
|
||||
AllowDShowMovies=0
|
||||
|
||||
@@ -128,8 +128,8 @@ NumSoundBuffers=0
|
||||
;Set to 1 to allow attaching sound files to combat float messages
|
||||
AllowSoundForFloats=0
|
||||
|
||||
;Set to 1 to automatically search for alternative formats (mp3/wma/wav) when Fallout tries to play an acm
|
||||
;Set to 2 to play alternative music files even if original acm files are not present in the music folder
|
||||
;Set to 1 to automatically search for alternative formats (mp3/wma/wav) when Fallout tries to play an ACM
|
||||
;Set to 2 to play alternative music files even if original ACM files are not present in the music folder
|
||||
;This does not effect the play_sfall_sound and stop_sfall_sound script functions
|
||||
AllowDShowSound=0
|
||||
|
||||
@@ -371,9 +371,9 @@ SaveInCombatFix=1
|
||||
;Player's level is capped once the highest specified level is reached
|
||||
;XPTable=50,100,200
|
||||
|
||||
;Set to 1 to enable additional weapon animation codes from o-t
|
||||
;Set to 1 to enable additional weapon animation codes from o to t
|
||||
;The 4 byte value at 0x39 of weapon protos may range from 0 to 15 rather than 0 to 10
|
||||
;Since the letters 'n' and 'r' are in use for other animations, an animation code of 11 corrisponds to 's' and 15 to 't'
|
||||
;Since the letters 'n' and 'r' are in use for other animations, an animation code of 11 corresponds to 's' and 15 to 't'
|
||||
AdditionalWeaponAnims=1
|
||||
|
||||
;Uncomment these lines to modify the default modifiers for aimed shots at specific bodyparts
|
||||
|
||||
@@ -458,4 +458,18 @@
|
||||
#define C_ATTACK_KNOCKBACK_VALUE5 (0xB0)
|
||||
#define C_ATTACK_KNOCKBACK_VALUE6 (0xB4)
|
||||
|
||||
/* Playback mode defines for the soundplay function */
|
||||
#define soundraw (0x80000000) // sfall flag
|
||||
#define Stereo8bit (soundstereo)
|
||||
#define Stereo8bitLoop (soundstereo bwor soundloop)
|
||||
#define Mono16bit (sound16bit)
|
||||
#define Mono16bitLoop (sound16bit bwor soundloop)
|
||||
#define Stereo16bit (soundstereo bwor sound16bit)
|
||||
#define Stereo16bitLoop (soundstereo bwor sound16bit bwor soundloop)
|
||||
|
||||
// Volume reduction: 0x0000XXXX - min, 0x7FFFXXXX - mute
|
||||
#define SoundVolume25 (0x20000000)
|
||||
#define SoundVolumeHalf (0x40000000)
|
||||
#define SoundVolume75 (0x60000000)
|
||||
|
||||
#endif // DEFINE_EXTRA_H
|
||||
|
||||
@@ -67,6 +67,7 @@ get/set_proto_data are used to manipulate the in memory copies of the .pro files
|
||||
the list_xxx functions can be used to loop over all items on a map. list_begin takes an argument telling sfall what you want to list. (Defined in sfall.h) It returns a list pointer, which you iterate through with list_next. Finally, when you've finished with the list use list_end on it. Not calling list_end will result in a memory leak. Alternatively, use list_as_array to get the whole list at once as a temp array variable, which can be looped over using len_array and which you don't need to remember to free afterwards.
|
||||
|
||||
play_sfall_sound and stop_sfall_sound are used to play mp3/wav/wma files. The path given is relative to the Fallout folder. Specify mode as 1 to loop the file continuously, 2 to replace the current background game music with playing the specified file in loop mode, or 0 to play the file once. If you don't wish to loop, play_sfall_sound returns 0. If you do loop, it returns an id which can be passed back to stop_sfall_sound when you want to stop the effect. All sounds effects will be stopped on game reload, looping or not. These functions do not require 'AllowDShowSound' to be set to 1 in ddraw.ini.
|
||||
Starting from sfall 4.2.8/3.8.28, you can pass a value in range from 0 to 32767 in the 'mode' argument for a reduced sound volume; the value 32767 is the minimum volume (mute). To set the volume, You need to convert the number to hexadecimal and use the argument format 0xZZZZ000Y, where ZZZZ is the volume value, and Y is the playback mode.
|
||||
|
||||
arrays are created and manipulated with the xxx_array functions. An array must first be created with create_array or temp_array, specifying how many data elements the array can hold. You can store any of ints, floats and strings in an array, and can mix all 3 in a single array. The id returned by create/temp_array can then be used with the other array functions. Arrays are shared between all scripts. (i.e. you can call create_array from one script, and then use the returned id from another script.) They are also saved across savegames. You must remember to free any arrays you create with create_array when you are done with them, or you will leak memory. arrays created with temp_array will be automatically freed at the end of the frame. These functions are safe, in that supplying a bad id or trying to access out of range elements will not crash the script. create_array is the only function that returns a permanent array, all other functions which return arrays (string_split, list_as_array etc,) all return temp arrays. You can use fix_array to make a temp array permanent.
|
||||
|
||||
|
||||
@@ -221,6 +221,7 @@
|
||||
#define FO_VAR_retvals 0x43EA7C
|
||||
#define FO_VAR_rotation 0x631D34
|
||||
#define FO_VAR_sad 0x530014
|
||||
#define FO_VAR_sampleRate 0x66815C
|
||||
#define FO_VAR_scr_size 0x6AC9F0
|
||||
#define FO_VAR_script_engine_running 0x51C714
|
||||
#define FO_VAR_script_path_base 0x51C710
|
||||
|
||||
@@ -176,8 +176,9 @@ VAR_(queue, DWORD)
|
||||
VAR_(quick_done, DWORD)
|
||||
VAR_(read_callback, DWORD)
|
||||
VAR_(RedColor, BYTE)
|
||||
VAR_(rotation, DWORD)
|
||||
VAR2(retvals, fo::ElevatorExit, 24, 4) // 24 elevators, 4 exits each
|
||||
VAR_(rotation, DWORD)
|
||||
VAR_(sampleRate, DWORD)
|
||||
VAR_(script_path_base, const char*)
|
||||
VAR_(scr_size, fo::BoundRect)
|
||||
VAR_(scriptListInfo, fo::ScriptListInfoItem*) // dynamic array
|
||||
|
||||
@@ -3492,9 +3492,9 @@ void BugFixes::init()
|
||||
HookCall(0x481409, main_death_scene_hook);
|
||||
|
||||
// Fix for trying to loot corpses with the "NoSteal" flag
|
||||
MakeCall(0x4123F8, action_loot_container_hack, 1);
|
||||
SafeWrite8(0x4123F2, CommonObj::protoId);
|
||||
BlockCall(0x4123F3);
|
||||
MakeCall(0x4123F8, action_loot_container_hack, 1);
|
||||
|
||||
// Fix the music volume when entering the dialog
|
||||
SafeWrite32(0x44525D, (DWORD)FO_VAR_background_volume);
|
||||
|
||||
@@ -527,8 +527,7 @@ static void OverrideMusicDirPatch() {
|
||||
SafeWriteBatch<DWORD>((DWORD)musicOverridePath, {0x4449C2, 0x4449DB}); // set paths if not present in the cfg
|
||||
if (overrideMode == 2) {
|
||||
SafeWriteBatch<DWORD>((DWORD)musicOverridePath, {0x518E78, 0x518E7C});
|
||||
__int64 data = 0x90909040EB; // jmp 0x44FD35 (skip paths initialization)
|
||||
SafeWriteBytes(0x44FCF3, (BYTE*)&data, 5);
|
||||
SafeWrite16(0x44FCF3, 0x40EB); // jmp 0x44FD35 (skip paths initialization)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+81
-47
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
//#include <unordered_map>
|
||||
#include <algorithm>
|
||||
#include <dshow.h>
|
||||
|
||||
#include "..\main.h"
|
||||
@@ -103,44 +104,29 @@ static void WipeSounds() {
|
||||
|
||||
LRESULT CALLBACK SoundWndProc(HWND wnd, UINT msg, WPARAM w, LPARAM l) {
|
||||
if (msg == WM_APP) {
|
||||
DWORD id = l;
|
||||
sDSSound* sound = nullptr;
|
||||
long index = -1;
|
||||
if (id & SoundFlags::looping) {
|
||||
for (size_t i = 0; i < loopingSounds.size(); i++) {
|
||||
if (loopingSounds[i]->id == id) {
|
||||
sound = loopingSounds[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0; i < playingSounds.size(); i++) {
|
||||
if (playingSounds[i]->id == id) {
|
||||
sound = playingSounds[i];
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(l & 0xA0000000)) return 0;
|
||||
sDSSound* sound = reinterpret_cast<sDSSound*>(l & ~0xA0000000);
|
||||
LONG e = 0;
|
||||
LONG_PTR p1 = 0, p2 = 0;
|
||||
if (sound && !FAILED(sound->pEvent->GetEvent(&e, &p1, &p2, 0))) {
|
||||
sound->pEvent->FreeEventParams(e, p1, p2);
|
||||
if (!FAILED(sound->pEvent->GetEvent(&e, &p1, &p2, 0))) {
|
||||
if (e == EC_COMPLETE) {
|
||||
if (id & SoundFlags::looping) {
|
||||
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 {
|
||||
FreeSound(sound);
|
||||
playingSounds.erase(playingSounds.begin() + index);
|
||||
if (id & SoundFlags::on_stop) { // speech sound playback is completed
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,7 +136,7 @@ LRESULT CALLBACK SoundWndProc(HWND wnd, UINT msg, WPARAM w, LPARAM l) {
|
||||
}
|
||||
|
||||
static void CreateSndWnd() {
|
||||
dlog("Creating sfall sound callback windows.", DL_INIT);
|
||||
dlog("Creating sfall sound callback window.", DL_INIT);
|
||||
if (Graphics::mode == 0) CoInitialize(0);
|
||||
|
||||
WNDCLASSEX wcx;
|
||||
@@ -162,7 +148,7 @@ static void CreateSndWnd() {
|
||||
wcx.lpszClassName = "sfallSndWnd";
|
||||
|
||||
RegisterClassEx(&wcx);
|
||||
soundwindow = CreateWindow("sfallSndWnd", "SndWnd", 0, 0, 0, 0, 0, HWND_MESSAGE, 0, GetModuleHandleA(0), 0);
|
||||
soundwindow = CreateWindowA("sfallSndWnd", "SndWnd", 0, 0, 0, 0, 0, HWND_MESSAGE, 0, wcx.hInstance, 0);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
@@ -204,12 +190,11 @@ long Sound::CalculateVolumeDB(long masterVolume, long passVolume) {
|
||||
if (masterVolume <= 0 || passVolume <= 0) return -9999; // mute
|
||||
|
||||
const int volOffset = -100; // adjust the maximum volume
|
||||
const int minVolume = -2048;
|
||||
const int minVolume = -2100;
|
||||
|
||||
float multiply = (32767.0f / masterVolume);
|
||||
float volume = (((float)passVolume / 32767.0f) * 100.0f) / multiply; // calculate %
|
||||
volume = (minVolume * volume) / 100.0f;
|
||||
return static_cast<long>(minVolume - volume) + volOffset;
|
||||
passVolume = masterVolume * passVolume / 32767;
|
||||
long volume = static_cast<long>(minVolume * ((float)passVolume / 32767.0f)); // calculate % value
|
||||
return (minVolume - volume) + volOffset;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -218,7 +203,7 @@ long Sound::CalculateVolumeDB(long masterVolume, long passVolume) {
|
||||
sfx_volume: sound=null type=game_sfx passVolume=sndfx_volume
|
||||
speech_volume: sound=sound type=sfx_single passVolume=speech_volume
|
||||
*/
|
||||
static void __cdecl SfallSoundVolume(sDSSound* sound, SoundType type, long passVolume) {
|
||||
static void __cdecl SetSoundVolume(sDSSound* sound, SoundType type, long passVolume) {
|
||||
long volume, sfxVolume, masterVolume = fo::var::master_volume;
|
||||
|
||||
volume = Sound::CalculateVolumeDB(masterVolume, passVolume);
|
||||
@@ -266,7 +251,7 @@ static bool IsMute(SoundMode mode) {
|
||||
music_play: mode 2 - loop sound playback with the background game music turned off
|
||||
speech_play: mode 3 -
|
||||
*/
|
||||
static sDSSound* PlayingSound(const wchar_t* pathFile, SoundMode mode, bool isPaused = false) {
|
||||
static sDSSound* PlayingSound(const wchar_t* pathFile, SoundMode mode, long adjustVolume = 0, bool isPaused = false) {
|
||||
if (!soundwindow) CreateSndWnd();
|
||||
|
||||
if (IsMute(mode)) return nullptr;
|
||||
@@ -293,7 +278,11 @@ static sDSSound* PlayingSound(const wchar_t* pathFile, SoundMode mode, bool isPa
|
||||
sound->id = (isLoop) ? ++loopID : ++playID;
|
||||
if (isLoop) sound->id |= SoundFlags::looping; // sfx loop sound
|
||||
|
||||
if (mode == SoundMode::music_play) {
|
||||
switch (mode) {
|
||||
case SoundMode::engine_music_play:
|
||||
sound->id |= SoundFlags::engine; // engine play
|
||||
break;
|
||||
case SoundMode::music_play:
|
||||
sound->id |= SoundFlags::restore; // restore background game music on stop
|
||||
if (backgroundMusic)
|
||||
Sound::StopSfallSound(backgroundMusic->id);
|
||||
@@ -301,19 +290,21 @@ static sDSSound* PlayingSound(const wchar_t* pathFile, SoundMode mode, bool isPa
|
||||
__asm call fo::funcoffs::gsound_background_stop_;
|
||||
}
|
||||
backgroundMusic = sound;
|
||||
break;
|
||||
case SoundMode::speech_play:
|
||||
sound->pSeek->SetTimeFormat(&TIME_FORMAT_SAMPLE);
|
||||
sound->id |= SoundFlags::on_stop;
|
||||
break;
|
||||
}
|
||||
else if (mode == SoundMode::engine_music_play) sound->id |= SoundFlags::engine; // engine play
|
||||
else if (mode == SoundMode::speech_play) sound->id |= SoundFlags::on_stop;
|
||||
|
||||
if (sound->pSeek) sound->pSeek->SetTimeFormat(&TIME_FORMAT_SAMPLE);
|
||||
sound->pEvent->SetNotifyWindow((OAHWND)soundwindow, WM_APP, sound->id);
|
||||
sound->pEvent->SetNotifyWindow((OAHWND)soundwindow, WM_APP, ((unsigned long)sound | 0xA0000000));
|
||||
sound->pControl->Run();
|
||||
|
||||
if (isLoop) {
|
||||
SfallSoundVolume(sound, SoundType::sfx_loop, (mode == SoundMode::loop_play) ? fo::var::sndfx_volume : fo::var::background_volume);
|
||||
SetSoundVolume(sound, SoundType::sfx_loop, ((mode == SoundMode::loop_play) ? fo::var::sndfx_volume : fo::var::background_volume) - adjustVolume);
|
||||
loopingSounds.push_back(sound);
|
||||
} else {
|
||||
SfallSoundVolume(sound, SoundType::sfx_single, (mode == SoundMode::speech_play) ? fo::var::speech_volume : fo::var::sndfx_volume);
|
||||
SetSoundVolume(sound, SoundType::sfx_single, ((mode == SoundMode::speech_play) ? fo::var::speech_volume : fo::var::sndfx_volume) - adjustVolume);
|
||||
if (mode == SoundMode::speech_play) speechSound = sound;
|
||||
if (isPaused) {
|
||||
sound->pControl->Pause(); // for delayed playback
|
||||
@@ -392,7 +383,7 @@ static bool __fastcall SoundFileLoad(PlayType playType, const char* path) {
|
||||
backgroundMusic = PlayingSound(buf, SoundMode::engine_music_play); // background music loop
|
||||
if (!backgroundMusic) return false;
|
||||
} else {
|
||||
if (!PlayingSound(buf, ((playType >= PlayType::lips) ? SoundMode::speech_play : SoundMode::single_play), (playType == PlayType::slides))) {
|
||||
if (!PlayingSound(buf, ((playType >= PlayType::lips) ? SoundMode::speech_play : SoundMode::single_play), 0, (playType == PlayType::slides))) {
|
||||
return false;
|
||||
}
|
||||
if (playType == PlayType::lips) {
|
||||
@@ -427,8 +418,11 @@ DWORD Sound::PlaySfallSound(const char* path, long mode) {
|
||||
if (len <= 3 || len >= MAX_PATH) return 0;
|
||||
buf[len] = L'\0';
|
||||
|
||||
short volAdjust = (mode & 0x7FFF0000) >> 16;
|
||||
mode &= 0xF;
|
||||
if (mode > SoundMode::music_play) mode = SoundMode::music_play;
|
||||
sDSSound* sound = PlayingSound(buf, (SoundMode)mode);
|
||||
sDSSound* sound = PlayingSound(buf, (SoundMode)mode, volAdjust);
|
||||
|
||||
return (mode && sound) ? sound->id : 0;
|
||||
}
|
||||
|
||||
@@ -710,7 +704,7 @@ static void __declspec(naked) gsound_background_volume_set_hack() {
|
||||
push eax;
|
||||
push 0; // SoundType::sfx_loop
|
||||
push ecx; // set volume for background music
|
||||
call SfallSoundVolume;
|
||||
call SetSoundVolume;
|
||||
add esp, 8;
|
||||
pop eax;
|
||||
pop edx;
|
||||
@@ -729,7 +723,7 @@ static void __declspec(naked) gsound_master_volume_set_hack() {
|
||||
push dword ptr ds:[FO_VAR_background_volume];
|
||||
push 3; // SoundType::game_master
|
||||
push 0; // set volume for all sounds
|
||||
call SfallSoundVolume;
|
||||
call SetSoundVolume;
|
||||
add esp, 12;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
@@ -746,7 +740,7 @@ static void __declspec(naked) gsound_set_sfx_volume_hack() {
|
||||
push eax;
|
||||
push 2; // SoundType::game_sfx
|
||||
push 0; // set volume for all sounds
|
||||
call SfallSoundVolume;
|
||||
call SetSoundVolume;
|
||||
add esp, 12;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
@@ -819,7 +813,44 @@ end:
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) soundStartInterpret_hook() {
|
||||
__asm {
|
||||
mov ebp, eax; // keep sound data
|
||||
call fo::funcoffs::soundSetCallback_;
|
||||
xor ebx, ebx;
|
||||
mov eax, [esp + 0x18 - 0x18 + 4]; // play mode flags
|
||||
and eax, 0x80000000; // check raw format flag (for backward compatibility mode)
|
||||
jnz rawFile;
|
||||
push ecx;
|
||||
push fo::funcoffs::audioFileSize_;
|
||||
mov ecx, fo::funcoffs::audioRead_;
|
||||
push eax;
|
||||
mov ebx, fo::funcoffs::audioCloseFile_;
|
||||
push fo::funcoffs::audioSeek_;
|
||||
mov edx, fo::funcoffs::audioOpen_;
|
||||
push eax;
|
||||
mov eax, ebp;
|
||||
call fo::funcoffs::soundSetFileIO_;
|
||||
pop ecx;
|
||||
mov bx, [esp + 0x18 - 0x18 + 4+2]; // get volume adjustment: 0 - max, 32767 - mute
|
||||
and bx, ~0x8000;
|
||||
rawFile:
|
||||
xor edx, edx;
|
||||
mov eax, ds:[FO_VAR_sndfx_volume];
|
||||
sub ax, bx; // reduce volume
|
||||
cmovg edx, eax; // volume > 0
|
||||
mov eax, ebp;
|
||||
jmp fo::funcoffs::soundVolume_; // set sfx volume
|
||||
}
|
||||
}
|
||||
|
||||
constexpr int SampleRate = 44100; // 44.1kHz
|
||||
|
||||
void Sound::init() {
|
||||
// Set the sample rate for the primary sound buffer
|
||||
//SafeWrite32(0x44FDBC, SampleRate);
|
||||
//LoadGameHook::OnAfterGameInit() += []() { fo::var::sampleRate = SampleRate / 2; }; // Revert to 22kHz for secondary sound buffers
|
||||
|
||||
LoadGameHook::OnGameReset() += WipeSounds;
|
||||
LoadGameHook::OnBeforeGameClose() += WipeSounds;
|
||||
|
||||
@@ -874,6 +905,9 @@ void Sound::init() {
|
||||
SafeWrite8(0x42B6F5, CodeType::JumpShort); // bypass chance
|
||||
}
|
||||
}
|
||||
|
||||
// Support for ACM audio file playback and volume adjustment for the soundplay script function
|
||||
HookCall(0x4661B3, soundStartInterpret_hook);
|
||||
}
|
||||
|
||||
void Sound::exit() {
|
||||
|
||||
+3
-4
@@ -136,10 +136,9 @@ void SafeMemSet(DWORD addr, BYTE val, int len) {
|
||||
void BlockCall(DWORD addr) {
|
||||
DWORD oldProtect;
|
||||
|
||||
VirtualProtect((void *)addr, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((DWORD*)addr) = 0x00441F0F; // long NOP (0F1F440000)
|
||||
*((BYTE*)(addr + 4)) = 0x00;
|
||||
VirtualProtect((void *)addr, 5, oldProtect, &oldProtect);
|
||||
VirtualProtect((void*)addr, 4, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((DWORD*)addr) = 0x00441F0F; // long NOP (0F1F4400-XX)
|
||||
VirtualProtect((void*)addr, 4, oldProtect, &oldProtect);
|
||||
|
||||
CheckConflict(addr, 5);
|
||||
}
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@
|
||||
|
||||
#define VERSION_MAJOR 4
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_BUILD 7
|
||||
#define VERSION_BUILD 8
|
||||
#define VERSION_REV 0
|
||||
|
||||
#define VERSION_STRING "4.2.7"
|
||||
#define VERSION_STRING "4.2.8"
|
||||
|
||||
Reference in New Issue
Block a user