mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Windows opcodes (#505)
* create_win / hide_window * get_window_attributes * get_window_under_mouse * set_window_flag * dialog_message * display_stats
This commit is contained in:
@@ -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 | implemented: only message_box, get_text_width, show_window, create_message_window | - |
|
||||
| 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: get_window_under_mouse, create_win, get_window_attribute, message_box, set_window_flag, dialog_message, get_text_width, hide_window, 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 | implemented: critter_inven_obj2, item_weight | - |
|
||||
| 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 / 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. |
|
||||
|
||||
@@ -46,6 +46,8 @@ 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,
|
||||
@@ -326,6 +328,7 @@ 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,
|
||||
@@ -493,10 +496,16 @@ 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,6 +55,7 @@ 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);
|
||||
|
||||
|
||||
+24
-1
@@ -663,7 +663,7 @@ static int gCharacterEditorPrimaryStatMinusBtns[7];
|
||||
static unsigned char* gCharacterEditorWindowBuffer;
|
||||
|
||||
// 0x57060C edit_win
|
||||
static int gCharacterEditorWindow;
|
||||
static int gCharacterEditorWindow = -1;
|
||||
|
||||
// + stats buttons
|
||||
//
|
||||
@@ -5680,6 +5680,29 @@ 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,6 +14,8 @@ 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
|
||||
|
||||
|
||||
@@ -3495,6 +3495,11 @@ bool gameDialogIsBarterWindowExpanded()
|
||||
return gBarterWindowExpanded;
|
||||
}
|
||||
|
||||
int gameDialogGetWindow()
|
||||
{
|
||||
return windowGetWindow(gGameDialogWindow) != nullptr ? gGameDialogWindow : -1;
|
||||
}
|
||||
|
||||
// 0x448660 gdialog_barter_cleanup_tables
|
||||
void gameDialogBarterCleanupTables()
|
||||
{
|
||||
|
||||
@@ -40,6 +40,7 @@ void gameDialogSetBarterModifier(int modifier);
|
||||
int gameDialogBarter(int modifier);
|
||||
void gameDialogEndBarter();
|
||||
bool gameDialogIsBarterWindowExpanded();
|
||||
int gameDialogGetWindow();
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
|
||||
+73
-21
@@ -352,6 +352,7 @@ 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();
|
||||
@@ -594,7 +595,7 @@ static int gInventoryWindowDudeFid;
|
||||
static Inventory* _pud;
|
||||
|
||||
// 0x59E964 i_wid
|
||||
static int gInventoryWindow;
|
||||
static int gInventoryWindow = -1;
|
||||
|
||||
// item2
|
||||
// 0x59E968 i_rhand
|
||||
@@ -695,6 +696,31 @@ 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;
|
||||
@@ -957,8 +983,6 @@ void inventoryOpen()
|
||||
}
|
||||
}
|
||||
|
||||
ScopedGameMode gm(GameMode::kInventory);
|
||||
|
||||
if (inventoryCommonInit() == -1) {
|
||||
return;
|
||||
}
|
||||
@@ -997,6 +1021,7 @@ 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();
|
||||
@@ -2743,8 +2768,6 @@ static void _adjust_fid()
|
||||
// 0x4717E4
|
||||
void inventoryOpenUseItemOn(Object* targetObj)
|
||||
{
|
||||
ScopedGameMode gm(GameMode::kUseOn);
|
||||
|
||||
if (inventoryCommonInit() == -1) {
|
||||
return;
|
||||
}
|
||||
@@ -2752,6 +2775,7 @@ 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();
|
||||
|
||||
@@ -3088,7 +3112,7 @@ int objectGetCarriedQuantityByPid(Object* object, int pid)
|
||||
// Renders character's summary of SPECIAL stats, equipped armor bonuses,
|
||||
// and weapon's damage/range.
|
||||
//
|
||||
// 0x471D5C
|
||||
// 0x471D5C display_stats
|
||||
static void inventoryRenderSummary()
|
||||
{
|
||||
int summaryStats[7];
|
||||
@@ -4350,8 +4374,6 @@ 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.
|
||||
@@ -4417,6 +4439,7 @@ int inventoryOpenLooting(Object* looter, Object* target)
|
||||
}
|
||||
|
||||
bool isoWasEnabled = _setup_inventory(INVENTORY_WINDOW_TYPE_LOOT);
|
||||
ScopedGameMode gm(GameMode::kLoot);
|
||||
|
||||
Object** critters = nullptr;
|
||||
int critterCount = 0;
|
||||
@@ -6338,6 +6361,46 @@ 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];
|
||||
@@ -6350,10 +6413,8 @@ int inventoryUnwieldSlot(Object* critter, InvenSlot slot)
|
||||
}
|
||||
|
||||
bool isDude = critter == gDude;
|
||||
bool uiModeActive = GameMode::isInGameMode(GameMode::kInventory)
|
||||
|| GameMode::isInGameMode(GameMode::kUseOn)
|
||||
|| GameMode::isInGameMode(GameMode::kLoot)
|
||||
|| GameMode::isInGameMode(GameMode::kBarter);
|
||||
InventoryWindowType inventoryWindowType;
|
||||
bool uiModeActive = inventoryGetCurrentWindowType(&inventoryWindowType);
|
||||
bool update = false;
|
||||
|
||||
if (slot != InvenSlot::Armor && !uiModeActive) {
|
||||
@@ -6443,15 +6504,6 @@ 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,6 +62,9 @@ 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);
|
||||
|
||||
|
||||
+20
-1
@@ -72,7 +72,9 @@ static unsigned char* _opbtns[OPTIONS_WINDOW_BUTTONS_COUNT];
|
||||
static bool gOptionsWindowGameMouseObjectsWasVisible;
|
||||
|
||||
// 0x663900 optnwin
|
||||
static int gOptionsWindow;
|
||||
static int gOptionsWindow = -1;
|
||||
|
||||
static int gPauseWindow = -1;
|
||||
|
||||
// 0x663908 winbuf
|
||||
static unsigned char* gOptionsWindowBuffer;
|
||||
@@ -303,6 +305,7 @@ static int optionsWindowInit()
|
||||
static int optionsWindowFree()
|
||||
{
|
||||
windowDestroy(gOptionsWindow);
|
||||
gOptionsWindow = -1;
|
||||
fontSetCurrent(gOptionsWindowOldFont);
|
||||
messageListFree(&gPreferencesMessageList);
|
||||
|
||||
@@ -389,6 +392,8 @@ int showPause(bool preserveWorldState)
|
||||
return -1;
|
||||
}
|
||||
|
||||
gPauseWindow = window;
|
||||
|
||||
unsigned char* windowBuffer = windowGetBuffer(window);
|
||||
memcpy(windowBuffer,
|
||||
frmImages[PAUSE_WINDOW_FRM_BACKGROUND].getData(),
|
||||
@@ -477,6 +482,7 @@ int showPause(bool preserveWorldState)
|
||||
}
|
||||
|
||||
windowDestroy(window);
|
||||
gPauseWindow = -1;
|
||||
messageListFree(&gPreferencesMessageList);
|
||||
|
||||
if (!preserveWorldState) {
|
||||
@@ -529,4 +535,17 @@ 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,6 +6,7 @@ namespace fallout {
|
||||
int showOptions();
|
||||
int showPause(bool preserveWorldState);
|
||||
int _init_options_menu();
|
||||
int optionsGetWindow();
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
|
||||
+6
-1
@@ -354,7 +354,7 @@ int gPipboyPreviousMouseX;
|
||||
int gPipboyPreviousMouseY;
|
||||
|
||||
// 0x6644C4 pip_win
|
||||
int gPipboyWindow;
|
||||
int gPipboyWindow = -1;
|
||||
|
||||
// 0x6644F4 holodisk
|
||||
int _holodisk;
|
||||
@@ -1014,6 +1014,11 @@ int pipboyLoad(File* stream)
|
||||
return _save_pipboy(stream);
|
||||
}
|
||||
|
||||
int pipboyGetWindow()
|
||||
{
|
||||
return windowGetWindow(gPipboyWindow) != nullptr ? gPipboyWindow : -1;
|
||||
}
|
||||
|
||||
// 0x497BD8
|
||||
static void pipboyWindowHandleStatus(int userInput)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ void pipboyInit();
|
||||
void pipboyReset();
|
||||
int pipboySave(File* stream);
|
||||
int pipboyLoad(File* stream);
|
||||
int pipboyGetWindow();
|
||||
|
||||
extern MessageList gPipboyMessageList;
|
||||
int pipboyMessageListInit();
|
||||
|
||||
+261
-11
@@ -7,6 +7,8 @@
|
||||
#include <string>
|
||||
|
||||
#include "art.h"
|
||||
#include "automap.h"
|
||||
#include "character_editor.h"
|
||||
#include "color.h"
|
||||
#include "combat.h"
|
||||
#include "config.h" // For Config, configInit, configFree
|
||||
@@ -24,6 +26,8 @@
|
||||
#include "message.h"
|
||||
#include "object.h"
|
||||
#include "opcode_context.h"
|
||||
#include "options.h"
|
||||
#include "pipboy.h"
|
||||
#include "platform_compat.h"
|
||||
#include "proto_instance.h"
|
||||
#include "scripts.h"
|
||||
@@ -32,9 +36,11 @@
|
||||
#include "sfall_ini.h"
|
||||
#include "sfall_opcodes.h"
|
||||
#include "sfall_script_hooks.h"
|
||||
#include "skilldex.h"
|
||||
#include "text_font.h"
|
||||
#include "tile.h"
|
||||
#include "window.h"
|
||||
#include "window_manager.h"
|
||||
#include "worldmap.h"
|
||||
|
||||
#include <assert.h>
|
||||
@@ -44,8 +50,11 @@ namespace fallout {
|
||||
static void mf_attack_is_aimed(OpcodeContext& ctx);
|
||||
static void mf_car_gas_amount(OpcodeContext& ctx);
|
||||
static void mf_combat_data(OpcodeContext& ctx);
|
||||
static void mf_create_win(OpcodeContext& ctx);
|
||||
static void mf_critter_inven_obj2(OpcodeContext& ctx);
|
||||
static void mf_dialog_obj(OpcodeContext& ctx);
|
||||
static void mf_dialog_message(OpcodeContext& ctx);
|
||||
static void mf_display_stats(OpcodeContext& ctx);
|
||||
static void mf_get_combat_free_move(OpcodeContext& ctx);
|
||||
static void mf_get_cursor_mode(OpcodeContext& ctx);
|
||||
static void mf_get_flags(OpcodeContext& ctx);
|
||||
@@ -54,7 +63,10 @@ static void mf_get_object_data(OpcodeContext& ctx);
|
||||
static void mf_get_outline(OpcodeContext& ctx);
|
||||
static void mf_get_sfall_arg_at(OpcodeContext& ctx);
|
||||
static void mf_get_text_width(OpcodeContext& ctx);
|
||||
static void mf_get_window_attribute(OpcodeContext& ctx);
|
||||
static void mf_hide_window(OpcodeContext& ctx);
|
||||
static void mf_intface_redraw(OpcodeContext& ctx);
|
||||
static void mf_inventory_redraw(OpcodeContext& ctx);
|
||||
static void mf_item_weight(OpcodeContext& ctx);
|
||||
static void mf_loot_obj(OpcodeContext& ctx);
|
||||
static void mf_message_box(OpcodeContext& ctx);
|
||||
@@ -72,6 +84,7 @@ static void mf_set_cursor_mode(OpcodeContext& ctx);
|
||||
static void mf_set_flags(OpcodeContext& ctx);
|
||||
static void mf_set_iface_tag_text(OpcodeContext& ctx);
|
||||
static void mf_set_outline(OpcodeContext& ctx);
|
||||
static void mf_set_window_flag(OpcodeContext& ctx);
|
||||
static void mf_set_unique_id(OpcodeContext& ctx);
|
||||
static void mf_show_window(OpcodeContext& ctx);
|
||||
static void mf_signal_close_game(OpcodeContext& ctx);
|
||||
@@ -93,15 +106,14 @@ const MetaruleInfo kMetarules[] = {
|
||||
// {"add_g_timer_event", mf_add_g_timer_event, 2, 2, -1, {ARG_INT, ARG_INT}},
|
||||
// {"add_trait", mf_add_trait, 1, 1, -1, {ARG_INT}},
|
||||
{ "art_cache_clear", mf_art_cache_flush, 0, 0 },
|
||||
// {"art_frame_data", mf_art_frame_data, 1, 3, 0, {ARG_INTSTR, ARG_INT, ARG_INT}},
|
||||
{ "attack_is_aimed", mf_attack_is_aimed, 0, 0 },
|
||||
{ "car_gas_amount", mf_car_gas_amount, 0, 0 },
|
||||
{ "combat_data", mf_combat_data, 0, 0 },
|
||||
// {"create_win", mf_create_win, 5, 6, -1, {ARG_STRING, ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
{ "create_win", mf_create_win, 5, 6, -1, { ARG_STRING, ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT } },
|
||||
{ "critter_inven_obj2", mf_critter_inven_obj2, 2, 2, 0, { ARG_OBJECT, ARG_INT } },
|
||||
// {"dialog_message", mf_dialog_message, 1, 1, -1, {ARG_STRING}},
|
||||
{ "dialog_message", mf_dialog_message, 1, 1, -1, { ARG_STRING } },
|
||||
{ "dialog_obj", mf_dialog_obj, 0, 0 },
|
||||
// {"display_stats", mf_display_stats, 0, 0}, // refresh
|
||||
{ "display_stats", mf_display_stats, 0, 0 }, // refresh
|
||||
// {"draw_image", mf_draw_image, 1, 5, -1, {ARG_INTSTR, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"draw_image_scaled", mf_draw_image_scaled, 1, 6, -1, {ARG_INTSTR, ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"exec_map_update_scripts", mf_exec_map_update_scripts, 0, 0},
|
||||
@@ -126,18 +138,17 @@ const MetaruleInfo kMetarules[] = {
|
||||
// {"get_string_pointer", mf_get_string_pointer, 1, 1, 0, {ARG_STRING}}, // note: deprecated; do not implement
|
||||
// {"get_terrain_name", mf_get_terrain_name, 0, 2, -1, {ARG_INT, ARG_INT}},
|
||||
{ "get_text_width", mf_get_text_width, 1, 1, 0, { ARG_STRING } },
|
||||
// {"get_window_attribute", mf_get_window_attribute, 1, 2, -1, {ARG_INT, ARG_INT}},
|
||||
{ "get_window_attribute", mf_get_window_attribute, 1, 2, -1, { ARG_INT, ARG_INT } },
|
||||
// {"has_fake_perk_npc", mf_has_fake_perk_npc, 2, 2, 0, {ARG_OBJECT, ARG_STRING}},
|
||||
// {"has_fake_trait_npc", mf_has_fake_trait_npc, 2, 2, 0, {ARG_OBJECT, ARG_STRING}},
|
||||
// {"hide_window", mf_hide_window, 0, 1, -1, {ARG_STRING}},
|
||||
// {"interface_art_draw", mf_interface_art_draw, 4, 6, -1, {ARG_INT, ARG_INTSTR, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
{ "hide_window", mf_hide_window, 0, 1, -1, { ARG_STRING } },
|
||||
// {"interface_overlay", mf_interface_overlay, 2, 6, -1, {ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"interface_print", mf_interface_print, 5, 6, -1, {ARG_STRING, ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"intface_hide", mf_intface_hide, 0, 0},
|
||||
// {"intface_is_hidden", mf_intface_is_hidden, 0, 0},
|
||||
{ "intface_redraw", mf_intface_redraw, 0, 1 },
|
||||
// {"intface_show", mf_intface_show, 0, 0},
|
||||
// {"inventory_redraw", mf_inventory_redraw, 0, 1, -1, {ARG_INT}},
|
||||
{ "inventory_redraw", mf_inventory_redraw, 0, 1, -1, { ARG_INT } },
|
||||
// {"item_make_explosive", mf_item_make_explosive, 3, 4, -1, {ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
{ "item_weight", mf_item_weight, 1, 1, 0, { ARG_OBJECT } },
|
||||
// {"lock_is_jammed", mf_lock_is_jammed, 1, 1, 0, {ARG_OBJECT}},
|
||||
@@ -177,7 +188,7 @@ const MetaruleInfo kMetarules[] = {
|
||||
// {"set_town_title", mf_set_town_title, 2, 2, -1, {ARG_INT, ARG_STRING}},
|
||||
{ "set_unique_id", mf_set_unique_id, 1, 2, -1, { ARG_OBJECT, ARG_INT } },
|
||||
// {"set_unjam_locks_time", mf_set_unjam_locks_time, 1, 1, -1, {ARG_INT}},
|
||||
// {"set_window_flag", mf_set_window_flag, 3, 3, -1, {ARG_INTSTR, ARG_INT, ARG_INT}},
|
||||
{ "set_window_flag", mf_set_window_flag, 3, 3, -1, { ARG_INTSTR, ARG_INT, ARG_INT } },
|
||||
{ "show_window", mf_show_window, 0, 1, -1, { ARG_STRING } },
|
||||
{ "signal_close_game", mf_signal_close_game, 0, 0 },
|
||||
// {"spatial_radius", mf_spatial_radius, 1, 1, 0, {ARG_OBJECT}},
|
||||
@@ -189,13 +200,102 @@ const MetaruleInfo kMetarules[] = {
|
||||
{ "tile_refresh_display", mf_tile_refresh_display, 0, 0 },
|
||||
// {"unjam_lock", mf_unjam_lock, 1, 1, -1, {ARG_OBJECT}},
|
||||
{ "unwield_slot", mf_unwield_slot, 2, 2, -1, { ARG_OBJECT, ARG_INT } },
|
||||
// {"win_fill_color", mf_win_fill_color, 0, 5, -1, {ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
{ "opcode_exists", mf_opcode_exists, 1, 1 },
|
||||
};
|
||||
const std::size_t kMetarulesCount = sizeof(kMetarules) / sizeof(kMetarules[0]);
|
||||
|
||||
constexpr int kMetarulesMax = sizeof(kMetarules) / sizeof(kMetarules[0]);
|
||||
|
||||
enum class InterfaceWindowLookupResult {
|
||||
Found,
|
||||
Missing,
|
||||
Invalid,
|
||||
};
|
||||
|
||||
/*
|
||||
// Valid window types for get_window_attribute
|
||||
#define WINTYPE_INVENTORY (0) // any inventory window (player/loot/use/barter)
|
||||
#define WINTYPE_DIALOG (1)
|
||||
#define WINTYPE_PIPBOY (2)
|
||||
#define WINTYPE_WORLDMAP (3)
|
||||
#define WINTYPE_IFACEBAR (4) // the interface bar
|
||||
#define WINTYPE_CHARACTER (5)
|
||||
#define WINTYPE_SKILLDEX (6)
|
||||
#define WINTYPE_ESCMENU (7) // escape menu
|
||||
#define WINTYPE_AUTOMAP (8)
|
||||
*/
|
||||
static InterfaceWindowLookupResult getInterfaceWindowByType(int winType, int& window)
|
||||
{
|
||||
switch (winType) {
|
||||
case 0:
|
||||
window = inventoryGetWindow();
|
||||
break;
|
||||
case 1:
|
||||
window = gameDialogGetWindow();
|
||||
break;
|
||||
case 2:
|
||||
window = pipboyGetWindow();
|
||||
break;
|
||||
case 3:
|
||||
window = worldmapGetWindow();
|
||||
break;
|
||||
case 4:
|
||||
window = windowGetWindow(gInterfaceBarWindow) != nullptr ? gInterfaceBarWindow : -1;
|
||||
break;
|
||||
case 5:
|
||||
window = characterEditorGetWindow();
|
||||
break;
|
||||
case 6:
|
||||
window = skilldexGetWindow();
|
||||
break;
|
||||
case 7:
|
||||
window = optionsGetWindow();
|
||||
break;
|
||||
case 8:
|
||||
window = automapGetWindow();
|
||||
break;
|
||||
default:
|
||||
window = -1;
|
||||
return InterfaceWindowLookupResult::Invalid;
|
||||
}
|
||||
|
||||
return window != -1 ? InterfaceWindowLookupResult::Found : InterfaceWindowLookupResult::Missing;
|
||||
}
|
||||
|
||||
static int getCurrentInterfaceWindow()
|
||||
{
|
||||
int window = -1;
|
||||
if (GameMode::isInGameMode(GameMode::kInventory)
|
||||
|| GameMode::isInGameMode(GameMode::kUseOn)
|
||||
|| GameMode::isInGameMode(GameMode::kLoot)
|
||||
|| GameMode::isInGameMode(GameMode::kBarter)) {
|
||||
window = inventoryGetWindow();
|
||||
} else if (GameMode::isInGameMode(GameMode::kDialog)) {
|
||||
window = gameDialogGetWindow();
|
||||
} else if (GameMode::isInGameMode(GameMode::kPipboy)) {
|
||||
window = pipboyGetWindow();
|
||||
} else if (GameMode::isInGameMode(GameMode::kWorldmap)) {
|
||||
window = worldmapGetWindow();
|
||||
} else if (GameMode::isInGameMode(GameMode::kEditor)) {
|
||||
window = characterEditorGetWindow();
|
||||
} else if (GameMode::isInGameMode(GameMode::kSkilldex)) {
|
||||
window = skilldexGetWindow();
|
||||
} else if (GameMode::isInGameMode(GameMode::kOptions)) {
|
||||
window = optionsGetWindow();
|
||||
} else if (GameMode::isInGameMode(GameMode::kAutomap)) {
|
||||
window = automapGetWindow();
|
||||
} else if (windowGetWindow(gInterfaceBarWindow) != nullptr) {
|
||||
window = gInterfaceBarWindow;
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static bool applyWindowFlag(int windowId, int bitFlag, bool enabled)
|
||||
{
|
||||
return scriptWindowSetFlag(windowId, bitFlag, enabled);
|
||||
}
|
||||
|
||||
void mf_art_cache_flush(OpcodeContext& ctx)
|
||||
{
|
||||
artCacheFlush();
|
||||
@@ -236,6 +336,35 @@ void mf_combat_data(OpcodeContext& ctx)
|
||||
}
|
||||
}
|
||||
|
||||
void mf_create_win(OpcodeContext& ctx)
|
||||
{
|
||||
int flags = ctx.numArgs() > 5
|
||||
? ctx.arg(5).asInt()
|
||||
: WINDOW_MOVE_ON_TOP;
|
||||
|
||||
int color = (flags & WINDOW_TRANSPARENT) != 0 ? 0 : 256;
|
||||
if (scriptWindowCreate(ctx.stringArg(0),
|
||||
ctx.arg(1).asInt(),
|
||||
ctx.arg(2).asInt(),
|
||||
ctx.arg(3).asInt(),
|
||||
ctx.arg(4).asInt(),
|
||||
color,
|
||||
flags)
|
||||
== -1) {
|
||||
ctx.printError("%s() - couldn't create window.", ctx.name());
|
||||
ctx.setReturn(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void mf_display_stats(OpcodeContext& ctx)
|
||||
{
|
||||
if (GameMode::isInGameMode(GameMode::kInventory)) {
|
||||
inventoryDisplayStats();
|
||||
} else if (GameMode::isInGameMode(GameMode::kEditor)) {
|
||||
characterEditorDisplayStats();
|
||||
}
|
||||
}
|
||||
|
||||
void mf_critter_inven_obj2(OpcodeContext& ctx)
|
||||
{
|
||||
Object* obj = ctx.arg(0).asObject();
|
||||
@@ -268,6 +397,14 @@ void mf_dialog_obj(OpcodeContext& ctx)
|
||||
}
|
||||
}
|
||||
|
||||
void mf_dialog_message(OpcodeContext& ctx)
|
||||
{
|
||||
if (GameMode::isInGameMode(GameMode::kDialog)
|
||||
&& !GameMode::isInGameMode(GameMode::kDialogReview)) {
|
||||
gameDialogRenderSupplementaryMessage(ctx.stringArg(0));
|
||||
}
|
||||
}
|
||||
|
||||
void mf_get_combat_free_move(OpcodeContext& ctx)
|
||||
{
|
||||
ctx.setReturn(_combat_free_move);
|
||||
@@ -331,6 +468,67 @@ void mf_get_text_width(OpcodeContext& ctx)
|
||||
ctx.setReturn(fontGetStringWidth(ctx.stringArg(0)));
|
||||
}
|
||||
|
||||
void mf_get_window_attribute(OpcodeContext& ctx)
|
||||
{
|
||||
int attrType = ctx.numArgs() > 1 ? ctx.arg(1).asInt() : 0;
|
||||
int window = -1;
|
||||
InterfaceWindowLookupResult lookup = getInterfaceWindowByType(ctx.arg(0).asInt(), window);
|
||||
if (lookup == InterfaceWindowLookupResult::Missing) {
|
||||
if (attrType != 0) {
|
||||
ctx.printError("%s() - failed to get the interface window.", ctx.name());
|
||||
ctx.setReturn(-1);
|
||||
} else {
|
||||
ctx.setReturn(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (lookup == InterfaceWindowLookupResult::Invalid) {
|
||||
ctx.printError("%s() - invalid window type number.", ctx.name());
|
||||
ctx.setReturn(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
Rect rect;
|
||||
if (windowGetRect(window, &rect) == -1) {
|
||||
ctx.setReturn(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (attrType) {
|
||||
case -1: {
|
||||
ArrayId arrayId = CreateTempArray(-1, 0);
|
||||
SetArray(arrayId, programMakeString(ctx.program(), "left"), ProgramValue(rect.left), false, ctx.program());
|
||||
SetArray(arrayId, programMakeString(ctx.program(), "top"), ProgramValue(rect.top), false, ctx.program());
|
||||
SetArray(arrayId, programMakeString(ctx.program(), "right"), ProgramValue(rect.right), false, ctx.program());
|
||||
SetArray(arrayId, programMakeString(ctx.program(), "bottom"), ProgramValue(rect.bottom), false, ctx.program());
|
||||
ctx.setReturn(ProgramValue(arrayId));
|
||||
break;
|
||||
}
|
||||
case 0: // basically an existence check
|
||||
ctx.setReturn(1);
|
||||
break;
|
||||
case 1:
|
||||
ctx.setReturn(rect.left);
|
||||
break;
|
||||
case 2:
|
||||
ctx.setReturn(rect.top);
|
||||
break;
|
||||
case 3:
|
||||
ctx.setReturn(windowGetWidth(window));
|
||||
break;
|
||||
case 4:
|
||||
ctx.setReturn(windowGetHeight(window));
|
||||
break;
|
||||
case 5:
|
||||
ctx.setReturn(window);
|
||||
break;
|
||||
default:
|
||||
ctx.setReturn(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mf_intface_redraw(OpcodeContext& ctx)
|
||||
{
|
||||
if (ctx.numArgs() == 0) {
|
||||
@@ -341,6 +539,11 @@ void mf_intface_redraw(OpcodeContext& ctx)
|
||||
}
|
||||
}
|
||||
|
||||
void mf_inventory_redraw(OpcodeContext& ctx)
|
||||
{
|
||||
inventoryRedraw(ctx.numArgs() > 0 ? ctx.arg(0).asInt() : -1);
|
||||
}
|
||||
|
||||
void mf_item_weight(OpcodeContext& ctx)
|
||||
{
|
||||
Object* object = ctx.arg(0).asObject();
|
||||
@@ -355,7 +558,7 @@ void mf_item_weight(OpcodeContext& ctx)
|
||||
|
||||
void mf_loot_obj(OpcodeContext& ctx)
|
||||
{
|
||||
if (GameMode::isInGameMode(GameMode::kInventory)) {
|
||||
if (GameMode::isInGameMode(GameMode::kLoot)) {
|
||||
ctx.setReturn(inventoryGetTargetObject());
|
||||
} else {
|
||||
ctx.setReturn(nullptr);
|
||||
@@ -524,6 +727,41 @@ void mf_set_outline(OpcodeContext& ctx)
|
||||
object->outline = outline;
|
||||
}
|
||||
|
||||
void mf_set_window_flag(OpcodeContext& ctx)
|
||||
{
|
||||
int bitFlag = ctx.arg(1).asInt();
|
||||
switch (bitFlag) {
|
||||
case WINDOW_DONT_MOVE_TOP:
|
||||
case WINDOW_MOVE_ON_TOP:
|
||||
case WINDOW_HIDDEN:
|
||||
case WINDOW_MODAL:
|
||||
case WINDOW_TRANSPARENT:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
bool enabled = ctx.arg(2).asInt() != 0;
|
||||
if (ctx.arg(0).isString()) {
|
||||
const char* windowName = ctx.stringArg(0);
|
||||
if (!scriptWindowSetNamedFlag(windowName, bitFlag, enabled)) {
|
||||
ctx.printError("%s() - window '%s' is not found.", ctx.name(), windowName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int windowId = ctx.arg(0).asInt();
|
||||
if (windowId <= 0) {
|
||||
windowId = getCurrentInterfaceWindow();
|
||||
}
|
||||
|
||||
if (windowId == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
applyWindowFlag(windowId, bitFlag, enabled);
|
||||
}
|
||||
|
||||
void mf_set_unique_id(OpcodeContext& ctx)
|
||||
{
|
||||
Object* object = ctx.arg(0).asObject();
|
||||
@@ -552,6 +790,18 @@ void mf_show_window(OpcodeContext& ctx)
|
||||
}
|
||||
}
|
||||
|
||||
void mf_hide_window(OpcodeContext& ctx)
|
||||
{
|
||||
if (ctx.numArgs() == 0) {
|
||||
scriptWindowHide();
|
||||
} else {
|
||||
const char* windowName = ctx.stringArg(0);
|
||||
if (!scriptWindowHideNamed(windowName)) {
|
||||
ctx.printError("%s() - window '%s' is not found.", ctx.name(), windowName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mf_tile_refresh_display(OpcodeContext& ctx)
|
||||
{
|
||||
tileWindowRefresh();
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "stat.h"
|
||||
#include "svga.h"
|
||||
#include "tile.h"
|
||||
#include "window_manager.h"
|
||||
#include "worldmap.h"
|
||||
|
||||
namespace fallout {
|
||||
@@ -899,6 +900,11 @@ static void op_get_mouse_buttons(Program* program)
|
||||
programStackPushInteger(program, mouse_get_last_buttons());
|
||||
}
|
||||
|
||||
static void op_get_window_under_mouse(Program* program)
|
||||
{
|
||||
programStackPushInteger(program, _win_last_button_winID());
|
||||
}
|
||||
|
||||
// get_screen_width
|
||||
static void op_get_screen_width(Program* program)
|
||||
{
|
||||
@@ -1873,6 +1879,7 @@ void sfallOpcodesInit()
|
||||
// 0x821e - int get_mouse_buttons()
|
||||
interpreterRegisterOpcode(0x821E, op_get_mouse_buttons);
|
||||
// 0x821f - int get_window_under_mouse()
|
||||
interpreterRegisterOpcode(0x821F, op_get_window_under_mouse);
|
||||
|
||||
// 0x8163 - int get_year()
|
||||
interpreterRegisterOpcode(0x8163, op_get_year);
|
||||
|
||||
+6
-1
@@ -95,7 +95,7 @@ static MessageList gSkilldexMessageList;
|
||||
static MessageListItem gSkilldexMessageListItem;
|
||||
|
||||
// 0x668140 skldxwin
|
||||
static int gSkilldexWindow;
|
||||
static int gSkilldexWindow = -1;
|
||||
|
||||
// 0x668144 winbuf_2
|
||||
static unsigned char* gSkilldexWindowBuffer;
|
||||
@@ -147,6 +147,11 @@ int skilldexOpen()
|
||||
return rc;
|
||||
}
|
||||
|
||||
int skilldexGetWindow()
|
||||
{
|
||||
return windowGetWindow(gSkilldexWindow) != nullptr ? gSkilldexWindow : -1;
|
||||
}
|
||||
|
||||
// 0x4AC054 skilldex_start
|
||||
static int skilldexWindowInit()
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ typedef enum SkilldexRC {
|
||||
} SkilldexRC;
|
||||
|
||||
int skilldexOpen();
|
||||
int skilldexGetWindow();
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
|
||||
+83
-18
@@ -158,9 +158,6 @@ static ManagedWindow gManagedWindows[MANAGED_WINDOW_COUNT];
|
||||
// 0x672D70 inputFunc
|
||||
static WindowInputHandler** gWindowInputHandlers;
|
||||
|
||||
// 0x672D74 createWindowFunc
|
||||
static ManagedWindowCreateCallback* off_672D74;
|
||||
|
||||
// NOTE: This value is never set.
|
||||
//
|
||||
// 0x672D78 selectWindowFunc
|
||||
@@ -704,6 +701,50 @@ bool scriptWindowShow()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool scriptWindowHideNamed(const char* windowName)
|
||||
{
|
||||
for (int index = 0; index < MANAGED_WINDOW_COUNT; index++) {
|
||||
ManagedWindow* managedWindow = &(gManagedWindows[index]);
|
||||
if (managedWindow->window != -1) {
|
||||
if (compat_stricmp(managedWindow->name, windowName) == 0) {
|
||||
windowHide(managedWindow->window);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool scriptWindowSetFlag(int windowId, int bitFlag, bool enabled)
|
||||
{
|
||||
if (!windowIsValidWindowId(windowId) || windowId == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Window* window = windowGetWindow(windowId);
|
||||
if (window == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bitFlag == WINDOW_HIDDEN) {
|
||||
if (enabled) {
|
||||
windowHide(windowId);
|
||||
} else {
|
||||
windowShow(windowId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
window->flags |= bitFlag;
|
||||
} else {
|
||||
window->flags &= ~bitFlag;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x4B7734
|
||||
int scriptWindowWidth()
|
||||
{
|
||||
@@ -843,9 +884,6 @@ int scriptWindowCreate(const char* windowName, int x, int y, int width, int heig
|
||||
managedWindow->buttonsLength = 0;
|
||||
|
||||
flags |= WINDOW_MANAGED | WINDOW_USE_DEFAULTS;
|
||||
if (off_672D74 != nullptr) {
|
||||
off_672D74(windowIndex, managedWindow->name, &flags);
|
||||
}
|
||||
|
||||
managedWindow->window = windowCreate(x, y, width, height, a6, flags);
|
||||
managedWindow->cursorY = 0;
|
||||
@@ -950,23 +988,30 @@ unsigned char* scriptWindowGetBuffer()
|
||||
// 0x4B8330
|
||||
int scriptWindowPush(const char* windowName)
|
||||
{
|
||||
if (_winTOS >= MANAGED_WINDOW_COUNT) {
|
||||
return -1;
|
||||
int oldCurrentWindowIndex = gCurrentManagedWindowIndex;
|
||||
|
||||
int existingIndex = -1;
|
||||
for (int index = 0; index <= _winTOS; index++) {
|
||||
if (_winStack[index] == oldCurrentWindowIndex) {
|
||||
existingIndex = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int oldCurrentWindowIndex = gCurrentManagedWindowIndex;
|
||||
// CE: check duplicates before checking capacity; removing one frees a stack slot.
|
||||
int newTopIndex = existingIndex == -1 ? _winTOS + 1 : _winTOS;
|
||||
if (newTopIndex >= MANAGED_WINDOW_COUNT) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int windowIndex = scriptWindowSelect(windowName);
|
||||
if (windowIndex == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: Check.
|
||||
for (int index = 0; index < _winTOS; index++) {
|
||||
if (_winStack[index] == oldCurrentWindowIndex) {
|
||||
memcpy(&(_winStack[index]), &(_winStack[index + 1]), sizeof(*_winStack) * (_winTOS - index));
|
||||
break;
|
||||
}
|
||||
if (existingIndex != -1) {
|
||||
memmove(&(_winStack[existingIndex]), &(_winStack[existingIndex + 1]), sizeof(*_winStack) * (_winTOS - existingIndex));
|
||||
_winTOS--;
|
||||
}
|
||||
|
||||
_winTOS++;
|
||||
@@ -983,9 +1028,15 @@ int _popWindow()
|
||||
}
|
||||
|
||||
int windowIndex = _winStack[_winTOS];
|
||||
ManagedWindow* managedWindow = &(gManagedWindows[windowIndex]);
|
||||
_winTOS--;
|
||||
|
||||
if (windowIndex < 0 || windowIndex >= MANAGED_WINDOW_COUNT) {
|
||||
gCurrentManagedWindowIndex = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ManagedWindow* managedWindow = &(gManagedWindows[windowIndex]);
|
||||
|
||||
return scriptWindowSelect(managedWindow->name);
|
||||
}
|
||||
|
||||
@@ -1745,8 +1796,7 @@ bool scriptWindowAddButtonGfx(const char* buttonName, char* pressedFileName, cha
|
||||
}
|
||||
|
||||
if (hoverFileName != nullptr) {
|
||||
// TODO: this almost certainly should be hoverFileName
|
||||
unsigned char* hover = datafileRead(normalFileName, &width, &height);
|
||||
unsigned char* hover = datafileRead(hoverFileName, &width, &height);
|
||||
if (hover != nullptr) {
|
||||
if (managedButton->hover == nullptr) {
|
||||
managedButton->hover = (unsigned char*)internal_malloc_safe(managedButton->height * managedButton->width, __FILE__, __LINE__); // "..\\int\\WINDOW.C, 1849
|
||||
@@ -2657,4 +2707,19 @@ bool scriptWindowShowNamed(const char* windowName)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool scriptWindowSetNamedFlag(const char* windowName, int bitFlag, bool enabled)
|
||||
{
|
||||
for (int index = 0; index < MANAGED_WINDOW_COUNT; index++) {
|
||||
ManagedWindow* managedWindow = &(gManagedWindows[index]);
|
||||
if (managedWindow->window != -1) {
|
||||
if (compat_stricmp(managedWindow->name, windowName) == 0) {
|
||||
// note: Sfall also updates managedWindow->flags, but that is unused
|
||||
return scriptWindowSetFlag(managedWindow->window, bitFlag, enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
@@ -65,6 +65,7 @@ void _doRightButtonRelease(int btn, int keyCode);
|
||||
void _setButtonGFX(int width, int height, unsigned char* normal);
|
||||
bool scriptWindowHide();
|
||||
bool scriptWindowShow();
|
||||
bool scriptWindowHideNamed(const char* name);
|
||||
int scriptWindowWidth();
|
||||
int scriptWindowHeight();
|
||||
bool scriptWindowDraw();
|
||||
@@ -131,6 +132,8 @@ void _drawScaledBuf(unsigned char* dest, int destWidth, int destHeight, unsigned
|
||||
void _fillBuf3x3(unsigned char* src, int srcWidth, int srcHeight, unsigned char* dest, int destWidth, int destHeight);
|
||||
|
||||
bool scriptWindowShowNamed(const char* name);
|
||||
bool scriptWindowSetFlag(int windowId, int bitFlag, bool enabled);
|
||||
bool scriptWindowSetNamedFlag(const char* name, int bitFlag, bool enabled);
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
|
||||
@@ -1121,9 +1121,14 @@ void _refresh_all(Rect* rect, unsigned char* dest)
|
||||
}
|
||||
|
||||
// 0x4D7888
|
||||
bool windowIsValidWindowId(int win)
|
||||
{
|
||||
return win >= 0 && win < MAX_WINDOW_COUNT;
|
||||
}
|
||||
|
||||
Window* windowGetWindow(int win)
|
||||
{
|
||||
if (win == -1) {
|
||||
if (!windowIsValidWindowId(win)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user