mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3822e25201 | ||
|
|
2ba6cbee3a | ||
|
|
cb90129ebd | ||
|
|
13d5fd2e83 | ||
|
|
7c3cbbac05 | ||
|
|
a5a317ab40 | ||
|
|
372483a5ca | ||
|
|
d46549dd11 | ||
|
|
c6970e35de | ||
|
|
68e7d3e903 |
+51
@@ -1,6 +1,8 @@
|
|||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "svga.h"
|
#include "svga.h"
|
||||||
@@ -339,4 +341,53 @@ void transSrcCopy(unsigned char* dest, int destPitch, unsigned char* src, int sr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void blitBufferToBufferStretchAndFixEdges(
|
||||||
|
unsigned char* src, int srcW, int srcH, int srcPitch,
|
||||||
|
unsigned char* dst, int dstW, int dstH, int dstPitch,
|
||||||
|
int numStates)
|
||||||
|
{
|
||||||
|
// Temp buffer for over-stretched result (per state)
|
||||||
|
const int stretchW = dstW + 1;
|
||||||
|
const int stretchH = dstH + 1;
|
||||||
|
const int stretchPitch = stretchW;
|
||||||
|
|
||||||
|
std::vector<unsigned char> tempBuffer(stretchW * stretchH * numStates);
|
||||||
|
|
||||||
|
// Stretch all states to slightly larger temp buffer
|
||||||
|
blitBufferToBufferStretch(
|
||||||
|
src, srcW, srcH * numStates, srcPitch,
|
||||||
|
tempBuffer.data(), stretchW, stretchH * numStates, stretchPitch);
|
||||||
|
|
||||||
|
// Now copy only the top-left dstW x dstH portion per state into the final buffer
|
||||||
|
for (int state = 0; state < numStates; ++state) {
|
||||||
|
unsigned char* tempFrame = tempBuffer.data() + stretchW * stretchH * state;
|
||||||
|
unsigned char* finalFrame = dst + dstW * dstH * state;
|
||||||
|
|
||||||
|
for (int y = 0; y < dstH; ++y) {
|
||||||
|
memcpy(
|
||||||
|
finalFrame + y * dstW,
|
||||||
|
tempFrame + y * stretchPitch,
|
||||||
|
dstW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void calculateScaledSize(int srcWidth, int srcHeight, int targetWidth, int targetHeight, int mode, int& outWidth, int& outHeight)
|
||||||
|
{
|
||||||
|
if (mode == 2) {
|
||||||
|
// Fullscreen stretch
|
||||||
|
outWidth = targetWidth;
|
||||||
|
outHeight = targetHeight;
|
||||||
|
} else {
|
||||||
|
// Maintain aspect ratio
|
||||||
|
if (targetHeight * srcWidth >= targetWidth * srcHeight) {
|
||||||
|
outWidth = targetWidth;
|
||||||
|
outHeight = (targetWidth * srcHeight) / srcWidth;
|
||||||
|
} else {
|
||||||
|
outWidth = (targetHeight * srcWidth) / srcHeight;
|
||||||
|
outHeight = targetHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace fallout
|
} // namespace fallout
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ void _swap_color_buf(unsigned char* buf, int width, int height, int pitch, int c
|
|||||||
void bufferOutline(unsigned char* buf, int width, int height, int pitch, int a5);
|
void bufferOutline(unsigned char* buf, int width, int height, int pitch, int a5);
|
||||||
void srcCopy(unsigned char* dest, int destPitch, unsigned char* src, int srcPitch, int width, int height);
|
void srcCopy(unsigned char* dest, int destPitch, unsigned char* src, int srcPitch, int width, int height);
|
||||||
void transSrcCopy(unsigned char* dest, int destPitch, unsigned char* src, int srcPitch, int width, int height);
|
void transSrcCopy(unsigned char* dest, int destPitch, unsigned char* src, int srcPitch, int width, int height);
|
||||||
|
void blitBufferToBufferStretchAndFixEdges(
|
||||||
|
unsigned char* src, int srcW, int srcH, int srcPitch,
|
||||||
|
unsigned char* dst, int dstW, int dstH, int dstPitch,
|
||||||
|
int numStates = 1);
|
||||||
|
void calculateScaledSize(int srcWidth, int srcHeight, int targetWidth, int targetHeight, int mode, int& outWidth, int& outHeight);
|
||||||
|
|
||||||
} // namespace fallout
|
} // namespace fallout
|
||||||
|
|
||||||
|
|||||||
+180
-99
@@ -168,6 +168,14 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4
|
|||||||
int skipOpeningMovies = 0;
|
int skipOpeningMovies = 0;
|
||||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_SKIP_OPENING_MOVIES_KEY, &skipOpeningMovies);
|
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_SKIP_OPENING_MOVIES_KEY, &skipOpeningMovies);
|
||||||
|
|
||||||
|
// load preferences before Splash screen to get proper brightness
|
||||||
|
if (_init_options_menu() != 0) {
|
||||||
|
debugPrint("Failed on init_options_menu\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
debugPrint(">init_options_menu\n");
|
||||||
|
|
||||||
if (!gIsMapper && skipOpeningMovies < 2) {
|
if (!gIsMapper && skipOpeningMovies < 2) {
|
||||||
showSplash();
|
showSplash();
|
||||||
}
|
}
|
||||||
@@ -341,7 +349,7 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4
|
|||||||
|
|
||||||
debugPrint(">scr_disable\t");
|
debugPrint(">scr_disable\t");
|
||||||
|
|
||||||
if (_init_options_menu() != 0) {
|
if (_init_options_menu() != 0) {
|
||||||
debugPrint("Failed on init_options_menu\n");
|
debugPrint("Failed on init_options_menu\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1193,71 +1201,139 @@ static void gameFreeGlobalVars()
|
|||||||
// 0x443F74
|
// 0x443F74
|
||||||
static void showHelp()
|
static void showHelp()
|
||||||
{
|
{
|
||||||
ScopedGameMode gm(GameMode::kHelp);
|
ScopedGameMode gm(GameMode::kHelp); // Switch to Help game mode.
|
||||||
|
|
||||||
bool isoWasEnabled = isoDisable();
|
bool isoWasEnabled = isoDisable();
|
||||||
gameMouseObjectsHide();
|
gameMouseObjectsHide();
|
||||||
|
|
||||||
gameMouseSetCursor(MOUSE_CURSOR_NONE);
|
gameMouseSetCursor(MOUSE_CURSOR_NONE);
|
||||||
|
|
||||||
bool colorCycleWasEnabled = colorCycleEnabled();
|
bool colorCycleWasEnabled = colorCycleEnabled();
|
||||||
colorCycleDisable();
|
colorCycleDisable();
|
||||||
|
|
||||||
// CE: Help screen uses separate color palette which is incompatible with
|
// load the optional stretch setting from f2_res.ini
|
||||||
// colors in other windows. Setup overlay to hide everything.
|
int helpScreenStretchMode = 0;
|
||||||
int overlay = windowCreate(0, 0, screenGetWidth(), screenGetHeight(), 0, WINDOW_HIDDEN | WINDOW_MOVE_ON_TOP);
|
int stretchGameMode = 0;
|
||||||
|
Config config;
|
||||||
|
if (configInit(&config)) {
|
||||||
|
if (configRead(&config, "f2_res.ini", false)) {
|
||||||
|
configGetInt(&config, "STATIC_SCREENS", "HELP_SCRN_SIZE", &helpScreenStretchMode);
|
||||||
|
|
||||||
int helpWindowX = (screenGetWidth() - HELP_SCREEN_WIDTH) / 2;
|
if (configGetInt(&config, "STATIC_SCREENS", "STRETCH_GAME", &stretchGameMode)) {
|
||||||
int helpWindowY = (screenGetHeight() - HELP_SCREEN_HEIGHT) / 2;
|
helpScreenStretchMode = stretchGameMode; // always override if key exists
|
||||||
int win = windowCreate(helpWindowX, helpWindowY, HELP_SCREEN_WIDTH, HELP_SCREEN_HEIGHT, 0, WINDOW_HIDDEN | WINDOW_MOVE_ON_TOP);
|
}
|
||||||
|
}
|
||||||
|
configFree(&config);
|
||||||
|
}
|
||||||
|
|
||||||
|
int screenWidth = screenGetWidth();
|
||||||
|
int screenHeight = screenGetHeight();
|
||||||
|
|
||||||
|
// Create an invisible fullscreen overlay window to cover everything.
|
||||||
|
int overlay = windowCreate(0, 0, screenWidth, screenHeight, 0, WINDOW_HIDDEN | WINDOW_MOVE_ON_TOP);
|
||||||
|
|
||||||
|
FrmImage helpFrmImage;
|
||||||
|
int helpFid = buildFid(OBJ_TYPE_INTERFACE, 297, 0, 0, 0); // Load Help screen graphic (FID 297).
|
||||||
|
if (!helpFrmImage.lock(helpFid)) {
|
||||||
|
if (colorCycleWasEnabled)
|
||||||
|
colorCycleEnable();
|
||||||
|
gameMouseObjectsShow();
|
||||||
|
if (isoWasEnabled)
|
||||||
|
isoEnable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* helpData = helpFrmImage.getData();
|
||||||
|
int helpWidth = HELP_SCREEN_WIDTH;
|
||||||
|
int helpHeight = HELP_SCREEN_HEIGHT;
|
||||||
|
|
||||||
|
unsigned char* bufferToBlit = helpData;
|
||||||
|
int blitWidth = helpWidth;
|
||||||
|
int blitHeight = helpHeight;
|
||||||
|
|
||||||
|
// Check if stretching is needed (based on config or screen too small).
|
||||||
|
if (helpScreenStretchMode != 0 || screenWidth < helpWidth || screenHeight < helpHeight) {
|
||||||
|
int scaledWidth, scaledHeight;
|
||||||
|
|
||||||
|
calculateScaledSize(
|
||||||
|
helpWidth,
|
||||||
|
helpHeight,
|
||||||
|
screenWidth,
|
||||||
|
screenHeight,
|
||||||
|
helpScreenStretchMode,
|
||||||
|
scaledWidth,
|
||||||
|
scaledHeight);
|
||||||
|
|
||||||
|
// Allocate memory for the scaled image.
|
||||||
|
unsigned char* scaled = reinterpret_cast<unsigned char*>(internal_malloc((scaledWidth + 1) * (scaledHeight + 1)));
|
||||||
|
if (scaled != nullptr) {
|
||||||
|
// Stretch and fix the original help image into the new buffer.
|
||||||
|
blitBufferToBufferStretchAndFixEdges(
|
||||||
|
helpData, helpWidth, helpHeight, helpWidth, // Source buffer and dimensions
|
||||||
|
scaled, scaledWidth, scaledHeight, scaledWidth, // Destination buffer and dimensions
|
||||||
|
1 // numStates = 1 for a single image
|
||||||
|
);
|
||||||
|
|
||||||
|
bufferToBlit = scaled;
|
||||||
|
blitWidth = scaledWidth;
|
||||||
|
blitHeight = scaledHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Center the window on the screen.
|
||||||
|
int x = (screenWidth - blitWidth) / 2;
|
||||||
|
int y = (screenHeight - blitHeight) / 2;
|
||||||
|
|
||||||
|
// Create window for the help screen.
|
||||||
|
int win = windowCreate(x, y, blitWidth, blitHeight, 0, WINDOW_HIDDEN | WINDOW_MOVE_ON_TOP);
|
||||||
if (win != -1) {
|
if (win != -1) {
|
||||||
unsigned char* windowBuffer = windowGetBuffer(win);
|
unsigned char* windowBuffer = windowGetBuffer(win);
|
||||||
if (windowBuffer != nullptr) {
|
if (windowBuffer != nullptr) {
|
||||||
FrmImage backgroundFrmImage;
|
// Clear palette to black before displaying.
|
||||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 297, 0, 0, 0);
|
paletteSetEntries(gPaletteBlack);
|
||||||
if (backgroundFrmImage.lock(backgroundFid)) {
|
|
||||||
paletteSetEntries(gPaletteBlack);
|
|
||||||
blitBufferToBuffer(backgroundFrmImage.getData(), HELP_SCREEN_WIDTH, HELP_SCREEN_HEIGHT, HELP_SCREEN_WIDTH, windowBuffer, HELP_SCREEN_WIDTH);
|
|
||||||
|
|
||||||
colorPaletteLoad("art\\intrface\\helpscrn.pal");
|
// Copy the help image into the window.
|
||||||
paletteSetEntries(_cmap);
|
blitBufferToBuffer(bufferToBlit, blitWidth, blitHeight, blitWidth, windowBuffer, blitWidth);
|
||||||
|
|
||||||
// CE: Fill overlay with darkest color in the palette. It might
|
// Load the help screen's specific palette.
|
||||||
// not be completely black, but at least it's uniform.
|
colorPaletteLoad("art\\intrface\\helpscrn.pal");
|
||||||
bufferFill(windowGetBuffer(overlay),
|
paletteSetEntries(_cmap);
|
||||||
screenGetWidth(),
|
|
||||||
screenGetHeight(),
|
|
||||||
screenGetWidth(),
|
|
||||||
intensityColorTable[_colorTable[0]][0]);
|
|
||||||
|
|
||||||
windowShow(overlay);
|
// Fill the overlay with the darkest palette color to hide everything behind.
|
||||||
windowShow(win);
|
bufferFill(windowGetBuffer(overlay), screenWidth, screenHeight, screenWidth, intensityColorTable[_colorTable[0]][0]);
|
||||||
|
|
||||||
while (inputGetInput() == -1 && _game_user_wants_to_quit == 0) {
|
windowShow(overlay);
|
||||||
sharedFpsLimiter.mark();
|
windowShow(win);
|
||||||
renderPresent();
|
|
||||||
sharedFpsLimiter.throttle();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (mouseGetEvent() != 0) {
|
while (inputGetInput() == -1 && _game_user_wants_to_quit == 0) {
|
||||||
sharedFpsLimiter.mark();
|
sharedFpsLimiter.mark();
|
||||||
|
renderPresent();
|
||||||
inputGetInput();
|
sharedFpsLimiter.throttle();
|
||||||
|
|
||||||
renderPresent();
|
|
||||||
sharedFpsLimiter.throttle();
|
|
||||||
}
|
|
||||||
|
|
||||||
paletteSetEntries(gPaletteBlack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (mouseGetEvent() != 0) {
|
||||||
|
sharedFpsLimiter.mark();
|
||||||
|
inputGetInput();
|
||||||
|
renderPresent();
|
||||||
|
sharedFpsLimiter.throttle();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fade back to black.
|
||||||
|
paletteSetEntries(gPaletteBlack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
windowDestroy(overlay);
|
windowDestroy(overlay);
|
||||||
windowDestroy(win);
|
windowDestroy(win);
|
||||||
colorPaletteLoad("color.pal");
|
colorPaletteLoad("color.pal");
|
||||||
paletteSetEntries(_cmap);
|
paletteSetEntries(_cmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free temporary scaled buffer if it was allocated.
|
||||||
|
if (bufferToBlit != helpData) {
|
||||||
|
internal_free(bufferToBlit);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore previous state.
|
||||||
if (colorCycleWasEnabled) {
|
if (colorCycleWasEnabled) {
|
||||||
colorCycleEnable();
|
colorCycleEnable();
|
||||||
}
|
}
|
||||||
@@ -1371,7 +1447,7 @@ static int gameDbInit()
|
|||||||
char* path_file_name_template = nullptr;
|
char* path_file_name_template = nullptr;
|
||||||
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_PATCH_FILE, &path_file_name_template);
|
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_PATCH_FILE, &path_file_name_template);
|
||||||
if (path_file_name_template == nullptr || *path_file_name_template == '\0') {
|
if (path_file_name_template == nullptr || *path_file_name_template == '\0') {
|
||||||
path_file_name_template = (char*)"patch%03d.dat";
|
path_file_name_template = "patch%03d.dat";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (patch_index = 0; patch_index < 1000; patch_index++) {
|
for (patch_index = 0; patch_index < 1000; patch_index++) {
|
||||||
@@ -1394,8 +1470,9 @@ static int gameDbInit()
|
|||||||
// 0x444384
|
// 0x444384
|
||||||
static void showSplash()
|
static void showSplash()
|
||||||
{
|
{
|
||||||
int splash = settings.system.splash;
|
int splashIndex = settings.system.splash;
|
||||||
|
|
||||||
|
// path to local splash folder
|
||||||
char path[64];
|
char path[64];
|
||||||
const char* language = settings.system.language.c_str();
|
const char* language = settings.system.language.c_str();
|
||||||
if (compat_stricmp(language, ENGLISH) != 0) {
|
if (compat_stricmp(language, ENGLISH) != 0) {
|
||||||
@@ -1404,19 +1481,19 @@ static void showSplash()
|
|||||||
snprintf(path, sizeof(path), "art\\splash\\");
|
snprintf(path, sizeof(path), "art\\splash\\");
|
||||||
}
|
}
|
||||||
|
|
||||||
File* stream;
|
// open a splash file, cycle through SPLASH_COUNT entries
|
||||||
for (int index = 0; index < SPLASH_COUNT; index++) {
|
File* stream = nullptr;
|
||||||
|
for (int attempt = 0; attempt < SPLASH_COUNT; attempt++) {
|
||||||
char filePath[64];
|
char filePath[64];
|
||||||
snprintf(filePath, sizeof(filePath), "%ssplash%d.rix", path, splash);
|
snprintf(filePath, sizeof(filePath), "%ssplash%d.rix", path, splashIndex);
|
||||||
stream = fileOpen(filePath, "rb");
|
stream = fileOpen(filePath, "rb");
|
||||||
if (stream != nullptr) {
|
if (stream != nullptr) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
splash++;
|
splashIndex++;
|
||||||
|
if (splashIndex >= SPLASH_COUNT) {
|
||||||
if (splash >= SPLASH_COUNT) {
|
splashIndex = 0;
|
||||||
splash = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1424,105 +1501,109 @@ static void showSplash()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allocate memory for the palette
|
||||||
unsigned char* palette = reinterpret_cast<unsigned char*>(internal_malloc(768));
|
unsigned char* palette = reinterpret_cast<unsigned char*>(internal_malloc(768));
|
||||||
if (palette == nullptr) {
|
if (palette == nullptr) {
|
||||||
fileClose(stream);
|
fileClose(stream);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify RIX image version (needed?)
|
||||||
int version;
|
int version;
|
||||||
fileReadInt32(stream, &version);
|
fileReadInt32(stream, &version);
|
||||||
if (version != 'RIX3') {
|
if (version != 'RIX3') {
|
||||||
fileClose(stream);
|
fileClose(stream);
|
||||||
|
internal_free(palette);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
short width;
|
// Read image dimensions
|
||||||
fileRead(&width, sizeof(width), 1, stream);
|
short splashWidth, splashHeight;
|
||||||
|
fileRead(&splashWidth, sizeof(splashWidth), 1, stream);
|
||||||
|
fileRead(&splashHeight, sizeof(splashHeight), 1, stream);
|
||||||
|
|
||||||
short height;
|
// Allocate memory for the image pixel data
|
||||||
fileRead(&height, sizeof(height), 1, stream);
|
unsigned char* splashData = reinterpret_cast<unsigned char*>(internal_malloc(splashWidth * splashHeight));
|
||||||
|
if (splashData == nullptr) {
|
||||||
unsigned char* data = reinterpret_cast<unsigned char*>(internal_malloc(width * height));
|
|
||||||
if (data == nullptr) {
|
|
||||||
internal_free(palette);
|
internal_free(palette);
|
||||||
fileClose(stream);
|
fileClose(stream);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load palette and image data
|
||||||
paletteSetEntries(gPaletteBlack);
|
paletteSetEntries(gPaletteBlack);
|
||||||
fileSeek(stream, 10, SEEK_SET);
|
fileSeek(stream, 10, SEEK_SET);
|
||||||
fileRead(palette, 1, 768, stream);
|
fileRead(palette, 1, 768, stream);
|
||||||
fileRead(data, 1, width * height, stream);
|
fileRead(splashData, 1, splashWidth * splashHeight, stream);
|
||||||
fileClose(stream);
|
fileClose(stream);
|
||||||
|
|
||||||
// Fix of wrong Palette, without it this makes background bright
|
int splashScreenStretchMode = 0;
|
||||||
// Basically just swapping first and last colors, this problem presented ONLY in F2, F1 has right palette in every splash
|
int stretchGameMode = 0;
|
||||||
memcpy(palette + (255 * 3), palette, 3);
|
|
||||||
memset(palette, 0, 3);
|
|
||||||
|
|
||||||
for (int i = 0; i < width * height; i++) {
|
|
||||||
if (data[i] == 0) {
|
|
||||||
data[i] = 255;
|
|
||||||
} else if (data[i] == 255) {
|
|
||||||
data[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int size = 0;
|
|
||||||
|
|
||||||
// TODO: Move to settings.
|
|
||||||
Config config;
|
Config config;
|
||||||
if (configInit(&config)) {
|
if (configInit(&config)) {
|
||||||
if (configRead(&config, "f2_res.ini", false)) {
|
if (configRead(&config, "f2_res.ini", false)) {
|
||||||
configGetInt(&config, "STATIC_SCREENS", "SPLASH_SCRN_SIZE", &size);
|
configGetInt(&config, "STATIC_SCREENS", "SPLASH_SCRN_SIZE", &splashScreenStretchMode);
|
||||||
}
|
|
||||||
|
|
||||||
|
if (configGetInt(&config, "STATIC_SCREENS", "STRETCH_GAME", &stretchGameMode)) {
|
||||||
|
splashScreenStretchMode = stretchGameMode; // always override if key exists
|
||||||
|
}
|
||||||
|
}
|
||||||
configFree(&config);
|
configFree(&config);
|
||||||
}
|
}
|
||||||
|
|
||||||
int screenWidth = screenGetWidth();
|
int screenWidth = screenGetWidth();
|
||||||
int screenHeight = screenGetHeight();
|
int screenHeight = screenGetHeight();
|
||||||
|
|
||||||
if (size != 0 || screenWidth < width || screenHeight < height) {
|
// Stretch image if required or if it doesn't fit the screen
|
||||||
int scaledWidth;
|
if (splashScreenStretchMode != 0 || screenWidth < splashWidth || screenHeight < splashHeight) {
|
||||||
int scaledHeight;
|
int scaledWidth, scaledHeight;
|
||||||
|
|
||||||
if (size == 2) {
|
calculateScaledSize(
|
||||||
scaledWidth = screenWidth;
|
splashWidth,
|
||||||
scaledHeight = screenHeight;
|
splashHeight,
|
||||||
} else {
|
screenWidth,
|
||||||
if (screenHeight * width >= screenWidth * height) {
|
screenHeight,
|
||||||
scaledWidth = screenWidth;
|
splashScreenStretchMode,
|
||||||
scaledHeight = screenWidth * height / width;
|
scaledWidth,
|
||||||
} else {
|
scaledHeight);
|
||||||
scaledWidth = screenHeight * width / height;
|
|
||||||
scaledHeight = screenHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char* scaled = reinterpret_cast<unsigned char*>(internal_malloc(scaledWidth * scaledHeight));
|
unsigned char* scaled = reinterpret_cast<unsigned char*>(internal_malloc((scaledWidth) * (scaledHeight)));
|
||||||
if (scaled != nullptr) {
|
if (scaled != nullptr) {
|
||||||
blitBufferToBufferStretch(data, width, height, width, scaled, scaledWidth, scaledHeight, scaledWidth);
|
// Stretch the splash screen and fix edge artifacts
|
||||||
|
blitBufferToBufferStretchAndFixEdges(
|
||||||
|
splashData,
|
||||||
|
splashWidth,
|
||||||
|
splashHeight,
|
||||||
|
splashWidth,
|
||||||
|
scaled,
|
||||||
|
scaledWidth,
|
||||||
|
scaledHeight,
|
||||||
|
scaledWidth,
|
||||||
|
1 // numStates = 1 for a single splash image
|
||||||
|
);
|
||||||
|
|
||||||
|
int x = (screenWidth > scaledWidth) ? (screenWidth - scaledWidth) / 2 : 0;
|
||||||
|
int y = (screenHeight > scaledHeight) ? (screenHeight - scaledHeight) / 2 : 0;
|
||||||
|
|
||||||
int x = screenWidth > scaledWidth ? (screenWidth - scaledWidth) / 2 : 0;
|
|
||||||
int y = screenHeight > scaledHeight ? (screenHeight - scaledHeight) / 2 : 0;
|
|
||||||
_scr_blit(scaled, scaledWidth, scaledHeight, 0, 0, scaledWidth, scaledHeight, x, y);
|
_scr_blit(scaled, scaledWidth, scaledHeight, 0, 0, scaledWidth, scaledHeight, x, y);
|
||||||
paletteFadeTo(palette);
|
paletteFadeTo(palette);
|
||||||
|
|
||||||
internal_free(scaled);
|
internal_free(scaled);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int x = (screenWidth - width) / 2;
|
// Center image without scaling
|
||||||
int y = (screenHeight - height) / 2;
|
int x = (screenWidth - splashWidth) / 2;
|
||||||
_scr_blit(data, width, height, 0, 0, width, height, x, y);
|
int y = (screenHeight - splashHeight) / 2;
|
||||||
|
_scr_blit(splashData, splashWidth, splashHeight, 0, 0, splashWidth, splashHeight, x, y);
|
||||||
paletteFadeTo(palette);
|
paletteFadeTo(palette);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal_free(data);
|
// Clean up
|
||||||
|
internal_free(splashData);
|
||||||
internal_free(palette);
|
internal_free(palette);
|
||||||
|
|
||||||
settings.system.splash = splash + 1;
|
// Save index for next splash image
|
||||||
|
settings.system.splash = splashIndex + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gameShowDeathDialog(const char* message)
|
int gameShowDeathDialog(const char* message)
|
||||||
|
|||||||
+74
-20
@@ -553,6 +553,15 @@ static int inventoryMessageListFree()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to flip the button buffer horizontally
|
||||||
|
void flipBufferHorizontally(unsigned char* src, int width, int height, int pitch) {
|
||||||
|
for (int y = 0; y < height; y++) {
|
||||||
|
for (int x = 0; x < width / 2; x++) {
|
||||||
|
std::swap(src[y * pitch + x], src[y * pitch + (width - 1 - x)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 0x46E7B0
|
// 0x46E7B0
|
||||||
void inventoryOpen()
|
void inventoryOpen()
|
||||||
{
|
{
|
||||||
@@ -1009,60 +1018,105 @@ static bool _setup_inventory(int inventoryWindowType)
|
|||||||
int fid;
|
int fid;
|
||||||
int btn;
|
int btn;
|
||||||
|
|
||||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
fid = buildFid(OBJ_TYPE_INTERFACE, 299, 0, 0, 0);
|
||||||
_inventoryFrmImages[0].lock(fid);
|
_inventoryFrmImages[0].lock(fid);
|
||||||
|
|
||||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
fid = buildFid(OBJ_TYPE_INTERFACE, 300, 0, 0, 0);
|
||||||
_inventoryFrmImages[1].lock(fid);
|
_inventoryFrmImages[1].lock(fid);
|
||||||
|
|
||||||
|
// Inventory, Use On, and Loot screens have incorrect buttons
|
||||||
|
// Game currently doesn't have the correct button resource
|
||||||
|
// We are going to scale and flip the menu buttons as a temporary solution
|
||||||
|
|
||||||
|
// Base button dimensions
|
||||||
|
int buttonBaseWidth = 26;
|
||||||
|
int buttonBaseHeight = 26;
|
||||||
|
|
||||||
|
int buttonWidth = 21;
|
||||||
|
int buttonHeight = 21;
|
||||||
|
|
||||||
|
unsigned char* scaledNormal = reinterpret_cast<unsigned char*>(SDL_malloc(21 * 21));
|
||||||
|
unsigned char* scaledPressed = reinterpret_cast<unsigned char*>(SDL_malloc(21 * 21));
|
||||||
|
if (!scaledNormal || !scaledPressed) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create flipped copies (to align highlights to top right light source)
|
||||||
|
unsigned char* flippedNormal = reinterpret_cast<unsigned char*>(SDL_malloc(buttonBaseWidth * buttonBaseHeight));
|
||||||
|
unsigned char* flippedPressed = reinterpret_cast<unsigned char*>(SDL_malloc(buttonBaseWidth * buttonBaseHeight));
|
||||||
|
|
||||||
|
if (!flippedNormal || !flippedPressed) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy and flip the original images
|
||||||
|
memcpy(flippedNormal, _inventoryFrmImages[0].getData(), buttonBaseWidth * buttonBaseHeight);
|
||||||
|
memcpy(flippedPressed, _inventoryFrmImages[1].getData(), buttonBaseWidth * buttonBaseHeight);
|
||||||
|
|
||||||
|
// Flip them with the helper
|
||||||
|
flipBufferHorizontally(flippedNormal, buttonBaseWidth, buttonBaseHeight, buttonBaseWidth);
|
||||||
|
flipBufferHorizontally(flippedPressed, buttonBaseWidth, buttonBaseHeight, buttonBaseWidth);
|
||||||
|
|
||||||
|
// Use the flipped buffers as source and scale them
|
||||||
|
blitBufferToBufferStretchAndFixEdges(
|
||||||
|
flippedNormal, buttonBaseWidth, buttonBaseHeight, buttonBaseWidth,
|
||||||
|
scaledNormal, buttonWidth, buttonHeight, buttonWidth);
|
||||||
|
blitBufferToBufferStretchAndFixEdges(
|
||||||
|
flippedPressed, buttonBaseWidth, buttonBaseHeight, buttonBaseWidth,
|
||||||
|
scaledPressed, buttonWidth, buttonHeight, buttonWidth);
|
||||||
|
|
||||||
|
// Free the temp buffers
|
||||||
|
SDL_free(flippedNormal);
|
||||||
|
SDL_free(flippedPressed);
|
||||||
|
|
||||||
if (_inventoryFrmImages[0].isLocked() && _inventoryFrmImages[1].isLocked()) {
|
if (_inventoryFrmImages[0].isLocked() && _inventoryFrmImages[1].isLocked()) {
|
||||||
btn = -1;
|
btn = -1;
|
||||||
switch (inventoryWindowType) {
|
switch (inventoryWindowType) {
|
||||||
case INVENTORY_WINDOW_TYPE_NORMAL:
|
case INVENTORY_WINDOW_TYPE_NORMAL:
|
||||||
// Done button
|
// Done button
|
||||||
btn = buttonCreate(gInventoryWindow,
|
btn = buttonCreate(gInventoryWindow,
|
||||||
437,
|
434,
|
||||||
329,
|
325,
|
||||||
15,
|
21,
|
||||||
16,
|
21,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
KEY_ESCAPE,
|
KEY_ESCAPE,
|
||||||
_inventoryFrmImages[0].getData(),
|
scaledNormal, // scaled and flipped button
|
||||||
_inventoryFrmImages[1].getData(),
|
scaledPressed, // scaled and flipped button
|
||||||
nullptr,
|
nullptr,
|
||||||
BUTTON_FLAG_TRANSPARENT);
|
BUTTON_FLAG_TRANSPARENT);
|
||||||
break;
|
break;
|
||||||
case INVENTORY_WINDOW_TYPE_USE_ITEM_ON:
|
case INVENTORY_WINDOW_TYPE_USE_ITEM_ON:
|
||||||
// Cancel button
|
// Cancel button
|
||||||
btn = buttonCreate(gInventoryWindow,
|
btn = buttonCreate(gInventoryWindow,
|
||||||
233,
|
230,
|
||||||
328,
|
325,
|
||||||
15,
|
21,
|
||||||
16,
|
21,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
KEY_ESCAPE,
|
KEY_ESCAPE,
|
||||||
_inventoryFrmImages[0].getData(),
|
scaledNormal, // scaled and flipped button
|
||||||
_inventoryFrmImages[1].getData(),
|
scaledPressed, // scaled and flipped button
|
||||||
nullptr,
|
nullptr,
|
||||||
BUTTON_FLAG_TRANSPARENT);
|
BUTTON_FLAG_TRANSPARENT);
|
||||||
break;
|
break;
|
||||||
case INVENTORY_WINDOW_TYPE_LOOT:
|
case INVENTORY_WINDOW_TYPE_LOOT:
|
||||||
// Done button
|
// Done button
|
||||||
btn = buttonCreate(gInventoryWindow,
|
btn = buttonCreate(gInventoryWindow,
|
||||||
476,
|
473,
|
||||||
331,
|
327,
|
||||||
15,
|
21,
|
||||||
16,
|
21,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
KEY_ESCAPE,
|
KEY_ESCAPE,
|
||||||
_inventoryFrmImages[0].getData(),
|
scaledNormal, // scaled and flipped button
|
||||||
_inventoryFrmImages[1].getData(),
|
scaledPressed, // scaled and flipped button
|
||||||
nullptr,
|
nullptr,
|
||||||
BUTTON_FLAG_TRANSPARENT);
|
BUTTON_FLAG_TRANSPARENT);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user