mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2de6715dd | ||
|
|
df4b787e86 | ||
|
|
6b442546cc | ||
|
|
2c08cc0b3a | ||
|
|
09a1971cd8 |
@@ -205,6 +205,8 @@ set(FALLOUT_ENGINE_SOURCES
|
||||
"src/proto_types.h"
|
||||
"src/proto.cc"
|
||||
"src/proto.h"
|
||||
"src/prototype_options.cc"
|
||||
"src/prototype_options.h"
|
||||
"src/queue.cc"
|
||||
"src/queue.h"
|
||||
"src/random.cc"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
+161
-9
@@ -1,6 +1,9 @@
|
||||
#include "art.h"
|
||||
|
||||
#include <lodepng.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -134,6 +137,7 @@ static int* gArtCritterFidShoudRunData;
|
||||
|
||||
static std::unordered_map<std::string, std::shared_ptr<NamedCacheEntry>> gNamedArtCache;
|
||||
constexpr int kNamedCacheMaxBytes = 32 * 1024 * 1024; // 32MB soft limit
|
||||
constexpr size_t kMaxNamedPngPixels = 16 * 1024 * 1024;
|
||||
static unsigned int gNamedArtCacheMruCounter = 0;
|
||||
static int gNamedArtCacheCurrentBytes = 0;
|
||||
|
||||
@@ -1116,7 +1120,7 @@ static int artReadFrameData(unsigned char* data, File* stream, int count, int* p
|
||||
// 0x419E1C
|
||||
static int artReadHeader(Art* art, File* stream)
|
||||
{
|
||||
if (fileReadInt32(stream, &(art->field_0)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(art->version)) == -1) return -1;
|
||||
if (fileReadInt16(stream, &(art->framesPerSecond)) == -1) return -1;
|
||||
if (fileReadInt16(stream, &(art->actionFrame)) == -1) return -1;
|
||||
if (fileReadInt16(stream, &(art->frameCount)) == -1) return -1;
|
||||
@@ -1133,13 +1137,137 @@ static int artReadHeader(Art* art, File* stream)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Original function was slightly different, but never used. Basically
|
||||
// it's a memory allocating variant of `artRead` (which reads data into given
|
||||
// buffer). This function is useful to load custom `frm` files since `Art` now
|
||||
// needs more memory then it's on-disk size (due to memory padding).
|
||||
//
|
||||
// 0x419EC0
|
||||
Art* artLoad(const char* path)
|
||||
static bool artPathHasExtension(const char* path, const char* extension)
|
||||
{
|
||||
size_t pathLength = strlen(path);
|
||||
size_t extensionLength = strlen(extension);
|
||||
if (pathLength < extensionLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return compat_stricmp(path + pathLength - extensionLength, extension) == 0;
|
||||
}
|
||||
|
||||
static bool artReadFile(const char* path, std::vector<unsigned char>& data)
|
||||
{
|
||||
int size = 0;
|
||||
if (dbGetFileSize(path, &size) != 0 || size <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data.resize(size);
|
||||
return dbGetFileContents(path, data.data()) == 0;
|
||||
}
|
||||
|
||||
static bool artUnpackIndexedPngPixels(const std::vector<unsigned char>& indexedData, unsigned width, unsigned height, unsigned bitdepth, unsigned char* output)
|
||||
{
|
||||
size_t pixelCount = static_cast<size_t>(width) * static_cast<size_t>(height);
|
||||
if (bitdepth == 8) {
|
||||
if (indexedData.size() < pixelCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(output, indexedData.data(), pixelCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char mask = static_cast<unsigned char>((1 << bitdepth) - 1);
|
||||
size_t neededBytes = (pixelCount * bitdepth + 7) / 8;
|
||||
if (indexedData.size() < neededBytes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t index = 0; index < pixelCount; index++) {
|
||||
size_t bitOffset = index * bitdepth;
|
||||
unsigned char byte = indexedData[bitOffset / 8];
|
||||
unsigned shift = 8 - bitdepth - static_cast<unsigned>(bitOffset % 8);
|
||||
output[index] = (byte >> shift) & mask;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static Art* artLoadIndexedPng(const char* path)
|
||||
{
|
||||
std::vector<unsigned char> encoded;
|
||||
if (!artReadFile(path, encoded)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
lodepng::State state;
|
||||
state.decoder.color_convert = 0;
|
||||
|
||||
std::vector<unsigned char> indexedData;
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
unsigned error = lodepng::decode(indexedData, width, height, state, encoded);
|
||||
if (error != 0) {
|
||||
debugPrint("ART: failed to decode indexed PNG %s: %s\n", path, lodepng_error_text(error));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (state.info_png.color.colortype != LCT_PALETTE) {
|
||||
debugPrint("ART: PNG is not palette-indexed: %s\n", path);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (lodepng_has_palette_alpha(&state.info_png.color)) {
|
||||
debugPrint("ART: indexed PNG transparency is unsupported, reserve palette index 0 instead: %s\n", path);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t pixelCount = static_cast<size_t>(width) * static_cast<size_t>(height);
|
||||
|
||||
if (width == 0 || height == 0 || width > SHRT_MAX || height > SHRT_MAX) {
|
||||
debugPrint("ART: invalid indexed PNG dimensions for %s: %ux%u\n", path, width, height);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (pixelCount > kMaxNamedPngPixels || pixelCount > INT_MAX) {
|
||||
debugPrint("ART: indexed PNG is too large: %s\n", path);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Art header = {};
|
||||
header.version = 4;
|
||||
header.framesPerSecond = 10;
|
||||
header.actionFrame = 0;
|
||||
header.frameCount = 1;
|
||||
header.dataSize = sizeof(ArtFrame) + static_cast<int>(pixelCount);
|
||||
|
||||
int currentPadding = paddingForSize(sizeof(Art));
|
||||
for (int rotation = 0; rotation < ROTATION_COUNT; rotation++) {
|
||||
header.dataOffsets[rotation] = 0;
|
||||
header.padding[rotation] = currentPadding;
|
||||
}
|
||||
|
||||
int dataSize = artGetDataSize(&header);
|
||||
unsigned char* data = reinterpret_cast<unsigned char*>(internal_malloc(dataSize));
|
||||
if (data == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
memset(data, 0, dataSize);
|
||||
Art* art = reinterpret_cast<Art*>(data);
|
||||
*art = header;
|
||||
|
||||
ArtFrame* frame = reinterpret_cast<ArtFrame*>(data + sizeof(Art) + art->padding[0]);
|
||||
frame->width = static_cast<short>(width);
|
||||
frame->height = static_cast<short>(height);
|
||||
frame->size = static_cast<int>(pixelCount);
|
||||
frame->x = 0;
|
||||
frame->y = 0;
|
||||
|
||||
if (!artUnpackIndexedPngPixels(indexedData, width, height, state.info_png.color.bitdepth, reinterpret_cast<unsigned char*>(frame) + sizeof(ArtFrame))) {
|
||||
debugPrint("ART: failed to read indexed PNG pixels: %s\n", path);
|
||||
internal_free(data);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return art;
|
||||
}
|
||||
|
||||
static Art* artLoadFrm(const char* path)
|
||||
{
|
||||
File* stream = fileOpen(path, "rb");
|
||||
if (stream == nullptr) {
|
||||
@@ -1167,6 +1295,30 @@ Art* artLoad(const char* path)
|
||||
return reinterpret_cast<Art*>(data);
|
||||
}
|
||||
|
||||
// NOTE: Original function was slightly different, but never used. Basically
|
||||
// it's a memory allocating variant of `artRead` (which reads data into given
|
||||
// buffer). This function is useful to load custom `frm` files since `Art` now
|
||||
// needs more memory then it's on-disk size (due to memory padding).
|
||||
//
|
||||
// 0x419EC0
|
||||
Art* artLoad(const char* path)
|
||||
{
|
||||
if (path == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (artPathHasExtension(path, ".png")) {
|
||||
return artLoadIndexedPng(path);
|
||||
}
|
||||
|
||||
Art* art = artLoadFrm(path);
|
||||
if (art != nullptr) {
|
||||
return art;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static Art* artLoadLocalized(const char* path)
|
||||
{
|
||||
const char* localizedPath;
|
||||
@@ -1239,7 +1391,7 @@ int artWriteFrameData(unsigned char* data, File* stream, int count)
|
||||
// 0x41A138
|
||||
int artWriteHeader(Art* art, File* stream)
|
||||
{
|
||||
if (fileWriteInt32(stream, art->field_0) == -1) return -1;
|
||||
if (fileWriteInt32(stream, art->version) == -1) return -1;
|
||||
if (fileWriteInt16(stream, art->framesPerSecond) == -1) return -1;
|
||||
if (fileWriteInt16(stream, art->actionFrame) == -1) return -1;
|
||||
if (fileWriteInt16(stream, art->frameCount) == -1) return -1;
|
||||
|
||||
@@ -69,7 +69,7 @@ typedef enum Background {
|
||||
} Background;
|
||||
|
||||
typedef struct Art {
|
||||
int field_0;
|
||||
int version;
|
||||
short framesPerSecond;
|
||||
short actionFrame;
|
||||
short frameCount;
|
||||
|
||||
+4
-4
@@ -779,9 +779,9 @@ static void inventoryLootApplyLayout(int columns)
|
||||
|
||||
static void inventoryNormalLayoutUpdate()
|
||||
{
|
||||
int columns = inventoryChooseColumns(inventoryFrmImage, INVENTORY_WINDOW_WIDTH + INVENTORY_SLOT_WIDTH, INVENTORY_NORMAL_BACKGROUND_FRM_ID, "invbox2.frm");
|
||||
int columns = inventoryChooseColumns(inventoryFrmImage, INVENTORY_WINDOW_WIDTH + INVENTORY_SLOT_WIDTH, INVENTORY_NORMAL_BACKGROUND_FRM_ID, "INVBOX2.PNG");
|
||||
if (columns == 1) {
|
||||
inventoryBackgroundLoad(inventoryFrmImage, INVENTORY_NORMAL_BACKGROUND_FRM_ID, "invbox2.frm", 1);
|
||||
inventoryBackgroundLoad(inventoryFrmImage, INVENTORY_NORMAL_BACKGROUND_FRM_ID, "INVBOX2.PNG", 1);
|
||||
}
|
||||
|
||||
inventoryNormalApplyLayout(columns);
|
||||
@@ -789,9 +789,9 @@ static void inventoryNormalLayoutUpdate()
|
||||
|
||||
static void inventoryLootLayoutUpdate()
|
||||
{
|
||||
int columns = inventoryChooseColumns(inventoryLootFrmImage, INVENTORY_LOOT_WINDOW_WIDTH_EXPANDED, INVENTORY_LOOT_BACKGROUND_FRM_ID, "loot2.frm");
|
||||
int columns = inventoryChooseColumns(inventoryLootFrmImage, INVENTORY_LOOT_WINDOW_WIDTH_EXPANDED, INVENTORY_LOOT_BACKGROUND_FRM_ID, "LOOT2.png");
|
||||
if (columns == 1) {
|
||||
inventoryBackgroundLoad(inventoryLootFrmImage, INVENTORY_LOOT_BACKGROUND_FRM_ID, "loot2.frm", 1);
|
||||
inventoryBackgroundLoad(inventoryLootFrmImage, INVENTORY_LOOT_BACKGROUND_FRM_ID, "LOOT2.png", 1);
|
||||
}
|
||||
|
||||
inventoryLootApplyLayout(columns);
|
||||
|
||||
@@ -147,6 +147,11 @@ int _kb_getch()
|
||||
return rc;
|
||||
}
|
||||
|
||||
int keyboardGetLastScanCode()
|
||||
{
|
||||
return gLastKeyboardEvent.scanCode;
|
||||
}
|
||||
|
||||
// 0x4CBE00 kb_disable
|
||||
void keyboardDisable()
|
||||
{
|
||||
|
||||
@@ -346,6 +346,7 @@ int keyboardInit();
|
||||
void keyboardFree();
|
||||
void keyboardReset();
|
||||
int _kb_getch();
|
||||
int keyboardGetLastScanCode();
|
||||
void keyboardDisable();
|
||||
void keyboardEnable();
|
||||
int keyboardIsDisabled();
|
||||
|
||||
+14
-2
@@ -30,6 +30,7 @@
|
||||
#include "platform_compat.h"
|
||||
#include "preferences.h"
|
||||
#include "proto.h"
|
||||
#include "prototype_options.h"
|
||||
#include "random.h"
|
||||
#include "scripts.h"
|
||||
#include "settings.h"
|
||||
@@ -75,6 +76,7 @@ static bool _main_show_death_scene = false;
|
||||
static bool _main_death_voiceover_done;
|
||||
|
||||
static int commandLineDevLoadGameSlot = -1;
|
||||
static bool commandLineDevOptionsMenu = false;
|
||||
|
||||
// 0x48099C
|
||||
int falloutMain(int argc, char** argv)
|
||||
@@ -111,7 +113,10 @@ int falloutMain(int argc, char** argv)
|
||||
mouseShowCursor();
|
||||
int devLoadGameSlot = commandLineDevLoadGameSlot;
|
||||
int mainMenuRc;
|
||||
if (devLoadGameSlot != -1) {
|
||||
if (commandLineDevOptionsMenu) {
|
||||
commandLineDevOptionsMenu = false;
|
||||
mainMenuRc = MAIN_MENU_PROTOTYPE_OPTIONS;
|
||||
} else if (devLoadGameSlot != -1) {
|
||||
commandLineDevLoadGameSlot = -1;
|
||||
mainMenuRc = MAIN_MENU_LOAD_GAME;
|
||||
} else {
|
||||
@@ -217,6 +222,10 @@ int falloutMain(int argc, char** argv)
|
||||
mainMenuWindowHide(true);
|
||||
doPreferences(true);
|
||||
break;
|
||||
case MAIN_MENU_PROTOTYPE_OPTIONS:
|
||||
mainMenuWindowHide(true);
|
||||
showPrototypeOptionsMenu(true);
|
||||
break;
|
||||
case MAIN_MENU_CREDITS:
|
||||
mainMenuWindowHide(true);
|
||||
creditsOpen("credits.txt", -1, false);
|
||||
@@ -264,9 +273,12 @@ static void mainParseCommandLineArguments(int argc, char** argv)
|
||||
{
|
||||
const char* devLoadGamePrefix = "--dev-load-game=";
|
||||
size_t devLoadGamePrefixLength = strlen(devLoadGamePrefix);
|
||||
const char* devOptionsMenuFlag = "--dev-options-menu";
|
||||
|
||||
for (int arg = 1; arg < argc; arg += 1) {
|
||||
if (strncmp(argv[arg], devLoadGamePrefix, devLoadGamePrefixLength) == 0) {
|
||||
if (strcmp(argv[arg], devOptionsMenuFlag) == 0) {
|
||||
commandLineDevOptionsMenu = true;
|
||||
} else if (strncmp(argv[arg], devLoadGamePrefix, devLoadGamePrefixLength) == 0) {
|
||||
int slot;
|
||||
if (mainTryParseDevLoadGameSlot(argv[arg] + devLoadGamePrefixLength, &slot)) {
|
||||
commandLineDevLoadGameSlot = slot;
|
||||
|
||||
@@ -355,6 +355,10 @@ int mainMenuWindowHandleEvents()
|
||||
if (keyCode == KEY_CTRL_R) {
|
||||
rc = MAIN_MENU_SELFRUN;
|
||||
continue;
|
||||
} else if (keyCode == KEY_UPPERCASE_Z || keyCode == KEY_LOWERCASE_Z) {
|
||||
main_menu_play_sound("nmselec1");
|
||||
rc = MAIN_MENU_PROTOTYPE_OPTIONS;
|
||||
continue;
|
||||
} else if (keyCode == KEY_PLUS || keyCode == KEY_EQUAL) {
|
||||
brightnessIncrease();
|
||||
} else if (keyCode == KEY_MINUS || keyCode == KEY_UNDERSCORE) {
|
||||
|
||||
@@ -14,6 +14,7 @@ typedef enum MainMenuOption {
|
||||
MAIN_MENU_EXIT,
|
||||
MAIN_MENU_SELFRUN,
|
||||
MAIN_MENU_OPTIONS,
|
||||
MAIN_MENU_PROTOTYPE_OPTIONS,
|
||||
} MainMenuOption;
|
||||
|
||||
int mainMenuWindowInit();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
#ifndef FALLOUT_PROTOTYPE_OPTIONS_H_
|
||||
#define FALLOUT_PROTOTYPE_OPTIONS_H_
|
||||
|
||||
namespace fallout {
|
||||
|
||||
int showPrototypeOptionsMenu(bool animated);
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
#endif /* FALLOUT_PROTOTYPE_OPTIONS_H_ */
|
||||
@@ -364,6 +364,16 @@ void sfall_kb_clear_synthetic_key_events()
|
||||
syntheticKeyEvents.clear();
|
||||
}
|
||||
|
||||
int sfall_kb_get_scancode_from_key(int key)
|
||||
{
|
||||
return get_scancode_from_key(key);
|
||||
}
|
||||
|
||||
int sfall_kb_get_key_from_scancode(int sdlScanCode)
|
||||
{
|
||||
return get_key_from_scancode(static_cast<SDL_Scancode>(sdlScanCode));
|
||||
}
|
||||
|
||||
int sfall_kb_handle_key_pressed(int sdlScanCode, bool pressed)
|
||||
{
|
||||
if (!gGameLoaded) return SDL_SCANCODE_UNKNOWN;
|
||||
|
||||
@@ -15,6 +15,9 @@ bool sfall_kb_consume_synthetic_key_event(int sdlScanCode, bool pressed);
|
||||
/// Clears queued synthetic `tap_key` markers after SDL key events are discarded.
|
||||
void sfall_kb_clear_synthetic_key_events();
|
||||
|
||||
int sfall_kb_get_scancode_from_key(int key);
|
||||
int sfall_kb_get_key_from_scancode(int sdlScanCode);
|
||||
|
||||
int sfall_kb_handle_key_pressed(int sdlScanCode, bool pressed);
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
+76
-11
@@ -64,9 +64,15 @@ static void tileRenderRoof(int fid, int x, int y, Rect* rect, int light);
|
||||
static void _draw_grid(int tile, int elevation, Rect* rect);
|
||||
static void tileRenderFloor(int fid, int x, int y, Rect* rect);
|
||||
static int _tile_make_line(int currentCenterTile, int newCenterTile, int* tiles, int tilesCapacity);
|
||||
static void tileToScrollCoord(int tile, int* outX, int* outY);
|
||||
static void debugLogScrollLimitBlock(int tile, int centerCoordX, int centerCoordY, int dudeCoordX, int dudeCoordY, int dx, int dy);
|
||||
static void debugLogScrollObjectBlock(int tile);
|
||||
static void debugLogScrollBorderBlock(int tile, int tileX, int tileY);
|
||||
|
||||
// 0x50E7C7 minus_4_0f
|
||||
static double const dbl_50E7C7 = -4.0;
|
||||
static constexpr int kScrollLimitX = 480;
|
||||
static constexpr int kScrollLimitY = 400;
|
||||
|
||||
// 0x51D950 borderInitialized
|
||||
bool gTileBorderInitialized = false;
|
||||
@@ -484,6 +490,58 @@ static void tileSetBorder(int windowWidth, int windowHeight, int hexGridWidth, i
|
||||
gTileBorderInitialized = true;
|
||||
}
|
||||
|
||||
static void tileToScrollCoord(int tile, int* outX, int* outY)
|
||||
{
|
||||
int x = tile % gHexGridWidth;
|
||||
int y = (tile / gHexGridWidth) + (x / 2);
|
||||
|
||||
*outY = y;
|
||||
*outX = 2 * x - y;
|
||||
}
|
||||
|
||||
static void debugLogScrollLimitBlock(int tile, int centerCoordX, int centerCoordY, int dudeCoordX, int dudeCoordY, int dx, int dy)
|
||||
{
|
||||
int tileCoordX;
|
||||
int tileCoordY;
|
||||
tileToScrollCoord(tile, &tileCoordX, &tileCoordY);
|
||||
|
||||
debugPrint("tileSetCenter: scroll limit blocked tile=%d center=%d dude=%d tileCoord=(%d,%d) centerCoord=(%d,%d) dudeCoord=(%d,%d) dist=(%d,%d) limit=(%d,%d)\n",
|
||||
tile,
|
||||
gCenterTile,
|
||||
gDude != nullptr ? gDude->tile : -1,
|
||||
tileCoordX,
|
||||
tileCoordY,
|
||||
centerCoordX,
|
||||
centerCoordY,
|
||||
dudeCoordX,
|
||||
dudeCoordY,
|
||||
dx,
|
||||
dy,
|
||||
kScrollLimitX,
|
||||
kScrollLimitY);
|
||||
}
|
||||
|
||||
static void debugLogScrollObjectBlock(int tile)
|
||||
{
|
||||
debugPrint("tileSetCenter: scroll blocker object blocked tile=%d center=%d elev=%d\n",
|
||||
tile,
|
||||
gCenterTile,
|
||||
gElevation);
|
||||
}
|
||||
|
||||
static void debugLogScrollBorderBlock(int tile, int tileX, int tileY)
|
||||
{
|
||||
debugPrint("tileSetCenter: tile border blocked tile=%d center=%d tileXY=(%d,%d) borderX=[%d,%d] borderY=[%d,%d]\n",
|
||||
tile,
|
||||
gCenterTile,
|
||||
tileX,
|
||||
tileY,
|
||||
gTileBorderMinX,
|
||||
gTileBorderMaxX,
|
||||
gTileBorderMinY,
|
||||
gTileBorderMaxY);
|
||||
}
|
||||
|
||||
// NOTE: Collapsed.
|
||||
//
|
||||
// 0x4B129C
|
||||
@@ -542,20 +600,25 @@ int tileSetCenter(int tile, int flags)
|
||||
|
||||
if ((flags & TILE_SET_CENTER_FLAG_IGNORE_SCROLL_RESTRICTIONS) == 0) {
|
||||
if (gTileScrollLimitingEnabled) {
|
||||
int tileScreenX;
|
||||
int tileScreenY;
|
||||
tileToScreenXY(tile, &tileScreenX, &tileScreenY);
|
||||
int tileCoordX;
|
||||
int tileCoordY;
|
||||
tileToScrollCoord(tile, &tileCoordX, &tileCoordY);
|
||||
|
||||
int dudeScreenX;
|
||||
int dudeScreenY;
|
||||
tileToScreenXY(gDude->tile, &dudeScreenX, &dudeScreenY);
|
||||
int dudeCoordX;
|
||||
int dudeCoordY;
|
||||
tileToScrollCoord(gDude->tile, &dudeCoordX, &dudeCoordY);
|
||||
|
||||
int dx = abs(dudeScreenX - tileScreenX);
|
||||
int dy = abs(dudeScreenY - tileScreenY);
|
||||
int dx = 16 * abs(tileCoordX - dudeCoordX);
|
||||
int dy = 12 * abs(tileCoordY - dudeCoordY);
|
||||
|
||||
if (dx > abs(dudeScreenX - _tile_offx)
|
||||
|| dy > abs(dudeScreenY - _tile_offy)) {
|
||||
if (dx >= 480 || dy >= 400) {
|
||||
if (dx >= kScrollLimitX || dy >= kScrollLimitY) {
|
||||
int centerCoordX;
|
||||
int centerCoordY;
|
||||
tileToScrollCoord(gCenterTile, ¢erCoordX, ¢erCoordY);
|
||||
|
||||
if (16 * abs(centerCoordX - dudeCoordX) < dx
|
||||
|| 12 * abs(centerCoordY - dudeCoordY) < dy) {
|
||||
debugLogScrollLimitBlock(tile, centerCoordX, centerCoordY, dudeCoordX, dudeCoordY, dx, dy);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -563,6 +626,7 @@ int tileSetCenter(int tile, int flags)
|
||||
|
||||
if (gTileScrollBlockingEnabled && !settings.ui.ignore_map_edges) {
|
||||
if (_obj_scroll_blocking_at(tile, gElevation) == 0) {
|
||||
debugLogScrollObjectBlock(tile);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -573,6 +637,7 @@ int tileSetCenter(int tile, int flags)
|
||||
|
||||
if (gTileBorderInitialized && !settings.ui.ignore_map_edges) {
|
||||
if (tile_x <= gTileBorderMinX || tile_x >= gTileBorderMaxX || tile_y <= gTileBorderMinY || tile_y >= gTileBorderMaxY) {
|
||||
debugLogScrollBorderBlock(tile, tile_x, tile_y);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user