From 9d34a4c70add053d9930ada40ae117a36db09a71 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Sat, 3 Oct 2020 21:01:54 +0800 Subject: [PATCH] Added support for transparent interface windows (#25) --- artifacts/scripting/headers/define_extra.h | 7 +- sfall/Define.h | 2 +- sfall/FalloutEngine.cpp | 83 ++++++++-- sfall/FalloutEngine.h | 26 ++- sfall/FalloutFuncs_def.h | 4 +- sfall/FalloutStructs.h | 12 +- sfall/Graphics.cpp | 182 ++++++++++++++++++++- sfall/ScriptOps/InterfaceOps.hpp | 2 +- sfall/Sound.cpp | 2 +- 9 files changed, 286 insertions(+), 34 deletions(-) diff --git a/artifacts/scripting/headers/define_extra.h b/artifacts/scripting/headers/define_extra.h index 56935c7a..ce67aa67 100644 --- a/artifacts/scripting/headers/define_extra.h +++ b/artifacts/scripting/headers/define_extra.h @@ -105,10 +105,11 @@ #define CFLG_NOKNOCKDOWN CFLG_NOKNOCKBACK // obsolete /* Window flags */ -#define WIN_FLAG_MOVEONTOP (0x4) -#define WIN_FLAG_HIDDEN (0x8) +#define WIN_FLAG_DONTMOVE (0x2) // does not move the window to the foreground when clicking on the window +#define WIN_FLAG_MOVEONTOP (0x4) // places the window on top of other windows +#define WIN_FLAG_HIDDEN (0x8) // hidden window #define WIN_FLAG_EXCLUSIVE (0x10) -#define WIN_FLAG_TRANSPARENT (0x20) +#define WIN_FLAG_TRANSPARENT (0x20) // transparent window flag, the window color with index 0 will be transparent /* Message window flags */ #define MSGBOX_AUTOSIZE (0x0) diff --git a/sfall/Define.h b/sfall/Define.h index b3e6c069..b4bdd532 100644 --- a/sfall/Define.h +++ b/sfall/Define.h @@ -701,7 +701,7 @@ namespace WinFlags { enum WinButtonFlags : long { OwnerFlag = 0x1, - UnknownFlag2 = 0x2, + DontMoveTop = 0x2, MoveOnTop = 0x4, Hidden = 0x8, Exclusive = 0x10, diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index 68d770c8..dec18634 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -187,6 +187,7 @@ DWORD* ptr_pud = reinterpret_cast(_pud); DWORD* ptr_queue = reinterpret_cast(_queue); DWORD* ptr_quick_done = reinterpret_cast(_quick_done); DWORD* ptr_read_callback = reinterpret_cast(_read_callback); +RectList** ptr_rectList = reinterpret_cast(_rectList); BYTE* ptr_RedColor = reinterpret_cast(_RedColor); DWORD* ptr_retvals = reinterpret_cast(_retvals); DWORD* ptr_rotation = reinterpret_cast(_rotation); @@ -444,6 +445,7 @@ const DWORD gmouse_is_scrolling_ = 0x44B54C; const DWORD gmouse_set_cursor_ = 0x44C840; const DWORD gmovie_play_ = 0x44E690; const DWORD gmovieIsPlaying_ = 0x44EB14; +const DWORD GNW_button_refresh_ = 0x4D9A58; const DWORD GNW_do_bk_process_ = 0x4C8D1C; const DWORD GNW_find_ = 0x4D7888; const DWORD GNW_win_refresh_ = 0x4D6FD8; @@ -580,6 +582,7 @@ const DWORD message_make_path_ = 0x484CB8; const DWORD message_search_ = 0x484C30; const DWORD mouse_click_in_ = 0x4CA934; const DWORD mouse_get_position_ = 0x4CA9DC; +const DWORD mouse_get_rect_ = 0x4CA9A0; const DWORD mouse_hide_ = 0x4CA534; const DWORD mouse_in_ = 0x4CA8C8; const DWORD mouse_show_ = 0x4CA34C; @@ -676,6 +679,9 @@ const DWORD queue_find_next_ = 0x4A2994; const DWORD queue_leaving_map_ = 0x4A2920; const DWORD queue_next_time_ = 0x4A2808; const DWORD queue_remove_this_ = 0x4A264C; +const DWORD rect_clip_ = 0x4C6AAC; +const DWORD rect_malloc_ = 0x4C6BB8; +const DWORD refresh_all_ = 0x4D7814; const DWORD refresh_box_bar_win_ = 0x4614CC; const DWORD register_begin_ = 0x413AF4; const DWORD register_clear_ = 0x413C4C; @@ -770,6 +776,7 @@ const DWORD trans_cscale_ = 0x4D3560; const DWORD use_inventory_on_ = 0x4717E4; const DWORD _word_wrap_ = 0x4BC6F0; const DWORD win_add_ = 0x4D6238; +const DWORD win_clip_ = 0x4D75B0; const DWORD win_delete_ = 0x4D6468; const DWORD win_disable_button_ = 0x4D94D0; const DWORD win_draw_ = 0x4D6F5C; @@ -1063,7 +1070,7 @@ void __fastcall WindowTransCscale(long i_width, long i_height, long s_width, lon } // buf_to_buf_ function with pure MMX implementation -void __cdecl BufToBuf(void* src, long width, long height, long src_width, void* dst, long dst_width) { +void __cdecl BufToBuf(BYTE* src, long width, long height, long src_width, BYTE* dst, long dst_width) { if (height <= 0 || width <= 0) return; size_t blockCount = width / 64; // 64 bytes @@ -1128,6 +1135,57 @@ end: } } +// trans_buf_to_buf_ function implementation +void __cdecl TransBufToBuf(BYTE* src, long width, long height, long src_width, BYTE* dst, long dst_width) { + if (height <= 0 || width <= 0) return; + + size_t blockCount = width / 8; + size_t lastBytes = width % 8; + size_t s_pitch = src_width - width; + size_t d_pitch = dst_width - width; + + __asm { + mov esi, src; + mov edi, dst; + pxor mm3, mm3; + } + do { + size_t count = blockCount; + while (count--) { + __asm { + movq mm0, qword ptr [esi]; // 8 bytes + movq mm1, qword ptr [edi]; + movq mm2, mm0; // src copy to mm2 + pcmpeqb mm2, mm3; // mm2 = (src == 0) ? 1 : 0; + lea esi, [esi + 8]; + movq mm4, mm2; + pandn mm2, mm0; // mm2 = mm2 AND (NOT mm0) + pand mm4, mm1; + por mm2, mm4; + movq qword ptr [edi], mm2; + lea edi, [edi + 8]; + } + } + size_t bytes = lastBytes; + while (bytes--) { + __asm { + mov al, [esi]; + lea esi, [esi + 1]; + test al, al; + jz skip; + mov [edi], al; + skip: + lea edi, [edi + 1]; + } + } + __asm { + add esi, s_pitch; + add edi, d_pitch; + } + } while (--height); + __asm emms; +} + long __fastcall GetGameConfigString(const char* outValue, const char* section, const char* param) { __asm { mov ebx, param; @@ -1472,22 +1530,15 @@ void DrawToSurface(long width, long height, long fromX, long fromY, long fromWid } } -// Fills the specified non-scripted interface window with black color -void ClearWindow(DWORD winID, bool refresh) { - __asm { - xor ebx, ebx; - push ebx; - mov eax, winID; - call win_height_; - push eax; - mov eax, winID; - call win_width_; - mov ecx, eax; - mov edx, ebx; - mov eax, winID; - call win_fill_; +// Fills the specified non-scripted interface window with index color 0 (black color) +void ClearWindow(long winID, bool refresh) { + WINinfo* win = GNWFind(winID); + for (long i = 0; i < win->height; i++) { + std::memset(win->surface, 0, win->width); + } + if (refresh) { + GNWWinRefresh(win, &win->rect, 0); } - if (refresh) WinDraw(winID); } //--------------------------------------------------------- diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index 51562398..a3b6ae71 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -234,12 +234,15 @@ #define _queue 0x6648C0 #define _quick_done 0x5193BC #define _read_callback 0x51DEEC +#define _rectList 0x51DEF4 #define _retvals 0x43EA7C #define _rm_FrameCount 0x6B36A8 #define _rotation 0x631D34 #define _sad 0x530014 #define _sampleRate 0x66815C +#define _scr_blit 0x6ACA18 #define _scr_size 0x6AC9F0 +#define _screen_buffer 0x51E3FC #define _script_engine_running 0x51C714 #define _scriptListInfo 0x51C7C8 #define _skill_data 0x51D118 @@ -486,6 +489,7 @@ extern DWORD* ptr_pud; extern DWORD* ptr_queue; extern DWORD* ptr_quick_done; extern DWORD* ptr_read_callback; +extern RectList** ptr_rectList; extern BYTE* ptr_RedColor; extern DWORD* ptr_retvals; extern DWORD* ptr_rotation; @@ -726,6 +730,7 @@ extern const DWORD gmouse_is_scrolling_; extern const DWORD gmouse_set_cursor_; extern const DWORD gmovie_play_; extern const DWORD gmovieIsPlaying_; +extern const DWORD GNW_button_refresh_; extern const DWORD GNW_do_bk_process_; extern const DWORD GNW_find_; extern const DWORD GNW_win_refresh_; @@ -868,6 +873,7 @@ extern const DWORD message_make_path_; extern const DWORD message_search_; extern const DWORD mouse_click_in_; extern const DWORD mouse_get_position_; +extern const DWORD mouse_get_rect_; extern const DWORD mouse_hide_; extern const DWORD mouse_in_; extern const DWORD mouse_show_; @@ -967,6 +973,9 @@ extern const DWORD queue_find_next_; extern const DWORD queue_leaving_map_; extern const DWORD queue_next_time_; extern const DWORD queue_remove_this_; +extern const DWORD rect_clip_; +extern const DWORD rect_malloc_; +extern const DWORD refresh_all_; extern const DWORD refresh_box_bar_win_; extern const DWORD register_begin_; extern const DWORD register_clear_; @@ -1061,6 +1070,7 @@ extern const DWORD trans_cscale_; extern const DWORD use_inventory_on_; extern const DWORD _word_wrap_; extern const DWORD win_add_; +extern const DWORD win_clip_; extern const DWORD win_delete_; extern const DWORD win_disable_button_; extern const DWORD win_draw_; @@ -1175,7 +1185,10 @@ void __fastcall DisplayInWindow(long w_here, long width, long height, void* data void __fastcall WindowTransCscale(long i_width, long i_height, long s_width, long s_height, long xy_shift, long w_width, void* data); // buf_to_buf_ function with pure MMX implementation -void __cdecl BufToBuf(void* src, long width, long height, long src_width, void* dst, long dst_width); +void __cdecl BufToBuf(BYTE* src, long width, long height, long src_width, BYTE* dst, long dst_width); + +// trans_buf_to_buf_ function implementation +void __cdecl TransBufToBuf(BYTE* src, long width, long height, long src_width, BYTE* dst, long dst_width); long __fastcall GetGameConfigString(const char* outValue, const char* section, const char* param); @@ -1248,6 +1261,13 @@ long __fastcall GetGameConfigString(const char* outValue, const char* section, c ///////////////////////////////// ENGINE UTILS ///////////////////////////////// +// rect_free_ function for inline implementation +__forceinline void sf_rect_free(RectList* rect) { + RectList* front = *ptr_rectList; + *ptr_rectList = rect; + rect->nextRect = front; +} + // returns message string from given file or "Error" when not found const char* GetMessageStr(const MSGList* fileAddr, long messageId); @@ -1302,8 +1322,8 @@ void DrawToSurface(long width, long height, long fromX, long fromY, long fromWid void DrawToSurface(long width, long height, long fromX, long fromY, long fromWidth, BYTE* fromSurf, long toX, long toY, long toWidth, long toHeight, BYTE* toSurf); -// Fills the specified non-scripted interface window with black color -void ClearWindow(DWORD winID, bool refresh = true); +// Fills the specified non-scripted interface window with index color 0 (black color) +void ClearWindow(long winID, bool refresh = true); // Print text to surface void __stdcall PrintText(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface); diff --git a/sfall/FalloutFuncs_def.h b/sfall/FalloutFuncs_def.h index 47cea18a..e9591cc7 100644 --- a/sfall/FalloutFuncs_def.h +++ b/sfall/FalloutFuncs_def.h @@ -34,7 +34,8 @@ WRAP_WATCOM_FFUNC3(long, ItemAddForce, item_add_force_, TGameObj*, critter, TGam WRAP_WATCOM_FFUNC3(long, ItemWMpCost, item_w_mp_cost_, TGameObj*, source, long, hitMode, long, isCalled) WRAP_WATCOM_FFUNC7(void, MakeStraightPathFunc, make_straight_path_func_, TGameObj*, objFrom, DWORD, tileFrom, DWORD, tileTo, void*, rotationPtr, DWORD*, result, long, flags, void*, func) WRAP_WATCOM_FFUNC3(long, MessageFind, message_find_, DWORD*, msgFile, long, msgNumber, DWORD*, outBuf) -WRAP_WATCOM_FFUNC4(long, MouseClickIn, mouse_click_in_, long, x, long, y, long, x_end, long, y_end) +WRAP_WATCOM_FFUNC4(long, MouseClickIn, mouse_click_in_, long, x, long, y, long, x_offs, long, y_offs) +WRAP_WATCOM_FFUNC4(long, MouseIn, mouse_in_, long, x, long, y, long, x_offs, long, y_offs) WRAP_WATCOM_FFUNC3(TGameObj*, ObjBlockingAt, obj_blocking_at_, TGameObj*, object, long, tile, long, elevation) WRAP_WATCOM_FFUNC3(long, ObjNewSidInst, obj_new_sid_inst_, TGameObj*, object, long, sType, long, scriptIndex) WRAP_WATCOM_FFUNC3(long, ObjectUnderMouse, object_under_mouse_, long, crSwitch, long, inclDude, long, elevation) @@ -43,6 +44,7 @@ WRAP_WATCOM_FFUNC3(long, ScrGetLocalVar, scr_get_local_var_, long, sid, long, va WRAP_WATCOM_FFUNC3(long, ScrSetLocalVar, scr_set_local_var_, long, sid, long, varId, long, value) WRAP_WATCOM_FFUNC3(long, TileNumInDirection, tile_num_in_direction_, long, tile, long, rotation, long, distance) WRAP_WATCOM_FFUNC8(void, TransCscale, trans_cscale_, void*, fromBuff, long, width, long, height, long, pitch, void*, toBuff, long, toWidth, long, toHeight, long, toPitch) +WRAP_WATCOM_FFUNC3(void, WinClip, win_clip_, WINinfo*, window, RectList**, rects, void*, buffer) WRAP_WATCOM_FFUNC3(const char*, InterpretGetString, interpretGetString_, TProgram*, scriptPtr, DWORD, dataType, DWORD, strId) diff --git a/sfall/FalloutStructs.h b/sfall/FalloutStructs.h index 33e9034d..b79ddd8f 100644 --- a/sfall/FalloutStructs.h +++ b/sfall/FalloutStructs.h @@ -42,10 +42,18 @@ struct sArt { struct BoundRect { long x; long y; - long offx; // left + long offx; // right long offy; // bottom }; +struct RectList { + union { + BoundRect rect; + RECT wRect; + }; + RectList* nextRect; +}; + // Game objects (items, critters, etc.), including those stored in inventories. struct TGameObj { long id; @@ -285,7 +293,7 @@ struct FrmFile { // sizeof 2954 long oriFrameOffset[6]; // 0x22 long frameAreaSize; // 0x3A union { - FrmFrameData* const frameData; + FrmFrameData* frameData; struct { short width; // 0x3E short height; // 0x40 diff --git a/sfall/Graphics.cpp b/sfall/Graphics.cpp index f04cdf08..e198bb1d 100644 --- a/sfall/Graphics.cpp +++ b/sfall/Graphics.cpp @@ -30,7 +30,7 @@ typedef HRESULT (__stdcall *DDrawCreateProc)(void*, IDirectDraw**, void*); //typedef IDirect3D9* (__stdcall *D3DCreateProc)(UINT version); -static IDirectDrawSurface* primaryDDSurface = nullptr; +static IDirectDrawSurface* primaryDDSurface = nullptr; // aka _GNW95_DDPrimarySurface static DWORD ResWidth; static DWORD ResHeight; @@ -781,7 +781,7 @@ public: int pitch = dRect.Pitch; if (GPUBlt) { - BufToBuf(lockTarget, width, mveDesc.dwHeight, width, dRect.pBits, pitch); + BufToBuf(lockTarget, width, mveDesc.dwHeight, width, (BYTE*)dRect.pBits, pitch); //char* pBits = (char*)dRect.pBits; //for (DWORD y = 0; y < mveDesc.dwHeight; y++) { // CopyMemory(&pBits[y * pitch], &lockTarget[y * width], width); @@ -867,7 +867,7 @@ public: if (isPrimary) { if (GPUBlt) { D3DLOCKED_RECT buf; - HRESULT hr = mainTex->LockRect(0, &buf, 0, 0); + HRESULT hr = mainTex->LockRect(0, &buf, a, 0); if (hr) goto surface; // lock failed, use old method mainTexLock = true; @@ -1233,9 +1233,9 @@ HRESULT __stdcall FakeDirectDrawCreate2(void*, IDirectDraw** b, void*) { float hScale = (float)gHeight / ResHeight; if (wScale == 1.0f && hScale == 1.0f) textureFilter = 0; // disable texture filtering if the set resolutions are equal if (textureFilter == 1) { - int ws = static_cast(wScale); - int hs = static_cast(hScale); - if (ws == wScale && hs == hScale) textureFilter = 0; // disable for integer scales + if (static_cast(wScale) == wScale && static_cast(hScale) == hScale) { + textureFilter = 0; // disable for integer scales + } } } @@ -1267,6 +1267,163 @@ static __declspec(naked) void palette_fade_to_hook() { } } +//////////////////////////////////////////////////////////////////////////////// + +static void __forceinline UpdateDDSurface(BYTE* surface, int width, int height, int widthFrom, RECT* rect) { + DDSURFACEDESC desc; + RECT lockRect = { rect->left, rect->top, rect->right + 1, rect->bottom + 1 }; + + primaryDDSurface->Lock(&lockRect, &desc, 0, 0); + + BufToBuf(surface, width, height, widthFrom, (BYTE*)desc.lpSurface, desc.lPitch); // + (desc.lPitch * rect->top) + rect->left + + primaryDDSurface->Unlock(desc.lpSurface); +} + +static BYTE* GetBuffer() { + return (BYTE*)*(DWORD*)_screen_buffer; +} + +static void __fastcall sf_GNW_win_refresh(WINinfo* win, RECT* updateRect, BYTE* toBuffer) { + if (win->flags & WinFlags::Hidden) return; + RectList* rects; + + if (win->flags & WinFlags::Transparent && !*(DWORD*)_doing_refresh_all) { + __asm { + mov eax, updateRect; + mov edx, ds:[_screen_buffer]; + call refresh_all_; + } + int w = updateRect->right - updateRect->left + 1; + + if (*ptr_mouse_is_hidden || !MouseIn(updateRect->left, updateRect->top, updateRect->right, updateRect->bottom)) { + if (!DeviceLost) { + int h = (updateRect->bottom - updateRect->top) + 1; + UpdateDDSurface(GetBuffer(), w, h, w, updateRect); // update the entire rectangle area + } + } else { + //fo::func::mouse_show(); + RECT mouseRect; + __asm { + lea eax, mouseRect; + mov edx, eax; + call mouse_get_rect_; + mov eax, updateRect; + call rect_clip_; + mov rects, eax; + } + while (rects) { // updates everything except the cursor area + //__asm { + // mov eax, win; + // mov edx, rects; + // call GNW_button_refresh_; + //} + if (!DeviceLost) { + int wRect = (rects->wRect.right - rects->wRect.left) + 1; + int hRect = (rects->wRect.bottom - rects->wRect.top) + 1; + UpdateDDSurface(&GetBuffer()[rects->wRect.left - updateRect->left] + (rects->wRect.top - updateRect->top) * w, wRect, hRect, w, &rects->wRect); + } + RectList* next = rects->nextRect; + sf_rect_free(rects); + rects = next; + } + } + return; + } + + /* Allocates memory for 10 RectList (if no memory was allocated), returns the first Rect and removes it from the list */ + __asm { + call rect_malloc_; + mov rects, eax; + } + if (!rects) return; + + rects->rect.x = updateRect->left; + rects->rect.y = updateRect->top; + rects->rect.offx = updateRect->right; + rects->rect.offy = updateRect->bottom; + rects->nextRect = nullptr; + RECT &rect = rects->wRect; + + /* + If the border of the updateRect rectangle is located outside the window, then assign to rects->rect the border of the window rectangle + Otherwise, rects->rect contains the borders from the update rectangle (updateRect) + */ + if (win->wRect.left >= rect.left) rect.left = win->wRect.left; + if (win->wRect.top >= rect.top) rect.top = win->wRect.top; + if (win->wRect.right <= rect.right) rect.right = win->wRect.right; + if (win->wRect.bottom <= rect.bottom) rect.bottom = win->wRect.bottom; + + if (rect.right < rect.left || rect.bottom < rect.top) { + sf_rect_free(rects); + return; + } + + int widthFrom = win->width; + int toWidth = (toBuffer) ? updateRect->right - updateRect->left + 1 : Gfx_GetGameWidthRes(); + + WinClip(win, &rects, toBuffer); + + RectList* currRect = rects; + while (currRect) { + RECT &crect = currRect->wRect; + int width = (crect.right - crect.left) + 1; // for current rectangle + int height = (crect.bottom - crect.top) + 1;; // for current rectangle + + BYTE* surface; + if (win->wID) { + __asm { + mov eax, win; + mov edx, currRect; + call GNW_button_refresh_; + } + surface = &win->surface[crect.left - win->rect.x] + ((crect.top - win->rect.y) * win->width); + } else { + surface = new BYTE[height * width](); // black background + widthFrom = width; // replace with rectangle + } + + auto drawFunc = (win->flags & WinFlags::Transparent && win->wID) ? TransBufToBuf : BufToBuf; + if (toBuffer) { + drawFunc(surface, width, height, widthFrom, &toBuffer[crect.left - updateRect->left] + ((crect.top - updateRect->top) * toWidth), toWidth); + } else { + // copy to buffer instead of DD surface (buffering) + drawFunc(surface, width, height, widthFrom, &GetBuffer()[crect.left] + (crect.top * toWidth), toWidth); + //if (!DeviceLost) UpdateDDSurface(surface, width, height, widthFrom, crect); + } + if (win->wID == 0) delete[] surface; + + currRect = currRect->nextRect; + } + + while (rects) { + // copy all rectangles from the buffer to the DD surface (buffering) + if (!toBuffer && !DeviceLost) { + int width = (rects->rect.offx - rects->rect.x) + 1; + int height = (rects->rect.offy - rects->rect.y) + 1; + int widthFrom = toWidth; + UpdateDDSurface(&GetBuffer()[rects->rect.x] + (rects->rect.y * widthFrom), width, height, widthFrom, &rects->wRect); + } + RectList* next = rects->nextRect; + sf_rect_free(rects); + rects = next; + } + + if (!toBuffer && !*(DWORD*)_doing_refresh_all && !*ptr_mouse_is_hidden && MouseIn(updateRect->left, updateRect->top, updateRect->right, updateRect->bottom)) { + MouseShow(); + } +} + +static __declspec(naked) void GNW_win_refresh_hack(void* from, int widthFrom, int heightFrom, int xFrom, int yFrom, int width, int height, int x, int y) { + __asm { + push ebx; // toBuffer + mov ecx, eax; + call sf_GNW_win_refresh; + pop ecx; + retn; + } +} + void Graphics_OnGameLoad() { // ResetShaders for (DWORD d = 0; d < shadersSize; d++) SAFERELEASE(shaders[d].Effect); shaders.clear(); @@ -1320,6 +1477,19 @@ void GraphicsInit() { // Replace the srcCopy_ function with a pure MMX implementation MakeJump(0x4D36D4, BufToBuf); // buf_to_buf_ + // Replace the transSrcCopy_ function + MakeJump(0x4D3704, TransBufToBuf); // trans_buf_to_buf_ + + // Enable support for transparent interface windows + SafeWrite16(0x4D5D46, 0x9090); // win_init_ (create screen_buffer) + if (GraphicsMode) { + // custom implementation of the GNW_win_refresh function + MakeJump(0x4D6FD9, GNW_win_refresh_hack); + SafeWrite16(0x4D75E6, 0x9090); // win_clip_ (remove _buffering checking) + } else { // for default or HRP graphics mode + SafeWrite8(0x4D5DAB, 0x1D); // ecx > ebx (enable _buffering) + BlockCall(0x431076); // dialogMessage_ + } } void GraphicsExit() { diff --git a/sfall/ScriptOps/InterfaceOps.hpp b/sfall/ScriptOps/InterfaceOps.hpp index 93114201..c006bcfa 100644 --- a/sfall/ScriptOps/InterfaceOps.hpp +++ b/sfall/ScriptOps/InterfaceOps.hpp @@ -447,7 +447,7 @@ static void mf_create_win() { if (CreateWindowFunc(opHandler.arg(0).strValue(), opHandler.arg(1).rawValue(), opHandler.arg(2).rawValue(), // y, x opHandler.arg(3).rawValue(), opHandler.arg(4).rawValue(), // w, h - 256, flags) == -1) + (flags & WinFlags::Transparent) ? 0 : 256, flags) == -1) { opHandler.printOpcodeError("create_win() - couldn't create window."); opHandler.setReturn(-1); diff --git a/sfall/Sound.cpp b/sfall/Sound.cpp index a99549a2..baa79f3f 100644 --- a/sfall/Sound.cpp +++ b/sfall/Sound.cpp @@ -345,7 +345,7 @@ static bool __fastcall SoundFileLoad(PlayType playType, const char* path) { if (!path) return false; /*if (playType == PLAYTYPE_sfx) { - auto it = sfxSoundsFiles.find(path); + std::unordered_map::iterator it = sfxSoundsFiles.find(path); if (it != sfxSoundsFiles.cend()) { return (PlayingSound(it->second.c_str(), SNDMODE_single_play) != nullptr); }