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 | |
|---|---|---|---|
|
|
9e3e94ffd9 | ||
|
|
25e006cffd | ||
|
|
3edd00d85f | ||
|
|
2bfa10411c | ||
|
|
a9eddc1705 |
@@ -75,10 +75,10 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
|
||||
| Global scripts / Global script functions | set_global_script_repeat<br>set_global_script_type<br>available_global_script_types | âś… except available_global_script_types | - |
|
||||
| Combat | attack_is_aimed<br>block_combat<br>force_aimed_shots<br>disable_aimed_shots<br>get_attack_type<br>get/set_bodypart_hit_modifier<br>combat_data<br>get/set/reset_critical_table<br>get_last_target<br>get_last_attacker<br>set_critter_burst_disable<br>get/set_critter_current_ap<br>set_spray_settings<br>get/set_combat_free_move | âś… except block_combat, force_aimed_shots, disable_aimed_shots, get_last_target, get_last_attacker, set_spray_settings | - |
|
||||
| Car | set_car_current_town<br>car_gas_amount<br>set_car_intface_art | implemented: all except set_car_intface_art | - |
|
||||
| Interface / Windows and images | art_frame_data<br>interface_art_draw<br>interface_print<br>draw_image<br>draw_image_scaled<br>get_window_under_mouse<br>create_win<br>get_window_attribute<br>message_box<br>set_window_flag<br>win_fill_color<br>interface_overlay<br>dialog_message<br>get_text_width<br>hide_window<br>show_window<br>create_message_window | âś… except interface_print, draw_image, draw_image_scaled, interface_overlay | - |
|
||||
| Interface / Windows and images | art_frame_data<br>interface_art_draw<br>interface_print<br>draw_image<br>draw_image_scaled<br>get_window_under_mouse<br>create_win<br>get_window_attribute<br>message_box<br>set_window_flag<br>win_fill_color<br>interface_overlay<br>dialog_message<br>get_text_width<br>hide_window<br>show_window<br>create_message_window | implemented: only message_box, get_text_width, show_window, create_message_window | - |
|
||||
| Interface / Outline | outlined_object<br>get_outline<br>set_outline | âś… | - |
|
||||
| Interface / Main interface | intface_is_hidden<br>intface_redraw<br>intface_hide<br>intface_show<br>set_quest_failure_value | implemented: only intface_redraw | `intface_redraw` only supports the zero-argument form; the optional-argument path is explicitly unimplemented. |
|
||||
| Interface / Inventory | display_stats<br>inventory_redraw<br>critter_inven_obj2<br>get_current_inven_size<br>item_weight | âś… except get_current_inven_size | - |
|
||||
| Interface / Inventory | display_stats<br>inventory_redraw<br>critter_inven_obj2<br>get_current_inven_size<br>item_weight | implemented: critter_inven_obj2, item_weight | - |
|
||||
| Interface / Cursor | get/set_cursor_mode | âś… | - |
|
||||
| Locks | lock_is_jammed<br>unjam_lock<br>set_unjam_locks_time | not implemented | - |
|
||||
| INI settings | get_ini_setting<br>get_ini_string<br>get_ini_section<br>get_ini_sections<br>get_ini_config<br>get_ini_config_db<br>set_ini_setting | âś… | `modified_ini` is intentionally omitted as deprecated. |
|
||||
|
||||
+79
-141
@@ -10,7 +10,6 @@
|
||||
|
||||
#include "animation.h"
|
||||
#include "content_config.h"
|
||||
#include "datafile.h"
|
||||
#include "debug.h"
|
||||
#include "draw.h"
|
||||
#include "game.h"
|
||||
@@ -525,6 +524,34 @@ unsigned char* artLockFrameData(int fid, int frame, int direction, CacheEntry**
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 0x4191CC
|
||||
unsigned char* artLockFrameDataReturningSize(int fid, CacheEntry** handlePtr, int* widthPtr, int* heightPtr)
|
||||
{
|
||||
*handlePtr = nullptr;
|
||||
|
||||
Art* art = nullptr;
|
||||
cacheLock(&gArtCache, fid, (void**)&art, handlePtr);
|
||||
|
||||
if (art == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
*widthPtr = artGetWidth(art, 0, 0);
|
||||
if (*widthPtr == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
*heightPtr = artGetHeight(art, 0, 0);
|
||||
if (*heightPtr == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
return artGetFrameData(art, 0, 0);
|
||||
}
|
||||
|
||||
// 0x419260
|
||||
int artUnlock(CacheEntry* handle)
|
||||
{
|
||||
@@ -1194,51 +1221,6 @@ static bool artIndexedPngHasSupportedTransparency(const LodePNGColorMode& color)
|
||||
return true;
|
||||
}
|
||||
|
||||
static Art* artAllocateSingleFrame(int width, int height, unsigned char** frameDataPtr)
|
||||
{
|
||||
if (width <= 0 || height <= 0 || width > SHRT_MAX || height > SHRT_MAX) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t pixelCount = static_cast<size_t>(width) * static_cast<size_t>(height);
|
||||
if (pixelCount > kMaxNamedPngPixels || pixelCount > INT_MAX) {
|
||||
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;
|
||||
|
||||
*frameDataPtr = reinterpret_cast<unsigned char*>(frame) + sizeof(ArtFrame);
|
||||
return art;
|
||||
}
|
||||
|
||||
static Art* artLoadIndexedPng(const char* path)
|
||||
{
|
||||
std::vector<unsigned char> encoded;
|
||||
@@ -1273,44 +1255,47 @@ static Art* artLoadIndexedPng(const char* path)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
unsigned char* frameData = nullptr;
|
||||
Art* art = artAllocateSingleFrame(static_cast<int>(width), static_cast<int>(height), &frameData);
|
||||
if (art == nullptr) {
|
||||
size_t pixelCount = static_cast<size_t>(width) * static_cast<size_t>(height);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!artUnpackIndexedPngPixels(indexedData, width, height, state.info_png.color.bitdepth, frameData)) {
|
||||
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(art);
|
||||
internal_free(data);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return art;
|
||||
}
|
||||
|
||||
static Art* artLoadPcx(const char* path)
|
||||
{
|
||||
char mutablePath[COMPAT_MAX_PATH];
|
||||
strncpy(mutablePath, path, sizeof(mutablePath));
|
||||
mutablePath[sizeof(mutablePath) - 1] = '\0';
|
||||
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
unsigned char* pcxData = datafileRead(mutablePath, &width, &height);
|
||||
if (pcxData == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
unsigned char* frameData = nullptr;
|
||||
Art* art = artAllocateSingleFrame(width, height, &frameData);
|
||||
if (art != nullptr) {
|
||||
memcpy(frameData, pcxData, static_cast<size_t>(width) * static_cast<size_t>(height));
|
||||
}
|
||||
|
||||
internal_free(pcxData);
|
||||
return art;
|
||||
}
|
||||
|
||||
static Art* artLoadFrm(const char* path)
|
||||
{
|
||||
File* stream = fileOpen(path, "rb");
|
||||
@@ -1355,10 +1340,6 @@ Art* artLoad(const char* path)
|
||||
return artLoadIndexedPng(path);
|
||||
}
|
||||
|
||||
if (artPathHasExtension(path, ".pcx")) {
|
||||
return artLoadPcx(path);
|
||||
}
|
||||
|
||||
Art* art = artLoadFrm(path);
|
||||
if (art != nullptr) {
|
||||
return art;
|
||||
@@ -1510,7 +1491,7 @@ public:
|
||||
|
||||
const Art* art() const { return _art.get(); }
|
||||
|
||||
ArtFrame* frame(int frame, int direction) const;
|
||||
unsigned char* frameData(int frame, int direction, int& outWidth, int& outHeight) const;
|
||||
|
||||
unsigned int mru = 0;
|
||||
|
||||
@@ -1523,9 +1504,17 @@ NamedCacheEntry::NamedCacheEntry(ArtPtr&& art)
|
||||
{
|
||||
}
|
||||
|
||||
ArtFrame* NamedCacheEntry::frame(int frame, int direction) const
|
||||
unsigned char* NamedCacheEntry::frameData(int frame, int direction, int& outWidth, int& outHeight) const
|
||||
{
|
||||
return artGetFrame(_art.get(), frame, direction);
|
||||
unsigned char* data = artGetFrameData(_art.get(), frame, direction);
|
||||
if (!data) {
|
||||
outWidth = 0;
|
||||
outHeight = 0;
|
||||
return nullptr;
|
||||
}
|
||||
outWidth = artGetWidth(_art.get(), frame, direction);
|
||||
outHeight = artGetHeight(_art.get(), frame, direction);
|
||||
return data;
|
||||
}
|
||||
|
||||
std::shared_ptr<NamedCacheEntry> artLockNamedFrameData(const char* path)
|
||||
@@ -1608,12 +1597,9 @@ ObjectType FrmId::objectType() const
|
||||
FrmImage::FrmImage()
|
||||
{
|
||||
_key = nullptr;
|
||||
_frame = nullptr;
|
||||
_data = nullptr;
|
||||
_width = 0;
|
||||
_height = 0;
|
||||
_xOffset = 0;
|
||||
_yOffset = 0;
|
||||
}
|
||||
|
||||
FrmImage::~FrmImage()
|
||||
@@ -1624,12 +1610,9 @@ FrmImage::~FrmImage()
|
||||
FrmImage::FrmImage(FrmImage&& other) noexcept
|
||||
: _namedKey(std::move(other._namedKey))
|
||||
, _key(other._key)
|
||||
, _frame(other._frame)
|
||||
, _data(other._data)
|
||||
, _width(other._width)
|
||||
, _height(other._height)
|
||||
, _xOffset(other._xOffset)
|
||||
, _yOffset(other._yOffset)
|
||||
{
|
||||
other.resetInternal();
|
||||
}
|
||||
@@ -1640,12 +1623,9 @@ FrmImage& FrmImage::operator=(FrmImage&& other) noexcept
|
||||
unlock();
|
||||
_namedKey = std::move(other._namedKey);
|
||||
_key = other._key;
|
||||
_frame = other._frame;
|
||||
_data = other._data;
|
||||
_width = other._width;
|
||||
_height = other._height;
|
||||
_xOffset = other._xOffset;
|
||||
_yOffset = other._yOffset;
|
||||
|
||||
other.resetInternal();
|
||||
}
|
||||
@@ -1653,60 +1633,33 @@ FrmImage& FrmImage::operator=(FrmImage&& other) noexcept
|
||||
}
|
||||
|
||||
bool FrmImage::lock(const FrmId& frmId)
|
||||
{
|
||||
return lock(frmId, 0, 0);
|
||||
}
|
||||
|
||||
bool FrmImage::lock(const FrmId& frmId, int frame, int direction)
|
||||
{
|
||||
if (frmId.fid() >= 0) {
|
||||
return lock(frmId.fid(), frame, direction);
|
||||
return lock(frmId.fid());
|
||||
}
|
||||
if (frmId.filePath() != nullptr) {
|
||||
return frmId.hasObjectType()
|
||||
? lock(frmId.objectType(), frmId.filePath(), frame, direction)
|
||||
: lock(frmId.filePath(), frame, direction);
|
||||
? lock(frmId.objectType(), frmId.filePath())
|
||||
: lock(frmId.filePath());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FrmImage::lock(unsigned int fid)
|
||||
{
|
||||
return lock(fid, 0, 0);
|
||||
}
|
||||
|
||||
bool FrmImage::lock(unsigned int fid, int frame, int direction)
|
||||
{
|
||||
if (isLocked()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Art* art = artLock(fid, &_key);
|
||||
if (art == nullptr) {
|
||||
_data = artLockFrameDataReturningSize(fid, &_key, &_width, &_height);
|
||||
if (!_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_frame = artGetFrame(art, frame, direction);
|
||||
if (_frame == nullptr) {
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
_data = reinterpret_cast<unsigned char*>(_frame) + sizeof(ArtFrame);
|
||||
_width = _frame->width;
|
||||
_height = _frame->height;
|
||||
_xOffset = _frame->x;
|
||||
_yOffset = _frame->y;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FrmImage::lock(const char* frmPath)
|
||||
{
|
||||
return lock(frmPath, 0, 0);
|
||||
}
|
||||
|
||||
bool FrmImage::lock(const char* frmPath, int frame, int direction)
|
||||
{
|
||||
if (isLocked()) {
|
||||
return false;
|
||||
@@ -1715,33 +1668,21 @@ bool FrmImage::lock(const char* frmPath, int frame, int direction)
|
||||
_namedKey = artLockNamedFrameData(frmPath);
|
||||
if (!_namedKey) return false;
|
||||
|
||||
_frame = _namedKey->frame(frame, direction);
|
||||
if (_frame == nullptr) {
|
||||
unlock();
|
||||
_data = _namedKey->frameData(0, 0, _width, _height);
|
||||
if (_data == nullptr) {
|
||||
_namedKey = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
_data = reinterpret_cast<unsigned char*>(_frame) + sizeof(ArtFrame);
|
||||
_width = _frame->width;
|
||||
_height = _frame->height;
|
||||
_xOffset = _frame->x;
|
||||
_yOffset = _frame->y;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FrmImage::lock(ObjectType objType, const char* frmRelativePath)
|
||||
{
|
||||
return lock(objType, frmRelativePath, 0, 0);
|
||||
}
|
||||
|
||||
bool FrmImage::lock(ObjectType objType, const char* frmRelativePath, int frame, int direction)
|
||||
{
|
||||
if (objType < OBJ_TYPE_ITEM || objType >= OBJ_TYPE_COUNT) {
|
||||
return false;
|
||||
}
|
||||
snprintf(_art_name, sizeof(_art_name), "%s%s%s\\%s", _cd_path_base, "art\\", gArtListDescriptions[objType].name, frmRelativePath);
|
||||
return lock(_art_name, frame, direction);
|
||||
return lock(_art_name);
|
||||
}
|
||||
|
||||
void FrmImage::unlock()
|
||||
@@ -1756,12 +1697,9 @@ void FrmImage::resetInternal()
|
||||
{
|
||||
_namedKey = nullptr;
|
||||
_key = nullptr;
|
||||
_frame = nullptr;
|
||||
_data = nullptr;
|
||||
_width = 0;
|
||||
_height = 0;
|
||||
_xOffset = 0;
|
||||
_yOffset = 0;
|
||||
}
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
@@ -128,6 +128,7 @@ void artRender(int fid, unsigned char* dest, int width, int height, int pitch);
|
||||
int art_list_str(int fid, char* name);
|
||||
Art* artLock(int fid, CacheEntry** cache_entry);
|
||||
unsigned char* artLockFrameData(int fid, int frame, int direction, CacheEntry** out_cache_entry);
|
||||
unsigned char* artLockFrameDataReturningSize(int fid, CacheEntry** out_cache_entry, int* widthPtr, int* heightPtr);
|
||||
int artUnlock(CacheEntry* cache_entry);
|
||||
int artCacheFlush();
|
||||
int artCopyFileName(int objectType, int id, char* dest);
|
||||
@@ -184,8 +185,8 @@ private:
|
||||
const char* _path = nullptr;
|
||||
};
|
||||
|
||||
// RAII helper for locking one selected frame from FID-backed or path-backed art.
|
||||
// lock/unlock use caches instead of just loading/unloading directly.
|
||||
// A helper for using RAII to read single-frame FRM's.
|
||||
// lock/unlock use the art-cache instead of just loading/unloading directly.
|
||||
class FrmImage {
|
||||
public:
|
||||
FrmImage();
|
||||
@@ -200,19 +201,13 @@ public:
|
||||
|
||||
bool isLocked() const { return _key != nullptr || _namedKey; }
|
||||
bool lock(const FrmId& frmId);
|
||||
bool lock(const FrmId& frmId, int frame, int direction);
|
||||
bool lock(unsigned int fid);
|
||||
bool lock(unsigned int fid, int frame, int direction);
|
||||
bool lock(const char* frmPath);
|
||||
bool lock(const char* frmPath, int frame, int direction);
|
||||
bool lock(ObjectType objType, const char* frmRelativePath);
|
||||
bool lock(ObjectType objType, const char* frmRelativePath, int frame, int direction);
|
||||
void unlock();
|
||||
|
||||
int getWidth() const { return _width; }
|
||||
int getHeight() const { return _height; }
|
||||
int getXOffset() const { return _xOffset; }
|
||||
int getYOffset() const { return _yOffset; }
|
||||
// Returns FRM frame data if locked, nullptr otherwise.
|
||||
unsigned char* getData() const { return _data; }
|
||||
|
||||
@@ -223,12 +218,9 @@ private:
|
||||
|
||||
std::shared_ptr<NamedCacheEntry> _namedKey;
|
||||
CacheEntry* _key = nullptr;
|
||||
ArtFrame* _frame = nullptr;
|
||||
unsigned char* _data = nullptr;
|
||||
int _width = 0;
|
||||
int _height = 0;
|
||||
int _xOffset = 0;
|
||||
int _yOffset = 0;
|
||||
};
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
@@ -46,8 +46,6 @@ static void _decode_map_data(int elevation);
|
||||
static int automapCreate();
|
||||
static int _copy_file_data(File* stream1, File* stream2, int length);
|
||||
|
||||
static int gAutomapWindow = -1;
|
||||
|
||||
typedef enum AutomapFrm {
|
||||
AUTOMAP_FRM_BACKGROUND,
|
||||
AUTOMAP_FRM_BUTTON_UP,
|
||||
@@ -328,7 +326,6 @@ void automapShow(bool isInGame, bool isUsingScanner)
|
||||
int automapWindowY = (screenGetHeight() - AUTOMAP_WINDOW_HEIGHT) / 2;
|
||||
// adding WINDOW_TRANSPARENT and WINDOW_DRAGGABLE_BY_BACKGROUND for testing temporarily
|
||||
int window = windowCreate(automapWindowX, automapWindowY, AUTOMAP_WINDOW_WIDTH, AUTOMAP_WINDOW_HEIGHT, color, WINDOW_MODAL | WINDOW_MOVE_ON_TOP | WINDOW_TRANSPARENT | WINDOW_DRAGGABLE_BY_BACKGROUND);
|
||||
gAutomapWindow = window;
|
||||
|
||||
int scannerBtn = buttonCreate(window,
|
||||
111,
|
||||
@@ -496,16 +493,10 @@ void automapShow(bool isInGame, bool isUsingScanner)
|
||||
}
|
||||
|
||||
windowDestroy(window);
|
||||
gAutomapWindow = -1;
|
||||
fontSetCurrent(oldFont);
|
||||
touch_set_touchscreen_mode(false);
|
||||
}
|
||||
|
||||
int automapGetWindow()
|
||||
{
|
||||
return windowGetWindow(gAutomapWindow) != nullptr ? gAutomapWindow : -1;
|
||||
}
|
||||
|
||||
// Renders automap in Map window.
|
||||
//
|
||||
// 0x41BD1C draw_top_down_map
|
||||
|
||||
@@ -55,7 +55,6 @@ void automapShow(bool isInGame, bool isUsingScanner);
|
||||
int automapRenderInPipboyWindow(int win, int map, int elevation);
|
||||
int automapSaveCurrent();
|
||||
int automapGetHeader(AutomapHeader** automapHeaderPtr);
|
||||
int automapGetWindow();
|
||||
|
||||
void automapSetDisplayMap(int map, bool available);
|
||||
|
||||
|
||||
+30
-30
@@ -112,6 +112,8 @@ typedef enum EditorFolder {
|
||||
EDITOR_FOLDER_KILLS,
|
||||
} EditorFolder;
|
||||
|
||||
static void characterEditorMessageListReset();
|
||||
|
||||
enum {
|
||||
EDITOR_DERIVED_STAT_ARMOR_CLASS,
|
||||
EDITOR_DERIVED_STAT_ACTION_POINTS,
|
||||
@@ -587,6 +589,12 @@ static int gCharacterEditorOptionalTraitBtns[TRAIT_COUNT];
|
||||
// 0x5700E8 mesg
|
||||
static MessageListItem gCharacterEditorMessageListItem;
|
||||
|
||||
static void characterEditorMessageListReset()
|
||||
{
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_EDITOR, nullptr);
|
||||
messageListFree(&gCharacterEditorMessageList);
|
||||
}
|
||||
|
||||
// 0x5700F8 old_str1
|
||||
static char gCharacterEditorCardTitle[48];
|
||||
|
||||
@@ -1284,18 +1292,35 @@ static int characterEditorWindowInit()
|
||||
if (!messageListLoad(&gCharacterEditorMessageList, path)) {
|
||||
return -1;
|
||||
}
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_EDITOR, &gCharacterEditorMessageList);
|
||||
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, (gCharacterEditorIsCreationMode ? 169 : 177), 0, 0, 0);
|
||||
if (!_editorBackgroundFrmImage.lock(fid)) {
|
||||
messageListFree(&gCharacterEditorMessageList);
|
||||
characterEditorMessageListReset();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (karmaInit() == -1) {
|
||||
_editorBackgroundFrmImage.unlock();
|
||||
characterEditorMessageListReset();
|
||||
if (gCharacterEditorIsoWasEnabled) {
|
||||
isoEnable();
|
||||
}
|
||||
colorCycleEnable();
|
||||
gameMouseSetCursor(MOUSE_CURSOR_ARROW);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (genericReputationInit() == -1) {
|
||||
karmaFree();
|
||||
_editorBackgroundFrmImage.unlock();
|
||||
|
||||
characterEditorMessageListReset();
|
||||
if (gCharacterEditorIsoWasEnabled) {
|
||||
isoEnable();
|
||||
}
|
||||
colorCycleEnable();
|
||||
gameMouseSetCursor(MOUSE_CURSOR_ARROW);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1318,11 +1343,9 @@ static int characterEditorWindowInit()
|
||||
while (--i >= 0) {
|
||||
_editorFrmImages[i].unlock();
|
||||
}
|
||||
return -1;
|
||||
|
||||
_editorBackgroundFrmImage.unlock();
|
||||
|
||||
messageListFree(&gCharacterEditorMessageList);
|
||||
characterEditorMessageListReset();
|
||||
|
||||
if (gCharacterEditorIsoWasEnabled) {
|
||||
isoEnable();
|
||||
@@ -1360,7 +1383,7 @@ static int characterEditorWindowInit()
|
||||
|
||||
_editorBackgroundFrmImage.unlock();
|
||||
|
||||
messageListFree(&gCharacterEditorMessageList);
|
||||
characterEditorMessageListReset();
|
||||
if (gCharacterEditorIsoWasEnabled) {
|
||||
isoEnable();
|
||||
}
|
||||
@@ -1389,7 +1412,7 @@ static int characterEditorWindowInit()
|
||||
|
||||
_editorBackgroundFrmImage.unlock();
|
||||
|
||||
messageListFree(&gCharacterEditorMessageList);
|
||||
characterEditorMessageListReset();
|
||||
if (gCharacterEditorIsoWasEnabled) {
|
||||
isoEnable();
|
||||
}
|
||||
@@ -1869,7 +1892,7 @@ static void characterEditorWindowFree()
|
||||
// SFALL: Custom town reputation.
|
||||
customTownReputationFree();
|
||||
|
||||
messageListFree(&gCharacterEditorMessageList);
|
||||
characterEditorMessageListReset();
|
||||
|
||||
interfaceBarRefresh();
|
||||
|
||||
@@ -5680,29 +5703,6 @@ void characterEditorReset()
|
||||
gCharacterEditorLastLevel = 1;
|
||||
}
|
||||
|
||||
int characterEditorGetWindow()
|
||||
{
|
||||
return windowGetWindow(gCharacterEditorWindow) != nullptr ? gCharacterEditorWindow : -1;
|
||||
}
|
||||
|
||||
void characterEditorDisplayStats()
|
||||
{
|
||||
if (windowGetWindow(gCharacterEditorWindow) == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
critterUpdateDerivedStats(gDude);
|
||||
critterAdjustHitPoints(gDude, 0);
|
||||
|
||||
characterEditorDrawSkills(0);
|
||||
characterEditorDrawPrimaryStat(RENDER_ALL_STATS, 0, 0);
|
||||
characterEditorDrawPcStats();
|
||||
characterEditorDrawDerivedStats();
|
||||
characterEditorDrawFolders();
|
||||
characterEditorDrawCard();
|
||||
windowRefresh(gCharacterEditorWindow);
|
||||
}
|
||||
|
||||
// level up if needed
|
||||
//
|
||||
// 0x43C228 UpdateLevel
|
||||
|
||||
@@ -14,8 +14,6 @@ char* _strmfe(char* dest, const char* name, const char* ext);
|
||||
int characterEditorSave(File* stream);
|
||||
int characterEditorLoad(File* stream);
|
||||
void characterEditorReset();
|
||||
int characterEditorGetWindow();
|
||||
void characterEditorDisplayStats();
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
|
||||
+12
-6
@@ -86,6 +86,8 @@ typedef enum GameDialogReviewWindowButtonFrm {
|
||||
GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_COUNT,
|
||||
} GameDialogReviewWindowButtonFrm;
|
||||
|
||||
static void partyMemberCustomizationMessageListReset();
|
||||
|
||||
typedef enum GameDialogReaction {
|
||||
GAME_DIALOG_REACTION_GOOD = 49,
|
||||
GAME_DIALOG_REACTION_NEUTRAL = 50,
|
||||
@@ -583,6 +585,12 @@ static int gGameDialogReviewWindowOldFont;
|
||||
// 0x58F470 gdialog_buttons
|
||||
static int _gdialog_buttons[9];
|
||||
|
||||
static void partyMemberCustomizationMessageListReset()
|
||||
{
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_CUSTOM, nullptr);
|
||||
messageListFree(&gCustomMessageList);
|
||||
}
|
||||
|
||||
// 0x58F4C8 oldFont
|
||||
static int _oldFont;
|
||||
|
||||
@@ -3495,11 +3503,6 @@ bool gameDialogIsBarterWindowExpanded()
|
||||
return gBarterWindowExpanded;
|
||||
}
|
||||
|
||||
int gameDialogGetWindow()
|
||||
{
|
||||
return windowGetWindow(gGameDialogWindow) != nullptr ? gGameDialogWindow : -1;
|
||||
}
|
||||
|
||||
// 0x448660 gdialog_barter_cleanup_tables
|
||||
void gameDialogBarterCleanupTables()
|
||||
{
|
||||
@@ -3971,10 +3974,12 @@ int partyMemberCustomizationWindowInit()
|
||||
if (!messageListLoad(&gCustomMessageList, "game\\custom.msg")) {
|
||||
return -1;
|
||||
}
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_CUSTOM, &gCustomMessageList);
|
||||
|
||||
FrmImage backgroundFrmImage;
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 391, 0, 0, 0);
|
||||
if (!backgroundFrmImage.lock(backgroundFid)) {
|
||||
partyMemberCustomizationMessageListReset();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -4086,6 +4091,7 @@ int partyMemberCustomizationWindowInit()
|
||||
void partyMemberCustomizationWindowFree()
|
||||
{
|
||||
if (gGameDialogWindow == -1) {
|
||||
partyMemberCustomizationMessageListReset();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4123,7 +4129,7 @@ void partyMemberCustomizationWindowFree()
|
||||
windowDestroy(gGameDialogWindow);
|
||||
gGameDialogWindow = -1;
|
||||
|
||||
messageListFree(&gCustomMessageList);
|
||||
partyMemberCustomizationMessageListReset();
|
||||
}
|
||||
|
||||
// 0x449B3C
|
||||
|
||||
@@ -40,7 +40,6 @@ void gameDialogSetBarterModifier(int modifier);
|
||||
int gameDialogBarter(int modifier);
|
||||
void gameDialogEndBarter();
|
||||
bool gameDialogIsBarterWindowExpanded();
|
||||
int gameDialogGetWindow();
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
|
||||
+22
-72
@@ -352,7 +352,6 @@ static void inventoryNormalLayoutUpdate();
|
||||
static bool inventoryBackgroundLoad(FrmImage& image, int col1FrmId, const char* col2Name, int columns);
|
||||
static int inventoryChooseColumns(FrmImage& image, int expandedWidth, int col1FrmId, const char* col2Name);
|
||||
static void inventoryCreateSlotButtons(int baseKeyCode, int scrollerX, int scrollerY, int columns);
|
||||
static bool inventoryGetCurrentWindowType(InventoryWindowType* inventoryWindowTypePtr);
|
||||
static int inventoryGetWindowWidth(int inventoryWindowType);
|
||||
static int inventoryGetWindowHeight(int inventoryWindowType);
|
||||
static void inventoryNormalClampStackOffset();
|
||||
@@ -696,31 +695,6 @@ static void inventoryCreateSlotButtons(int baseKeyCode, int scrollerX, int scrol
|
||||
}
|
||||
}
|
||||
|
||||
static bool inventoryGetCurrentWindowType(InventoryWindowType* inventoryWindowTypePtr)
|
||||
{
|
||||
if (GameMode::isInGameMode(GameMode::kBarter)) {
|
||||
*inventoryWindowTypePtr = INVENTORY_WINDOW_TYPE_TRADE;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GameMode::isInGameMode(GameMode::kLoot)) {
|
||||
*inventoryWindowTypePtr = INVENTORY_WINDOW_TYPE_LOOT;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GameMode::isInGameMode(GameMode::kUseOn)) {
|
||||
*inventoryWindowTypePtr = INVENTORY_WINDOW_TYPE_USE_ITEM_ON;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GameMode::isInGameMode(GameMode::kInventory)) {
|
||||
*inventoryWindowTypePtr = INVENTORY_WINDOW_TYPE_NORMAL;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int inventoryGetWindowWidth(int inventoryWindowType)
|
||||
{
|
||||
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_NORMAL) return inventoryLayout.windowWidth;
|
||||
@@ -963,6 +937,7 @@ static int inventoryMessageListInit()
|
||||
if (!messageListLoad(&gInventoryMessageList, path))
|
||||
return -1;
|
||||
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_INVENTORY, &gInventoryMessageList);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -970,6 +945,7 @@ static int inventoryMessageListInit()
|
||||
// 0x46E7A0
|
||||
static int inventoryMessageListFree()
|
||||
{
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_INVENTORY, nullptr);
|
||||
messageListFree(&gInventoryMessageList);
|
||||
return 0;
|
||||
}
|
||||
@@ -983,6 +959,8 @@ void inventoryOpen()
|
||||
}
|
||||
}
|
||||
|
||||
ScopedGameMode gm(GameMode::kInventory);
|
||||
|
||||
if (inventoryCommonInit() == -1) {
|
||||
return;
|
||||
}
|
||||
@@ -1021,7 +999,6 @@ void inventoryOpen()
|
||||
inventoryRenderSummary();
|
||||
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_NORMAL);
|
||||
inventorySetCursor(INVENTORY_WINDOW_CURSOR_HAND);
|
||||
ScopedGameMode gm(GameMode::kInventory);
|
||||
|
||||
for (;;) {
|
||||
sharedFpsLimiter.mark();
|
||||
@@ -2768,6 +2745,8 @@ static void _adjust_fid()
|
||||
// 0x4717E4
|
||||
void inventoryOpenUseItemOn(Object* targetObj)
|
||||
{
|
||||
ScopedGameMode gm(GameMode::kUseOn);
|
||||
|
||||
if (inventoryCommonInit() == -1) {
|
||||
return;
|
||||
}
|
||||
@@ -2775,7 +2754,6 @@ void inventoryOpenUseItemOn(Object* targetObj)
|
||||
bool isoWasEnabled = _setup_inventory(INVENTORY_WINDOW_TYPE_USE_ITEM_ON);
|
||||
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_USE_ITEM_ON);
|
||||
inventorySetCursor(INVENTORY_WINDOW_CURSOR_HAND);
|
||||
ScopedGameMode gm(GameMode::kUseOn);
|
||||
for (;;) {
|
||||
sharedFpsLimiter.mark();
|
||||
|
||||
@@ -3112,7 +3090,7 @@ int objectGetCarriedQuantityByPid(Object* object, int pid)
|
||||
// Renders character's summary of SPECIAL stats, equipped armor bonuses,
|
||||
// and weapon's damage/range.
|
||||
//
|
||||
// 0x471D5C display_stats
|
||||
// 0x471D5C
|
||||
static void inventoryRenderSummary()
|
||||
{
|
||||
int summaryStats[7];
|
||||
@@ -4374,6 +4352,8 @@ int inventoryOpenLooting(Object* looter, Object* target)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ScopedGameMode gm(GameMode::kLoot);
|
||||
|
||||
if (FID_TYPE(target->fid) == OBJ_TYPE_CRITTER) {
|
||||
if (critterFlagCheck(target->pid, CRITTER_NO_STEAL)) {
|
||||
// You can't find anything to take from that.
|
||||
@@ -4439,7 +4419,6 @@ int inventoryOpenLooting(Object* looter, Object* target)
|
||||
}
|
||||
|
||||
bool isoWasEnabled = _setup_inventory(INVENTORY_WINDOW_TYPE_LOOT);
|
||||
ScopedGameMode gm(GameMode::kLoot);
|
||||
|
||||
Object** critters = nullptr;
|
||||
int critterCount = 0;
|
||||
@@ -6361,46 +6340,6 @@ int inventorySetTimer(Object* item)
|
||||
return seconds;
|
||||
}
|
||||
|
||||
int inventoryGetWindow()
|
||||
{
|
||||
return windowGetWindow(gInventoryWindow) != nullptr ? gInventoryWindow : -1;
|
||||
}
|
||||
|
||||
void inventoryDisplayStats()
|
||||
{
|
||||
if (windowGetWindow(gInventoryWindow) == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
inventoryRenderSummary();
|
||||
windowRefresh(gInventoryWindow);
|
||||
}
|
||||
|
||||
void inventoryRedraw(int redrawSide)
|
||||
{
|
||||
if (windowGetWindow(gInventoryWindow) == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
InventoryWindowType inventoryWindowType;
|
||||
if (!inventoryGetCurrentWindowType(&inventoryWindowType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (redrawSide <= 0) {
|
||||
_stack_offset[_curr_stack] = 0;
|
||||
_display_inventory(0, -1, inventoryWindowType);
|
||||
}
|
||||
|
||||
if (redrawSide != 0
|
||||
&& (inventoryWindowType == INVENTORY_WINDOW_TYPE_LOOT
|
||||
|| inventoryWindowType == INVENTORY_WINDOW_TYPE_TRADE)) {
|
||||
_target_stack_offset[_target_curr_stack] = 0;
|
||||
_display_target_inventory(0, -1, _target_pud, inventoryWindowType);
|
||||
windowRefresh(gInventoryWindow);
|
||||
}
|
||||
}
|
||||
|
||||
Object* inventoryGetTargetObject()
|
||||
{
|
||||
return _target_stack[_target_curr_stack];
|
||||
@@ -6413,8 +6352,10 @@ int inventoryUnwieldSlot(Object* critter, InvenSlot slot)
|
||||
}
|
||||
|
||||
bool isDude = critter == gDude;
|
||||
InventoryWindowType inventoryWindowType;
|
||||
bool uiModeActive = inventoryGetCurrentWindowType(&inventoryWindowType);
|
||||
bool uiModeActive = GameMode::isInGameMode(GameMode::kInventory)
|
||||
|| GameMode::isInGameMode(GameMode::kUseOn)
|
||||
|| GameMode::isInGameMode(GameMode::kLoot)
|
||||
|| GameMode::isInGameMode(GameMode::kBarter);
|
||||
bool update = false;
|
||||
|
||||
if (slot != InvenSlot::Armor && !uiModeActive) {
|
||||
@@ -6504,6 +6445,15 @@ int inventoryUnwieldSlot(Object* critter, InvenSlot slot)
|
||||
return 0;
|
||||
}
|
||||
|
||||
InventoryWindowType inventoryWindowType = INVENTORY_WINDOW_TYPE_NORMAL;
|
||||
if (GameMode::isInGameMode(GameMode::kBarter)) {
|
||||
inventoryWindowType = INVENTORY_WINDOW_TYPE_TRADE;
|
||||
} else if (GameMode::isInGameMode(GameMode::kLoot)) {
|
||||
inventoryWindowType = INVENTORY_WINDOW_TYPE_LOOT;
|
||||
} else if (GameMode::isInGameMode(GameMode::kUseOn)) {
|
||||
inventoryWindowType = INVENTORY_WINDOW_TYPE_USE_ITEM_ON;
|
||||
}
|
||||
|
||||
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_NORMAL) {
|
||||
inventoryRenderSummary();
|
||||
}
|
||||
|
||||
@@ -62,9 +62,6 @@ int inventoryOpenLooting(Object* looter, Object* target);
|
||||
int inventoryOpenStealing(Object* thief, Object* target);
|
||||
void barterProcessUI(int win, Object* barterer, Object* playerTable, Object* bartererTable, int barterMod);
|
||||
int inventorySetTimer(Object* item);
|
||||
int inventoryGetWindow();
|
||||
void inventoryDisplayStats();
|
||||
void inventoryRedraw(int redrawSide);
|
||||
Object* inventoryGetTargetObject();
|
||||
int inventoryUnwieldSlot(Object* critter, InvenSlot slot);
|
||||
|
||||
|
||||
+18
-6
@@ -120,6 +120,8 @@ typedef enum LoadSaveScrollDirection {
|
||||
LOAD_SAVE_SCROLL_DIRECTION_DOWN,
|
||||
} LoadSaveScrollDirection;
|
||||
|
||||
static void loadSaveMessageListReset();
|
||||
|
||||
typedef struct LoadSaveSlotData {
|
||||
char signature[24];
|
||||
short versionMinor;
|
||||
@@ -330,6 +332,12 @@ static char _str1[COMPAT_MAX_PATH];
|
||||
// 0x6145FC str
|
||||
static char _str[COMPAT_MAX_PATH];
|
||||
|
||||
static void loadSaveMessageListReset()
|
||||
{
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_LSGAME, nullptr);
|
||||
messageListFree(&gLoadSaveMessageList);
|
||||
}
|
||||
|
||||
// 0x614700 lsgbuf
|
||||
static unsigned char* gLoadSaveWindowBuffer;
|
||||
|
||||
@@ -459,6 +467,7 @@ int lsgSaveGame(int mode)
|
||||
if (!messageListLoad(&gLoadSaveMessageList, path)) {
|
||||
return -1;
|
||||
}
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_LSGAME, &gLoadSaveMessageList);
|
||||
|
||||
_snapshotBuf = nullptr;
|
||||
int v6 = _QuickSnapShot();
|
||||
@@ -476,6 +485,7 @@ int lsgSaveGame(int mode)
|
||||
gameMouseSetCursor(MOUSE_CURSOR_ARROW);
|
||||
|
||||
if (v6 != -1) {
|
||||
loadSaveMessageListReset();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -491,7 +501,7 @@ int lsgSaveGame(int mode)
|
||||
};
|
||||
showDialogBox(_str0, body, 1, 169, 116, _colorTable[32328], nullptr, _colorTable[32328], DIALOG_BOX_LARGE);
|
||||
|
||||
messageListFree(&gLoadSaveMessageList);
|
||||
loadSaveMessageListReset();
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -1092,6 +1102,7 @@ int lsgLoadGame(int mode)
|
||||
if (!messageListLoad(&gLoadSaveMessageList, path)) {
|
||||
return -1;
|
||||
}
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_LSGAME, &gLoadSaveMessageList);
|
||||
|
||||
if (window != -1) {
|
||||
windowDestroy(window);
|
||||
@@ -1103,7 +1114,7 @@ int lsgLoadGame(int mode)
|
||||
strcpy(_str1, getmsg(&gLoadSaveMessageList, &messageListItem, 135));
|
||||
showDialogBox(_str0, body, 1, 169, 116, _colorTable[32328], nullptr, _colorTable[32328], DIALOG_BOX_LARGE);
|
||||
|
||||
messageListFree(&gLoadSaveMessageList);
|
||||
loadSaveMessageListReset();
|
||||
mapNewMap();
|
||||
_game_user_wants_to_quit = GAME_QUIT_REQUEST_MAIN_MENU;
|
||||
|
||||
@@ -1597,10 +1608,11 @@ static int lsgWindowInit(int windowType)
|
||||
if (!messageListLoad(&gLoadSaveMessageList, _str)) {
|
||||
return -1;
|
||||
}
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_LSGAME, &gLoadSaveMessageList);
|
||||
|
||||
_snapshot = (unsigned char*)internal_malloc(61632);
|
||||
if (_snapshot == nullptr) {
|
||||
messageListFree(&gLoadSaveMessageList);
|
||||
loadSaveMessageListReset();
|
||||
fontSetCurrent(gLoadSaveWindowOldFont);
|
||||
return -1;
|
||||
}
|
||||
@@ -1652,7 +1664,7 @@ static int lsgWindowInit(int windowType)
|
||||
_loadsaveFrmImages[index].unlock();
|
||||
}
|
||||
internal_free(_snapshot);
|
||||
messageListFree(&gLoadSaveMessageList);
|
||||
loadSaveMessageListReset();
|
||||
fontSetCurrent(gLoadSaveWindowOldFont);
|
||||
|
||||
if (windowType != LOAD_SAVE_WINDOW_TYPE_LOAD_GAME_FROM_MAIN_MENU) {
|
||||
@@ -1678,7 +1690,7 @@ static int lsgWindowInit(int windowType)
|
||||
if (gLoadSaveWindow == -1) {
|
||||
// FIXME: Leaking frms.
|
||||
internal_free(_snapshot);
|
||||
messageListFree(&gLoadSaveMessageList);
|
||||
loadSaveMessageListReset();
|
||||
fontSetCurrent(gLoadSaveWindowOldFont);
|
||||
|
||||
if (windowType != LOAD_SAVE_WINDOW_TYPE_LOAD_GAME_FROM_MAIN_MENU) {
|
||||
@@ -1816,7 +1828,7 @@ static int lsgWindowFree(int windowType)
|
||||
|
||||
windowDestroy(gLoadSaveWindow);
|
||||
fontSetCurrent(gLoadSaveWindowOldFont);
|
||||
messageListFree(&gLoadSaveMessageList);
|
||||
loadSaveMessageListReset();
|
||||
|
||||
for (int index = 0; index < LOAD_SAVE_FRM_COUNT; index++) {
|
||||
_loadsaveFrmImages[index].unlock();
|
||||
|
||||
+2
-4
@@ -183,13 +183,12 @@ bool messageListInit(MessageList* messageList)
|
||||
// 0x484964 message_exit
|
||||
bool messageListFree(MessageList* messageList)
|
||||
{
|
||||
int i;
|
||||
MessageListItem* entry;
|
||||
|
||||
if (messageList == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int i;
|
||||
MessageListItem* entry;
|
||||
for (i = 0; i < messageList->entries_num; i++) {
|
||||
entry = &(messageList->entries[i]);
|
||||
|
||||
@@ -212,7 +211,6 @@ bool messageListFree(MessageList* messageList)
|
||||
return true;
|
||||
}
|
||||
|
||||
// message_load
|
||||
// 0x484AA4 message_load
|
||||
bool messageListLoad(MessageList* messageList, const char* path)
|
||||
{
|
||||
|
||||
+13
-23
@@ -12,41 +12,31 @@ namespace fallout {
|
||||
// CE: Working with standard message lists is tricky in Sfall. Many message
|
||||
// lists are initialized only for the duration of appropriate modal window. This
|
||||
// is not documented in Sfall and shifts too much responsibility to scripters
|
||||
// (who should check game mode before accessing volatile message lists). For now
|
||||
// CE only exposes persistent standard message lists:
|
||||
// - combat.msg
|
||||
// - combatai.msg
|
||||
// - scrname.msg
|
||||
// - misc.msg
|
||||
// - item.msg
|
||||
// - map.msg
|
||||
// - proto.msg
|
||||
// - script.msg
|
||||
// - skill.msg
|
||||
// - stat.msg
|
||||
// - trait.msg
|
||||
// - worldmap.msg
|
||||
// (who should check game mode before accessing volatile message lists). CE
|
||||
// always exposes persistent standard message lists and additionally exposes
|
||||
// some volatile lists for the duration of their UI lifetime:
|
||||
enum StandardMessageList {
|
||||
STANDARD_MESSAGE_LIST_COMBAT,
|
||||
STANDARD_MESSAGE_LIST_COMBAT_AI,
|
||||
STANDARD_MESSAGE_LIST_COMBAT, // transient
|
||||
STANDARD_MESSAGE_LIST_COMBAT_AI, // transient
|
||||
STANDARD_MESSAGE_LIST_SCRNAME,
|
||||
STANDARD_MESSAGE_LIST_MISC,
|
||||
STANDARD_MESSAGE_LIST_CUSTOM,
|
||||
STANDARD_MESSAGE_LIST_INVENTORY,
|
||||
STANDARD_MESSAGE_LIST_CUSTOM, // transient
|
||||
STANDARD_MESSAGE_LIST_INVENTORY, // transient
|
||||
STANDARD_MESSAGE_LIST_ITEM,
|
||||
STANDARD_MESSAGE_LIST_LSGAME,
|
||||
STANDARD_MESSAGE_LIST_LSGAME, // transient
|
||||
STANDARD_MESSAGE_LIST_MAP,
|
||||
STANDARD_MESSAGE_LIST_OPTIONS,
|
||||
STANDARD_MESSAGE_LIST_OPTIONS, // transient
|
||||
STANDARD_MESSAGE_LIST_PERK,
|
||||
STANDARD_MESSAGE_LIST_PIPBOY,
|
||||
STANDARD_MESSAGE_LIST_QUESTS,
|
||||
STANDARD_MESSAGE_LIST_PIPBOY, // transient
|
||||
STANDARD_MESSAGE_LIST_QUESTS, // transient
|
||||
STANDARD_MESSAGE_LIST_PROTO,
|
||||
STANDARD_MESSAGE_LIST_SCRIPT,
|
||||
STANDARD_MESSAGE_LIST_SKILL,
|
||||
STANDARD_MESSAGE_LIST_SKILLDEX,
|
||||
STANDARD_MESSAGE_LIST_SKILLDEX, // transient
|
||||
STANDARD_MESSAGE_LIST_STAT,
|
||||
STANDARD_MESSAGE_LIST_TRAIT,
|
||||
STANDARD_MESSAGE_LIST_WORLDMAP,
|
||||
STANDARD_MESSAGE_LIST_EDITOR, // transient; yes, this is supposed to be at the end rather than alphabetical
|
||||
STANDARD_MESSAGE_LIST_COUNT,
|
||||
};
|
||||
|
||||
|
||||
+16
-25
@@ -43,6 +43,7 @@ typedef enum OptionsWindowFrm {
|
||||
static int optionsWindowInit();
|
||||
static int optionsWindowFree();
|
||||
static void _ShadeScreen(bool preserveWorldState);
|
||||
static void optionsMessageListReset();
|
||||
|
||||
// 0x48FC0C
|
||||
static const int gPauseWindowFrmIds[PAUSE_WINDOW_FRM_COUNT] = {
|
||||
@@ -74,8 +75,6 @@ static bool gOptionsWindowGameMouseObjectsWasVisible;
|
||||
// 0x663900 optnwin
|
||||
static int gOptionsWindow;
|
||||
|
||||
static int gPauseWindow = -1;
|
||||
|
||||
// 0x663908 winbuf
|
||||
static unsigned char* gOptionsWindowBuffer;
|
||||
|
||||
@@ -87,6 +86,12 @@ static bool gOptionsWindowIsoWasEnabled;
|
||||
|
||||
static FrmImage _optionsFrmImages[OPTIONS_WINDOW_FRM_COUNT];
|
||||
|
||||
static void optionsMessageListReset()
|
||||
{
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_OPTIONS, nullptr);
|
||||
messageListFree(&gPreferencesMessageList);
|
||||
}
|
||||
|
||||
// 0x48FC50 do_optionsFunc
|
||||
int showOptions()
|
||||
{
|
||||
@@ -138,6 +143,7 @@ int showOptions()
|
||||
case 502:
|
||||
// PREFERENCES
|
||||
doPreferences(false);
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_OPTIONS, &gPreferencesMessageList);
|
||||
break;
|
||||
case KEY_PLUS:
|
||||
case KEY_EQUAL:
|
||||
@@ -184,6 +190,7 @@ static int optionsWindowInit()
|
||||
if (!messageListLoad(&gPreferencesMessageList, path)) {
|
||||
return -1;
|
||||
}
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_OPTIONS, &gPreferencesMessageList);
|
||||
|
||||
for (int index = 0; index < OPTIONS_WINDOW_FRM_COUNT; index++) {
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gOptionsWindowFrmIds[index], 0, 0, 0);
|
||||
@@ -192,7 +199,7 @@ static int optionsWindowInit()
|
||||
_optionsFrmImages[index].unlock();
|
||||
}
|
||||
|
||||
messageListFree(&gPreferencesMessageList);
|
||||
optionsMessageListReset();
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -210,7 +217,7 @@ static int optionsWindowInit()
|
||||
_optionsFrmImages[index].unlock();
|
||||
}
|
||||
|
||||
messageListFree(&gPreferencesMessageList);
|
||||
optionsMessageListReset();
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -238,7 +245,7 @@ static int optionsWindowInit()
|
||||
_optionsFrmImages[index].unlock();
|
||||
}
|
||||
|
||||
messageListFree(&gPreferencesMessageList);
|
||||
optionsMessageListReset();
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -305,9 +312,8 @@ static int optionsWindowInit()
|
||||
static int optionsWindowFree()
|
||||
{
|
||||
windowDestroy(gOptionsWindow);
|
||||
gOptionsWindow = -1;
|
||||
fontSetCurrent(gOptionsWindowOldFont);
|
||||
messageListFree(&gPreferencesMessageList);
|
||||
optionsMessageListReset();
|
||||
|
||||
for (int index = 0; index < OPTIONS_WINDOW_BUTTONS_COUNT; index++) {
|
||||
internal_free(_opbtns[index]);
|
||||
@@ -368,6 +374,7 @@ int showPause(bool preserveWorldState)
|
||||
// FIXME: Leaking graphics.
|
||||
return -1;
|
||||
}
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_OPTIONS, &gPreferencesMessageList);
|
||||
|
||||
int pauseWindowX = (screenGetWidth() - frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getWidth()) / 2;
|
||||
int pauseWindowY = (screenGetHeight() - frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getHeight()) / 2;
|
||||
@@ -386,14 +393,12 @@ int showPause(bool preserveWorldState)
|
||||
256,
|
||||
WINDOW_MODAL | WINDOW_DONT_MOVE_TOP);
|
||||
if (window == -1) {
|
||||
messageListFree(&gPreferencesMessageList);
|
||||
optionsMessageListReset();
|
||||
|
||||
debugPrint("\n** Error opening pause window! **\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gPauseWindow = window;
|
||||
|
||||
unsigned char* windowBuffer = windowGetBuffer(window);
|
||||
memcpy(windowBuffer,
|
||||
frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getData(),
|
||||
@@ -482,8 +487,7 @@ int showPause(bool preserveWorldState)
|
||||
}
|
||||
|
||||
windowDestroy(window);
|
||||
gPauseWindow = -1;
|
||||
messageListFree(&gPreferencesMessageList);
|
||||
optionsMessageListReset();
|
||||
|
||||
if (!preserveWorldState) {
|
||||
if (gameMouseWasVisible) {
|
||||
@@ -535,17 +539,4 @@ int _init_options_menu()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int optionsGetWindow()
|
||||
{
|
||||
if (windowGetWindow(gOptionsWindow) != nullptr) {
|
||||
return gOptionsWindow;
|
||||
}
|
||||
|
||||
if (windowGetWindow(gPauseWindow) != nullptr) {
|
||||
return gPauseWindow;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
@@ -6,7 +6,6 @@ namespace fallout {
|
||||
int showOptions();
|
||||
int showPause(bool preserveWorldState);
|
||||
int _init_options_menu();
|
||||
int optionsGetWindow();
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
|
||||
+6
-5
@@ -595,6 +595,7 @@ int pipboyMessageListInit()
|
||||
if (!(messageListLoad(&gPipboyMessageList, path))) {
|
||||
return -1;
|
||||
}
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_PIPBOY, &gPipboyMessageList);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -602,6 +603,7 @@ int pipboyMessageListInit()
|
||||
void pipboyMessageListFree()
|
||||
{
|
||||
if (gPipboyMessageList.entries != nullptr) {
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_PIPBOY, nullptr);
|
||||
messageListFree(&gPipboyMessageList);
|
||||
}
|
||||
messageListInit(&gPipboyMessageList);
|
||||
@@ -1014,11 +1016,6 @@ int pipboyLoad(File* stream)
|
||||
return _save_pipboy(stream);
|
||||
}
|
||||
|
||||
int pipboyGetWindow()
|
||||
{
|
||||
return windowGetWindow(gPipboyWindow) != nullptr ? gPipboyWindow : -1;
|
||||
}
|
||||
|
||||
// 0x497BD8
|
||||
static void pipboyWindowHandleStatus(int userInput)
|
||||
{
|
||||
@@ -2702,6 +2699,7 @@ static int questInit()
|
||||
|
||||
File* stream = fileOpen("data\\quests.txt", "rt");
|
||||
if (stream == nullptr) {
|
||||
messageListFree(&gQuestsMessageList);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2769,12 +2767,14 @@ static int questInit()
|
||||
qsort(gQuestDescriptions, gQuestsCount, sizeof(*gQuestDescriptions), questDescriptionCompare);
|
||||
|
||||
fileClose(stream);
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_QUESTS, &gQuestsMessageList);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
|
||||
fileClose(stream);
|
||||
messageListFree(&gQuestsMessageList);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -2789,6 +2789,7 @@ static void questFree()
|
||||
|
||||
gQuestsCount = 0;
|
||||
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_QUESTS, nullptr);
|
||||
messageListFree(&gQuestsMessageList);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ void pipboyInit();
|
||||
void pipboyReset();
|
||||
int pipboySave(File* stream);
|
||||
int pipboyLoad(File* stream);
|
||||
int pipboyGetWindow();
|
||||
|
||||
extern MessageList gPipboyMessageList;
|
||||
int pipboyMessageListInit();
|
||||
|
||||
+11
-1
@@ -115,6 +115,7 @@ int _SavePrefs(bool save);
|
||||
static int preferencesWindowInit();
|
||||
static int preferencesWindowFree();
|
||||
static void _DoThing(int eventCode);
|
||||
static void preferencesMessageListReset();
|
||||
|
||||
// 0x48FBD0 row1Ytab
|
||||
static const int _row1Ytab[PRIMARY_PREF_COUNT] = {
|
||||
@@ -231,6 +232,12 @@ static MessageList gPreferencesMessageList;
|
||||
// 0x663840 optnmesg
|
||||
static MessageListItem gPreferencesMessageListItem;
|
||||
|
||||
static void preferencesMessageListReset()
|
||||
{
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_OPTIONS, nullptr);
|
||||
messageListFree(&gPreferencesMessageList);
|
||||
}
|
||||
|
||||
// 0x6638C8 text_delay_back
|
||||
static double gPreferencesTextBaseDelay2;
|
||||
|
||||
@@ -990,6 +997,7 @@ static int preferencesWindowInit()
|
||||
if (!messageListLoad(&gPreferencesMessageList, path)) {
|
||||
return -1;
|
||||
}
|
||||
messageListRepositorySetStandardMessageList(STANDARD_MESSAGE_LIST_OPTIONS, &gPreferencesMessageList);
|
||||
|
||||
_oldFont = fontGetCurrent();
|
||||
|
||||
@@ -1001,6 +1009,7 @@ static int preferencesWindowInit()
|
||||
while (--i >= 0) {
|
||||
_preferencesFrmImages[i].unlock();
|
||||
}
|
||||
preferencesMessageListReset();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1019,6 +1028,7 @@ static int preferencesWindowInit()
|
||||
for (i = 0; i < PREFERENCES_WINDOW_FRM_COUNT; i++) {
|
||||
_preferencesFrmImages[i].unlock();
|
||||
}
|
||||
preferencesMessageListReset();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1210,7 +1220,7 @@ static int preferencesWindowFree()
|
||||
|
||||
fontSetCurrent(_oldFont);
|
||||
|
||||
messageListFree(&gPreferencesMessageList);
|
||||
preferencesMessageListReset();
|
||||
touch_set_touchscreen_mode(false);
|
||||
|
||||
return 0;
|
||||
|
||||
+12
-483
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user