mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61b9b38e97 | ||
|
|
ec79058ab8 | ||
|
|
88b322e40b | ||
|
|
d873cd0ec3 | ||
|
|
6c728ddc3d | ||
|
|
3cdab90b2d | ||
|
|
18f7e425b4 |
@@ -105,13 +105,13 @@ docker run --rm -v $(pwd):/src emscripten/emsdk:3.1.74 sh -c 'git config --globa
|
||||
|
||||
## Configuration
|
||||
|
||||
The main configuration file is `fallout2.cfg`. There are several important settings you might need to adjust for your installation. Depending on your Fallout distribution main game assets `master.dat`, `critter.dat`, `patch000.dat`, and `data` folder might be either all lowercased, or all uppercased. You can either update `master_dat`, `critter_dat`, `master_patches` and `critter_patches` settings to match your file names, or rename files to match entries in your `fallout2.cfg`.
|
||||
The main configuration file is `fallout2-ce.cfg`. There are several important settings you might need to adjust for your installation. Depending on your Fallout distribution main game assets `master.dat`, `critter.dat`, `patch000.dat`, and `data` folder might be either all lowercased, or all uppercased. You can either update `master_dat`, `critter_dat`, `master_patches` and `critter_patches` settings to match your file names, or rename files to match entries in your `fallout2-ce.cfg`.
|
||||
|
||||
The `sound` folder (with `music` folder inside) might be located either in `data` folder, or be in the Fallout folder. Update `music_path1` setting to match your hierarchy, usually it's `data/sound/music/` or `sound/music/`. Make sure it matches your path exactly (so it might be `SOUND/MUSIC/` if you've installed Fallout from CD). Music files themselves (with `ACM` extension) should be all uppercased, regardless of `sound` and `music` folders.
|
||||
|
||||
Additional settings for screen resolution, UI customization, and map options are now integrated into the main `fallout2.cfg` file (previously part of `f2_res.ini` from Mash's HRP). When Fallout 2 CE starts, if it detects an existing `f2_res.ini` file, it automatically migrates these settings into `fallout2.cfg`. After migration, `fallout2.cfg` becomes the single source of truth for this configuration.
|
||||
Additional settings for screen resolution, UI customization, and map options are now integrated into the main `fallout2-ce.cfg` file (previously part of `f2_res.ini` from Mash's HRP). When Fallout 2 CE starts, if it detects an existing `f2_res.ini` file, it automatically migrates these settings into main config. After that, `fallout2-ce.cfg` becomes the single source of truth for this configuration.
|
||||
|
||||
Here are some important settings in `fallout2.cfg` under the `[screen]` and `[ui]` sections. See [the example config](https://github.com/fallout2-ce/fallout2-ce/tree/refs/heads/main/files/fallout2.cfg) for a full list of settings.
|
||||
Here are some important settings in `fallout2-ce.cfg` under the `[screen]` and `[ui]` sections. See [the example config](https://github.com/fallout2-ce/fallout2-ce/tree/refs/heads/main/files/ce.cfg) for a full list of settings.
|
||||
|
||||
```ini
|
||||
[screen]
|
||||
|
||||
@@ -10,7 +10,7 @@ Settings previously read from `ddraw.ini` have been moved into standard CE confi
|
||||
|
||||
Most settings that control game behavior (premade characters, extra message files, combat tweaks, worldmap, etc.) have been moved into [`<DAT>/config/game.cfg`](files/ce.dat/config/game.cfg), which is a content-mod config file intended to be overridden by mods. See that file for the full list with descriptions.
|
||||
|
||||
The following settings were moved into [`fallout2.cfg`](files/fallout2.cfg) instead:
|
||||
The following settings were moved into [`fallout2-ce.cfg`](files/ce.cfg) instead:
|
||||
|
||||
| ddraw.ini section | ddraw.ini key | fallout2.cfg section | fallout2.cfg key |
|
||||
| --- | --- | --- | --- |
|
||||
|
||||
+51
-21
@@ -1,11 +1,11 @@
|
||||
#include "debug.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <SDL.h>
|
||||
#include <string>
|
||||
|
||||
#include "memory.h"
|
||||
#include "platform_compat.h"
|
||||
@@ -15,11 +15,17 @@ namespace fallout {
|
||||
|
||||
static int _debug_puts(char* string);
|
||||
static void _debug_clear();
|
||||
static int _debug_mono(char* string);
|
||||
static int _debug_log(char* string);
|
||||
static int _debug_screen(char* string);
|
||||
static int _debug_mono(const char* string);
|
||||
static int _debug_log(const char* string);
|
||||
static int _debug_screen(const char* string);
|
||||
static void _debug_putc(int ch);
|
||||
static void _debug_scroll();
|
||||
static void debugFlushBuffer();
|
||||
|
||||
// Messages logged before any debug proc is registered are held here and
|
||||
// flushed when the first proc is registered.
|
||||
static std::string gDebugBuffer;
|
||||
static constexpr size_t kDebugBufferMaxSize = 64 * 1024;
|
||||
|
||||
// 0x51DEF8
|
||||
static FILE* _fd = nullptr;
|
||||
@@ -35,6 +41,10 @@ static DebugPrintProc* gDebugPrintProc = nullptr;
|
||||
|
||||
void debugModeInit(const char* debugMode)
|
||||
{
|
||||
if (debugMode == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// CE: Handle debug mode (exactly as seen in `mapper2.exe`).
|
||||
if (compat_stricmp(debugMode, "environment") == 0) {
|
||||
_debug_register_env();
|
||||
@@ -47,6 +57,10 @@ void debugModeInit(const char* debugMode)
|
||||
} else if (compat_stricmp(debugMode, "gnw") == 0) {
|
||||
_debug_register_func(_win_debug);
|
||||
}
|
||||
|
||||
if (gDebugPrintProc == nullptr) {
|
||||
gDebugBuffer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// 0x4C6CD0
|
||||
@@ -66,6 +80,7 @@ void _debug_register_mono()
|
||||
|
||||
gDebugPrintProc = _debug_mono;
|
||||
_debug_clear();
|
||||
debugFlushBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +94,7 @@ void _debug_register_log(const char* fileName, const char* mode)
|
||||
|
||||
_fd = compat_fopen(fileName, mode);
|
||||
gDebugPrintProc = _debug_log;
|
||||
debugFlushBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +108,7 @@ void _debug_register_screen()
|
||||
}
|
||||
|
||||
gDebugPrintProc = _debug_screen;
|
||||
debugFlushBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +154,7 @@ void _debug_register_func(DebugPrintProc* proc)
|
||||
}
|
||||
|
||||
gDebugPrintProc = proc;
|
||||
debugFlushBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,25 +164,37 @@ int debugPrint(const char* format, ...)
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
int rc;
|
||||
|
||||
if (gDebugPrintProc != nullptr) {
|
||||
char string[260];
|
||||
vsnprintf(string, sizeof(string), format, args);
|
||||
|
||||
rc = gDebugPrintProc(string);
|
||||
} else {
|
||||
#ifndef NDEBUG
|
||||
SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, format, args);
|
||||
#endif
|
||||
rc = -1;
|
||||
}
|
||||
char string[260];
|
||||
int len = vsnprintf(string, sizeof(string), format, args);
|
||||
|
||||
va_end(args);
|
||||
|
||||
int rc;
|
||||
if (gDebugPrintProc != nullptr) {
|
||||
rc = gDebugPrintProc(string);
|
||||
} else {
|
||||
if (len > 0 && gDebugBuffer.size() + len <= kDebugBufferMaxSize) {
|
||||
gDebugBuffer += string;
|
||||
}
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
SDL_Log("%s", string);
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void debugFlushBuffer()
|
||||
{
|
||||
if (gDebugBuffer.empty() || gDebugPrintProc == nullptr) {
|
||||
return;
|
||||
}
|
||||
gDebugPrintProc(gDebugBuffer.c_str());
|
||||
gDebugBuffer.clear();
|
||||
}
|
||||
|
||||
// 0x4C6F94
|
||||
static int _debug_puts(char* string)
|
||||
{
|
||||
@@ -203,7 +233,7 @@ static void _debug_clear()
|
||||
}
|
||||
|
||||
// 0x4C7004
|
||||
static int _debug_mono(char* string)
|
||||
static int _debug_mono(const char* string)
|
||||
{
|
||||
if (gDebugPrintProc == _debug_mono) {
|
||||
while (*string != '\0') {
|
||||
@@ -215,7 +245,7 @@ static int _debug_mono(char* string)
|
||||
}
|
||||
|
||||
// 0x4C7028
|
||||
static int _debug_log(char* string)
|
||||
static int _debug_log(const char* string)
|
||||
{
|
||||
if (gDebugPrintProc == _debug_log) {
|
||||
if (_fd == nullptr) {
|
||||
@@ -235,7 +265,7 @@ static int _debug_log(char* string)
|
||||
}
|
||||
|
||||
// 0x4C7068
|
||||
static int _debug_screen(char* string)
|
||||
static int _debug_screen(const char* string)
|
||||
{
|
||||
if (gDebugPrintProc == _debug_screen) {
|
||||
printf("%s", string);
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace fallout {
|
||||
|
||||
typedef int(DebugPrintProc)(char* string);
|
||||
typedef int(DebugPrintProc)(const char* string);
|
||||
|
||||
void debugModeInit(const char* debugMode);
|
||||
void _GNW_debug_init();
|
||||
|
||||
@@ -152,6 +152,8 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int fl
|
||||
|
||||
settingsInit(isMapper, argc, argv);
|
||||
|
||||
debugModeInit(settings.debug.mode.c_str());
|
||||
|
||||
gIsMapper = isMapper;
|
||||
|
||||
if (gameDbInit() == -1) {
|
||||
|
||||
+31
-39
@@ -26,7 +26,7 @@ constexpr char kMapperConfigFileName[] = "mapper2.cfg";
|
||||
// 0x5186D0
|
||||
bool gGameConfigInitialized = false;
|
||||
|
||||
// fallout2.cfg
|
||||
// ce.cfg
|
||||
//
|
||||
// 0x58E950
|
||||
Config gGameConfig;
|
||||
@@ -47,9 +47,9 @@ char gGameConfigFilePath[COMPAT_MAX_PATH];
|
||||
// additional check for [argc], so it will crash if you pass NULL, or an empty
|
||||
// array into [argv].
|
||||
//
|
||||
// The executable path from [argv] is used resolve path to `fallout2.cfg`,
|
||||
// The executable path from [argv] is used resolve path to `<executable>ce.cfg`,
|
||||
// which should be in the same folder. This function provide defaults if
|
||||
// `fallout2.cfg` is not present, or cannot be read for any reason.
|
||||
// file is not present, or cannot be read for any reason.
|
||||
//
|
||||
// Finally, this function merges key-value pairs from [argv] if any, see
|
||||
// [configParseCommandLineArguments] for expected format.
|
||||
@@ -86,53 +86,45 @@ bool gameConfigInit(bool isMapper, int argc, char** argv)
|
||||
char* customConfigFileName = nullptr;
|
||||
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_CONFIG_FILE, &customConfigFileName);
|
||||
|
||||
const char* configFileName = customConfigFileName != nullptr && *customConfigFileName != '\0'
|
||||
? customConfigFileName
|
||||
: kDefaultGameConfigFileName;
|
||||
// CE: Derive config file name from executable name.
|
||||
char exeDrive[COMPAT_MAX_DRIVE];
|
||||
char exeDir[COMPAT_MAX_DIR];
|
||||
char exeFname[COMPAT_MAX_FNAME];
|
||||
compat_splitpath(argv[0], exeDrive, exeDir, exeFname, nullptr);
|
||||
|
||||
// Make `fallout2.cfg` file path.
|
||||
char* executable = argv[0];
|
||||
char* ch = strrchr(executable, '\\');
|
||||
if (ch != nullptr) {
|
||||
*ch = '\0';
|
||||
if (isMapper) {
|
||||
snprintf(gGameConfigFilePath,
|
||||
sizeof(gGameConfigFilePath),
|
||||
"%s\\%s",
|
||||
executable,
|
||||
kMapperConfigFileName);
|
||||
} else {
|
||||
snprintf(gGameConfigFilePath,
|
||||
sizeof(gGameConfigFilePath),
|
||||
"%s\\%s",
|
||||
executable,
|
||||
configFileName);
|
||||
}
|
||||
*ch = '\\';
|
||||
} else {
|
||||
if (isMapper) {
|
||||
strcpy(gGameConfigFilePath, kMapperConfigFileName);
|
||||
} else {
|
||||
strcpy(gGameConfigFilePath, configFileName);
|
||||
}
|
||||
}
|
||||
char derivedConfigFileName[COMPAT_MAX_FNAME + 5];
|
||||
snprintf(derivedConfigFileName, sizeof(derivedConfigFileName), "%s.cfg", exeFname);
|
||||
|
||||
const char* defaultConfigFileName = isMapper ? kMapperConfigFileName : kDefaultGameConfigFileName;
|
||||
|
||||
const bool hasCustomConfigFileName = customConfigFileName != nullptr && *customConfigFileName != '\0';
|
||||
const char* configFileName = hasCustomConfigFileName ? customConfigFileName : derivedConfigFileName;
|
||||
|
||||
compat_makepath(gGameConfigFilePath, exeDrive, exeDir, configFileName, nullptr);
|
||||
|
||||
const bool usingDerivedConfig = !hasCustomConfigFileName
|
||||
&& compat_stricmp(derivedConfigFileName, defaultConfigFileName) != 0;
|
||||
|
||||
configRead(&gGameConfig, gGameConfigFilePath, false);
|
||||
|
||||
// Init debug mode ASAP to catch early debug messages.
|
||||
char* debugMode;
|
||||
configGetString(&gGameConfig, GAME_CONFIG_DEBUG_KEY, GAME_CONFIG_MODE_KEY, &debugMode);
|
||||
debugModeInit(debugMode);
|
||||
|
||||
debugPrint("Game config loaded from %s.\n", gGameConfigFilePath);
|
||||
|
||||
if (usingDerivedConfig) {
|
||||
char defaultConfigFilePath[COMPAT_MAX_PATH];
|
||||
compat_makepath(defaultConfigFilePath, exeDrive, exeDir, defaultConfigFileName, nullptr);
|
||||
if (gameConfigMigrateFromDefaultConfig(defaultConfigFilePath, &gGameConfig)) {
|
||||
debugPrint("Migrated settings from %s.\n", defaultConfigFileName);
|
||||
configWriteEx(&gGameConfig, gGameConfigFilePath, CONFIG_RETAIN_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isMapper && gameConfigMigrateFromF2Res(gGameConfigFilePath, &gGameConfig)) {
|
||||
debugPrint("Migrated settings from f2_res.ini.\n");
|
||||
configWriteEx(&gGameConfig, gGameConfigFilePath, CONFIG_RETAIN_ALL);
|
||||
}
|
||||
|
||||
// Add key-values from command line, which overrides both defaults and
|
||||
// whatever was loaded from `fallout2.cfg`.
|
||||
// whatever was loaded from cfg.
|
||||
configParseCommandLineArguments(&gGameConfig, argc, argv);
|
||||
|
||||
// Writes default values to config, skipping keys that were already loaded.
|
||||
@@ -151,7 +143,7 @@ EM_ASYNC_JS(void, do_save_idbfs_gameconfig, (), {
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
// Saves game config into `fallout2.cfg`.
|
||||
// Saves game config into cfg.
|
||||
//
|
||||
// 0x444C14
|
||||
bool gameConfigSave()
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace fallout {
|
||||
#define GAME_CONFIG_SCREEN_KEY "screen"
|
||||
#define GAME_CONFIG_UI_KEY "ui"
|
||||
#define GAME_CONFIG_SOUND_KEY "sound"
|
||||
#define GAME_CONFIG_META_KEY "meta"
|
||||
|
||||
#define GAME_CONFIG_MASTER_DAT_KEY "master_dat"
|
||||
#define GAME_CONFIG_MASTER_PATCHES_KEY "master_patches"
|
||||
|
||||
@@ -88,9 +88,9 @@ namespace {
|
||||
|
||||
} // namespace
|
||||
|
||||
// Migrate settings F2_RES.INI to fallout2.cfg
|
||||
// Migrate settings F2_RES.INI to ce.cfg
|
||||
//
|
||||
// Only happens a single time, after which fallout2.cfg is the source of truth
|
||||
// Only happens a single time, after which game config is the source of truth
|
||||
bool gameConfigMigrateFromF2Res(const char* gameConfigFilePath, Config* gameConfig)
|
||||
{
|
||||
if (gameConfigFilePath == nullptr || gameConfig == nullptr) {
|
||||
@@ -129,6 +129,46 @@ bool gameConfigMigrateFromF2Res(const char* gameConfigFilePath, Config* gameConf
|
||||
return migrated;
|
||||
}
|
||||
|
||||
// Imports all key-value pairs from defaultConfigFilePath into gameConfig,
|
||||
// overwriting any existing values. Runs once, gated by [meta] migrated=1.
|
||||
bool gameConfigMigrateFromDefaultConfig(const char* defaultConfigFilePath, Config* gameConfig)
|
||||
{
|
||||
constexpr char kMigratedKey[] = "migrated";
|
||||
if (defaultConfigFilePath == nullptr || gameConfig == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool migrated;
|
||||
if (configGetBool(gameConfig, GAME_CONFIG_META_KEY, kMigratedKey, &migrated) && migrated) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Config defaultConfig;
|
||||
if (!configInit(&defaultConfig)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
migrated = false;
|
||||
if (configRead(&defaultConfig, defaultConfigFilePath, false)) {
|
||||
for (int i = 0; i < defaultConfig.entriesLength; i++) {
|
||||
const char* section = defaultConfig.entries[i].key;
|
||||
ConfigSection* srcSection = static_cast<ConfigSection*>(defaultConfig.entries[i].value);
|
||||
for (int j = 0; j < srcSection->entriesLength; j++) {
|
||||
const char* key = srcSection->entries[j].key;
|
||||
const char* value = *static_cast<char**>(srcSection->entries[j].value);
|
||||
configSetString(gameConfig, section, key, value);
|
||||
migrated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (migrated) {
|
||||
configSetBool(gameConfig, GAME_CONFIG_META_KEY, kMigratedKey, true);
|
||||
}
|
||||
configFree(&defaultConfig);
|
||||
return migrated;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr char kSfallMisc[] = "Misc";
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
namespace fallout {
|
||||
|
||||
bool gameConfigMigrateFromF2Res(const char* gameConfigFilePath, Config* gameConfig);
|
||||
bool gameConfigMigrateFromDefaultConfig(const char* defaultConfigFilePath, Config* gameConfig);
|
||||
void contentConfigTryMigrateFromSfall(const char* contentConfigPath);
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
+4
-4
@@ -28,7 +28,7 @@ typedef struct ProgramListNode {
|
||||
static unsigned int _defaultTimerFunc();
|
||||
static unsigned int getInterpreterTime();
|
||||
static char* defaultFilename(char* path);
|
||||
static int outputString(char* string);
|
||||
static int outputString(const char* string);
|
||||
static int checkWait(Program* program);
|
||||
static char* programGetCurrentProcedureName(Program* program);
|
||||
opcode_t stackReadInt16(unsigned char* data, int pos);
|
||||
@@ -150,7 +150,7 @@ static unsigned int interpreterTimerTick = 1000;
|
||||
static char* (*interpreterFilenameMangler)(char*) = defaultFilename;
|
||||
|
||||
// 0x51904C
|
||||
static int (*interpreterOutputFunc)(char*) = outputString;
|
||||
static int (*interpreterOutputFunc)(const char*) = outputString;
|
||||
|
||||
// 0x519050
|
||||
static int interpreterCpuBurstSize = 10;
|
||||
@@ -195,7 +195,7 @@ char* _interpretMangleName(char* s)
|
||||
}
|
||||
|
||||
// 0x4670C0 (unused)
|
||||
static int outputString(char* /*string*/)
|
||||
static int outputString(const char*)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -207,7 +207,7 @@ static int checkWait(Program* program)
|
||||
}
|
||||
|
||||
// 0x4670FC
|
||||
void _interpretOutputFunc(int (*func)(char*))
|
||||
void _interpretOutputFunc(int (*func)(const char*))
|
||||
{
|
||||
interpreterOutputFunc = func;
|
||||
}
|
||||
|
||||
+1
-1
@@ -216,7 +216,7 @@ extern OpcodeHandler* gInterpreterOpcodeHandlers[OPCODE_MAX_COUNT];
|
||||
extern int _TimeOut;
|
||||
|
||||
char* _interpretMangleName(char* s);
|
||||
void _interpretOutputFunc(int (*func)(char*));
|
||||
void _interpretOutputFunc(int (*func)(const char*));
|
||||
int _interpretOutput(const char* format, ...);
|
||||
[[noreturn]] void programFatalError(const char* str, ...);
|
||||
void programPrintError(const char* format, ...);
|
||||
|
||||
+1
-1
@@ -857,7 +857,7 @@ int scriptWindowCreate(const char* windowName, int x, int y, int width, int heig
|
||||
}
|
||||
|
||||
// 0x4B80A4
|
||||
int scriptWindowOutput(char* string)
|
||||
int scriptWindowOutput(const char* string)
|
||||
{
|
||||
if (gCurrentManagedWindowIndex == -1) {
|
||||
return 0;
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ bool scriptWindowDelete(const char* windowName);
|
||||
int scriptWindowResize(const char* windowName, int x, int y, int width, int height);
|
||||
int scriptWindowScale(const char* windowName, int x, int y, int width, int height);
|
||||
int scriptWindowCreate(const char* windowName, int x, int y, int width, int height, int a6, int flags);
|
||||
int scriptWindowOutput(char* string);
|
||||
int scriptWindowOutput(const char* string);
|
||||
bool scriptWindowGotoXY(int x, int y);
|
||||
bool scriptWindowSelectId(int index);
|
||||
int scriptWindowSelect(const char* windowName);
|
||||
|
||||
@@ -807,7 +807,7 @@ int _create_pull_down(char** stringList, int stringListLength, int x, int y, int
|
||||
}
|
||||
|
||||
// 0x4DC30C
|
||||
int _win_debug(char* string)
|
||||
int _win_debug(const char* string)
|
||||
{
|
||||
if (!gWindowSystemInitialized) {
|
||||
return -1;
|
||||
@@ -895,7 +895,7 @@ int _win_debug(char* string)
|
||||
char temp[2];
|
||||
temp[1] = '\0';
|
||||
|
||||
char* pch = string;
|
||||
const char* pch = string;
|
||||
while (*pch != '\0') {
|
||||
int characterWidth = fontGetCharacterWidth(*pch);
|
||||
if (*pch == '\n' || _currx + characterWidth > winWidth - 9) {
|
||||
|
||||
@@ -20,7 +20,7 @@ int win_yes_no(const char* question, int x, int y, int color);
|
||||
int _win_msg(const char* string, int x, int y, int color);
|
||||
int _win_pull_down(char** items, int itemsLength, int x, int y, int color);
|
||||
int _create_pull_down(char** stringList, int stringListLength, int x, int y, int foregroundColor, int backgroundColor, Rect* rect);
|
||||
int _win_debug(char* string);
|
||||
int _win_debug(const char* string);
|
||||
void _win_debug_delete(int btn, int keyCode);
|
||||
int _win_register_menu_bar(int win, int x, int y, int width, int height, int foregroundColor, int backgroundColor);
|
||||
int _win_register_menu_pulldown(int win, int x, char* title, int keyCode, int itemsLength, char** items, int foregroundColor, int backgroundColor);
|
||||
|
||||
Reference in New Issue
Block a user