mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added support for transparent interface windows (#25)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -18,10 +18,8 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "Functions.h"
|
||||
#include "FunctionOffsets.h"
|
||||
#include "Structs.h"
|
||||
#include "Variables.h"
|
||||
#include "VariableOffsets.h"
|
||||
|
||||
#include "EngineUtils.h"
|
||||
@@ -345,22 +343,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 fo::funcoffs::win_height_;
|
||||
push eax;
|
||||
mov eax, winID;
|
||||
call fo::funcoffs::win_width_;
|
||||
mov ecx, eax;
|
||||
mov edx, ebx;
|
||||
mov eax, winID;
|
||||
call fo::funcoffs::win_fill_;
|
||||
// Fills the specified non-scripted interface window with index color 0 (black color)
|
||||
void ClearWindow(long winID, bool refresh) {
|
||||
fo::Window* win = fo::func::GNW_find(winID);
|
||||
for (long i = 0; i < win->height; i++) {
|
||||
std::memset(win->surface, 0, win->width);
|
||||
}
|
||||
if (refresh) {
|
||||
fo::func::GNW_win_refresh(win, &win->rect, 0);
|
||||
}
|
||||
if (refresh) fo::func::win_draw(winID);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
@@ -479,7 +470,7 @@ void RedrawObject(GameObject* obj) {
|
||||
void RefreshGNW(size_t from) {
|
||||
*(DWORD*)FO_VAR_doing_refresh_all = 1;
|
||||
for (size_t i = from; i < fo::var::num_windows; i++) {
|
||||
func::GNW_win_refresh(fo::var::window[i], &fo::var::scr_size, 0);
|
||||
fo::func::GNW_win_refresh(fo::var::window[i], &fo::var::scr_size, 0);
|
||||
}
|
||||
*(DWORD*)FO_VAR_doing_refresh_all = 0;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "Functions.h"
|
||||
#include "Variables.h"
|
||||
|
||||
//
|
||||
// Various utility functions, based on FO engine functions
|
||||
@@ -30,13 +31,20 @@
|
||||
namespace fo
|
||||
{
|
||||
|
||||
// returns weapon animation code
|
||||
long AnimCodeByWeapon(GameObject* weapon);
|
||||
|
||||
inline void DisplayPrint(const std::string& str) {
|
||||
__inline void DisplayPrint(const std::string& str) {
|
||||
fo::func::display_print(str.c_str());
|
||||
}
|
||||
|
||||
// rect_free_ function for inline implementation
|
||||
__forceinline void sf_rect_free(fo::RectList* rect) {
|
||||
fo::RectList* front = fo::var::rectList;
|
||||
fo::var::rectList = rect;
|
||||
rect->nextRect = front;
|
||||
}
|
||||
|
||||
// returns weapon animation code
|
||||
long AnimCodeByWeapon(GameObject* weapon);
|
||||
|
||||
// returns message string from given file or "Error" when not found
|
||||
const char* GetMessageStr(const MessageList* fileAddr, long messageId);
|
||||
|
||||
@@ -102,8 +110,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 PrintText(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface);
|
||||
|
||||
@@ -790,7 +790,7 @@ namespace WinFlags {
|
||||
enum WinButtonFlags : long
|
||||
{
|
||||
OwnerFlag = 0x1,
|
||||
UnknownFlag2 = 0x2,
|
||||
DontMoveTop = 0x2,
|
||||
MoveOnTop = 0x4,
|
||||
Hidden = 0x8,
|
||||
Exclusive = 0x10,
|
||||
|
||||
@@ -277,7 +277,7 @@ void __fastcall window_trans_cscale(long i_width, long i_height, long s_width, l
|
||||
}
|
||||
|
||||
// buf_to_buf_ function with pure MMX implementation
|
||||
void __cdecl buf_to_buf(void* src, long width, long height, long src_width, void* dst, long dst_width) {
|
||||
void __cdecl buf_to_buf(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
|
||||
@@ -342,6 +342,57 @@ end:
|
||||
}
|
||||
}
|
||||
|
||||
// trans_buf_to_buf_ function implementation
|
||||
void __cdecl trans_buf_to_buf(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 get_game_config_string(const char* outValue, const char* section, const char* param) {
|
||||
__asm {
|
||||
mov ebx, param;
|
||||
|
||||
@@ -75,7 +75,10 @@ void __fastcall displayInWindow(long w_here, long width, long height, void* data
|
||||
void __fastcall window_trans_cscale(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 buf_to_buf(void* src, long width, long height, long src_width, void* dst, long dst_width);
|
||||
void __cdecl buf_to_buf(BYTE* src, long width, long height, long src_width, BYTE* dst, long dst_width);
|
||||
|
||||
// trans_buf_to_buf_ function implementation
|
||||
void __cdecl trans_buf_to_buf(BYTE* src, long width, long height, long src_width, BYTE* dst, long dst_width);
|
||||
|
||||
long __fastcall get_game_config_string(const char* outValue, const char* section, const char* param);
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@ WRAP_WATCOM_FFUNC3(long, item_add_force, GameObject*, critter, GameObject*, item
|
||||
WRAP_WATCOM_FFUNC3(long, item_w_mp_cost, GameObject*, source, long, hitMode, long, isCalled)
|
||||
WRAP_WATCOM_FFUNC7(void, make_straight_path_func, GameObject*, objFrom, DWORD, tileFrom, DWORD, tileTo, void*, rotationPtr, DWORD*, result, long, flags, void*, func)
|
||||
WRAP_WATCOM_FFUNC3(long, message_find, DWORD*, msgFile, long, msgNumber, DWORD*, outBuf)
|
||||
WRAP_WATCOM_FFUNC4(long, mouse_click_in, long, x, long, y, long, x_end, long, y_end)
|
||||
WRAP_WATCOM_FFUNC4(long, mouse_click_in, long, x, long, y, long, x_offs, long, y_offs)
|
||||
WRAP_WATCOM_FFUNC4(long, mouse_in, long, x, long, y, long, x_offs, long, y_offs)
|
||||
WRAP_WATCOM_FFUNC3(GameObject*, obj_blocking_at, GameObject*, object, long, tile, long, elevation)
|
||||
WRAP_WATCOM_FFUNC4(long, obj_move_to_tile, GameObject*, object, long, tile, long, elevation, RECT*, rect)
|
||||
WRAP_WATCOM_FFUNC3(long, obj_new_sid_inst, GameObject*, object, long, sType, long, scriptIndex)
|
||||
@@ -47,6 +48,7 @@ WRAP_WATCOM_FFUNC3(long, scr_get_local_var, long, sid, long, varId, long*, value
|
||||
WRAP_WATCOM_FFUNC3(long, scr_set_local_var, long, sid, long, varId, long, value)
|
||||
WRAP_WATCOM_FFUNC3(long, tile_num_in_direction, long, tile, long, rotation,long, distance)
|
||||
WRAP_WATCOM_FFUNC8(void, trans_cscale, void*, fromBuff, long, width, long, height, long, pitch, void*, toBuff, long, toWidth, long, toHeight, long, toPitch)
|
||||
WRAP_WATCOM_FFUNC3(void, win_clip, Window*, window, RectList**, rects, void*, buffer)
|
||||
|
||||
WRAP_WATCOM_FFUNC3(const char*, interpretGetString, Program*, scriptPtr, DWORD, dataType, DWORD, strId)
|
||||
|
||||
|
||||
@@ -72,10 +72,18 @@ static_assert(sizeof(AnimationSet) == 2656, "Incorrect AnimationSet definition."
|
||||
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 GameObject {
|
||||
long id;
|
||||
@@ -315,7 +323,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
|
||||
|
||||
@@ -219,12 +219,15 @@
|
||||
#define FO_VAR_queue 0x6648C0
|
||||
#define FO_VAR_quick_done 0x5193BC
|
||||
#define FO_VAR_read_callback 0x51DEEC
|
||||
#define FO_VAR_rectList 0x51DEF4
|
||||
#define FO_VAR_retvals 0x43EA7C
|
||||
#define FO_VAR_rm_FrameCount 0x6B36A8
|
||||
#define FO_VAR_rotation 0x631D34
|
||||
#define FO_VAR_sad 0x530014
|
||||
#define FO_VAR_sampleRate 0x66815C
|
||||
#define FO_VAR_scr_blit 0x6ACA18
|
||||
#define FO_VAR_scr_size 0x6AC9F0
|
||||
#define FO_VAR_screen_buffer 0x51E3FC
|
||||
#define FO_VAR_script_engine_running 0x51C714
|
||||
#define FO_VAR_script_path_base 0x51C710
|
||||
#define FO_VAR_scriptListInfo 0x51C7C8
|
||||
|
||||
@@ -175,6 +175,7 @@ VAR_(pud, DWORD)
|
||||
VAR_(queue, DWORD)
|
||||
VAR_(quick_done, DWORD)
|
||||
VAR_(read_callback, DWORD)
|
||||
VAR_(rectList, fo::RectList*)
|
||||
VAR_(RedColor, BYTE)
|
||||
VAR2(retvals, fo::ElevatorExit, 24, 4) // 24 elevators, 4 exits each
|
||||
VAR_(rotation, DWORD)
|
||||
|
||||
+173
-6
@@ -34,7 +34,7 @@ namespace sfall
|
||||
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;
|
||||
@@ -656,7 +656,7 @@ public:
|
||||
int pitch = dRect.Pitch;
|
||||
|
||||
if (Graphics::GPUBlt) {
|
||||
fo::func::buf_to_buf(lockTarget, width, mveDesc.dwHeight, width, dRect.pBits, pitch);
|
||||
fo::func::buf_to_buf(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);
|
||||
@@ -742,7 +742,7 @@ public:
|
||||
if (isPrimary) {
|
||||
if (Graphics::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;
|
||||
@@ -1105,9 +1105,9 @@ HRESULT __stdcall InitFakeDirectDrawCreate(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<int>(wScale);
|
||||
int hs = static_cast<int>(hScale);
|
||||
if (ws == wScale && hs == hScale) textureFilter = 0; // disable for integer scales
|
||||
if (static_cast<int>(wScale) == wScale && static_cast<int>(hScale) == hScale) {
|
||||
textureFilter = 0; // disable for integer scales
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1139,6 +1139,160 @@ 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);
|
||||
|
||||
fo::func::buf_to_buf(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*)FO_VAR_screen_buffer;
|
||||
}
|
||||
|
||||
static void __fastcall sf_GNW_win_refresh(fo::Window* win, RECT* updateRect, BYTE* toBuffer) {
|
||||
if (win->flags & fo::WinFlags::Hidden) return;
|
||||
fo::RectList* rects;
|
||||
|
||||
if (win->flags & fo::WinFlags::Transparent && !*(DWORD*)FO_VAR_doing_refresh_all) {
|
||||
__asm {
|
||||
mov eax, updateRect;
|
||||
mov edx, ds:[FO_VAR_screen_buffer];
|
||||
call fo::funcoffs::refresh_all_;
|
||||
}
|
||||
int w = updateRect->right - updateRect->left + 1;
|
||||
|
||||
if (fo::var::mouse_is_hidden || !fo::func::mouse_in(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 fo::funcoffs::mouse_get_rect_;
|
||||
mov eax, updateRect;
|
||||
call fo::funcoffs::rect_clip_;
|
||||
mov rects, eax;
|
||||
}
|
||||
while (rects) { // updates everything except the cursor area
|
||||
//__asm {
|
||||
// mov eax, win;
|
||||
// mov edx, rects;
|
||||
// call fo::funcoffs::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);
|
||||
}
|
||||
fo::RectList* next = rects->nextRect;
|
||||
fo::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 fo::funcoffs::rect_malloc_;
|
||||
mov rects, eax;
|
||||
}
|
||||
if (!rects) return;
|
||||
|
||||
rects->rect = { updateRect->left, updateRect->top, updateRect->right, 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) {
|
||||
fo::sf_rect_free(rects);
|
||||
return;
|
||||
}
|
||||
|
||||
int widthFrom = win->width;
|
||||
int toWidth = (toBuffer) ? updateRect->right - updateRect->left + 1 : Graphics::GetGameWidthRes();
|
||||
|
||||
fo::func::win_clip(win, &rects, toBuffer);
|
||||
|
||||
fo::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 fo::funcoffs::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 & fo::WinFlags::Transparent && win->wID) ? fo::func::trans_buf_to_buf : fo::func::buf_to_buf;
|
||||
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);
|
||||
}
|
||||
fo::RectList* next = rects->nextRect;
|
||||
fo::sf_rect_free(rects);
|
||||
rects = next;
|
||||
}
|
||||
|
||||
if (!toBuffer && !*(DWORD*)FO_VAR_doing_refresh_all && !fo::var::mouse_is_hidden && fo::func::mouse_in(updateRect->left, updateRect->top, updateRect->right, updateRect->bottom)) {
|
||||
fo::func::mouse_show();
|
||||
}
|
||||
}
|
||||
|
||||
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::init() {
|
||||
Graphics::mode = GetConfigInt("Graphics", "Mode", 0);
|
||||
if (Graphics::mode == 6) {
|
||||
@@ -1176,6 +1330,19 @@ void Graphics::init() {
|
||||
|
||||
// Replace the srcCopy_ function with a pure MMX implementation
|
||||
MakeJump(0x4D36D4, fo::func::buf_to_buf); // buf_to_buf_
|
||||
// Replace the transSrcCopy_ function
|
||||
MakeJump(0x4D3704, fo::func::trans_buf_to_buf); // trans_buf_to_buf_
|
||||
|
||||
// Enable support for transparent interface windows
|
||||
SafeWrite16(0x4D5D46, 0x9090); // win_init_ (create screen_buffer)
|
||||
if (Graphics::mode) {
|
||||
// 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 Graphics::exit() {
|
||||
|
||||
@@ -380,7 +380,7 @@ void mf_create_win(OpcodeContext& ctx) {
|
||||
if (fo::func::createWindow(ctx.arg(0).strValue(),
|
||||
ctx.arg(1).rawValue(), ctx.arg(2).rawValue(), // y, x
|
||||
ctx.arg(3).rawValue(), ctx.arg(4).rawValue(), // w, h
|
||||
256, flags) == -1)
|
||||
(flags & fo::WinFlags::Transparent) ? 0 : 256, flags) == -1)
|
||||
{
|
||||
ctx.printOpcodeError("%s() - couldn't create window.", ctx.getMetaruleName());
|
||||
ctx.setReturn(-1);
|
||||
@@ -433,7 +433,7 @@ void mf_set_window_flag(OpcodeContext& ctx) {
|
||||
const char* name = ctx.arg(0).strValue();
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
if (_stricmp(name, fo::var::sWindows[i].name) == 0) {
|
||||
fo::Window* win =fo::func::GNW_find(fo::var::sWindows[i].wID);
|
||||
fo::Window* win = fo::func::GNW_find(fo::var::sWindows[i].wID);
|
||||
if (mode) {
|
||||
fo::var::sWindows[i].flags |= bitFlag;
|
||||
win->flags |= bitFlag;
|
||||
|
||||
Reference in New Issue
Block a user