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 <cstring>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
#include "color.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
|
||||
|
||||
@@ -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 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 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
|
||||
|
||||
|
||||
+180
-99
@@ -168,6 +168,14 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4
|
||||
int skipOpeningMovies = 0;
|
||||
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) {
|
||||
showSplash();
|
||||
}
|
||||
@@ -341,7 +349,7 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4
|
||||
|
||||
debugPrint(">scr_disable\t");
|
||||
|
||||
if (_init_options_menu() != 0) {
|
||||
if (_init_options_menu() != 0) {
|
||||
debugPrint("Failed on init_options_menu\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -1193,71 +1201,139 @@ static void gameFreeGlobalVars()
|
||||
// 0x443F74
|
||||
static void showHelp()
|
||||
{
|
||||
ScopedGameMode gm(GameMode::kHelp);
|
||||
ScopedGameMode gm(GameMode::kHelp); // Switch to Help game mode.
|
||||
|
||||
bool isoWasEnabled = isoDisable();
|
||||
gameMouseObjectsHide();
|
||||
|
||||
gameMouseSetCursor(MOUSE_CURSOR_NONE);
|
||||
|
||||
bool colorCycleWasEnabled = colorCycleEnabled();
|
||||
colorCycleDisable();
|
||||
|
||||
// CE: Help screen uses separate color palette which is incompatible with
|
||||
// colors in other windows. Setup overlay to hide everything.
|
||||
int overlay = windowCreate(0, 0, screenGetWidth(), screenGetHeight(), 0, WINDOW_HIDDEN | WINDOW_MOVE_ON_TOP);
|
||||
// load the optional stretch setting from f2_res.ini
|
||||
int helpScreenStretchMode = 0;
|
||||
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;
|
||||
int helpWindowY = (screenGetHeight() - HELP_SCREEN_HEIGHT) / 2;
|
||||
int win = windowCreate(helpWindowX, helpWindowY, HELP_SCREEN_WIDTH, HELP_SCREEN_HEIGHT, 0, WINDOW_HIDDEN | WINDOW_MOVE_ON_TOP);
|
||||
if (configGetInt(&config, "STATIC_SCREENS", "STRETCH_GAME", &stretchGameMode)) {
|
||||
helpScreenStretchMode = stretchGameMode; // always override if key exists
|
||||
}
|
||||
}
|
||||
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) {
|
||||
unsigned char* windowBuffer = windowGetBuffer(win);
|
||||
if (windowBuffer != nullptr) {
|
||||
FrmImage backgroundFrmImage;
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 297, 0, 0, 0);
|
||||
if (backgroundFrmImage.lock(backgroundFid)) {
|
||||
paletteSetEntries(gPaletteBlack);
|
||||
blitBufferToBuffer(backgroundFrmImage.getData(), HELP_SCREEN_WIDTH, HELP_SCREEN_HEIGHT, HELP_SCREEN_WIDTH, windowBuffer, HELP_SCREEN_WIDTH);
|
||||
// Clear palette to black before displaying.
|
||||
paletteSetEntries(gPaletteBlack);
|
||||
|
||||
colorPaletteLoad("art\\intrface\\helpscrn.pal");
|
||||
paletteSetEntries(_cmap);
|
||||
// Copy the help image into the window.
|
||||
blitBufferToBuffer(bufferToBlit, blitWidth, blitHeight, blitWidth, windowBuffer, blitWidth);
|
||||
|
||||
// CE: Fill overlay with darkest color in the palette. It might
|
||||
// not be completely black, but at least it's uniform.
|
||||
bufferFill(windowGetBuffer(overlay),
|
||||
screenGetWidth(),
|
||||
screenGetHeight(),
|
||||
screenGetWidth(),
|
||||
intensityColorTable[_colorTable[0]][0]);
|
||||
// Load the help screen's specific palette.
|
||||
colorPaletteLoad("art\\intrface\\helpscrn.pal");
|
||||
paletteSetEntries(_cmap);
|
||||
|
||||
windowShow(overlay);
|
||||
windowShow(win);
|
||||
// Fill the overlay with the darkest palette color to hide everything behind.
|
||||
bufferFill(windowGetBuffer(overlay), screenWidth, screenHeight, screenWidth, intensityColorTable[_colorTable[0]][0]);
|
||||
|
||||
while (inputGetInput() == -1 && _game_user_wants_to_quit == 0) {
|
||||
sharedFpsLimiter.mark();
|
||||
renderPresent();
|
||||
sharedFpsLimiter.throttle();
|
||||
}
|
||||
windowShow(overlay);
|
||||
windowShow(win);
|
||||
|
||||
while (mouseGetEvent() != 0) {
|
||||
sharedFpsLimiter.mark();
|
||||
|
||||
inputGetInput();
|
||||
|
||||
renderPresent();
|
||||
sharedFpsLimiter.throttle();
|
||||
}
|
||||
|
||||
paletteSetEntries(gPaletteBlack);
|
||||
while (inputGetInput() == -1 && _game_user_wants_to_quit == 0) {
|
||||
sharedFpsLimiter.mark();
|
||||
renderPresent();
|
||||
sharedFpsLimiter.throttle();
|
||||
}
|
||||
|
||||
while (mouseGetEvent() != 0) {
|
||||
sharedFpsLimiter.mark();
|
||||
inputGetInput();
|
||||
renderPresent();
|
||||
sharedFpsLimiter.throttle();
|
||||
}
|
||||
|
||||
// Fade back to black.
|
||||
paletteSetEntries(gPaletteBlack);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
windowDestroy(overlay);
|
||||
windowDestroy(win);
|
||||
colorPaletteLoad("color.pal");
|
||||
paletteSetEntries(_cmap);
|
||||
}
|
||||
|
||||
// Free temporary scaled buffer if it was allocated.
|
||||
if (bufferToBlit != helpData) {
|
||||
internal_free(bufferToBlit);
|
||||
}
|
||||
|
||||
// Restore previous state.
|
||||
if (colorCycleWasEnabled) {
|
||||
colorCycleEnable();
|
||||
}
|
||||
@@ -1371,7 +1447,7 @@ static int gameDbInit()
|
||||
char* path_file_name_template = nullptr;
|
||||
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') {
|
||||
path_file_name_template = (char*)"patch%03d.dat";
|
||||
path_file_name_template = "patch%03d.dat";
|
||||
}
|
||||
|
||||
for (patch_index = 0; patch_index < 1000; patch_index++) {
|
||||
@@ -1394,8 +1470,9 @@ static int gameDbInit()
|
||||
// 0x444384
|
||||
static void showSplash()
|
||||
{
|
||||
int splash = settings.system.splash;
|
||||
int splashIndex = settings.system.splash;
|
||||
|
||||
// path to local splash folder
|
||||
char path[64];
|
||||
const char* language = settings.system.language.c_str();
|
||||
if (compat_stricmp(language, ENGLISH) != 0) {
|
||||
@@ -1404,19 +1481,19 @@ static void showSplash()
|
||||
snprintf(path, sizeof(path), "art\\splash\\");
|
||||
}
|
||||
|
||||
File* stream;
|
||||
for (int index = 0; index < SPLASH_COUNT; index++) {
|
||||
// open a splash file, cycle through SPLASH_COUNT entries
|
||||
File* stream = nullptr;
|
||||
for (int attempt = 0; attempt < SPLASH_COUNT; attempt++) {
|
||||
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");
|
||||
if (stream != nullptr) {
|
||||
break;
|
||||
}
|
||||
|
||||
splash++;
|
||||
|
||||
if (splash >= SPLASH_COUNT) {
|
||||
splash = 0;
|
||||
splashIndex++;
|
||||
if (splashIndex >= SPLASH_COUNT) {
|
||||
splashIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1424,105 +1501,109 @@ static void showSplash()
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate memory for the palette
|
||||
unsigned char* palette = reinterpret_cast<unsigned char*>(internal_malloc(768));
|
||||
if (palette == nullptr) {
|
||||
fileClose(stream);
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify RIX image version (needed?)
|
||||
int version;
|
||||
fileReadInt32(stream, &version);
|
||||
if (version != 'RIX3') {
|
||||
fileClose(stream);
|
||||
internal_free(palette);
|
||||
return;
|
||||
}
|
||||
|
||||
short width;
|
||||
fileRead(&width, sizeof(width), 1, stream);
|
||||
// Read image dimensions
|
||||
short splashWidth, splashHeight;
|
||||
fileRead(&splashWidth, sizeof(splashWidth), 1, stream);
|
||||
fileRead(&splashHeight, sizeof(splashHeight), 1, stream);
|
||||
|
||||
short height;
|
||||
fileRead(&height, sizeof(height), 1, stream);
|
||||
|
||||
unsigned char* data = reinterpret_cast<unsigned char*>(internal_malloc(width * height));
|
||||
if (data == nullptr) {
|
||||
// Allocate memory for the image pixel data
|
||||
unsigned char* splashData = reinterpret_cast<unsigned char*>(internal_malloc(splashWidth * splashHeight));
|
||||
if (splashData == nullptr) {
|
||||
internal_free(palette);
|
||||
fileClose(stream);
|
||||
return;
|
||||
}
|
||||
|
||||
// Load palette and image data
|
||||
paletteSetEntries(gPaletteBlack);
|
||||
fileSeek(stream, 10, SEEK_SET);
|
||||
fileRead(palette, 1, 768, stream);
|
||||
fileRead(data, 1, width * height, stream);
|
||||
fileRead(splashData, 1, splashWidth * splashHeight, stream);
|
||||
fileClose(stream);
|
||||
|
||||
// Fix of wrong Palette, without it this makes background bright
|
||||
// Basically just swapping first and last colors, this problem presented ONLY in F2, F1 has right palette in every splash
|
||||
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.
|
||||
int splashScreenStretchMode = 0;
|
||||
int stretchGameMode = 0;
|
||||
Config config;
|
||||
if (configInit(&config)) {
|
||||
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);
|
||||
}
|
||||
|
||||
int screenWidth = screenGetWidth();
|
||||
int screenHeight = screenGetHeight();
|
||||
|
||||
if (size != 0 || screenWidth < width || screenHeight < height) {
|
||||
int scaledWidth;
|
||||
int scaledHeight;
|
||||
// Stretch image if required or if it doesn't fit the screen
|
||||
if (splashScreenStretchMode != 0 || screenWidth < splashWidth || screenHeight < splashHeight) {
|
||||
int scaledWidth, scaledHeight;
|
||||
|
||||
if (size == 2) {
|
||||
scaledWidth = screenWidth;
|
||||
scaledHeight = screenHeight;
|
||||
} else {
|
||||
if (screenHeight * width >= screenWidth * height) {
|
||||
scaledWidth = screenWidth;
|
||||
scaledHeight = screenWidth * height / width;
|
||||
} else {
|
||||
scaledWidth = screenHeight * width / height;
|
||||
scaledHeight = screenHeight;
|
||||
}
|
||||
}
|
||||
calculateScaledSize(
|
||||
splashWidth,
|
||||
splashHeight,
|
||||
screenWidth,
|
||||
screenHeight,
|
||||
splashScreenStretchMode,
|
||||
scaledWidth,
|
||||
scaledHeight);
|
||||
|
||||
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) {
|
||||
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);
|
||||
paletteFadeTo(palette);
|
||||
|
||||
internal_free(scaled);
|
||||
}
|
||||
} else {
|
||||
int x = (screenWidth - width) / 2;
|
||||
int y = (screenHeight - height) / 2;
|
||||
_scr_blit(data, width, height, 0, 0, width, height, x, y);
|
||||
// Center image without scaling
|
||||
int x = (screenWidth - splashWidth) / 2;
|
||||
int y = (screenHeight - splashHeight) / 2;
|
||||
_scr_blit(splashData, splashWidth, splashHeight, 0, 0, splashWidth, splashHeight, x, y);
|
||||
paletteFadeTo(palette);
|
||||
}
|
||||
|
||||
internal_free(data);
|
||||
// Clean up
|
||||
internal_free(splashData);
|
||||
internal_free(palette);
|
||||
|
||||
settings.system.splash = splash + 1;
|
||||
// Save index for next splash image
|
||||
settings.system.splash = splashIndex + 1;
|
||||
}
|
||||
|
||||
int gameShowDeathDialog(const char* message)
|
||||
|
||||
+74
-20
@@ -553,6 +553,15 @@ static int inventoryMessageListFree()
|
||||
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
|
||||
void inventoryOpen()
|
||||
{
|
||||
@@ -1009,60 +1018,105 @@ static bool _setup_inventory(int inventoryWindowType)
|
||||
int fid;
|
||||
int btn;
|
||||
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 299, 0, 0, 0);
|
||||
_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);
|
||||
|
||||
// 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()) {
|
||||
btn = -1;
|
||||
switch (inventoryWindowType) {
|
||||
case INVENTORY_WINDOW_TYPE_NORMAL:
|
||||
// Done button
|
||||
btn = buttonCreate(gInventoryWindow,
|
||||
437,
|
||||
329,
|
||||
15,
|
||||
16,
|
||||
434,
|
||||
325,
|
||||
21,
|
||||
21,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
KEY_ESCAPE,
|
||||
_inventoryFrmImages[0].getData(),
|
||||
_inventoryFrmImages[1].getData(),
|
||||
scaledNormal, // scaled and flipped button
|
||||
scaledPressed, // scaled and flipped button
|
||||
nullptr,
|
||||
BUTTON_FLAG_TRANSPARENT);
|
||||
break;
|
||||
case INVENTORY_WINDOW_TYPE_USE_ITEM_ON:
|
||||
// Cancel button
|
||||
btn = buttonCreate(gInventoryWindow,
|
||||
233,
|
||||
328,
|
||||
15,
|
||||
16,
|
||||
230,
|
||||
325,
|
||||
21,
|
||||
21,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
KEY_ESCAPE,
|
||||
_inventoryFrmImages[0].getData(),
|
||||
_inventoryFrmImages[1].getData(),
|
||||
scaledNormal, // scaled and flipped button
|
||||
scaledPressed, // scaled and flipped button
|
||||
nullptr,
|
||||
BUTTON_FLAG_TRANSPARENT);
|
||||
break;
|
||||
case INVENTORY_WINDOW_TYPE_LOOT:
|
||||
// Done button
|
||||
btn = buttonCreate(gInventoryWindow,
|
||||
476,
|
||||
331,
|
||||
15,
|
||||
16,
|
||||
473,
|
||||
327,
|
||||
21,
|
||||
21,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
KEY_ESCAPE,
|
||||
_inventoryFrmImages[0].getData(),
|
||||
_inventoryFrmImages[1].getData(),
|
||||
scaledNormal, // scaled and flipped button
|
||||
scaledPressed, // scaled and flipped button
|
||||
nullptr,
|
||||
BUTTON_FLAG_TRANSPARENT);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user