mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added code for game movies and edited other code
This commit is contained in:
@@ -173,6 +173,8 @@
|
||||
#define FO_VAR_last_level 0x5707B4
|
||||
#define FO_VAR_lastMovieH 0x638E64
|
||||
#define FO_VAR_lastMovieW 0x638E68
|
||||
#define FO_VAR_lastMovieX 0x638E6C
|
||||
#define FO_VAR_lastMovieY 0x638E70
|
||||
#define FO_VAR_lastTime 0x56FB58
|
||||
#define FO_VAR_lastWin 0x51DD80
|
||||
#define FO_VAR_Level_pc 0x6681B0
|
||||
@@ -212,6 +214,9 @@
|
||||
#define FO_VAR_movePointRect 0x518FD4
|
||||
#define FO_VAR_movie_list 0x518DA0
|
||||
#define FO_VAR_Mutate_ 0x5708B4
|
||||
#define FO_VAR_mve_win_rect 0x638E10
|
||||
#define FO_VAR_mveBH 0x6B402F
|
||||
#define FO_VAR_mveBW 0x6B3CFC
|
||||
#define FO_VAR_name_color 0x56D744
|
||||
#define FO_VAR_name_critter 0x51833C
|
||||
#define FO_VAR_name_font 0x56D74C
|
||||
@@ -299,6 +304,7 @@
|
||||
#define FO_VAR_stack_offset 0x59E844
|
||||
#define FO_VAR_stat_data 0x51D53C
|
||||
#define FO_VAR_stat_flag 0x66452A
|
||||
#define FO_VAR_subtitleH 0x638EA0
|
||||
#define FO_VAR_subtitleList 0x638E74
|
||||
#define FO_VAR_subtitles 0x663974
|
||||
#define FO_VAR_sWindows 0x6727B0
|
||||
@@ -338,6 +344,7 @@
|
||||
#define FO_VAR_wmBkWin 0x51DE14
|
||||
#define FO_VAR_wmBkWinBuf 0x51DE24
|
||||
#define FO_VAR_wmEncounterIconShow 0x672E48
|
||||
#define FO_VAR_wmInterfaceWasInitialized 0x51DE38
|
||||
#define FO_VAR_wmLastRndTime 0x51DEA0
|
||||
#define FO_VAR_wmMaxAreaNum 0x51DDFC
|
||||
#define FO_VAR_wmMaxMapNum 0x51DE10
|
||||
|
||||
@@ -43,12 +43,14 @@ static void __cdecl main_death_scene_hook_buf_to_buf(fo::FrmData* frm, long w, l
|
||||
|
||||
if (DeathScreen::DEATH_SCRN_SIZE || width > w || height > h) {
|
||||
if (DeathScreen::DEATH_SCRN_SIZE == 1) {
|
||||
long x = Image::GetAspectSize(w, h, (float)width, (float)height);
|
||||
long x = 0;
|
||||
long y = 0;
|
||||
if (x >= w) { // extract x/y image position
|
||||
y = x / w;
|
||||
x -= y * w;
|
||||
}
|
||||
Image::GetAspectSize(width, height, &x, &y, w, h);
|
||||
|
||||
//if (x >= w) { // extract x/y image position
|
||||
// y = x / w;
|
||||
// x -= y * w;
|
||||
//}
|
||||
if (x || y) {
|
||||
dst += x + (y * Setting::ScreenWidth());
|
||||
}
|
||||
|
||||
@@ -38,12 +38,9 @@ static void __cdecl game_help_hook_buf_to_buf(fo::FrmData* frm, long w, long h,
|
||||
|
||||
if (HelpScreen::HELP_SCRN_SIZE || width > w || height > h) {
|
||||
if (HelpScreen::HELP_SCRN_SIZE == 1) {
|
||||
long x = Image::GetAspectSize(w, h, (float)width, (float)height);
|
||||
long x = 0;
|
||||
long y = 0;
|
||||
if (x >= w) { // extract x/y image position
|
||||
y = x / w;
|
||||
x -= y * w;
|
||||
}
|
||||
Image::GetAspectSize(width, height, &x, &y, w, h);
|
||||
if (x || y) dst += x + (y * Setting::ScreenWidth());
|
||||
}
|
||||
Image::Scale(frm->frame.data, width, height, dst, w, h, Setting::ScreenWidth());
|
||||
|
||||
+13
-43
@@ -28,18 +28,25 @@ long Image::GetDarkColor(fo::PALETTE* palette) {
|
||||
return index;
|
||||
}
|
||||
|
||||
long Image::GetAspectSize(long &dW, long &dH, float sW, float sH) {
|
||||
long Image::GetAspectSize(long sW, long sH, long* x, long* y, long &dW, long &dH) {
|
||||
float sWf = (float)sW;
|
||||
float sHf = (float)sH;
|
||||
|
||||
float width = (float)dW;
|
||||
float height = (float)dH;
|
||||
float aspectD = (float)dW / dH;
|
||||
float aspectS = sW / sH;
|
||||
float aspectS = sWf / sHf;
|
||||
|
||||
if (aspectD < aspectS) {
|
||||
dH = (long)((sH / sW) * dW); // set new height
|
||||
return (long)(((height - dH) / 2) * dW); // shift y-offset center
|
||||
dH = (long)((sHf / sWf) * dW); // set new height
|
||||
long cy = (long)((height - dH) / 2); // shift y-offset center
|
||||
if (y) *y = cy;
|
||||
return cy * width;
|
||||
} else if (aspectD > aspectS) {
|
||||
dW = (long)((dH / sH) * sW); // set new width
|
||||
return (long)((width - dW) / 2); // shift x-offset center
|
||||
dW = (long)((dH / sHf) * sWf); // set new width
|
||||
long cx = (long)((width - dW) / 2); // shift x-offset center
|
||||
if (x) *x = cx;
|
||||
return cx;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -83,43 +90,6 @@ void Image::Scale(BYTE* src, long sWidth, long sHeight, BYTE* dst, long dWidth,
|
||||
while (--dHeight);
|
||||
}
|
||||
|
||||
// Fixme
|
||||
void Image::TransScale(BYTE* src, long sWidth, long sHeight, BYTE* dst, long dWigth, long dHeight, long dPitch, long tranColorIdx) {
|
||||
if (dWigth <= 0 || dHeight <= 0) return;
|
||||
|
||||
float sw = (float)sWidth;
|
||||
float sh = (float)sHeight;
|
||||
float xStep = sw / dWigth;
|
||||
float hStep = sh / dHeight;
|
||||
|
||||
long height = dHeight;
|
||||
dPitch -= dWigth;
|
||||
|
||||
float sy = 0.0f;
|
||||
do {
|
||||
float sx = 0.0f;
|
||||
int w = dWigth;
|
||||
do {
|
||||
BYTE pixel = *(src + std::lround(sx));
|
||||
if (pixel != tranColorIdx) *dst = pixel;
|
||||
dst++;
|
||||
sx += xStep;
|
||||
if (sx >= sw) sx = sw - 1.0f;
|
||||
} while (--w);
|
||||
|
||||
if (sHeight) {
|
||||
sy += hStep;
|
||||
float y = std::round(sy);
|
||||
if (y >= 1.0f && --sHeight) {
|
||||
src += sWidth * (int)y;
|
||||
sy -= y;
|
||||
}
|
||||
}
|
||||
dst += dPitch;
|
||||
}
|
||||
while (--height);
|
||||
}
|
||||
|
||||
// Simplified implementation of FMtext_to_buf_ engine function with text scaling
|
||||
void Image::ScaleText(BYTE* dstSurf, const char* text, long txtWidth, long dstWidth, long colorFlags, float scaleFactor) {
|
||||
if (*text) {
|
||||
|
||||
+1
-2
@@ -13,10 +13,9 @@ class Image {
|
||||
public:
|
||||
static long GetDarkColor(fo::PALETTE* palette);
|
||||
|
||||
static long GetAspectSize(long &dW, long &dH, float sW, float sH);
|
||||
static long GetAspectSize(long sW, long sH, long* x, long* y, long &dW, long &dH);
|
||||
|
||||
static void Scale(BYTE* src, long sWight, long sHeight, BYTE* dst, long dWight, long dHeight, long dPitch = 0, long sPitch = 0);
|
||||
static void TransScale(BYTE* src, long sWight, long sHeight, BYTE* dst, long dWight, long dHeight, long dPitch, long tranColorIdx);
|
||||
static void ScaleText(BYTE* dst, const char* text, long txtWidth, long dstWidth, long colorFlags, float scaleFactor);
|
||||
};
|
||||
|
||||
|
||||
+24
-10
@@ -84,7 +84,8 @@ static std::string GetBackupFileName(const char* runFileName, bool wait) {
|
||||
size_t n = bakExeName.rfind('.');
|
||||
if (n != std::string::npos) {
|
||||
bakExeName.replace(n, 4, ".hrp");
|
||||
while (remove(bakExeName.c_str()) != 0 && wait) Sleep(1000); // delete .hrp (if it exists)
|
||||
char c = 10;
|
||||
while (std::remove(bakExeName.c_str()) != 0 && wait && --c) Sleep(1000); // delete .hrp (if it exists)
|
||||
}
|
||||
return bakExeName;
|
||||
}
|
||||
@@ -96,18 +97,20 @@ static bool DisableExtHRP(const char* runFileName, std::string &cmdline) {
|
||||
std::rename(runFileName, bakExeName.c_str()); // rename the process file to .hrp
|
||||
CopyFileA(bakExeName.c_str(), runFileName, 0); // restore .exe (already unoccupied by a running process)
|
||||
|
||||
FILE* ft = fopen(runFileName,"r+b");
|
||||
FILE* ft = std::fopen(runFileName,"r+b");
|
||||
if (!ft) return false;
|
||||
fseek(ft, 0xD4880, SEEK_SET); // 0x4E4480
|
||||
std::fseek(ft, 0xD4880, SEEK_SET); // 0x4E4480
|
||||
|
||||
BYTE restore[] = {0xC7, 0x05, 0x88, 0x27, 0x6B, 0x00, 0x00, 0xE7, 0x4D, 0x00};
|
||||
fwrite(restore, 1, sizeof(restore), ft);
|
||||
_fwrite_nolock(restore, 1, sizeof(restore), ft);
|
||||
|
||||
// 0x4FE1C0 - 0x4FE1E7
|
||||
std::fseek(ft, 0xEE5C0, SEEK_SET);
|
||||
|
||||
DWORD restore1[10] = {0};
|
||||
_fwrite_nolock(restore1, 4, sizeof(restore1), ft);
|
||||
|
||||
fseek(ft, 0xEE5C0, SEEK_SET);
|
||||
BYTE restore1[39] = {0};
|
||||
fwrite(restore1, 1, sizeof(restore1), ft);
|
||||
fclose(ft);
|
||||
|
||||
cmdline.append(" -restart");
|
||||
|
||||
MessageBoxA(0, "High Resolution Patch has been successfully deactivated.", "sfall", MB_TASKMODAL | MB_ICONINFORMATION);
|
||||
@@ -176,7 +179,9 @@ void Setting::init(const char* exeFileName, std::string &cmdline) {
|
||||
//HookCall(0x482899, mem_copy);
|
||||
//SafeWrite16(0x4B2EA8, 0x9090); // _show_grid
|
||||
|
||||
if (!Setting::ExternalEnabled() && sf::IniReader::GetIntDefaultConfig("Main", "HiResMode", 1) == 0) return; // vanilla game mode
|
||||
bool resMode = sf::IniReader::GetIntDefaultConfig("Main", "HiResMode", 1) != 0;
|
||||
|
||||
if (!Setting::ExternalEnabled() && !resMode) return; // vanilla game mode
|
||||
|
||||
SCR_WIDTH = sf::IniReader::GetInt("Main", "SCR_WIDTH", 640, f2ResIni);
|
||||
SCR_HEIGHT = sf::IniReader::GetInt("Main", "SCR_HEIGHT", 480, f2ResIni);
|
||||
@@ -187,15 +192,24 @@ void Setting::init(const char* exeFileName, std::string &cmdline) {
|
||||
if (cmdline.find(" -restart") != std::string::npos) {
|
||||
GetBackupFileName(exeFileName, true); // delete after restart
|
||||
}
|
||||
if (resMode == false) return;
|
||||
|
||||
if (Setting::ExternalEnabled()) {
|
||||
char infoMsg[512];
|
||||
sf::Translate::Get("sfall", "HiResInfo",
|
||||
"This version of sfall has its own integrated High Resolution mode patch, which is compatible with the High Resolution Patch by Mash.\n\n"
|
||||
"If you want to continue using the High Resolution Patch by Mash without seeing this message, disable the \"HiResMode\" option in the ddraw.ini file.\n"
|
||||
"If you want to continue using the High Resolution Patch by Mash without seeing this message, disable the 'HiResMode' option in the ddraw.ini file.\n"
|
||||
"Or you can disable the external HRP to get new graphic improvements from sfall.\n\n"
|
||||
"Do you want to disable the High Resolution Patch by Mash?", infoMsg, 512);
|
||||
|
||||
// replace \n for translated message
|
||||
for (size_t i = 0; i < sizeof(infoMsg); i++) {
|
||||
if (infoMsg[i] == '\0') break;
|
||||
if (infoMsg[i] == '\\' && infoMsg[i + 1] == 'n') {
|
||||
infoMsg[i] = ' ';
|
||||
infoMsg[++i] = '\n';
|
||||
}
|
||||
}
|
||||
if (MessageBoxA(0, infoMsg, "sfall: Conflict of High Resolution patches", MB_TASKMODAL | MB_ICONWARNING | MB_YESNO) == IDYES) {
|
||||
if (!DisableExtHRP(exeFileName, cmdline)) {
|
||||
MessageBoxA(0, "An error occurred while trying to deactivate the High Resolution Patch.", "sfall", MB_TASKMODAL | MB_ICONERROR);
|
||||
|
||||
@@ -39,7 +39,7 @@ static long mainmenuWidth = 640;
|
||||
static float scaleWidth, scaleHeight; // multiplier for shifting buttons/text
|
||||
static float scaleFactor = 1.0f; // scale for buttons and text
|
||||
|
||||
static long offsetX, offsetY;
|
||||
static long offsetX = 0, offsetY = 0;
|
||||
|
||||
// draw image to main menu window
|
||||
static void __cdecl main_menu_create_hook_buf_to_buf(BYTE* src, long sw, long sh, long srcW, BYTE* dst, long dstW) {
|
||||
@@ -117,7 +117,7 @@ static long __fastcall main_menu_create_hook_add_win(long h, long y, long color,
|
||||
w = Setting::ScreenWidth();
|
||||
h = Setting::ScreenHeight();
|
||||
|
||||
x = Image::GetAspectSize(w, h, (float)sw, (float)sh);
|
||||
x = Image::GetAspectSize(sw, sh, 0, 0, w, h);
|
||||
|
||||
if (w > Setting::ScreenWidth()) w = Setting::ScreenWidth();
|
||||
if (h > Setting::ScreenHeight()) h = Setting::ScreenHeight();
|
||||
|
||||
@@ -4,8 +4,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "..\main.h"
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
|
||||
#include "Image.h"
|
||||
|
||||
#include "MoviesScreen.h"
|
||||
|
||||
namespace HRP
|
||||
@@ -15,8 +20,169 @@ namespace sf = sfall;
|
||||
|
||||
long MoviesScreen::MOVIE_SIZE;
|
||||
|
||||
static RECT movieToSize;
|
||||
|
||||
static void __fastcall SetMovieSize() {
|
||||
long sWidth = Setting::ScreenWidth();
|
||||
long sHeight = Setting::ScreenHeight();
|
||||
|
||||
long bH = fo::var::getInt(FO_VAR_mveBH);
|
||||
long bW = fo::var::getInt(FO_VAR_mveBW);
|
||||
|
||||
long subtitleHeight = (fo::var::getInt(FO_VAR_subtitles) && fo::var::getInt(FO_VAR_subtitleList)) ? fo::var::getInt(FO_VAR_subtitleH) + 4 : 0;
|
||||
|
||||
if (MoviesScreen::MOVIE_SIZE == 1 || bW > sWidth || bH > sHeight) {
|
||||
long aspectW = sWidth;
|
||||
long aspectH = sHeight - subtitleHeight;
|
||||
long x = 0;
|
||||
long y = 0;
|
||||
Image::GetAspectSize(bW, bH, &x, &y, aspectW, aspectH);
|
||||
|
||||
movieToSize.left = x;
|
||||
movieToSize.top = y;
|
||||
movieToSize.right = x + aspectW;
|
||||
movieToSize.bottom = y + aspectH;
|
||||
} else if (MoviesScreen::MOVIE_SIZE == 2) {
|
||||
movieToSize.top = 0;
|
||||
movieToSize.bottom = Setting::ScreenHeight() - subtitleHeight;
|
||||
|
||||
movieToSize.left = 0;
|
||||
movieToSize.right = Setting::ScreenWidth();
|
||||
} else {
|
||||
// set to center
|
||||
movieToSize.top = (Setting::ScreenHeight() - bH) / 2;
|
||||
movieToSize.bottom = bH + movieToSize.top;
|
||||
|
||||
movieToSize.left = (Setting::ScreenWidth() - bW) / 2;
|
||||
movieToSize.right = bW + movieToSize.left;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) nfConfig_hack() {
|
||||
__asm {
|
||||
call SetMovieSize;
|
||||
xor eax, eax;
|
||||
mov ecx, 27;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
// surface: _nf_mve_buf1
|
||||
static long __cdecl movie_MVE_ShowFrame(IDirectDrawSurface* surface, int bW, int bH, int x, int y, int w, int h) {
|
||||
RECT movieSize;
|
||||
movieSize.left = x;
|
||||
movieSize.right = x + bW;
|
||||
movieSize.top = y;
|
||||
movieSize.bottom = y + bH;
|
||||
|
||||
fo::var::setInt(FO_VAR_lastMovieX) = movieToSize.left;
|
||||
fo::var::setInt(FO_VAR_lastMovieY) = movieToSize.top;
|
||||
fo::var::setInt(FO_VAR_lastMovieW) = movieToSize.right - movieToSize.left;
|
||||
fo::var::setInt(FO_VAR_lastMovieH) = movieToSize.bottom - movieToSize.top;
|
||||
//FO_VAR_lastMovieBW = bW
|
||||
//FO_VAR_lastMovieBH = bH
|
||||
|
||||
return surface->Blt(&movieToSize, surface, &movieSize, MoviesScreen::MOVIE_SIZE, 0); // for sfall DX9
|
||||
}
|
||||
|
||||
// Adjust Y position
|
||||
static long __fastcall SubtitleAdjustPosition(long yTop, long yBottom) {
|
||||
if (yBottom > Setting::ScreenHeight()) return yTop - (yBottom - Setting::ScreenHeight());
|
||||
|
||||
if (MoviesScreen::MOVIE_SIZE == 0 || Setting::ScreenHeight() == 480) return yTop;
|
||||
|
||||
long y = fo::var::getInt(FO_VAR_lastMovieY);
|
||||
y += fo::var::getInt(FO_VAR_lastMovieH) + 4;
|
||||
|
||||
if (yTop >= y) return yTop;
|
||||
|
||||
long spaceHeight = Setting::ScreenHeight() - y;
|
||||
if (spaceHeight > fo::var::getInt(FO_VAR_subtitleH)) {
|
||||
spaceHeight -= fo::var::getInt(FO_VAR_subtitleH);
|
||||
y += spaceHeight / 2; // centering
|
||||
}
|
||||
|
||||
long yMax = Setting::ScreenHeight() - fo::var::getInt(FO_VAR_subtitleH);
|
||||
return (y < yMax) ? y : yMax;
|
||||
}
|
||||
|
||||
static void __declspec(naked) doSubtitle_hook() {
|
||||
__asm {
|
||||
mov ecx, esi;
|
||||
call SubtitleAdjustPosition;
|
||||
mov esi, eax;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) gmovie_play_hack_begin() {
|
||||
__asm {
|
||||
cmp ds:[FO_VAR_wmInterfaceWasInitialized], 1;
|
||||
jne skip;
|
||||
mov eax, fo::funcoffs::wmMouseBkProc_;
|
||||
call fo::funcoffs::remove_bk_process_;
|
||||
skip:
|
||||
mov edx, 1;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) gmovie_play_hack_end() {
|
||||
__asm {
|
||||
cmp ds:[FO_VAR_wmInterfaceWasInitialized], 1;
|
||||
jne skip;
|
||||
mov edx, eax;
|
||||
mov eax, fo::funcoffs::wmMouseBkProc_;
|
||||
call fo::funcoffs::add_bk_process_;
|
||||
mov eax, edx;
|
||||
skip:
|
||||
pop edx; // ret addr
|
||||
pop ebp;
|
||||
pop edi;
|
||||
pop esi;
|
||||
pop ecx;
|
||||
pop ebx;
|
||||
jmp edx;
|
||||
}
|
||||
}
|
||||
|
||||
void MoviesScreen::init() {
|
||||
|
||||
if (MOVIE_SIZE < 0) MOVIE_SIZE = 0;
|
||||
else if (MOVIE_SIZE > 2) MOVIE_SIZE = 2;
|
||||
|
||||
// gmovie_play_ set GNWWin window size
|
||||
sf::SafeWrite32(0x44E7D4, Setting::ScreenHeight());
|
||||
sf::SafeWrite32(0x44E7D9, Setting::ScreenWidth());
|
||||
sf::SafeWrite8(0x44E7D2, fo::WinFlags::Exclusive | fo::WinFlags::MoveOnTop); // fix
|
||||
//sf::SafeWrite8(0x44E7DE, 55); // for debugging
|
||||
|
||||
// movieStart_
|
||||
// Direct output to texture is used for DirectX9, and buffered method (output to GNWWin window) is used for DirectDraw
|
||||
if (0) {
|
||||
sf::SafeWrite8(0x487781, sf::CodeType::JumpShort); // force Buffered
|
||||
} else {
|
||||
sf::SafeWrite16(0x487781, 0x9090); // force Direct
|
||||
}
|
||||
|
||||
sf::SafeWrite32(0x4877D0, (DWORD)&movie_MVE_ShowFrame); // replace movie_MVE_ShowFrame_ with sfall function
|
||||
|
||||
sf::MakeCall(0x4F5D40, nfConfig_hack);
|
||||
|
||||
// openSubtitle_
|
||||
sf::HookCall(0x48738E, Setting::ScreenWidth); // replace windowGetXres_
|
||||
|
||||
// doSubtitle_ hacks
|
||||
sf::SafeWrite32(0x487580, Setting::ScreenHeight());
|
||||
sf::HookCall(0x4875BE, doSubtitle_hook);
|
||||
sf::SafeWrite8(0x4875C5, sf::CodeType::JumpShort); // jle > jmp
|
||||
|
||||
// Prevent processing scrolling global map during playback
|
||||
sf::MakeCall(0x44E6B2, gmovie_play_hack_begin);
|
||||
sf::MakeCalls(gmovie_play_hack_end, {0x44EAC9, 0x44EADD});
|
||||
|
||||
// Disable _MVE_lastBuffer copying function (unnecessary option for the engine)
|
||||
//sf::SafeWrite8(0x486F2E, sf::CodeType::Jump); // jz > jmp (cleanupMovie_)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,12 +54,9 @@ static void __cdecl endgame_display_image_hook_buf_to_buf(BYTE* src, long w, lon
|
||||
|
||||
if (SlidesScreen::END_SLIDE_SIZE || width > w || height > h) {
|
||||
if (SlidesScreen::END_SLIDE_SIZE == 1) {
|
||||
long x = Image::GetAspectSize(w, h, (float)width, (float)height);
|
||||
long x = 0;
|
||||
long y = 0;
|
||||
if (x >= w) { // extract x/y image position
|
||||
y = x / w;
|
||||
x -= y * w;
|
||||
}
|
||||
Image::GetAspectSize(width, height, &x, &y, w, h);
|
||||
if (x || y) dst += x + (y * Setting::ScreenWidth());
|
||||
}
|
||||
bottomPos = h;
|
||||
@@ -125,7 +122,7 @@ static void __declspec(naked) endgame_show_subtitles_hook_buf_fill() {
|
||||
|
||||
static void __fastcall endgame_pan_desert_hook_buf_fill(long, long, fo::FrmData* frm) {
|
||||
frmArt = frm;
|
||||
fo::func::endgame_load_palette(fo::ArtType::OBJ_TYPE_INTRFACE, 327); // panning desert image (DP.FRM)
|
||||
fo::func::endgame_load_palette(fo::ArtType::OBJ_TYPE_INTRFACE, 327); // panning desert image (DP.FRM)
|
||||
if (SlidesScreen::END_SLIDE_SIZE != 2) {
|
||||
color = Image::GetDarkColor((fo::PALETTE*)FO_VAR_cmap);
|
||||
std::memset((void*)fo::var::getInt(FO_VAR_endgame_window_buffer), color, Setting::ScreenWidth() * Setting::ScreenHeight());
|
||||
@@ -140,12 +137,9 @@ static void __cdecl endgame_pan_desert_hook_buf_to_buf(BYTE* src, long w, long h
|
||||
if (SlidesScreen::END_SLIDE_SIZE == 1) {
|
||||
long width = Setting::ScreenWidth();
|
||||
long height = Setting::ScreenHeight();
|
||||
long x = Image::GetAspectSize(width, height, (float)w, (float)h);
|
||||
long x = 0;
|
||||
long y = 0;
|
||||
if (x >= width) { // extract x/y image position
|
||||
y = x / width;
|
||||
x -= y * width;
|
||||
}
|
||||
Image::GetAspectSize(w, h, &x, &y, width, height);
|
||||
if (x || y) dst += x + (y * Setting::ScreenWidth());
|
||||
bottomPos = height;
|
||||
|
||||
|
||||
@@ -31,11 +31,8 @@ static void __cdecl game_splash_screen_hack_scr_blit(BYTE* srcPixels, long srcWi
|
||||
// stretch texture for DirectX
|
||||
if (SplashScreen::SPLASH_SCRN_SIZE || srcWidth > w || srcHeight > h) {
|
||||
if (SplashScreen::SPLASH_SCRN_SIZE == 1) {
|
||||
x = Image::GetAspectSize(w, h, (float)srcWidth, (float)srcHeight);
|
||||
if (x >= w) { // extract x/y image position
|
||||
y = x / w;
|
||||
x -= y * w;
|
||||
}
|
||||
x = 0;
|
||||
Image::GetAspectSize(srcWidth, srcHeight, &x, &y, w, h);
|
||||
|
||||
rect.top = y;
|
||||
rect.bottom = (y + h) - 1;
|
||||
|
||||
+39
-23
@@ -56,7 +56,7 @@ bool Graphics::IsWindowMode;
|
||||
bool Graphics::PlayAviMovie = false;
|
||||
bool Graphics::AviMovieWidthFit = false;
|
||||
|
||||
static DWORD yoffset;
|
||||
//static DWORD yoffset;
|
||||
//static DWORD xoffset;
|
||||
|
||||
bool DeviceLost = false;
|
||||
@@ -643,19 +643,27 @@ class FakeDirectDrawSurface : IDirectDrawSurface {
|
||||
private:
|
||||
ULONG Refs;
|
||||
bool isPrimary;
|
||||
|
||||
BYTE* lockTarget = nullptr;
|
||||
RECT* lockRect;
|
||||
|
||||
// size for secondary (mve) surface
|
||||
DWORD m_width;
|
||||
DWORD m_height;
|
||||
|
||||
public:
|
||||
static bool IsPlayMovie;
|
||||
|
||||
FakeDirectDrawSurface(bool primary) {
|
||||
FakeDirectDrawSurface(bool primary, DDSURFACEDESC* desc) {
|
||||
Refs = 1;
|
||||
isPrimary = primary;
|
||||
if (primary && Graphics::GPUBlt) {
|
||||
// use the mainTex texture as source buffer
|
||||
if (primary) {
|
||||
if (Graphics::GPUBlt == 0) lockTarget = new BYTE[ResWidth * ResHeight]();
|
||||
// for enabled GPUBlt, use the mainTex texture as source buffer
|
||||
} else {
|
||||
lockTarget = new BYTE[ResWidth * ResHeight]();
|
||||
m_width = desc->dwWidth;
|
||||
m_height = desc->dwHeight;
|
||||
lockTarget = new BYTE[m_width * m_height];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -678,11 +686,12 @@ public:
|
||||
HRESULT __stdcall AddAttachedSurface(LPDIRECTDRAWSURFACE) { UNUSEDFUNCTION; }
|
||||
HRESULT __stdcall AddOverlayDirtyRect(LPRECT) { UNUSEDFUNCTION; }
|
||||
|
||||
HRESULT __stdcall Blt(LPRECT dst, LPDIRECTDRAWSURFACE b, LPRECT scr, DWORD d, LPDDBLTFX e) { // called 0x4868DA movie_MVE_ShowFrame_ (used for game movies, only for w/o HRP)
|
||||
mveDesc.dwHeight = (dst->bottom - dst->top);
|
||||
yoffset = (ResHeight - mveDesc.dwHeight) / 2;
|
||||
mveDesc.lPitch = (dst->right - dst->left);
|
||||
// called 0x4868DA movie_MVE_ShowFrame_ used for game movies (only for w/o HRP by Mash)
|
||||
HRESULT __stdcall Blt(LPRECT dst, LPDIRECTDRAWSURFACE b, LPRECT scr, DWORD d, LPDDBLTFX e) {
|
||||
mveDesc.dwHeight = scr->bottom; //(dst->bottom - dst->top);
|
||||
mveDesc.lPitch = scr->right; //(dst->right - dst->left);
|
||||
//xoffset = (ResWidth - mveDesc.lPitch) / 2;
|
||||
//yoffset = (ResHeight - mveDesc.dwHeight) / 2;
|
||||
|
||||
//dlog_f("\nBlt: [mveDesc: w:%d, h:%d]", DL_INIT, mveDesc.lPitch, mveDesc.dwHeight);
|
||||
|
||||
@@ -698,11 +707,11 @@ public:
|
||||
DWORD width = mveDesc.lPitch; // the current size of the width of the mve movie
|
||||
|
||||
if (Graphics::GPUBlt) {
|
||||
fo::func::buf_to_buf(lockTarget, width, mveDesc.dwHeight, width, (BYTE*)dRect.pBits, dRect.Pitch);
|
||||
//char* pBits = (char*)dRect.pBits;
|
||||
//for (DWORD y = 0; y < mveDesc.dwHeight; y++) {
|
||||
// CopyMemory(&pBits[y * pitch], &lockTarget[y * width], width);
|
||||
//}
|
||||
if (d != 0) {
|
||||
fo::func::cscale(lockTarget, width, mveDesc.dwHeight, width, (BYTE*)dRect.pBits, dst->right - dst->left, dst->bottom - dst->top, dRect.Pitch);
|
||||
} else {
|
||||
fo::func::buf_to_buf(lockTarget, width, mveDesc.dwHeight, width, (BYTE*)dRect.pBits, dRect.Pitch);
|
||||
}
|
||||
} else {
|
||||
int pitch = dRect.Pitch / 4;
|
||||
DWORD* pBits = (DWORD*)dRect.pBits;
|
||||
@@ -719,6 +728,11 @@ public:
|
||||
mainTex->UnlockRect(0);
|
||||
d3d9Device->UpdateTexture(mainTex, mainTexD);
|
||||
|
||||
//IDirect3DSurface9 *mSurf, *mSurfD;
|
||||
//mainTex->GetSurfaceLevel(0, &mSurf);
|
||||
//mainTexD->GetSurfaceLevel(0, &mSurfD);
|
||||
//d3d9Device->StretchRect(mSurf, 0, mSurfD, 0, D3DTEXF_LINEAR);
|
||||
|
||||
//mainTexLock = false;
|
||||
//if (Graphics::PlayAviMovie) return DD_OK; // Blt method is not executed during avi playback because the sfShowFrame_ function is blocked
|
||||
|
||||
@@ -756,8 +770,8 @@ public:
|
||||
0x4CB887 GNW95_ShowRect_ [c=1]
|
||||
0x48699D movieShowFrame_ [c=1]
|
||||
0x4CBBFA GNW95_zero_vid_mem_ [c=1] (clear surface)
|
||||
0x4F5E91/0x4F5EBB sub_4F5E60 [c=0] (from MVE_rmStepMovie_)
|
||||
0x486861 movie_MVE_ShowFrame_ [c=1] (capture, never called)
|
||||
0x4F5E91/0x4F5EBB nf_mve_buf_lock [c=0] (from MVE_rmStepMovie_)
|
||||
*/
|
||||
HRESULT __stdcall Lock(LPRECT a, LPDDSURFACEDESC b, DWORD c, HANDLE d) {
|
||||
if (DeviceLost && Restore() == DD_FALSE) return DDERR_SURFACELOST; // DDERR_SURFACELOST 0x887601C2
|
||||
@@ -776,11 +790,12 @@ public:
|
||||
b->lpSurface = lockTarget;
|
||||
}
|
||||
} else {
|
||||
mveDesc.lPitch = fo::var::getInt(FO_VAR_lastMovieW);
|
||||
mveDesc.dwHeight = fo::var::getInt(FO_VAR_lastMovieH);
|
||||
//dlog_f("\nLock: [mveDesc: w:%d, h:%d]", DL_INIT, mveDesc.lPitch, mveDesc.dwHeight);
|
||||
mveDesc.dwWidth = m_width;
|
||||
mveDesc.lPitch = m_width; //fo::var::getInt(FO_VAR_lastMovieW);
|
||||
mveDesc.dwHeight = m_height; //fo::var::getInt(FO_VAR_lastMovieH);
|
||||
*b = mveDesc;
|
||||
b->lpSurface = lockTarget;
|
||||
//dlog_f("\nLock: [mveDesc: w:%d, h:%d]", DL_INIT, mveDesc.lPitch, mveDesc.dwHeight);
|
||||
}
|
||||
return DD_OK;
|
||||
}
|
||||
@@ -839,8 +854,9 @@ public:
|
||||
0x4CB8F0 GNW95_ShowRect_ (common game, primary)
|
||||
0x486A87 movieShowFrame_
|
||||
0x4CBC5A GNW95_zero_vid_mem_ (clear surface)
|
||||
0x4F5ECC sub_4F5E60 (from MVE_rmStepMovie_)
|
||||
0x4F5ECC nf_mve_buf_lock (from MVE_rmStepMovie_)
|
||||
0x4868BA movie_MVE_ShowFrame_ (capture never call)
|
||||
0x4F5EFA/0x4F5F0B nf_mve_buf_unlock (from MVE_rmStepMovie_)
|
||||
*/
|
||||
HRESULT __stdcall Unlock(LPVOID lockSurface) {
|
||||
if (!isPrimary) return DD_OK;
|
||||
@@ -1034,11 +1050,11 @@ public:
|
||||
0x4CB094 GNW95_init_DirectDraw_ (primary surface)
|
||||
0x4F5DD4/0x4F5DF9 nfConfig_ (mve surface)
|
||||
*/
|
||||
HRESULT __stdcall CreateSurface(LPDDSURFACEDESC a, LPDIRECTDRAWSURFACE* b, IUnknown* c) {
|
||||
if (a->ddsCaps.dwCaps == DDSCAPS_PRIMARYSURFACE && a->dwFlags == DDSD_CAPS) {
|
||||
*b = primarySurface = (IDirectDrawSurface*)new FakeDirectDrawSurface(true);
|
||||
HRESULT __stdcall CreateSurface(LPDDSURFACEDESC desc, LPDIRECTDRAWSURFACE* b, IUnknown* c) {
|
||||
if (desc->ddsCaps.dwCaps == DDSCAPS_PRIMARYSURFACE && desc->dwFlags == DDSD_CAPS) {
|
||||
*b = primarySurface = (IDirectDrawSurface*)new FakeDirectDrawSurface(true, nullptr);
|
||||
} else {
|
||||
*b = (IDirectDrawSurface*)new FakeDirectDrawSurface(false);
|
||||
*b = (IDirectDrawSurface*)new FakeDirectDrawSurface(false, desc);
|
||||
}
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user