mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added support for drawing PCX images to draw_image, draw_image_scaled, and interface_art_draw
Fixed bug in TalkingHeads.cpp.
This commit is contained in:
@@ -352,6 +352,7 @@ const DWORD critter_name_ = 0x42D0A8;
|
||||
const DWORD critter_pc_set_name_ = 0x42D138;
|
||||
const DWORD critterClearObjDrugs_ = 0x42DA54;
|
||||
const DWORD critterIsOverloaded_ = 0x42E66C;
|
||||
const DWORD datafileConvertData_ = 0x42EE84;
|
||||
const DWORD db_access_ = 0x4390B4;
|
||||
const DWORD db_dir_entry_ = 0x4C5D68;
|
||||
const DWORD db_fclose_ = 0x4C5EB4;
|
||||
@@ -554,6 +555,7 @@ const DWORD ListSkills_ = 0x436154;
|
||||
const DWORD ListTraits_ = 0x43B8A8;
|
||||
const DWORD loadColorTable_ = 0x4C78E4;
|
||||
const DWORD LoadGame_ = 0x47C640;
|
||||
const DWORD loadPCX_ = 0x496494;
|
||||
const DWORD loadProgram_ = 0x4A3B74;
|
||||
const DWORD LoadSlot_ = 0x47DC68;
|
||||
const DWORD load_frame_ = 0x419EC0;
|
||||
@@ -591,6 +593,7 @@ const DWORD move_inventory_ = 0x474708;
|
||||
const DWORD movieRun_ = 0x487AC8;
|
||||
const DWORD movieStop_ = 0x487150;
|
||||
const DWORD movieUpdate_ = 0x487BEC;
|
||||
const DWORD my_free_ = 0x4C5C2C;
|
||||
const DWORD new_obj_id_ = 0x4A386C;
|
||||
const DWORD NixHotLines_ = 0x4999C0;
|
||||
const DWORD nrealloc_ = 0x4F1669;
|
||||
@@ -1188,6 +1191,23 @@ void __cdecl TransBufToBuf(BYTE* src, long width, long height, long src_width, B
|
||||
__asm emms;
|
||||
}
|
||||
|
||||
BYTE* __fastcall LoadPCXData(const char* file, long* width, long* height) {
|
||||
__asm {
|
||||
mov eax, ecx;
|
||||
mov ebx, height;
|
||||
mov ecx, _pal;
|
||||
call loadPCX_;
|
||||
push eax;
|
||||
mov ebx, [width];
|
||||
mov edx, _pal;
|
||||
mov ecx, [height];
|
||||
mov ebx, [ebx];
|
||||
mov ecx, [ecx];
|
||||
call datafileConvertData_;
|
||||
pop eax;
|
||||
}
|
||||
}
|
||||
|
||||
long __fastcall GetGameConfigString(const char* outValue, const char* section, const char* param) {
|
||||
__asm {
|
||||
mov ebx, param;
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
#define _folder_card_title2 0x5705BC
|
||||
#define _frame_time 0x5709C4
|
||||
#define _free_perk 0x570A29
|
||||
#define _freePtr 0x519594
|
||||
#define _frstc_draw1 0x5707D8
|
||||
#define _game_config 0x58E950
|
||||
#define _game_global_vars 0x5186C0
|
||||
@@ -206,6 +207,7 @@
|
||||
#define _optionsButtonUpKey 0x518F28
|
||||
#define _optnwin 0x663900
|
||||
#define _outlined_object 0x518D94
|
||||
#define _pal 0x56D7E0
|
||||
#define _partyMemberAIOptions 0x519DB8
|
||||
#define _partyMemberCount 0x519DAC
|
||||
#define _partyMemberLevelUpInfoList 0x519DBC
|
||||
@@ -638,6 +640,7 @@ extern const DWORD critter_name_;
|
||||
extern const DWORD critter_pc_set_name_;
|
||||
extern const DWORD critterClearObjDrugs_;
|
||||
extern const DWORD critterIsOverloaded_;
|
||||
extern const DWORD datafileConvertData_;
|
||||
extern const DWORD db_access_;
|
||||
extern const DWORD db_dir_entry_;
|
||||
extern const DWORD db_fclose_;
|
||||
@@ -843,6 +846,7 @@ extern const DWORD ListSkills_;
|
||||
extern const DWORD ListTraits_;
|
||||
extern const DWORD loadColorTable_;
|
||||
extern const DWORD LoadGame_;
|
||||
extern const DWORD loadPCX_;
|
||||
extern const DWORD loadProgram_; // loads script from scripts/ folder by file name and returns pointer to it: char* <eax> - file name (w/o extension)
|
||||
extern const DWORD LoadSlot_;
|
||||
extern const DWORD load_frame_;
|
||||
@@ -883,6 +887,7 @@ extern const DWORD move_inventory_;
|
||||
extern const DWORD movieRun_;
|
||||
extern const DWORD movieStop_;
|
||||
extern const DWORD movieUpdate_;
|
||||
extern const DWORD my_free_;
|
||||
extern const DWORD new_obj_id_;
|
||||
extern const DWORD NixHotLines_;
|
||||
extern const DWORD nrealloc_;
|
||||
@@ -1195,6 +1200,8 @@ void __cdecl BufToBuf(BYTE* src, long width, long height, long src_width, BYTE*
|
||||
// trans_buf_to_buf_ function implementation
|
||||
void __cdecl TransBufToBuf(BYTE* src, long width, long height, long src_width, BYTE* dst, long dst_width);
|
||||
|
||||
BYTE* __fastcall LoadPCXData(const char* file, long* width, long* height);
|
||||
|
||||
long __fastcall GetGameConfigString(const char* outValue, const char* section, const char* param);
|
||||
|
||||
// X-Macro for wrapper functions.
|
||||
|
||||
@@ -531,6 +531,45 @@ static void mf_set_window_flag() {
|
||||
}
|
||||
}
|
||||
|
||||
static void __fastcall FreeArtFile(FrmFile* frmPtr) {
|
||||
if (frmPtr->id == 'PCX') {
|
||||
__asm mov eax, frmPtr;
|
||||
__asm mov eax, [eax]frmPtr.pixelData;
|
||||
__asm call ds:[_freePtr];
|
||||
delete[] frmPtr;
|
||||
} else {
|
||||
__asm mov eax, frmPtr;
|
||||
__asm call my_free_;
|
||||
}
|
||||
}
|
||||
|
||||
static FrmFile* LoadArtFile(const char* file, long frame, long direction, FrmFrameData* &framePtr, bool checkPCX) {
|
||||
FrmFile* frmPtr = nullptr;
|
||||
if (checkPCX) {
|
||||
const char* pos = strrchr(file, '.');
|
||||
if (pos && _stricmp(pos, ".PCX") == 0) {
|
||||
long w, h;
|
||||
BYTE* data = LoadPCXData(file, &w, &h);
|
||||
if (!data) return nullptr;
|
||||
|
||||
frmPtr = reinterpret_cast<FrmFile*>(new BYTE[78]);
|
||||
std::memset(frmPtr, 0, 74);
|
||||
|
||||
frmPtr->id = 'PCX';
|
||||
frmPtr->width = static_cast<short>(w);
|
||||
frmPtr->height = static_cast<short>(h);
|
||||
frmPtr->pixelData = data;
|
||||
framePtr = frmPtr->GetFrameData(0, 0);
|
||||
return frmPtr;
|
||||
}
|
||||
}
|
||||
if (LoadFrame(file, &frmPtr)) {
|
||||
return nullptr;
|
||||
}
|
||||
framePtr = frmPtr->GetFrameData(direction, frame);
|
||||
return frmPtr;
|
||||
}
|
||||
|
||||
static long GetArtFIDFile(long fid, const char* &file) {
|
||||
long direction = 0;
|
||||
long _fid = fid & 0xFFFFFFF;
|
||||
@@ -544,16 +583,6 @@ static long GetArtFIDFile(long fid, const char* &file) {
|
||||
return direction;
|
||||
}
|
||||
|
||||
static FrmFile* LoadArtFile(const char* file, long frame, long direction, FrmFrameData* &framePtr) {
|
||||
FrmFile* frmPtr = nullptr;
|
||||
if (LoadFrame(file, &frmPtr)) {
|
||||
return nullptr;
|
||||
}
|
||||
framePtr = frmPtr->GetFrameData(direction, frame);
|
||||
|
||||
return frmPtr;
|
||||
}
|
||||
|
||||
static void mf_draw_image() {
|
||||
if (*(DWORD*)_currentWindow == -1) {
|
||||
opHandler.printOpcodeError("draw_image() - no created/selected window for the image.");
|
||||
@@ -562,7 +591,9 @@ static void mf_draw_image() {
|
||||
}
|
||||
long direction = 0;
|
||||
const char* file = nullptr;
|
||||
if (opHandler.arg(0).isInt()) { // art id
|
||||
|
||||
bool isID = opHandler.arg(0).isInt();
|
||||
if (isID) { // art id
|
||||
long fid = opHandler.arg(0).rawValue();
|
||||
if (fid == -1) {
|
||||
opHandler.setReturn(-1);
|
||||
@@ -586,17 +617,18 @@ static void mf_draw_image() {
|
||||
}
|
||||
|
||||
FrmFrameData* framePtr;
|
||||
FrmFile* frmPtr = LoadArtFile(file, frameno, direction, framePtr);
|
||||
FrmFile* frmPtr = LoadArtFile(file, frameno, direction, framePtr, !isID);
|
||||
if (frmPtr == nullptr) {
|
||||
opHandler.printOpcodeError("draw_image() - cannot open the file: %s", file);
|
||||
opHandler.setReturn(-1);
|
||||
return;
|
||||
}
|
||||
BYTE* pixelData = (frmPtr->id == 'PCX') ? frmPtr->pixelData : framePtr->data;
|
||||
|
||||
// with x/y frame offsets
|
||||
WindowDisplayBuf(x + frmPtr->xshift[direction], framePtr->width, y + frmPtr->yshift[direction], framePtr->height, framePtr->data, noTrans);
|
||||
WindowDisplayBuf(x + frmPtr->xshift[direction], framePtr->width, y + frmPtr->yshift[direction], framePtr->height, pixelData, noTrans);
|
||||
|
||||
MemFree(frmPtr);
|
||||
FreeArtFile(frmPtr);
|
||||
opHandler.setReturn(1);
|
||||
}
|
||||
|
||||
@@ -608,7 +640,9 @@ static void mf_draw_image_scaled() {
|
||||
}
|
||||
long direction = 0;
|
||||
const char* file = nullptr;
|
||||
if (opHandler.arg(0).isInt()) { // art id
|
||||
|
||||
bool isID = opHandler.arg(0).isInt();
|
||||
if (isID) { // art id
|
||||
long fid = opHandler.arg(0).rawValue();
|
||||
if (fid == -1) {
|
||||
opHandler.setReturn(-1);
|
||||
@@ -633,16 +667,17 @@ static void mf_draw_image_scaled() {
|
||||
}
|
||||
|
||||
FrmFrameData* framePtr;
|
||||
FrmFile* frmPtr = LoadArtFile(file, frameno, direction, framePtr);
|
||||
FrmFile* frmPtr = LoadArtFile(file, frameno, direction, framePtr, !isID);
|
||||
if (frmPtr == nullptr) {
|
||||
opHandler.printOpcodeError("draw_image_scaled() - cannot open the file: %s", file);
|
||||
opHandler.setReturn(-1);
|
||||
return;
|
||||
}
|
||||
long result = 1;
|
||||
BYTE* pixelData = (frmPtr->id == 'PCX') ? frmPtr->pixelData : framePtr->data;
|
||||
|
||||
if (opHandler.numArgs() < 3) {
|
||||
DisplayInWindow(framePtr->width, framePtr->width, framePtr->height, framePtr->data); // scaled to window size (w/o transparent)
|
||||
DisplayInWindow(framePtr->width, framePtr->width, framePtr->height, pixelData); // scaled to window size (w/o transparent)
|
||||
} else {
|
||||
// draw to scale
|
||||
long s_width, s_height;
|
||||
@@ -666,11 +701,11 @@ static void mf_draw_image_scaled() {
|
||||
|
||||
long w_width = WindowWidth();
|
||||
long xy_pos = (y * w_width) + x;
|
||||
WindowTransCscale(framePtr->width, framePtr->height, s_width, s_height, xy_pos, w_width, framePtr->data); // custom scaling
|
||||
WindowTransCscale(framePtr->width, framePtr->height, s_width, s_height, xy_pos, w_width, pixelData); // custom scaling
|
||||
}
|
||||
|
||||
exit:
|
||||
MemFree(frmPtr);
|
||||
FreeArtFile(frmPtr);
|
||||
opHandler.setReturn(result);
|
||||
}
|
||||
|
||||
@@ -682,12 +717,11 @@ static void mf_interface_art_draw() {
|
||||
bool useShift = false;
|
||||
long direction = -1, w = -1, h = -1;
|
||||
|
||||
if (opHandler.arg(1).isInt()) { // art id
|
||||
bool isID = opHandler.arg(1).isInt();
|
||||
if (isID) { // art id
|
||||
long fid = opHandler.arg(1).rawValue();
|
||||
if (fid == -1) {
|
||||
result = -1;
|
||||
goto exit;
|
||||
}
|
||||
if (fid == -1) goto exit;
|
||||
|
||||
useShift = (((fid & 0xF000000) >> 24) == OBJ_TYPE_CRITTER);
|
||||
direction = GetArtFIDFile(fid, file);
|
||||
} else {
|
||||
@@ -706,10 +740,9 @@ static void mf_interface_art_draw() {
|
||||
long frame = (opHandler.numArgs() > 4) ? opHandler.arg(4).rawValue() : 0;
|
||||
|
||||
FrmFrameData* framePtr;
|
||||
FrmFile* frmPtr = LoadArtFile(file, frame, direction, framePtr);
|
||||
FrmFile* frmPtr = LoadArtFile(file, frame, direction, framePtr, !isID);
|
||||
if (frmPtr == nullptr) {
|
||||
opHandler.printOpcodeError("interface_art_draw() - cannot open the file: %s", file);
|
||||
result = -1;
|
||||
goto exit;
|
||||
}
|
||||
int x = opHandler.arg(2).rawValue();
|
||||
@@ -725,14 +758,15 @@ static void mf_interface_art_draw() {
|
||||
int width = (w >= 0) ? w : framePtr->width;
|
||||
int height = (h >= 0) ? h : framePtr->height;
|
||||
|
||||
TransCscale(framePtr->data, framePtr->width, framePtr->height, framePtr->width,
|
||||
TransCscale(((frmPtr->id == 'PCX') ? frmPtr->pixelData : framePtr->data), framePtr->width, framePtr->height, framePtr->width,
|
||||
interfaceWin->surface + (y * interfaceWin->width) + x, width, height, interfaceWin->width
|
||||
);
|
||||
|
||||
if (!(opHandler.arg(0).rawValue() & 0x1000000)) {
|
||||
GNWWinRefresh(interfaceWin, &interfaceWin->rect, 0);
|
||||
}
|
||||
MemFree(frmPtr);
|
||||
|
||||
FreeArtFile(frmPtr);
|
||||
result = 1;
|
||||
} else {
|
||||
opHandler.printOpcodeError("interface_art_draw() - the game interface window is not created or invalid value for the interface.");
|
||||
@@ -825,10 +859,10 @@ static void mf_get_window_attribute() {
|
||||
result = 1;
|
||||
break;
|
||||
case 1: // x
|
||||
result = win->wRect.left;
|
||||
result = win->rect.x;
|
||||
break;
|
||||
case 2: // y
|
||||
result = win->wRect.top;
|
||||
result = win->rect.y;
|
||||
break;
|
||||
}
|
||||
opHandler.setReturn(result);
|
||||
|
||||
@@ -164,21 +164,23 @@ static bool LoadFrm(Frm* frm) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static WINinfo* dialogWin = nullptr;
|
||||
static long dialogWinX = 0, dialogWinY = 0;
|
||||
|
||||
static void __fastcall DrawHeadFrame(Frm* frm, int frameno) {
|
||||
if (frm && !frm->broken) {
|
||||
if (!frm->loaded && !LoadFrm(frm)) goto loadFail;
|
||||
FrmFrameData* frame = FramePtr((FrmHeaderData*)frm, frameno, 0);
|
||||
|
||||
if (dialogWin == nullptr) {
|
||||
dialogWin = GNWFind(*ptr_dialogueBackWindow);
|
||||
if (dialogWinX == -1) {
|
||||
WINinfo* dialogWin = GNWFind(*ptr_dialogueBackWindow);
|
||||
dialogWinX = dialogWin->rect.x;
|
||||
dialogWinY = dialogWin->rect.y;
|
||||
}
|
||||
Gfx_SetHeadTex(frm->textures[frameno],
|
||||
frame->width,
|
||||
frame->height,
|
||||
frame->x + frm->xshift + dialogWin->wRect.left,
|
||||
frame->y + frm->yshift + dialogWin->wRect.top
|
||||
frame->x + frm->xshift + dialogWinX,
|
||||
frame->y + frm->yshift + dialogWinY
|
||||
);
|
||||
showHighlights = frm->showHighlights;
|
||||
return;
|
||||
@@ -207,7 +209,7 @@ void __declspec(naked) gdDestroyHeadWindow_hack() {
|
||||
__asm {
|
||||
call Gfx_SetDefaultTechnique;
|
||||
mov showHighlights, 0;
|
||||
//mov dialogWin, 0; // uncomment if the dialog window position is supposed to change
|
||||
//mov dialogWinX, -1; // uncomment if the dialog window position is supposed to change
|
||||
pop ebp;
|
||||
pop edi;
|
||||
pop edx;
|
||||
|
||||
+3
-3
@@ -25,10 +25,10 @@
|
||||
#define VERSION_MAJOR 3
|
||||
#define VERSION_MINOR 8
|
||||
#define VERSION_BUILD 28
|
||||
#define VERSION_REV 0
|
||||
#define VERSION_REV 1
|
||||
|
||||
#ifdef WIN2K
|
||||
#define VERSION_STRING "3.8.28 win2k"
|
||||
#define VERSION_STRING "3.8.28.1 win2k"
|
||||
#else
|
||||
#define VERSION_STRING "3.8.28"
|
||||
#define VERSION_STRING "3.8.28.1"
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user