mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa69e343dc | ||
|
|
69cc853475 | ||
|
|
331bf79ec0 | ||
|
|
456f44b2a3 | ||
|
|
8d8b19e979 | ||
|
|
80bd1b2c8b | ||
|
|
0804ccac87 | ||
|
|
4ec9f88986 | ||
|
|
491384522f | ||
|
|
49f4376e89 | ||
|
|
f4688409fb |
+48
-2
@@ -447,11 +447,57 @@ void artRender(int fid, unsigned char* dest, int width, int height, int pitch)
|
||||
// mapper2.exe: 0x40A03C
|
||||
int art_list_str(int fid, char* name)
|
||||
{
|
||||
// TODO: Incomplete.
|
||||
if (fid == -1 || name == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
int objectType = (fid & 0xF000000) >> 24;
|
||||
int index = fid & 0xFFF;
|
||||
|
||||
const char* typeName = artGetObjectTypeName(objectType);
|
||||
if (typeName == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char path[260];
|
||||
snprintf(path, sizeof(path), "%s%s%s\\%s.lst", _cd_path_base, "art\\", typeName, typeName);
|
||||
|
||||
File* stream = fileOpen(path, "rt");
|
||||
if (stream == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char buffer[260];
|
||||
int line = 0;
|
||||
bool found = false;
|
||||
while (fileReadString(buffer, sizeof(buffer), stream) != nullptr) {
|
||||
if (line == index) {
|
||||
char* p = buffer;
|
||||
while (*p) {
|
||||
if (*p == ' ' || *p == '\n') {
|
||||
*p = '\0';
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
char* dst = name;
|
||||
const char* src = buffer;
|
||||
do {
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
} while (dst[-2] != '\0' || dst[-1] != '\0');
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
line++;
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
return found ? 0 : -1;
|
||||
}
|
||||
|
||||
// art_list_index
|
||||
int artListIndex(int objectType, const char* name)
|
||||
{
|
||||
if (objectType < 0 || objectType >= OBJ_TYPE_COUNT) return -1;
|
||||
|
||||
+1
-2
@@ -86,7 +86,6 @@ namespace fallout {
|
||||
#define SPLASH_HEIGHT (480)
|
||||
#define SPLASH_COUNT (10)
|
||||
|
||||
static int gameLoadGlobalVars();
|
||||
static int gameTakeScreenshot(int width, int height, unsigned char* buffer, unsigned char* palette);
|
||||
static void gameFreeGlobalVars();
|
||||
static bool tryLoadBaseCEModAtPath(const char* path, bool* found, bool* openFailed);
|
||||
@@ -1016,7 +1015,7 @@ int gameSetGlobalVar(int var, int value)
|
||||
|
||||
// game_load_info
|
||||
// 0x443CC8
|
||||
static int gameLoadGlobalVars()
|
||||
int gameLoadGlobalVars()
|
||||
{
|
||||
if (globalVarsRead("data\\vault13.gam", "GAME_GLOBAL_VARS:", &gGameGlobalVarsLength, &gGameGlobalVars) != 0) {
|
||||
return -1;
|
||||
|
||||
@@ -47,6 +47,7 @@ int gameRequestState(int newGameState);
|
||||
void gameUpdateState();
|
||||
int showQuitConfirmationDialog();
|
||||
|
||||
int gameLoadGlobalVars();
|
||||
int gameShowDeathDialog(const char* message);
|
||||
void gameHandleSkilldexResult(int rc);
|
||||
void* gameGetGlobalPointer(int var);
|
||||
|
||||
+22
-1
@@ -313,7 +313,6 @@ Object* gGameMouseHexCursor;
|
||||
// 0x596C74
|
||||
static Object* gGameMousePointedObject;
|
||||
|
||||
static int _gmouse_get_click_to_scroll();
|
||||
static void _gmouse_3d_enable_modes();
|
||||
static int gameMouseSetBouncingCursorFid(int fid);
|
||||
static int gameMouseRenderAccuracy(const char* string, int color);
|
||||
@@ -455,6 +454,15 @@ int _gmouse_get_click_to_scroll()
|
||||
return _gmouse_click_to_scroll;
|
||||
}
|
||||
|
||||
// gmouse_set_click_to_scroll
|
||||
void _gmouse_set_click_to_scroll(int value)
|
||||
{
|
||||
if (value != _gmouse_click_to_scroll) {
|
||||
_gmouse_click_to_scroll = value;
|
||||
_gmouse_clicked_on_edge = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 0x44B54C
|
||||
int _gmouse_is_scrolling()
|
||||
{
|
||||
@@ -2383,6 +2391,19 @@ int gameMouseHandleScrolling(int x, int y, int cursor)
|
||||
flags |= SCROLLABLE_S;
|
||||
}
|
||||
|
||||
// Click-to-scroll mode (mapper Alt-Z): only scroll while the left button is held at an
|
||||
// edge. Track this in _gmouse_clicked_on_edge so callers can react (e.g. suppress the
|
||||
// regular 3D cursor update while an edge-click scroll is active).
|
||||
// TODO: reconcile with other site where _gmouse_clicked_on_edge is set to true
|
||||
if (_gmouse_click_to_scroll) {
|
||||
bool atEdge = flags != 0;
|
||||
bool leftHeld = (mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_REPEAT) != 0;
|
||||
_gmouse_clicked_on_edge = atEdge && leftHeld;
|
||||
if (!_gmouse_clicked_on_edge) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int dx = 0;
|
||||
int dy = 0;
|
||||
|
||||
|
||||
@@ -82,6 +82,8 @@ void _gmouse_enable_scrolling();
|
||||
void _gmouse_disable_scrolling();
|
||||
bool gmouse_scrolling_is_enabled();
|
||||
int _gmouse_is_scrolling();
|
||||
int _gmouse_get_click_to_scroll();
|
||||
void _gmouse_set_click_to_scroll(int value);
|
||||
void gameMouseRefresh();
|
||||
void _gmouse_handle_event(int mouseX, int mouseY, int mouseState);
|
||||
int gameMouseSetCursor(int cursor);
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ static char _aErrorF2[] = "ERROR! F2";
|
||||
static IsoWindowRefreshProc* _map_scroll_refresh = isoWindowRefreshRectGame;
|
||||
|
||||
// 0x519544
|
||||
static const int _map_data_elev_flags[ELEVATION_COUNT] = {
|
||||
const int _map_data_elev_flags[ELEVATION_COUNT] = {
|
||||
2,
|
||||
4,
|
||||
8,
|
||||
|
||||
@@ -77,6 +77,7 @@ extern int gElevation;
|
||||
extern MessageList gMapMessageList;
|
||||
extern MapHeader gMapHeader;
|
||||
extern TileData* _square[ELEVATION_COUNT];
|
||||
extern const int _map_data_elev_flags[ELEVATION_COUNT];
|
||||
extern int gIsoWindow;
|
||||
|
||||
int isoInit();
|
||||
|
||||
+881
-70
File diff suppressed because it is too large
Load Diff
@@ -17,8 +17,8 @@ bool map_toggle_block_obj_viewing_on();
|
||||
|
||||
void map_load_dialog();
|
||||
void map_save_dialog();
|
||||
void map_save_as();
|
||||
void map_info_dialog();
|
||||
int map_save_as(const char* name);
|
||||
void map_get_name(char* buf);
|
||||
void create_spray_tool();
|
||||
void copy_spray_tile();
|
||||
// mode = 1 - enable, 0 - disable, -1 - toggle
|
||||
@@ -32,7 +32,9 @@ int pickHex();
|
||||
int pickToolbar(int topY);
|
||||
void placeObject(int pid, int fid);
|
||||
void placeTile(int pid, int fid);
|
||||
void copyObject();
|
||||
// Pass the current toolbar type to filter the region copy by type, or -1 to copy all object
|
||||
// types in the picked region (mirrors the original mapper's `copy_object(arg1)` arg).
|
||||
void copyObject(int filterType);
|
||||
void copyTile();
|
||||
void eraseObject();
|
||||
|
||||
|
||||
+448
-211
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,8 @@ extern unsigned char e_num[4][19 * 26];
|
||||
int mapper_main(int argc, char** argv);
|
||||
void print_toolbar_name(int object_type);
|
||||
int mapper_inven_unwield(Object* obj, int right_hand);
|
||||
void mapperShowTimedMsg(const char* msg);
|
||||
bool mapperYesNoDialog(const char* msg);
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
|
||||
@@ -615,6 +615,13 @@ int proto_build_all_type(int type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int proto_build_all_type_binary(int type)
|
||||
{
|
||||
// TODO: rebuild binary proto list for given object type.
|
||||
(void)type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int protoEdit(int protoId)
|
||||
{
|
||||
// TODO: implement proto editor dialog — load proto, show editor UI
|
||||
@@ -622,6 +629,26 @@ int protoEdit(int protoId)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void rebuild_spray_tools()
|
||||
{
|
||||
// TODO: rebuild spray tool (create/update pattern protos)
|
||||
}
|
||||
|
||||
void rebuild_binary()
|
||||
{
|
||||
// TODO: rebuild binary proto files from text sources
|
||||
}
|
||||
|
||||
void art_to_protos()
|
||||
{
|
||||
// TODO: create new proto entries for art files that have no proto yet
|
||||
}
|
||||
|
||||
void swap_protos()
|
||||
{
|
||||
// TODO: swap two prototype slots
|
||||
}
|
||||
|
||||
static unsigned char itemIconsBgColor()
|
||||
{
|
||||
return _colorTable[21];
|
||||
|
||||
@@ -16,6 +16,11 @@ void init_mapper_protos();
|
||||
const char* proto_wall_light_str(int flags);
|
||||
int proto_pick_ai_packet(int* value);
|
||||
int proto_build_all_type(int type);
|
||||
int proto_build_all_type_binary(int type);
|
||||
void rebuild_spray_tools();
|
||||
void rebuild_binary();
|
||||
void art_to_protos();
|
||||
void swap_protos();
|
||||
int protoEdit(int protoId);
|
||||
int protoChooseMultiPids(int pidType, protoChooseFidCallback fidFunc, protoChooseAddCallback addFunc);
|
||||
// protoInstEdit moved to mp_instance.h
|
||||
|
||||
+19
-5
@@ -330,12 +330,26 @@ int map_scr_add_spatial(int tile, int elevation)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void map_set_script()
|
||||
void map_set_script(int scriptIndex)
|
||||
{
|
||||
char info[256];
|
||||
snprintf(info, sizeof(info), "Map SID: %d", gMapSid);
|
||||
_win_msg(info, 80, 80, 0x10104);
|
||||
// TODO: full script selection dialog
|
||||
if (scriptIndex == -1) {
|
||||
if (gMapSid != -1) {
|
||||
scriptRemove(gMapSid);
|
||||
gMapSid = -1;
|
||||
}
|
||||
gMapHeader.scriptIndex = -1;
|
||||
} else {
|
||||
int idx = scriptIndex - 1;
|
||||
if (gMapSid == -1) {
|
||||
scriptAdd(&gMapSid, SCRIPT_TYPE_SYSTEM);
|
||||
}
|
||||
Script* script;
|
||||
if (scriptGetScript(gMapSid, &script) != -1) {
|
||||
script->index = idx;
|
||||
gMapHeader.scriptIndex = idx;
|
||||
_scr_find_str_run_info(idx, nullptr, gMapSid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void map_show_script()
|
||||
|
||||
@@ -8,7 +8,7 @@ int map_scr_remove_all_spatials();
|
||||
|
||||
int map_scr_add_spatial(int tile, int elevation);
|
||||
void map_scr_toggle_hexes();
|
||||
void map_set_script();
|
||||
void map_set_script(int scriptIndex);
|
||||
void map_show_script();
|
||||
void scr_debug_print_scripts();
|
||||
int scr_choose(int scriptType);
|
||||
|
||||
+771
-2
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,15 @@
|
||||
#ifndef FALLOUT_MAPPER_MP_TEXT_H_
|
||||
#define FALLOUT_MAPPER_MP_TEXT_H_
|
||||
|
||||
#include "db.h"
|
||||
|
||||
namespace fallout {
|
||||
|
||||
int proto_build_all_texts();
|
||||
void load_all_maps_text();
|
||||
// mode==0 → rebuild from text; mode==1 → generate text versions from binary maps.
|
||||
void load_all_maps_text(int mode = 0);
|
||||
void map_save_text();
|
||||
int obj_load_text(File* stream);
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
|
||||
+41
-7
@@ -31,7 +31,7 @@
|
||||
namespace fallout {
|
||||
|
||||
static int objectLoadAllInternal(File* stream);
|
||||
static void _object_fix_weapon_ammo(Object* obj);
|
||||
void _object_fix_weapon_ammo(Object* obj);
|
||||
static int objectWrite(Object* obj, File* stream);
|
||||
static int _obj_offset_table_init();
|
||||
static void _obj_offset_table_exit();
|
||||
@@ -51,7 +51,7 @@ static void objectDeallocate(Object** objectPtr);
|
||||
static int objectListNodeCreate(ObjectListNode** nodePtr);
|
||||
static void objectListNodeDestroy(ObjectListNode** nodePtr);
|
||||
static int objectGetListNode(Object* obj, ObjectListNode** out_node, ObjectListNode** out_prev_node);
|
||||
static void _obj_insert(ObjectListNode* ptr);
|
||||
void _obj_insert(ObjectListNode* ptr);
|
||||
static int _obj_remove(ObjectListNode* a1, ObjectListNode* a2);
|
||||
static int _obj_connect_to_tile(ObjectListNode* node, int tile_index, int elev, Rect* rect);
|
||||
static int _obj_adjust_light(Object* obj, int a2, Rect* rect);
|
||||
@@ -242,7 +242,7 @@ static Rect gObjectsUpdateAreaPixelBounds;
|
||||
// Contains objects that are bounded to tiles.
|
||||
//
|
||||
// 0x639DA0
|
||||
static ObjectListNode* gObjectListHeadByTile[HEX_GRID_SIZE];
|
||||
ObjectListNode* gObjectListHeadByTile[HEX_GRID_SIZE];
|
||||
|
||||
// 0x660EA0
|
||||
static unsigned char _glassGrayTable[256];
|
||||
@@ -598,7 +598,7 @@ static int objectLoadAllInternal(File* stream)
|
||||
// Fixes ammo pid and number of charges.
|
||||
//
|
||||
// 0x48911C
|
||||
static void _object_fix_weapon_ammo(Object* obj)
|
||||
void _object_fix_weapon_ammo(Object* obj)
|
||||
{
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_ITEM) {
|
||||
return;
|
||||
@@ -2308,7 +2308,7 @@ Object* objectFindNextAtLocation()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 0x0x48B66C
|
||||
// 0x48B66C
|
||||
void objectGetRect(Object* obj, Rect* rect)
|
||||
{
|
||||
if (obj == nullptr) {
|
||||
@@ -3852,7 +3852,7 @@ static int objectGetListNode(Object* object, ObjectListNode** nodePtr, ObjectLis
|
||||
}
|
||||
|
||||
// 0x48D8E8
|
||||
static void _obj_insert(ObjectListNode* objectListNode)
|
||||
void _obj_insert(ObjectListNode* objectListNode)
|
||||
{
|
||||
ObjectListNode** objectListNodePtr;
|
||||
|
||||
@@ -4021,7 +4021,7 @@ static int _obj_adjust_light(Object* obj, int a2, Rect* rect)
|
||||
obj->lightIntensity = 65536;
|
||||
}
|
||||
|
||||
int(*v70)[36] = _light_offsets[obj->tile & 1];
|
||||
int (*v70)[36] = _light_offsets[obj->tile & 1];
|
||||
int v7 = (obj->lightIntensity - 655) / (obj->lightDistance + 1);
|
||||
int v28[36];
|
||||
v28[0] = obj->lightIntensity - v7;
|
||||
@@ -5264,4 +5264,38 @@ int objectCreateWithFidPid(UniqueObject& obj, int fid, int pid)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int objectCreateEmpty(Object** objectPtr, ObjectListNode** nodePtr)
|
||||
{
|
||||
if (objectPtr == nullptr || nodePtr == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (objectListNodeCreate(nodePtr) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (objectAllocate(&((*nodePtr)->obj)) == -1) {
|
||||
objectListNodeDestroy(nodePtr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*objectPtr = (*nodePtr)->obj;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void objectDestroyEmpty(Object** objectPtr, ObjectListNode** nodePtr)
|
||||
{
|
||||
if (objectPtr == nullptr && nodePtr == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (objectPtr != nullptr && *objectPtr != nullptr) {
|
||||
objectDeallocate(objectPtr);
|
||||
}
|
||||
|
||||
if (nodePtr != nullptr && *nodePtr != nullptr) {
|
||||
objectListNodeDestroy(nodePtr);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
@@ -20,6 +20,7 @@ extern Object* _moveBlockObj;
|
||||
extern unsigned char _commonGrayTable[256];
|
||||
extern Object* gEgg;
|
||||
extern Object* gDude;
|
||||
extern ObjectListNode* gObjectListHeadByTile[HEX_GRID_SIZE];
|
||||
|
||||
int objectsInit(unsigned char* buf, int width, int height, int pitch);
|
||||
void objectsReset();
|
||||
@@ -99,6 +100,10 @@ void _obj_preload_art_cache(int flags);
|
||||
int _obj_save_dude(File* stream);
|
||||
int _obj_load_dude(File* stream);
|
||||
void _obj_fix_violence_settings(int* fid);
|
||||
void _object_fix_weapon_ammo(Object* obj);
|
||||
void _obj_insert(ObjectListNode* node);
|
||||
int objectCreateEmpty(Object** objectPtr, ObjectListNode** nodePtr);
|
||||
void objectDestroyEmpty(Object** objectPtr, ObjectListNode** nodePtr);
|
||||
|
||||
Object* objectTypedFindById(int id, int type);
|
||||
bool isExitGridAt(int tile, int elevation);
|
||||
|
||||
+162
@@ -247,6 +247,74 @@ int _proto_list_str(int pid, char* proto_path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Finds a proto pid by type name and proto name string (e.g., "critter.vault").
|
||||
// Returns 0 on success, -1 on failure.
|
||||
int proto_find_str(int pid, const char* name, int* outPid)
|
||||
{
|
||||
if (pid == -1) {
|
||||
if (outPid != nullptr) {
|
||||
*outPid = -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (name == nullptr || outPid == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Parse type name from pid
|
||||
int type = PID_TYPE(pid);
|
||||
if (type < 0 || type >= OBJ_TYPE_COUNT) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* typeName = artGetObjectTypeName(type);
|
||||
if (typeName == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Build path to <type>.lst
|
||||
char path[COMPAT_MAX_PATH];
|
||||
proto_make_path(path, pid);
|
||||
strcat(path, typeName);
|
||||
strcat(path, ".lst");
|
||||
|
||||
File* stream = fileOpen(path, "rt");
|
||||
if (stream == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Search for the name in the lst file
|
||||
char line[256];
|
||||
int foundPid = -1;
|
||||
while (fileReadString(line, sizeof(line), stream) != nullptr) {
|
||||
// Skip CR/LF
|
||||
char* pch = strpbrk(line, "\r\n");
|
||||
if (pch != nullptr) {
|
||||
*pch = '\0';
|
||||
}
|
||||
|
||||
// Parse "index name" format
|
||||
int index = 0;
|
||||
char foundName[256];
|
||||
if (sscanf(line, "%d %255s", &index, foundName) == 2) {
|
||||
if (strcmp(foundName, name) == 0) {
|
||||
foundPid = index << 24 | type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
if (foundPid == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*outPid = foundPid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x49E984
|
||||
size_t proto_size(int type)
|
||||
{
|
||||
@@ -2194,4 +2262,98 @@ int _ResetPlayer()
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parses a FID from text format (numeric value) and validates it.
|
||||
// Returns 0 on success, -1 on failure.
|
||||
int proto_read_text_fid(const char* text, int* fidPtr, int pidType)
|
||||
{
|
||||
if (text == nullptr || fidPtr == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int v6 = pidType;
|
||||
if (pidType == 255) {
|
||||
v6 = -1;
|
||||
}
|
||||
|
||||
int firstNum;
|
||||
if (sscanf(text, "%d", &firstNum) != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Skip past the first integer token
|
||||
const char* p = text;
|
||||
if (*p != ' ') {
|
||||
while (*p != ' ' && *p != '\0') {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
while (*p == ' ') {
|
||||
p++;
|
||||
}
|
||||
|
||||
int index = artListIndex(FID_TYPE(firstNum), p);
|
||||
|
||||
if (index == -1) {
|
||||
int type = (v6 == -1) ? FID_TYPE(firstNum) : v6;
|
||||
*fidPtr = buildFid(type, 0, 0, 0, 0);
|
||||
} else {
|
||||
int fid = buildFid(
|
||||
(firstNum & 0xF000000u) >> 24,
|
||||
index,
|
||||
(firstNum & 0xFF0000u) >> 16,
|
||||
static_cast<uint16_t>(firstNum & 0xF000) >> 12,
|
||||
0);
|
||||
|
||||
if (!_art_fid_valid(fid)) {
|
||||
int type = (v6 == -1) ? FID_TYPE(firstNum) : v6;
|
||||
fid = buildFid(type, 0, 0, 0, 0);
|
||||
debugPrint("\nError: proto_read_text_fid: art-check-valid failed: %s!\n", p);
|
||||
}
|
||||
|
||||
*fidPtr = fid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parses a PID from text format and validates it.
|
||||
// Text format: "number name" (e.g. "16777218 Vault13"). The name is looked up via proto_find_str
|
||||
// and must match the number's type. No fallback to raw numeric PID if the name isn't found.
|
||||
// Returns 0 on success, -1 on failure.
|
||||
int proto_read_text_pid(const char* text, int* pidPtr)
|
||||
{
|
||||
if (text == nullptr || pidPtr == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int firstNum;
|
||||
if (sscanf(text, "%d", &firstNum) != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Skip past the first integer token
|
||||
const char* p = text;
|
||||
if (*p != ' ') {
|
||||
while (*p != ' ' && *p != '\0') {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
while (*p == ' ') {
|
||||
p++;
|
||||
}
|
||||
|
||||
int foundPid;
|
||||
if (proto_find_str(firstNum, p, &foundPid) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Proto* proto;
|
||||
if (protoGetProto(foundPid, &proto) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*pidPtr = foundPid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user