23 Commits

Author SHA1 Message Date
Alexander Batalov
3cca4a81e9 Check back button to RMB emulation 2022-10-02 13:56:49 +03:00
Alexander Batalov
3924b6bba3 Fix back button on Android 2022-09-28 09:19:02 +03:00
Alexander Batalov
a1c1e03da0 Refactor artLockFrameData with FrmImage 2022-09-26 16:09:22 +03:00
Alexander Batalov
ac0a044a32 Refactor artLockFrameData with FrmImage 2022-09-26 15:17:22 +03:00
Alexander Batalov
4aae167bd8 Refactor artLockFrameData with FrmImage 2022-09-26 11:55:06 +03:00
Alexander Batalov
2e5be31ed4 Refactor artLockFrameData with FrmImage 2022-09-26 11:14:11 +03:00
Alexander Batalov
45278f66a5 Refactor artLockFrameData with FrmImage 2022-09-26 10:36:54 +03:00
Alexander Batalov
2205077d36 Refactor artLockFrameData with FrmImage 2022-09-26 10:28:44 +03:00
Alexander Batalov
67f966f7a9 Refactor artLockFrameData with FrmImage 2022-09-24 22:53:25 +03:00
Alexander Batalov
463968d798 Refactor artLockFrameData with FrmImage 2022-09-24 21:29:50 +03:00
Alexander Batalov
109dc6680c Refactor artLockFrameData with FrmImage 2022-09-24 21:22:40 +03:00
Alexander Batalov
23c5f070fa Refactor artLockFrameData with FrmImage 2022-09-24 21:04:32 +03:00
Alexander Batalov
fd9843f8dc Fix type warning 2022-09-24 19:43:27 +03:00
Alexander Batalov
443070226f Refactor artLockFrameData with FrmImage 2022-09-24 19:41:25 +03:00
Alexander Batalov
db63d8a085 Refactor artLockFrameData with FrmImage 2022-09-24 18:15:52 +03:00
Alexander Batalov
f203cfcc83 Refactor artLockFrameData with FrmImage 2022-09-24 17:31:13 +03:00
Alexander Batalov
9ceb490f72 Refactor artLockFrameData with FrmImage 2022-09-24 17:03:50 +03:00
Alexander Batalov
5b7a676b35 Refactor artLockFrameData with FrmImage 2022-09-24 16:51:16 +03:00
Alexander Batalov
e50e26cf87 Refactor artLockFrameData with FrmImage 2022-09-24 16:39:15 +03:00
Alexander Batalov
f59c072d68 Add FrmImage 2022-09-24 16:14:54 +03:00
Alexander Batalov
79c396c1a0 Uninline characterSelectorWindowFatalError 2022-09-24 10:28:30 +03:00
Alexander Batalov
9bb053b3ba Add namespace (#155) 2022-09-23 15:43:44 +03:00
Alexander Batalov
3168c2ec09 Improve some combat functions readability 2022-09-23 14:01:39 +03:00
232 changed files with 3280 additions and 2869 deletions

View File

@@ -2036,6 +2036,14 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
switch (event.getAction()) {
case KeyEvent.ACTION_DOWN:
case KeyEvent.ACTION_UP:
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
SDLActivity.onNativeMouse(MotionEvent.BUTTON_SECONDARY, MotionEvent.ACTION_DOWN, 0, 0, true);
} else if (event.getAction() == KeyEvent.ACTION_UP) {
SDLActivity.onNativeMouse(MotionEvent.BUTTON_SECONDARY, MotionEvent.ACTION_UP, 0, 0, true);
}
}
// mark the event as handled or it will be handled by system
// handling KEYCODE_BACK by system will call onBackPressed()
return true;

View File

@@ -35,6 +35,8 @@
#include "tile.h"
#include "trait.h"
namespace fallout {
#define MAX_KNOCKDOWN_DISTANCE 20
typedef enum ScienceRepairTargetType {
@@ -2114,3 +2116,5 @@ int _action_can_talk_to(Object* a1, Object* a2)
return 0;
}
} // namespace fallout

View File

@@ -4,6 +4,8 @@
#include "combat_defs.h"
#include "obj_types.h"
namespace fallout {
int _action_attack(Attack* attack);
int _action_use_an_item_on_object(Object* a1, Object* a2, Object* a3);
int _action_use_an_object(Object* a1, Object* a2);
@@ -21,4 +23,6 @@ bool actionCheckPush(Object* a1, Object* a2);
int actionPush(Object* a1, Object* a2);
int _action_can_talk_to(Object* a1, Object* a2);
} // namespace fallout
#endif /* ACTIONS_H */

View File

@@ -31,6 +31,8 @@
#include "tile.h"
#include "trait.h"
namespace fallout {
#define ANIMATION_SEQUENCE_LIST_CAPACITY 32
#define ANIMATION_DESCRIPTION_LIST_CAPACITY 55
#define ANIMATION_SAD_LIST_CAPACITY 24
@@ -3362,3 +3364,5 @@ int animationRegisterSetLightIntensity(Object* owner, int lightDistance, int lig
return 0;
}
} // namespace fallout

View File

@@ -4,6 +4,8 @@
#include "combat_defs.h"
#include "obj_types.h"
namespace fallout {
typedef enum AnimationRequestOptions {
ANIMATION_REQUEST_UNRESERVED = 0x01,
ANIMATION_REQUEST_RESERVED = 0x02,
@@ -156,4 +158,6 @@ void animationStop();
int animationRegisterSetLightIntensity(Object* owner, int lightDistance, int lightIntensity, int delay);
} // namespace fallout
#endif /* ANIMATION_H */

View File

@@ -14,6 +14,8 @@
#include "proto.h"
#include "sfall_config.h"
namespace fallout {
typedef struct ArtListDescription {
int flags;
char name[16];
@@ -1228,3 +1230,43 @@ int artWrite(const char* path, unsigned char* data)
fileClose(stream);
return 0;
}
FrmImage::FrmImage()
{
_key = nullptr;
_data = nullptr;
_width = 0;
_height = 0;
}
FrmImage::~FrmImage()
{
unlock();
}
bool FrmImage::lock(unsigned int fid)
{
if (isLocked()) {
return false;
}
_data = artLockFrameDataReturningSize(fid, &_key, &_width, &_height);
if (!_data) {
return false;
}
return true;
}
void FrmImage::unlock()
{
if (isLocked()) {
artUnlock(_key);
_key = nullptr;
_data = nullptr;
_width = 0;
_height = 0;
}
}
} // namespace fallout

View File

@@ -8,6 +8,8 @@
#include "platform_compat.h"
#include "proto_types.h"
namespace fallout {
typedef enum Head {
HEAD_INVALID,
HEAD_MARCUS,
@@ -149,4 +151,26 @@ int buildFid(int objectType, int frmId, int animType, int a4, int rotation);
int artRead(const char* path, unsigned char* data);
int artWrite(const char* path, unsigned char* data);
class FrmImage {
public:
FrmImage();
~FrmImage();
bool isLocked() const { return _key != nullptr; }
bool lock(unsigned int fid);
void unlock();
int getWidth() const { return _width; }
int getHeight() const { return _height; }
unsigned char* getData() const { return _data; }
private:
CacheEntry* _key;
unsigned char* _data;
int _width;
int _height;
};
} // namespace fallout
#endif

View File

@@ -10,6 +10,8 @@
#include "pointer_registry.h"
#include "sound.h"
namespace fallout {
static bool _defaultCompressionFunc(char* filePath);
static int audioSoundDecoderReadHandler(int fileHandle, void* buf, unsigned int size);
@@ -252,3 +254,5 @@ void audioExit()
gAudioListLength = 0;
gAudioList = NULL;
}
} // namespace fallout

View File

@@ -3,6 +3,8 @@
#include "audio_file.h"
namespace fallout {
int audioOpen(const char* fname, int mode, ...);
int audioClose(int fileHandle);
int audioRead(int fileHandle, void* buffer, unsigned int size);
@@ -13,4 +15,6 @@ int audioWrite(int handle, const void* buf, unsigned int size);
int audioInit(AudioFileIsCompressedProc* isCompressedProc);
void audioExit();
} // namespace fallout
#endif /* AUDIO_H */

View File

@@ -6,6 +6,8 @@
#include <SDL.h>
namespace fallout {
#define AUDIO_ENGINE_SOUND_BUFFERS 8
struct AudioEngineSoundBuffer {
@@ -430,3 +432,5 @@ bool audioEngineSoundBufferGetStatus(int soundBufferIndex, unsigned int* statusP
return true;
}
} // namespace fallout

View File

@@ -1,6 +1,8 @@
#ifndef AUDIO_ENGINE_H
#define AUDIO_ENGINE_H
namespace fallout {
#define AUDIO_ENGINE_SOUND_BUFFER_LOCK_FROM_WRITE_POS 0x00000001
#define AUDIO_ENGINE_SOUND_BUFFER_LOCK_ENTIRE_BUFFER 0x00000002
@@ -26,4 +28,6 @@ bool audioEngineSoundBufferLock(int soundBufferIndex, unsigned int writePos, uns
bool audioEngineSoundBufferUnlock(int soundBufferIndex, void* audioPtr1, unsigned int audioBytes1, void* audioPtr2, unsigned int audioBytes2);
bool audioEngineSoundBufferGetStatus(int soundBufferIndex, unsigned int* status);
} // namespace fallout
#endif /* AUDIO_ENGINE_H */

View File

@@ -10,6 +10,8 @@
#include "pointer_registry.h"
#include "sound.h"
namespace fallout {
static bool _defaultCompressionFunc__(char* filePath);
static int audioFileSoundDecoderReadHandler(int fileHandle, void* buffer, unsigned int size);
@@ -249,3 +251,5 @@ void audioFileExit()
gAudioFileListLength = 0;
gAudioFileList = NULL;
}
} // namespace fallout

View File

@@ -3,6 +3,8 @@
#include "sound_decoder.h"
namespace fallout {
typedef enum AudioFileFlags {
AUDIO_FILE_IN_USE = 0x01,
AUDIO_FILE_COMPRESSED = 0x02,
@@ -30,4 +32,6 @@ int audioFileWrite(int handle, const void* buf, unsigned int size);
int audioFileInit(AudioFileIsCompressedProc* isCompressedProc);
void audioFileExit();
} // namespace fallout
#endif /* AUDIO_FILE_H */

View File

@@ -25,6 +25,8 @@
#include "text_font.h"
#include "window_manager.h"
namespace fallout {
#define AUTOMAP_OFFSET_COUNT (AUTOMAP_MAP_COUNT * ELEVATION_COUNT)
#define AUTOMAP_WINDOW_WIDTH (519)
@@ -299,15 +301,10 @@ void automapShow(bool isInGame, bool isUsingScanner)
int frmIds[AUTOMAP_FRM_COUNT];
memcpy(frmIds, gAutomapFrmIds, sizeof(gAutomapFrmIds));
unsigned char* frmData[AUTOMAP_FRM_COUNT];
CacheEntry* frmHandle[AUTOMAP_FRM_COUNT];
FrmImage frmImages[AUTOMAP_FRM_COUNT];
for (int index = 0; index < AUTOMAP_FRM_COUNT; index++) {
int fid = buildFid(OBJ_TYPE_INTERFACE, frmIds[index], 0, 0, 0);
frmData[index] = artLockFrameData(fid, 0, 0, &(frmHandle[index]));
if (frmData[index] == NULL) {
while (--index >= 0) {
artUnlock(frmHandle[index]);
}
if (!frmImages[index].lock(fid)) {
return;
}
}
@@ -327,17 +324,53 @@ void automapShow(bool isInGame, bool isUsingScanner)
int automapWindowY = (screenGetHeight() - AUTOMAP_WINDOW_HEIGHT) / 2;
int window = windowCreate(automapWindowX, automapWindowY, AUTOMAP_WINDOW_WIDTH, AUTOMAP_WINDOW_HEIGHT, color, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
int scannerBtn = buttonCreate(window, 111, 454, 15, 16, -1, -1, -1, KEY_LOWERCASE_S, frmData[AUTOMAP_FRM_BUTTON_UP], frmData[AUTOMAP_FRM_BUTTON_DOWN], NULL, BUTTON_FLAG_TRANSPARENT);
int scannerBtn = buttonCreate(window,
111,
454,
15,
16,
-1,
-1,
-1,
KEY_LOWERCASE_S,
frmImages[AUTOMAP_FRM_BUTTON_UP].getData(),
frmImages[AUTOMAP_FRM_BUTTON_DOWN].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (scannerBtn != -1) {
buttonSetCallbacks(scannerBtn, _gsound_red_butt_press, _gsound_red_butt_release);
}
int cancelBtn = buttonCreate(window, 277, 454, 15, 16, -1, -1, -1, KEY_ESCAPE, frmData[AUTOMAP_FRM_BUTTON_UP], frmData[AUTOMAP_FRM_BUTTON_DOWN], NULL, BUTTON_FLAG_TRANSPARENT);
int cancelBtn = buttonCreate(window,
277,
454,
15,
16,
-1,
-1,
-1,
KEY_ESCAPE,
frmImages[AUTOMAP_FRM_BUTTON_UP].getData(),
frmImages[AUTOMAP_FRM_BUTTON_DOWN].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (cancelBtn != -1) {
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
}
int switchBtn = buttonCreate(window, 457, 340, 42, 74, -1, -1, KEY_LOWERCASE_L, KEY_LOWERCASE_H, frmData[AUTOMAP_FRM_SWITCH_UP], frmData[AUTOMAP_FRM_SWITCH_DOWN], NULL, BUTTON_FLAG_TRANSPARENT | BUTTON_FLAG_0x01);
int switchBtn = buttonCreate(window,
457,
340,
42,
74,
-1,
-1,
KEY_LOWERCASE_L,
KEY_LOWERCASE_H,
frmImages[AUTOMAP_FRM_SWITCH_UP].getData(),
frmImages[AUTOMAP_FRM_SWITCH_DOWN].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT | BUTTON_FLAG_0x01);
if (switchBtn != -1) {
buttonSetCallbacks(switchBtn, _gsound_toggle_butt_press_, _gsound_toggle_butt_press_);
}
@@ -358,7 +391,7 @@ void automapShow(bool isInGame, bool isUsingScanner)
gAutomapFlags |= AUTOMAP_WITH_SCANNER;
}
automapRenderInMapWindow(window, elevation, frmData[AUTOMAP_FRM_BACKGROUND], gAutomapFlags);
automapRenderInMapWindow(window, elevation, frmImages[AUTOMAP_FRM_BACKGROUND].getData(), gAutomapFlags);
bool isoWasEnabled = isoDisable();
gameMouseSetCursor(MOUSE_CURSOR_ARROW);
@@ -442,7 +475,7 @@ void automapShow(bool isInGame, bool isUsingScanner)
}
if (needsRefresh) {
automapRenderInMapWindow(window, elevation, frmData[AUTOMAP_FRM_BACKGROUND], gAutomapFlags);
automapRenderInMapWindow(window, elevation, frmImages[AUTOMAP_FRM_BACKGROUND].getData(), gAutomapFlags);
needsRefresh = false;
}
}
@@ -453,10 +486,6 @@ void automapShow(bool isInGame, bool isUsingScanner)
windowDestroy(window);
fontSetCurrent(oldFont);
for (int index = 0; index < AUTOMAP_FRM_COUNT; index++) {
artUnlock(frmHandle[index]);
}
}
// Renders automap in Map window.
@@ -1160,3 +1189,5 @@ void automapSetDisplayMap(int map, bool available)
_displayMapList[map] = available ? 0 : -1;
}
}
} // namespace fallout

View File

@@ -4,6 +4,8 @@
#include "db.h"
#include "map_defs.h"
namespace fallout {
#define AUTOMAP_DB ("AUTOMAP.DB")
#define AUTOMAP_TMP ("AUTOMAP.TMP")
@@ -56,4 +58,6 @@ int automapGetHeader(AutomapHeader** automapHeaderPtr);
void automapSetDisplayMap(int map, bool available);
} // namespace fallout
#endif /* AUTOMAP_H */

View File

@@ -11,6 +11,8 @@
static HANDLE gInterplayGenericAutorunMutex;
#endif
namespace fallout {
// 0x4139C0
bool autorunMutexCreate()
{
@@ -34,3 +36,5 @@ void autorunMutexClose()
}
#endif
}
} // namespace fallout

View File

@@ -1,7 +1,11 @@
#ifndef AUTORUN_H
#define AUTORUN_H
namespace fallout {
bool autorunMutexCreate();
void autorunMutexClose();
} // namespace fallout
#endif /* AUTORUN_H */

View File

@@ -9,6 +9,8 @@
#include "memory.h"
#include "sound.h"
namespace fallout {
// The initial number of cache entries in new cache.
#define CACHE_ENTRIES_INITIAL_CAPACITY (100)
@@ -613,3 +615,5 @@ static int cacheEntriesCompareByMostRecentHit(const void* a1, const void* a2)
return 0;
}
}
} // namespace fallout

View File

@@ -3,6 +3,8 @@
#include "heap.h"
namespace fallout {
#define INVALID_CACHE_ENTRY ((CacheEntry*)-1)
typedef enum CacheEntryFlags {
@@ -66,4 +68,6 @@ bool cacheUnlock(Cache* cache, CacheEntry* cacheEntry);
bool cacheFlush(Cache* cache);
bool cachePrintStats(Cache* cache, char* dest);
} // namespace fallout
#endif /* CACHE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,8 @@
#include "db.h"
namespace fallout {
extern int gCharacterEditorRemainingCharacterPoints;
int characterEditorShow(bool isCreationMode);
@@ -13,4 +15,6 @@ int characterEditorSave(File* stream);
int characterEditorLoad(File* stream);
void characterEditorReset();
} // namespace fallout
#endif /* CHARACTER_EDITOR_H */

View File

@@ -31,6 +31,8 @@
#include "trait.h"
#include "window_manager.h"
namespace fallout {
#define CS_WINDOW_WIDTH (640)
#define CS_WINDOW_HEIGHT (480)
@@ -81,6 +83,7 @@ static bool characterSelectorWindowRefresh();
static bool characterSelectorWindowRenderFace();
static bool characterSelectorWindowRenderStats();
static bool characterSelectorWindowRenderBio();
static bool characterSelectorWindowFatalError(bool result);
static void premadeCharactersLocalizePath(char* path);
@@ -109,92 +112,33 @@ static unsigned char* gCharacterSelectorBackground = NULL;
// 0x51C804
static int gCharacterSelectorWindowPreviousButton = -1;
// 0x51C808
static CacheEntry* gCharacterSelectorWindowPreviousButtonUpFrmHandle = NULL;
// 0x51C80C
static CacheEntry* gCharacterSelectorWindowPreviousButtonDownFrmHandle = NULL;
// 0x51C810
static int gCharacterSelectorWindowNextButton = -1;
// 0x51C814
static CacheEntry* gCharacterSelectorWindowNextButtonUpFrmHandle = NULL;
// 0x51C818
static CacheEntry* gCharacterSelectorWindowNextButtonDownFrmHandle = NULL;
// 0x51C81C
static int gCharacterSelectorWindowTakeButton = -1;
// 0x51C820
static CacheEntry* gCharacterSelectorWindowTakeButtonUpFrmHandle = NULL;
// 0x51C824
static CacheEntry* gCharacterSelectorWindowTakeButtonDownFrmHandle = NULL;
// 0x51C828
static int gCharacterSelectorWindowModifyButton = -1;
// 0x51C82C
static CacheEntry* gCharacterSelectorWindowModifyButtonUpFrmHandle = NULL;
// 0x51C830
static CacheEntry* gCharacterSelectorWindowModifyButtonDownFrmHandle = NULL;
// 0x51C834
static int gCharacterSelectorWindowCreateButton = -1;
// 0x51C838
static CacheEntry* gCharacterSelectorWindowCreateButtonUpFrmHandle = NULL;
// 0x51C83C
static CacheEntry* gCharacterSelectorWindowCreateButtonDownFrmHandle = NULL;
// 0x51C840
static int gCharacterSelectorWindowBackButton = -1;
// 0x51C844
static CacheEntry* gCharacterSelectorWindowBackButtonUpFrmHandle = NULL;
// 0x51C848
static CacheEntry* gCharacterSelectorWindowBackButtonDownFrmHandle = NULL;
// 0x667764
static unsigned char* gCharacterSelectorWindowTakeButtonUpFrmData;
// 0x667768
static unsigned char* gCharacterSelectorWindowModifyButtonDownFrmData;
// 0x66776C
static unsigned char* gCharacterSelectorWindowBackButtonUpFrmData;
// 0x667770
static unsigned char* gCharacterSelectorWindowCreateButtonUpFrmData;
// 0x667774
static unsigned char* gCharacterSelectorWindowModifyButtonUpFrmData;
// 0x667778
static unsigned char* gCharacterSelectorWindowBackButtonDownFrmData;
// 0x66777C
static unsigned char* gCharacterSelectorWindowCreateButtonDownFrmData;
// 0x667780
static unsigned char* gCharacterSelectorWindowTakeButtonDownFrmData;
// 0x667784
static unsigned char* gCharacterSelectorWindowNextButtonDownFrmData;
// 0x667788
static unsigned char* gCharacterSelectorWindowNextButtonUpFrmData;
// 0x66778C
static unsigned char* gCharacterSelectorWindowPreviousButtonUpFrmData;
// 0x667790
static unsigned char* gCharacterSelectorWindowPreviousButtonDownFrmData;
static FrmImage _takeButtonNormalFrmImage;
static FrmImage _takeButtonPressedFrmImage;
static FrmImage _modifyButtonNormalFrmImage;
static FrmImage _modifyButtonPressedFrmImage;
static FrmImage _createButtonNormalFrmImage;
static FrmImage _createButtonPressedFrmImage;
static FrmImage _backButtonNormalFrmImage;
static FrmImage _backButtonPressedFrmImage;
static FrmImage _nextButtonNormalFrmImage;
static FrmImage _nextButtonPressedFrmImage;
static FrmImage _previousButtonNormalFrmImage;
static FrmImage _previousButtonPressedFrmImage;
static std::vector<PremadeCharacterDescription> gCustomPremadeCharacterDescriptions;
@@ -305,9 +249,6 @@ int characterSelectorOpen()
// 0x4A7468
static bool characterSelectorWindowInit()
{
int backgroundFid;
unsigned char* backgroundFrmData;
if (gCharacterSelectorWindow != -1) {
return false;
}
@@ -316,22 +257,21 @@ static bool characterSelectorWindowInit()
int characterSelectorWindowY = (screenGetHeight() - CS_WINDOW_HEIGHT) / 2;
gCharacterSelectorWindow = windowCreate(characterSelectorWindowX, characterSelectorWindowY, CS_WINDOW_WIDTH, CS_WINDOW_HEIGHT, _colorTable[0], 0);
if (gCharacterSelectorWindow == -1) {
goto err;
return characterSelectorWindowFatalError(false);
}
gCharacterSelectorWindowBuffer = windowGetBuffer(gCharacterSelectorWindow);
if (gCharacterSelectorWindowBuffer == NULL) {
goto err;
return characterSelectorWindowFatalError(false);
}
CacheEntry* backgroundFrmHandle;
backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 174, 0, 0, 0);
backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
if (backgroundFrmData == NULL) {
goto err;
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 174, 0, 0, 0);
if (!backgroundFrmImage.lock(backgroundFid)) {
return characterSelectorWindowFatalError(false);
}
blitBufferToBuffer(backgroundFrmData,
blitBufferToBuffer(backgroundFrmImage.getData(),
CS_WINDOW_WIDTH,
CS_WINDOW_HEIGHT,
CS_WINDOW_WIDTH,
@@ -340,30 +280,28 @@ static bool characterSelectorWindowInit()
gCharacterSelectorBackground = (unsigned char*)internal_malloc(CS_WINDOW_BACKGROUND_WIDTH * CS_WINDOW_BACKGROUND_HEIGHT);
if (gCharacterSelectorBackground == NULL)
goto err;
return characterSelectorWindowFatalError(false);
blitBufferToBuffer(backgroundFrmData + CS_WINDOW_WIDTH * CS_WINDOW_BACKGROUND_Y + CS_WINDOW_BACKGROUND_X,
blitBufferToBuffer(backgroundFrmImage.getData() + CS_WINDOW_WIDTH * CS_WINDOW_BACKGROUND_Y + CS_WINDOW_BACKGROUND_X,
CS_WINDOW_BACKGROUND_WIDTH,
CS_WINDOW_BACKGROUND_HEIGHT,
CS_WINDOW_WIDTH,
gCharacterSelectorBackground,
CS_WINDOW_BACKGROUND_WIDTH);
artUnlock(backgroundFrmHandle);
backgroundFrmImage.unlock();
int fid;
// Setup "Previous" button.
fid = buildFid(OBJ_TYPE_INTERFACE, 122, 0, 0, 0);
gCharacterSelectorWindowPreviousButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowPreviousButtonUpFrmHandle);
if (gCharacterSelectorWindowPreviousButtonUpFrmData == NULL) {
goto err;
if (!_previousButtonNormalFrmImage.lock(fid)) {
return characterSelectorWindowFatalError(false);
}
fid = buildFid(OBJ_TYPE_INTERFACE, 123, 0, 0, 0);
gCharacterSelectorWindowPreviousButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowPreviousButtonDownFrmHandle);
if (gCharacterSelectorWindowPreviousButtonDownFrmData == NULL) {
goto err;
if (!_previousButtonPressedFrmImage.lock(fid)) {
return characterSelectorWindowFatalError(false);
}
gCharacterSelectorWindowPreviousButton = buttonCreate(gCharacterSelectorWindow,
@@ -375,27 +313,25 @@ static bool characterSelectorWindowInit()
-1,
-1,
500,
gCharacterSelectorWindowPreviousButtonUpFrmData,
gCharacterSelectorWindowPreviousButtonDownFrmData,
_previousButtonNormalFrmImage.getData(),
_previousButtonPressedFrmImage.getData(),
NULL,
0);
if (gCharacterSelectorWindowPreviousButton == -1) {
goto err;
return characterSelectorWindowFatalError(false);
}
buttonSetCallbacks(gCharacterSelectorWindowPreviousButton, _gsound_med_butt_press, _gsound_med_butt_release);
// Setup "Next" button.
fid = buildFid(OBJ_TYPE_INTERFACE, 124, 0, 0, 0);
gCharacterSelectorWindowNextButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowNextButtonUpFrmHandle);
if (gCharacterSelectorWindowNextButtonUpFrmData == NULL) {
goto err;
if (!_nextButtonNormalFrmImage.lock(fid)) {
return characterSelectorWindowFatalError(false);
}
fid = buildFid(OBJ_TYPE_INTERFACE, 125, 0, 0, 0);
gCharacterSelectorWindowNextButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowNextButtonDownFrmHandle);
if (gCharacterSelectorWindowNextButtonDownFrmData == NULL) {
goto err;
if (!_nextButtonPressedFrmImage.lock(fid)) {
return characterSelectorWindowFatalError(false);
}
gCharacterSelectorWindowNextButton = buttonCreate(gCharacterSelectorWindow,
@@ -407,27 +343,25 @@ static bool characterSelectorWindowInit()
-1,
-1,
501,
gCharacterSelectorWindowNextButtonUpFrmData,
gCharacterSelectorWindowNextButtonDownFrmData,
_nextButtonNormalFrmImage.getData(),
_nextButtonPressedFrmImage.getData(),
NULL,
0);
if (gCharacterSelectorWindowNextButton == -1) {
goto err;
return characterSelectorWindowFatalError(false);
}
buttonSetCallbacks(gCharacterSelectorWindowNextButton, _gsound_med_butt_press, _gsound_med_butt_release);
// Setup "Take" button.
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
gCharacterSelectorWindowTakeButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowTakeButtonUpFrmHandle);
if (gCharacterSelectorWindowTakeButtonUpFrmData == NULL) {
goto err;
if (!_takeButtonNormalFrmImage.lock(fid)) {
return characterSelectorWindowFatalError(false);
}
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
gCharacterSelectorWindowTakeButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowTakeButtonDownFrmHandle);
if (gCharacterSelectorWindowTakeButtonDownFrmData == NULL) {
goto err;
if (!_takeButtonPressedFrmImage.lock(fid)) {
return characterSelectorWindowFatalError(false);
}
gCharacterSelectorWindowTakeButton = buttonCreate(gCharacterSelectorWindow,
@@ -439,26 +373,24 @@ static bool characterSelectorWindowInit()
-1,
-1,
KEY_LOWERCASE_T,
gCharacterSelectorWindowTakeButtonUpFrmData,
gCharacterSelectorWindowTakeButtonDownFrmData,
_takeButtonNormalFrmImage.getData(),
_takeButtonPressedFrmImage.getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (gCharacterSelectorWindowTakeButton == -1) {
goto err;
return characterSelectorWindowFatalError(false);
}
buttonSetCallbacks(gCharacterSelectorWindowTakeButton, _gsound_red_butt_press, _gsound_red_butt_release);
// Setup "Modify" button.
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
gCharacterSelectorWindowModifyButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowModifyButtonUpFrmHandle);
if (gCharacterSelectorWindowModifyButtonUpFrmData == NULL)
goto err;
if (!_modifyButtonNormalFrmImage.lock(fid))
return characterSelectorWindowFatalError(false);
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
gCharacterSelectorWindowModifyButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowModifyButtonDownFrmHandle);
if (gCharacterSelectorWindowModifyButtonDownFrmData == NULL) {
goto err;
if (!_modifyButtonPressedFrmImage.lock(fid)) {
return characterSelectorWindowFatalError(false);
}
gCharacterSelectorWindowModifyButton = buttonCreate(gCharacterSelectorWindow,
@@ -470,27 +402,25 @@ static bool characterSelectorWindowInit()
-1,
-1,
KEY_LOWERCASE_M,
gCharacterSelectorWindowModifyButtonUpFrmData,
gCharacterSelectorWindowModifyButtonDownFrmData,
_modifyButtonNormalFrmImage.getData(),
_modifyButtonPressedFrmImage.getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (gCharacterSelectorWindowModifyButton == -1) {
goto err;
return characterSelectorWindowFatalError(false);
}
buttonSetCallbacks(gCharacterSelectorWindowModifyButton, _gsound_red_butt_press, _gsound_red_butt_release);
// Setup "Create" button.
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
gCharacterSelectorWindowCreateButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowCreateButtonUpFrmHandle);
if (gCharacterSelectorWindowCreateButtonUpFrmData == NULL) {
goto err;
if (!_createButtonNormalFrmImage.lock(fid)) {
return characterSelectorWindowFatalError(false);
}
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
gCharacterSelectorWindowCreateButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowCreateButtonDownFrmHandle);
if (gCharacterSelectorWindowCreateButtonDownFrmData == NULL) {
goto err;
if (!_createButtonPressedFrmImage.lock(fid)) {
return characterSelectorWindowFatalError(false);
}
gCharacterSelectorWindowCreateButton = buttonCreate(gCharacterSelectorWindow,
@@ -502,27 +432,25 @@ static bool characterSelectorWindowInit()
-1,
-1,
KEY_LOWERCASE_C,
gCharacterSelectorWindowCreateButtonUpFrmData,
gCharacterSelectorWindowCreateButtonDownFrmData,
_createButtonNormalFrmImage.getData(),
_createButtonPressedFrmImage.getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (gCharacterSelectorWindowCreateButton == -1) {
goto err;
return characterSelectorWindowFatalError(false);
}
buttonSetCallbacks(gCharacterSelectorWindowCreateButton, _gsound_red_butt_press, _gsound_red_butt_release);
// Setup "Back" button.
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
gCharacterSelectorWindowBackButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowBackButtonUpFrmHandle);
if (gCharacterSelectorWindowBackButtonUpFrmData == NULL) {
goto err;
if (!_backButtonNormalFrmImage.lock(fid)) {
return characterSelectorWindowFatalError(false);
}
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
gCharacterSelectorWindowBackButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowBackButtonDownFrmHandle);
if (gCharacterSelectorWindowBackButtonDownFrmData == NULL) {
goto err;
if (!_backButtonPressedFrmImage.lock(fid)) {
return characterSelectorWindowFatalError(false);
}
gCharacterSelectorWindowBackButton = buttonCreate(gCharacterSelectorWindow,
@@ -534,12 +462,12 @@ static bool characterSelectorWindowInit()
-1,
-1,
KEY_ESCAPE,
gCharacterSelectorWindowBackButtonUpFrmData,
gCharacterSelectorWindowBackButtonDownFrmData,
_backButtonNormalFrmImage.getData(),
_backButtonPressedFrmImage.getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (gCharacterSelectorWindowBackButton == -1) {
goto err;
return characterSelectorWindowFatalError(false);
}
buttonSetCallbacks(gCharacterSelectorWindowBackButton, _gsound_red_butt_press, _gsound_red_butt_release);
@@ -549,16 +477,10 @@ static bool characterSelectorWindowInit()
windowRefresh(gCharacterSelectorWindow);
if (!characterSelectorWindowRefresh()) {
goto err;
return characterSelectorWindowFatalError(false);
}
return true;
err:
characterSelectorWindowFree();
return false;
}
// 0x4A7AD4
@@ -573,102 +495,48 @@ static void characterSelectorWindowFree()
gCharacterSelectorWindowPreviousButton = -1;
}
if (gCharacterSelectorWindowPreviousButtonDownFrmData != NULL) {
artUnlock(gCharacterSelectorWindowPreviousButtonDownFrmHandle);
gCharacterSelectorWindowPreviousButtonDownFrmHandle = NULL;
gCharacterSelectorWindowPreviousButtonDownFrmData = NULL;
}
if (gCharacterSelectorWindowPreviousButtonUpFrmData != NULL) {
artUnlock(gCharacterSelectorWindowPreviousButtonUpFrmHandle);
gCharacterSelectorWindowPreviousButtonUpFrmHandle = NULL;
gCharacterSelectorWindowPreviousButtonUpFrmData = NULL;
}
_previousButtonNormalFrmImage.unlock();
_previousButtonPressedFrmImage.unlock();
if (gCharacterSelectorWindowNextButton != -1) {
buttonDestroy(gCharacterSelectorWindowNextButton);
gCharacterSelectorWindowNextButton = -1;
}
if (gCharacterSelectorWindowNextButtonDownFrmData != NULL) {
artUnlock(gCharacterSelectorWindowNextButtonDownFrmHandle);
gCharacterSelectorWindowNextButtonDownFrmHandle = NULL;
gCharacterSelectorWindowNextButtonDownFrmData = NULL;
}
if (gCharacterSelectorWindowNextButtonUpFrmData != NULL) {
artUnlock(gCharacterSelectorWindowNextButtonUpFrmHandle);
gCharacterSelectorWindowNextButtonUpFrmHandle = NULL;
gCharacterSelectorWindowNextButtonUpFrmData = NULL;
}
_nextButtonNormalFrmImage.unlock();
_nextButtonPressedFrmImage.unlock();
if (gCharacterSelectorWindowTakeButton != -1) {
buttonDestroy(gCharacterSelectorWindowTakeButton);
gCharacterSelectorWindowTakeButton = -1;
}
if (gCharacterSelectorWindowTakeButtonDownFrmData != NULL) {
artUnlock(gCharacterSelectorWindowTakeButtonDownFrmHandle);
gCharacterSelectorWindowTakeButtonDownFrmHandle = NULL;
gCharacterSelectorWindowTakeButtonDownFrmData = NULL;
}
if (gCharacterSelectorWindowTakeButtonUpFrmData != NULL) {
artUnlock(gCharacterSelectorWindowTakeButtonUpFrmHandle);
gCharacterSelectorWindowTakeButtonUpFrmHandle = NULL;
gCharacterSelectorWindowTakeButtonUpFrmData = NULL;
}
_takeButtonNormalFrmImage.unlock();
_takeButtonPressedFrmImage.unlock();
if (gCharacterSelectorWindowModifyButton != -1) {
buttonDestroy(gCharacterSelectorWindowModifyButton);
gCharacterSelectorWindowModifyButton = -1;
}
if (gCharacterSelectorWindowModifyButtonDownFrmData != NULL) {
artUnlock(gCharacterSelectorWindowModifyButtonDownFrmHandle);
gCharacterSelectorWindowModifyButtonDownFrmHandle = NULL;
gCharacterSelectorWindowModifyButtonDownFrmData = NULL;
}
if (gCharacterSelectorWindowModifyButtonUpFrmData != NULL) {
artUnlock(gCharacterSelectorWindowModifyButtonUpFrmHandle);
gCharacterSelectorWindowModifyButtonUpFrmHandle = NULL;
gCharacterSelectorWindowModifyButtonUpFrmData = NULL;
}
_modifyButtonNormalFrmImage.unlock();
_modifyButtonPressedFrmImage.unlock();
if (gCharacterSelectorWindowCreateButton != -1) {
buttonDestroy(gCharacterSelectorWindowCreateButton);
gCharacterSelectorWindowCreateButton = -1;
}
if (gCharacterSelectorWindowCreateButtonDownFrmData != NULL) {
artUnlock(gCharacterSelectorWindowCreateButtonDownFrmHandle);
gCharacterSelectorWindowCreateButtonDownFrmHandle = NULL;
gCharacterSelectorWindowCreateButtonDownFrmData = NULL;
}
if (gCharacterSelectorWindowCreateButtonUpFrmData != NULL) {
artUnlock(gCharacterSelectorWindowCreateButtonUpFrmHandle);
gCharacterSelectorWindowCreateButtonUpFrmHandle = NULL;
gCharacterSelectorWindowCreateButtonUpFrmData = NULL;
}
_createButtonNormalFrmImage.unlock();
_createButtonPressedFrmImage.unlock();
if (gCharacterSelectorWindowBackButton != -1) {
buttonDestroy(gCharacterSelectorWindowBackButton);
gCharacterSelectorWindowBackButton = -1;
}
if (gCharacterSelectorWindowBackButtonDownFrmData != NULL) {
artUnlock(gCharacterSelectorWindowBackButtonDownFrmHandle);
gCharacterSelectorWindowBackButtonDownFrmHandle = NULL;
gCharacterSelectorWindowBackButtonDownFrmData = NULL;
}
if (gCharacterSelectorWindowBackButtonUpFrmData != NULL) {
artUnlock(gCharacterSelectorWindowBackButtonUpFrmHandle);
gCharacterSelectorWindowBackButtonUpFrmHandle = NULL;
gCharacterSelectorWindowBackButtonUpFrmData = NULL;
}
_backButtonNormalFrmImage.unlock();
_backButtonPressedFrmImage.unlock();
if (gCharacterSelectorBackground != NULL) {
internal_free(gCharacterSelectorBackground);
@@ -715,18 +583,17 @@ static bool characterSelectorWindowRenderFace()
{
bool success = false;
CacheEntry* faceFrmHandle;
FrmImage faceFrmImage;
int faceFid = buildFid(OBJ_TYPE_INTERFACE, gCustomPremadeCharacterDescriptions[gCurrentPremadeCharacter].face, 0, 0, 0);
Art* frm = artLock(faceFid, &faceFrmHandle);
if (frm != NULL) {
unsigned char* data = artGetFrameData(frm, 0, 0);
if (faceFrmImage.lock(faceFid)) {
unsigned char* data = faceFrmImage.getData();
if (data != NULL) {
int width = artGetWidth(frm, 0, 0);
int height = artGetHeight(frm, 0, 0);
int width = faceFrmImage.getWidth();
int height = faceFrmImage.getHeight();
blitBufferToBufferTrans(data, width, height, width, (gCharacterSelectorWindowBuffer + CS_WINDOW_WIDTH * 23 + 27), CS_WINDOW_WIDTH);
success = true;
}
artUnlock(faceFrmHandle);
faceFrmImage.unlock();
}
return success;
@@ -1013,6 +880,15 @@ static bool characterSelectorWindowRenderBio()
return true;
}
// NOTE: Inlined.
//
// 0x4A8BD0
static bool characterSelectorWindowFatalError(bool result)
{
characterSelectorWindowFree();
return result;
}
void premadeCharactersInit()
{
char* fileNamesString;
@@ -1122,3 +998,5 @@ static void premadeCharactersLocalizePath(char* path)
strcpy(path, localizedPath);
}
}
} // namespace fallout

View File

@@ -1,9 +1,13 @@
#ifndef CHARACTER_SELECTOR_H
#define CHARACTER_SELECTOR_H
namespace fallout {
int characterSelectorOpen();
void premadeCharactersInit();
void premadeCharactersExit();
} // namespace fallout
#endif /* CHARACTER_SELECTOR_H */

View File

@@ -7,6 +7,8 @@
#include "core.h"
namespace fallout {
#define COLOR_PALETTE_STACK_CAPACITY 16
typedef struct ColorPaletteStackEntry {
@@ -679,3 +681,5 @@ void _colorsClose()
gColorPaletteStackSize = 0;
}
} // namespace fallout

View File

@@ -3,6 +3,8 @@
#include "memory_defs.h"
namespace fallout {
typedef const char*(ColorFileNameManger)(const char*);
typedef void(ColorTransitionCallback)();
@@ -40,4 +42,6 @@ bool colorPopColorPalette();
bool _initColors();
void _colorsClose();
} // namespace fallout
#endif /* COLOR_H */

View File

@@ -43,6 +43,8 @@
#include "trait.h"
#include "window_manager.h"
namespace fallout {
#define CALLED_SHOT_WINDOW_Y (20)
#define CALLED_SHOT_WINDOW_WIDTH (504)
#define CALLED_SHOT_WINDOW_HEIGHT (309)
@@ -85,7 +87,7 @@ typedef struct DamageCalculationContext {
int combatDifficultyDamageModifier;
} DamageCalculationContext;
static bool _combat_safety_invalidate_weapon_func(Object* critter, Object* weapon, int hitMode, Object* a4, int* a5, Object* a6);
static bool _combat_safety_invalidate_weapon_func(Object* attacker, Object* weapon, int hitMode, Object* defender, int* safeDistancePtr, Object* attackerFriend);
static void _combatInitAIInfoList();
static int aiInfoCopy(int srcIndex, int destIndex);
static int _combatAIInfoSetLastMove(Object* object, int move);
@@ -103,8 +105,8 @@ static void _combat_set_move_all();
static int _combat_turn(Object* a1, bool a2);
static bool _combat_should_end();
static bool _check_ranged_miss(Attack* attack);
static int _shoot_along_path(Attack* attack, int a2, int a3, int anim);
static int _compute_spray(Attack* attack, int accuracy, int* a3, int* a4, int anim);
static int _shoot_along_path(Attack* attack, int endTile, int rounds, int anim);
static int _compute_spray(Attack* attack, int accuracy, int* roundsHitMainTargetPtr, int* roundsSpentPtr, int anim);
static int attackComputeEnhancedKnockout(Attack* attack);
static int attackCompute(Attack* attack);
static int attackComputeCriticalHit(Attack* a1);
@@ -2247,39 +2249,39 @@ int combatSave(File* stream)
}
// 0x4213E8
bool _combat_safety_invalidate_weapon(Object* a1, Object* a2, int hitMode, Object* a4, int* a5)
bool _combat_safety_invalidate_weapon(Object* attacker, Object* weapon, int hitMode, Object* defender, int* safeDistancePtr)
{
return _combat_safety_invalidate_weapon_func(a1, a2, hitMode, a4, a5, NULL);
return _combat_safety_invalidate_weapon_func(attacker, weapon, hitMode, defender, safeDistancePtr, NULL);
}
// 0x4213FC
static bool _combat_safety_invalidate_weapon_func(Object* critter, Object* weapon, int hitMode, Object* a4, int* a5, Object* a6)
static bool _combat_safety_invalidate_weapon_func(Object* attacker, Object* weapon, int hitMode, Object* defender, int* safeDistancePtr, Object* attackerFriend)
{
if (a5 != NULL) {
*a5 = 0;
if (safeDistancePtr != NULL) {
*safeDistancePtr = 0;
}
if (critter->pid == PROTO_ID_0x10001E0) {
if (attacker->pid == PROTO_ID_0x10001E0) {
return false;
}
int intelligence = critterGetStat(critter, STAT_INTELLIGENCE);
int team = critter->data.critter.combat.team;
int v41 = weaponGetDamageRadius(weapon, hitMode);
int intelligence = critterGetStat(attacker, STAT_INTELLIGENCE);
int team = attacker->data.critter.combat.team;
int damageRadius = weaponGetDamageRadius(weapon, hitMode);
int maxDamage;
weaponGetDamageMinMax(weapon, NULL, &maxDamage);
int damageType = weaponGetDamageType(critter, weapon);
int damageType = weaponGetDamageType(attacker, weapon);
if (v41 > 0) {
if (damageRadius > 0) {
if (intelligence < 5) {
v41 -= 5 - intelligence;
if (v41 < 0) {
v41 = 0;
damageRadius -= 5 - intelligence;
if (damageRadius < 0) {
damageRadius = 0;
}
}
if (a6 != NULL) {
if (objectGetDistanceBetween(a4, a6) < v41) {
if (attackerFriend != NULL) {
if (objectGetDistanceBetween(defender, attackerFriend) < damageRadius) {
debugPrint("Friendly was in the way!");
return true;
}
@@ -2288,11 +2290,11 @@ static bool _combat_safety_invalidate_weapon_func(Object* critter, Object* weapo
for (int index = 0; index < _list_total; index++) {
Object* candidate = _combat_list[index];
if (candidate->data.critter.combat.team == team
&& candidate != critter
&& candidate != a4
&& candidate != attacker
&& candidate != defender
&& !critterIsDead(candidate)) {
int v14 = objectGetDistanceBetween(a4, candidate);
if (v14 < v41 && candidate != candidate->data.critter.combat.whoHitMe) {
int v14 = objectGetDistanceBetween(defender, candidate);
if (v14 < damageRadius && candidate != candidate->data.critter.combat.whoHitMe) {
int damageThreshold = critterGetStat(candidate, STAT_DAMAGE_THRESHOLD + damageType);
int damageResistance = critterGetStat(candidate, STAT_DAMAGE_RESISTANCE + damageType);
if (damageResistance * (maxDamage - damageThreshold) / 100 > 0) {
@@ -2302,11 +2304,9 @@ static bool _combat_safety_invalidate_weapon_func(Object* critter, Object* weapo
}
}
int v17 = objectGetDistanceBetween(a4, critter);
if (v17 <= v41) {
if (a5 != NULL) {
int v18 = objectGetDistanceBetween(a4, critter);
*a5 = v41 - v18 + 1;
if (objectGetDistanceBetween(defender, attacker) <= damageRadius) {
if (safeDistancePtr != NULL) {
*safeDistancePtr = damageRadius - objectGetDistanceBetween(defender, attacker) + 1;
return false;
}
@@ -2316,22 +2316,22 @@ static bool _combat_safety_invalidate_weapon_func(Object* critter, Object* weapo
return false;
}
int v19 = weaponGetAnimationForHitMode(weapon, hitMode);
if (v19 != ANIM_FIRE_BURST && v19 != ANIM_FIRE_CONTINUOUS) {
int anim = weaponGetAnimationForHitMode(weapon, hitMode);
if (anim != ANIM_FIRE_BURST && anim != ANIM_FIRE_CONTINUOUS) {
return false;
}
Attack attack;
attackInit(&attack, critter, a4, hitMode, HIT_LOCATION_TORSO);
attackInit(&attack, attacker, defender, hitMode, HIT_LOCATION_TORSO);
int accuracy = attackDetermineToHit(critter, critter->tile, a4, HIT_LOCATION_TORSO, hitMode, true);
int v33;
int a4a;
_compute_spray(&attack, accuracy, &v33, &a4a, v19);
int accuracy = attackDetermineToHit(attacker, attacker->tile, defender, HIT_LOCATION_TORSO, hitMode, true);
int roundsHitMainTarget;
int roundsSpent;
_compute_spray(&attack, accuracy, &roundsHitMainTarget, &roundsSpent, anim);
if (a6 != NULL) {
if (attackerFriend != NULL) {
for (int index = 0; index < attack.extrasLength; index++) {
if (attack.extras[index] == a6) {
if (attack.extras[index] == attackerFriend) {
debugPrint("Friendly was in the way!");
return true;
}
@@ -2341,8 +2341,8 @@ static bool _combat_safety_invalidate_weapon_func(Object* critter, Object* weapo
for (int index = 0; index < attack.extrasLength; index++) {
Object* candidate = attack.extras[index];
if (candidate->data.critter.combat.team == team
&& candidate != critter
&& candidate != a4
&& candidate != attacker
&& candidate != defender
&& !critterIsDead(candidate)
&& candidate != candidate->data.critter.combat.whoHitMe) {
int damageThreshold = critterGetStat(candidate, STAT_DAMAGE_THRESHOLD + damageType);
@@ -2357,9 +2357,9 @@ static bool _combat_safety_invalidate_weapon_func(Object* critter, Object* weapo
}
// 0x4217BC
bool _combatTestIncidentalHit(Object* a1, Object* a2, Object* a3, Object* a4)
bool _combatTestIncidentalHit(Object* attacker, Object* defender, Object* attackerFriend, Object* weapon)
{
return _combat_safety_invalidate_weapon_func(a1, a4, HIT_MODE_RIGHT_WEAPON_PRIMARY, a2, NULL, a3);
return _combat_safety_invalidate_weapon_func(attacker, weapon, HIT_MODE_RIGHT_WEAPON_PRIMARY, defender, NULL, attackerFriend);
}
// 0x4217D4
@@ -3604,39 +3604,39 @@ static bool _check_ranged_miss(Attack* attack)
}
// 0x423284
static int _shoot_along_path(Attack* attack, int a2, int a3, int anim)
static int _shoot_along_path(Attack* attack, int endTile, int rounds, int anim)
{
int v5 = a3;
int v17 = 0;
int v7 = attack->attacker->tile;
int remainingRounds = rounds;
int roundsHitMainTarget = 0;
int currentTile = attack->attacker->tile;
Object* critter = attack->attacker;
while (critter != NULL) {
if ((v5 <= 0 && anim != ANIM_FIRE_CONTINUOUS) || v7 == a2 || attack->extrasLength >= 6) {
if ((remainingRounds <= 0 && anim != ANIM_FIRE_CONTINUOUS) || currentTile == endTile || attack->extrasLength >= 6) {
break;
}
_make_straight_path_func(attack->attacker, v7, a2, NULL, &critter, 32, _obj_shoot_blocking_at);
_make_straight_path_func(attack->attacker, currentTile, endTile, NULL, &critter, 32, _obj_shoot_blocking_at);
if (critter != NULL) {
if (FID_TYPE(critter->fid) != OBJ_TYPE_CRITTER) {
break;
}
int v8 = attackDetermineToHit(attack->attacker, attack->attacker->tile, critter, HIT_LOCATION_TORSO, attack->hitMode, true);
int accuracy = attackDetermineToHit(attack->attacker, attack->attacker->tile, critter, HIT_LOCATION_TORSO, attack->hitMode, true);
if (anim == ANIM_FIRE_CONTINUOUS) {
v5 = 1;
remainingRounds = 1;
}
int a2a = 0;
while (randomBetween(1, 100) <= v8 && v5 > 0) {
v5 -= 1;
a2a += 1;
int roundsHit = 0;
while (randomBetween(1, 100) <= accuracy && remainingRounds > 0) {
remainingRounds -= 1;
roundsHit += 1;
}
if (a2a != 0) {
if (roundsHit != 0) {
if (critter == attack->defender) {
v17 += a2a;
roundsHitMainTarget += roundsHit;
} else {
int index;
for (index = 0; index < attack->extrasLength; index += 1) {
@@ -3649,7 +3649,7 @@ static int _shoot_along_path(Attack* attack, int a2, int a3, int anim)
attack->extras[index] = critter;
attackInit(&_shoot_ctd, attack->attacker, critter, attack->hitMode, HIT_LOCATION_TORSO);
_shoot_ctd.attackerFlags |= DAM_HIT;
attackComputeDamage(&_shoot_ctd, a2a, 2);
attackComputeDamage(&_shoot_ctd, roundsHit, 2);
if (index == attack->extrasLength) {
attack->extrasDamage[index] = _shoot_ctd.defenderDamage;
@@ -3666,21 +3666,21 @@ static int _shoot_along_path(Attack* attack, int a2, int a3, int anim)
}
}
v7 = critter->tile;
currentTile = critter->tile;
}
}
if (anim == ANIM_FIRE_CONTINUOUS) {
v17 = 0;
roundsHitMainTarget = 0;
}
return v17;
return roundsHitMainTarget;
}
// 0x423488
static int _compute_spray(Attack* attack, int accuracy, int* a3, int* a4, int anim)
static int _compute_spray(Attack* attack, int accuracy, int* roundsHitMainTargetPtr, int* roundsSpentPtr, int anim)
{
*a3 = 0;
*roundsHitMainTargetPtr = 0;
int ammoQuantity = ammoGetQuantity(attack->weapon);
int burstRounds = weaponGetBurstRounds(attack->weapon);
@@ -3688,7 +3688,7 @@ static int _compute_spray(Attack* attack, int accuracy, int* a3, int* a4, int an
ammoQuantity = burstRounds;
}
*a4 = ammoQuantity;
*roundsSpentPtr = ammoQuantity;
int criticalChance = critterGetStat(attack->attacker, STAT_CRITICAL_CHANCE);
int roll = randomRoll(accuracy, criticalChance, NULL);
@@ -3732,17 +3732,17 @@ static int _compute_spray(Attack* attack, int accuracy, int* a3, int* a4, int an
for (int index = 0; index < mainTargetRounds; index += 1) {
if (randomRoll(accuracy, 0, NULL) >= ROLL_SUCCESS) {
*a3 += 1;
*roundsHitMainTargetPtr += 1;
}
}
if (*a3 == 0 && _check_ranged_miss(attack)) {
*a3 = 1;
if (*roundsHitMainTargetPtr == 0 && _check_ranged_miss(attack)) {
*roundsHitMainTargetPtr = 1;
}
int range = weaponGetRange(attack->attacker, attack->hitMode);
int mainTargetEndTile = _tile_num_beyond(attack->attacker->tile, attack->defender->tile, range);
*a3 += _shoot_along_path(attack, mainTargetEndTile, centerRounds - *a3, anim);
*roundsHitMainTargetPtr += _shoot_along_path(attack, mainTargetEndTile, centerRounds - *roundsHitMainTargetPtr, anim);
int centerTile;
if (objectGetDistanceBetween(attack->attacker, attack->defender) <= 3) {
@@ -3755,14 +3755,14 @@ static int _compute_spray(Attack* attack, int accuracy, int* a3, int* a4, int an
int leftTile = tileGetTileInDirection(centerTile, (rotation + 1) % ROTATION_COUNT, 1);
int leftEndTile = _tile_num_beyond(attack->attacker->tile, leftTile, range);
*a3 += _shoot_along_path(attack, leftEndTile, leftRounds, anim);
*roundsHitMainTargetPtr += _shoot_along_path(attack, leftEndTile, leftRounds, anim);
int rightTile = tileGetTileInDirection(centerTile, (rotation + 5) % ROTATION_COUNT, 1);
int rightEndTile = _tile_num_beyond(attack->attacker->tile, rightTile, range);
*a3 += _shoot_along_path(attack, rightEndTile, rightRounds, anim);
*roundsHitMainTargetPtr += _shoot_along_path(attack, rightEndTile, rightRounds, anim);
if (roll != ROLL_FAILURE || (*a3 <= 0 && attack->extrasLength <= 0)) {
if (roll >= ROLL_SUCCESS && *a3 == 0 && attack->extrasLength == 0) {
if (roll != ROLL_FAILURE || (*roundsHitMainTargetPtr <= 0 && attack->extrasLength <= 0)) {
if (roll >= ROLL_SUCCESS && *roundsHitMainTargetPtr == 0 && attack->extrasLength == 0) {
roll = ROLL_FAILURE;
}
} else {
@@ -5402,22 +5402,19 @@ static void _combat_standup(Object* a1)
// 0x42603C
static void _print_tohit(unsigned char* dest, int destPitch, int accuracy)
{
CacheEntry* numbersFrmHandle;
int numbersFrmFid = buildFid(OBJ_TYPE_INTERFACE, 82, 0, 0, 0);
unsigned char* numbersFrmData = artLockFrameData(numbersFrmFid, 0, 0, &numbersFrmHandle);
if (numbersFrmData == NULL) {
FrmImage numbersFrmImage;
int numbersFid = buildFid(OBJ_TYPE_INTERFACE, 82, 0, 0, 0);
if (!numbersFrmImage.lock(numbersFid)) {
return;
}
if (accuracy >= 0) {
blitBufferToBuffer(numbersFrmData + 9 * (accuracy % 10), 9, 17, 360, dest + 9, destPitch);
blitBufferToBuffer(numbersFrmData + 9 * (accuracy / 10), 9, 17, 360, dest, destPitch);
blitBufferToBuffer(numbersFrmImage.getData() + 9 * (accuracy % 10), 9, 17, 360, dest + 9, destPitch);
blitBufferToBuffer(numbersFrmImage.getData() + 9 * (accuracy / 10), 9, 17, 360, dest, destPitch);
} else {
blitBufferToBuffer(numbersFrmData + 108, 6, 17, 360, dest + 9, destPitch);
blitBufferToBuffer(numbersFrmData + 108, 6, 17, 360, dest, destPitch);
blitBufferToBuffer(numbersFrmImage.getData() + 108, 6, 17, 360, dest + 9, destPitch);
blitBufferToBuffer(numbersFrmImage.getData() + 108, 6, 17, 360, dest, destPitch);
}
artUnlock(numbersFrmHandle);
}
// 0x42612C
@@ -5489,52 +5486,63 @@ static int calledShotSelectHitLocation(Object* critter, int* hitLocation, int hi
return -1;
}
int fid;
CacheEntry* handle;
unsigned char* data;
unsigned char* windowBuffer = windowGetBuffer(gCalledShotWindow);
fid = buildFid(OBJ_TYPE_INTERFACE, 118, 0, 0, 0);
data = artLockFrameData(fid, 0, 0, &handle);
if (data == NULL) {
FrmImage backgroundFrm;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 118, 0, 0, 0);
if (!backgroundFrm.lock(backgroundFid)) {
windowDestroy(gCalledShotWindow);
return -1;
}
blitBufferToBuffer(data, CALLED_SHOT_WINDOW_WIDTH, CALLED_SHOT_WINDOW_HEIGHT, CALLED_SHOT_WINDOW_WIDTH, windowBuffer, CALLED_SHOT_WINDOW_WIDTH);
artUnlock(handle);
blitBufferToBuffer(backgroundFrm.getData(),
CALLED_SHOT_WINDOW_WIDTH,
CALLED_SHOT_WINDOW_HEIGHT,
CALLED_SHOT_WINDOW_WIDTH,
windowBuffer,
CALLED_SHOT_WINDOW_WIDTH);
fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, ANIM_CALLED_SHOT_PIC, 0, 0);
data = artLockFrameData(fid, 0, 0, &handle);
if (data != NULL) {
blitBufferToBuffer(data, 170, 225, 170, windowBuffer + CALLED_SHOT_WINDOW_WIDTH * 31 + 168, CALLED_SHOT_WINDOW_WIDTH);
artUnlock(handle);
FrmImage critterFrm;
int critterFid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, ANIM_CALLED_SHOT_PIC, 0, 0);
if (critterFrm.lock(critterFid)) {
blitBufferToBuffer(critterFrm.getData(),
170,
225,
170,
windowBuffer + CALLED_SHOT_WINDOW_WIDTH * 31 + 168,
CALLED_SHOT_WINDOW_WIDTH);
}
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
CacheEntry* upHandle;
unsigned char* up = artLockFrameData(fid, 0, 0, &upHandle);
if (up == NULL) {
FrmImage cancelButtonNormalFrmImage;
int cancelButtonNormalFid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
if (!cancelButtonNormalFrmImage.lock(cancelButtonNormalFid)) {
windowDestroy(gCalledShotWindow);
return -1;
}
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
CacheEntry* downHandle;
unsigned char* down = artLockFrameData(fid, 0, 0, &downHandle);
if (down == NULL) {
artUnlock(upHandle);
FrmImage cancelButtonPressedFrmImage;
int cancelButtonPressedFid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
if (!cancelButtonPressedFrmImage.lock(cancelButtonPressedFid)) {
windowDestroy(gCalledShotWindow);
return -1;
}
// Cancel button
int btn = buttonCreate(gCalledShotWindow, 210, 268, 15, 16, -1, -1, -1, KEY_ESCAPE, up, down, NULL, BUTTON_FLAG_TRANSPARENT);
if (btn != -1) {
buttonSetCallbacks(btn, _gsound_red_butt_press, _gsound_red_butt_release);
int cancelBtn = buttonCreate(gCalledShotWindow,
210,
268,
15,
16,
-1,
-1,
-1,
KEY_ESCAPE,
cancelButtonNormalFrmImage.getData(),
cancelButtonPressedFrmImage.getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (cancelBtn != -1) {
buttonSetCallbacks(cancelBtn, _gsound_red_butt_press, _gsound_red_butt_release);
}
int oldFont = fontGetCurrent();
@@ -5594,8 +5602,6 @@ static int calledShotSelectHitLocation(Object* critter, int* hitLocation, int hi
fontSetCurrent(oldFont);
artUnlock(downHandle);
artUnlock(upHandle);
windowDestroy(gCalledShotWindow);
if (eventCode == KEY_ESCAPE) {
@@ -6781,3 +6787,5 @@ static void damageModCalculateYaam(DamageCalculationContext* context)
}
}
}
} // namespace fallout

View File

@@ -6,6 +6,8 @@
#include "obj_types.h"
#include "proto_types.h"
namespace fallout {
extern int _combatNumTurns;
extern unsigned int gCombatState;
@@ -17,8 +19,8 @@ void combatExit();
int _find_cid(int a1, int a2, Object** a3, int a4);
int combatLoad(File* stream);
int combatSave(File* stream);
bool _combat_safety_invalidate_weapon(Object* a1, Object* a2, int hitMode, Object* a4, int* a5);
bool _combatTestIncidentalHit(Object* a1, Object* a2, Object* a3, Object* a4);
bool _combat_safety_invalidate_weapon(Object* attacker, Object* weapon, int hitMode, Object* defender, int* safeDistancePtr);
bool _combatTestIncidentalHit(Object* attacker, Object* defender, Object* attackerFriend, Object* weapon);
Object* _combat_whose_turn();
void _combat_data_init(Object* obj);
Object* aiInfoGetFriendlyDead(Object* obj);
@@ -81,4 +83,6 @@ static inline bool isUnarmedHitMode(int hitMode)
|| (hitMode >= FIRST_ADVANCED_UNARMED_HIT_MODE && hitMode <= LAST_ADVANCED_UNARMED_HIT_MODE);
}
} // namespace fallout
#endif /* COMBAT_H */

View File

@@ -34,6 +34,8 @@
#include "text_object.h"
#include "tile.h"
namespace fallout {
#define AI_PACKET_CHEM_PRIMARY_DESIRE_COUNT (3)
typedef struct AiMessageRange {
@@ -120,7 +122,7 @@ static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a
static int _ai_move_closer(Object* a1, Object* a2, int a3);
static int _cai_retargetTileFromFriendlyFire(Object* source, Object* target, int* tilePtr);
static int _cai_retargetTileFromFriendlyFireSubFunc(AiRetargetData* aiRetargetData, int tile);
static bool _cai_attackWouldIntersect(Object* a1, Object* a2, Object* a3, int tile, int* distance);
static bool _cai_attackWouldIntersect(Object* attacker, Object* defender, Object* attackerFriend, int tile, int* distance);
static int _ai_switch_weapons(Object* a1, int* hitMode, Object** weapon, Object* a4);
static int _ai_called_shot(Object* a1, Object* a2, int a3);
static int _ai_attack(Object* a1, Object* a2, int a3);
@@ -2421,27 +2423,27 @@ static int _cai_retargetTileFromFriendlyFireSubFunc(AiRetargetData* aiRetargetDa
}
// 0x42A518
static bool _cai_attackWouldIntersect(Object* a1, Object* a2, Object* a3, int tile, int* distance)
static bool _cai_attackWouldIntersect(Object* attacker, Object* defender, Object* attackerFriend, int tile, int* distance)
{
int hitMode = HIT_MODE_RIGHT_WEAPON_PRIMARY;
bool aiming = false;
if (a1 == gDude) {
if (attacker == gDude) {
interfaceGetCurrentHitMode(&hitMode, &aiming);
}
Object* v8 = critterGetWeaponForHitMode(a1, hitMode);
if (v8 == NULL) {
Object* weapon = critterGetWeaponForHitMode(attacker, hitMode);
if (weapon == NULL) {
return false;
}
if (weaponGetRange(a1, hitMode) < 1) {
if (weaponGetRange(attacker, hitMode) < 1) {
return false;
}
Object* object = NULL;
_make_straight_path_func(a1, a1->tile, a2->tile, NULL, &object, 32, _obj_shoot_blocking_at);
if (object != a3) {
if (!_combatTestIncidentalHit(a1, a2, a3, v8)) {
_make_straight_path_func(attacker, attacker->tile, defender->tile, NULL, &object, 32, _obj_shoot_blocking_at);
if (object != attackerFriend) {
if (!_combatTestIncidentalHit(attacker, defender, attackerFriend, weapon)) {
return false;
}
}
@@ -3518,3 +3520,5 @@ void _combatai_delete_critter(Object* obj)
}
}
}
} // namespace fallout

View File

@@ -6,6 +6,8 @@
#include "db.h"
#include "obj_types.h"
namespace fallout {
typedef enum AiMessageType {
AI_MESSAGE_TYPE_RUN,
AI_MESSAGE_TYPE_MOVE,
@@ -66,4 +68,6 @@ void _combatai_notify_onlookers(Object* a1);
void _combatai_notify_friends(Object* a1);
void _combatai_delete_critter(Object* obj);
} // namespace fallout
#endif /* COMBAT_AI_H */

View File

@@ -1,6 +1,8 @@
#ifndef COMBAT_AI_DEFS_H
#define COMBAT_AI_DEFS_H
namespace fallout {
typedef enum AreaAttackMode {
AREA_ATTACK_MODE_ALWAYS,
AREA_ATTACK_MODE_SOMETIMES,
@@ -79,4 +81,6 @@ typedef enum HurtTooMuch {
HURT_COUNT,
} HurtTooMuch;
} // namespace fallout
#endif /* COMBAT_AI_DEFS_H */

View File

@@ -10,6 +10,8 @@
#define WEAPON_CRITICAL_FAILURE_TYPE_COUNT (7)
#define WEAPON_CRITICAL_FAILURE_EFFECT_COUNT (5)
namespace fallout {
typedef enum CombatState {
COMBAT_STATE_0x01 = 0x01,
COMBAT_STATE_0x02 = 0x02,
@@ -169,4 +171,6 @@ typedef enum CombatBadShot {
COMBAT_BAD_SHOT_BOTH_ARMS_CRIPPLED = 7,
} CombatBadShot;
} // namespace fallout
#endif /* COMBAT_DEFS_H */

View File

@@ -11,6 +11,8 @@
#include "memory.h"
#include "platform_compat.h"
namespace fallout {
#define CONFIG_FILE_MAX_LINE_LENGTH (256)
// The initial number of sections (or key-value) pairs in the config.
@@ -547,3 +549,5 @@ bool configSetBool(Config* config, const char* sectionKey, const char* key, bool
{
return configSetInt(config, sectionKey, key, value ? 1 : 0);
}
} // namespace fallout

View File

@@ -3,6 +3,8 @@
#include "dictionary.h"
namespace fallout {
// A representation of .INI file.
//
// It's implemented as a [Dictionary] whos keys are section names of .INI file,
@@ -31,4 +33,6 @@ bool configSetDouble(Config* config, const char* sectionKey, const char* key, do
bool configGetBool(Config* config, const char* sectionKey, const char* key, bool* valuePtr);
bool configSetBool(Config* config, const char* sectionKey, const char* key, bool value);
} // namespace fallout
#endif /* CONFIG_H */

View File

@@ -18,6 +18,8 @@
#include "window_manager.h"
#include "window_manager_private.h"
namespace fallout {
static void idleImpl();
// 0x51E234
@@ -4916,3 +4918,5 @@ static void idleImpl()
{
SDL_Delay(125);
}
} // namespace fallout

View File

@@ -8,6 +8,8 @@
#include "geometry.h"
#include "window.h"
namespace fallout {
#define MOUSE_DEFAULT_CURSOR_WIDTH 8
#define MOUSE_DEFAULT_CURSOR_HEIGHT 8
#define MOUSE_DEFAULT_CURSOR_SIZE (MOUSE_DEFAULT_CURSOR_WIDTH * MOUSE_DEFAULT_CURSOR_HEIGHT)
@@ -696,4 +698,6 @@ bool mouseHitTestInWindow(int win, int left, int top, int right, int bottom);
void mouseGetWheel(int* x, int* y);
void convertMouseWheelToArrowKey(int* keyCodePtr);
} // namespace fallout
#endif /* CORE_H */

View File

@@ -18,6 +18,8 @@
#include "text_font.h"
#include "window_manager.h"
namespace fallout {
#define CREDITS_WINDOW_WIDTH (640)
#define CREDITS_WINDOW_HEIGHT (480)
#define CREDITS_WINDOW_SCROLLING_DELAY (38)
@@ -274,3 +276,5 @@ static bool creditsFileParseNextLine(char* dest, int* font, int* color)
return false;
}
} // namespace fallout

View File

@@ -1,6 +1,10 @@
#ifndef CREDITS_H
#define CREDITS_H
namespace fallout {
void creditsOpen(const char* path, int fid, bool useReversedStyle);
} // namespace fallout
#endif /* CREDITS_H */

View File

@@ -31,6 +31,8 @@
#include "trait.h"
#include "worldmap.h"
namespace fallout {
// Maximum length of dude's name length.
#define DUDE_NAME_MAX_LENGTH (32)
@@ -1390,3 +1392,5 @@ bool _critter_flag_check(int pid, int flag)
protoGetProto(pid, &proto);
return (proto->critter.data.flags & flag) != 0;
}
} // namespace fallout

View File

@@ -5,6 +5,8 @@
#include "obj_types.h"
#include "proto_types.h"
namespace fallout {
typedef enum DudeState {
DUDE_STATE_SNEAKING = 0,
DUDE_STATE_LEVEL_UP_AVAILABLE = 3,
@@ -69,4 +71,6 @@ bool critterIsEncumbered(Object* critter);
bool critterIsFleeing(Object* a1);
bool _critter_flag_check(int pid, int flag);
} // namespace fallout
#endif /* CRITTER_H */

View File

@@ -5,6 +5,8 @@
#include "game_config.h"
#include "palette.h"
namespace fallout {
#define COLOR_CYCLE_PERIOD_1 (200U)
#define COLOR_CYCLE_PERIOD_2 (142U)
#define COLOR_CYCLE_PERIOD_3 (100U)
@@ -332,3 +334,5 @@ void colorCycleTicker()
paletteSetEntriesInRange(palette + 229 * 3, 229, 255);
}
}
} // namespace fallout

View File

@@ -1,6 +1,8 @@
#ifndef CYCLE_H
#define CYCLE_H
namespace fallout {
void colorCycleInit();
void colorCycleReset();
void colorCycleFree();
@@ -10,4 +12,6 @@ bool colorCycleEnabled();
void cycleSetSpeedFactor(int value);
void colorCycleTicker();
} // namespace fallout
#endif /* CYCLE_H */

View File

@@ -8,6 +8,8 @@
#include "pcx.h"
#include "platform_compat.h"
namespace fallout {
// 0x5184AC
DatafileLoader* gDatafileLoader = NULL;
@@ -193,3 +195,5 @@ unsigned char* datafileLoad(char* path, int* sizePtr)
*sizePtr = size;
return data;
}
} // namespace fallout

View File

@@ -1,6 +1,8 @@
#ifndef DATAFILE_H
#define DATAFILE_H
namespace fallout {
typedef unsigned char*(DatafileLoader)(char* path, unsigned char* palette, int* widthPtr, int* heightPtr);
typedef char*(DatafileNameMangler)(char* path);
@@ -21,4 +23,6 @@ void sub_42F024(unsigned char* data, int* widthPtr, int* heightPtr);
unsigned char* datafileGetPalette();
unsigned char* datafileLoad(char* path, int* sizePtr);
} // namespace fallout
#endif /* DATAFILE_H */

View File

@@ -7,6 +7,8 @@
#include "platform_compat.h"
#include "xfile.h"
namespace fallout {
typedef struct FileList {
XList xlist;
struct FileList* next;
@@ -738,3 +740,5 @@ int _db_list_compare(const void* p1, const void* p2)
{
return compat_stricmp(*(const char**)p1, *(const char**)p2);
}
} // namespace fallout

View File

@@ -6,6 +6,8 @@
#include "memory_defs.h"
#include "xfile.h"
namespace fallout {
typedef XFile File;
typedef void FileReadProgressHandler();
typedef char* StrdupProc(const char* string);
@@ -66,4 +68,6 @@ int fileGetSize(File* stream);
void fileSetReadProgressHandler(FileReadProgressHandler* handler, int size);
void _db_enable_hash_table_();
} // namespace fallout
#endif /* DB_H */

View File

@@ -19,6 +19,8 @@
#include "window_manager.h"
#include "word_wrap.h"
namespace fallout {
#define FILE_DIALOG_LINE_COUNT 12
#define FILE_DIALOG_DOUBLE_CLICK_DELAY 32
@@ -193,81 +195,67 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
: DIALOG_TYPE_MEDIUM;
}
CacheEntry* backgroundHandle;
int backgroundWidth;
int backgroundHeight;
int fid = buildFid(OBJ_TYPE_INTERFACE, gDialogBoxBackgroundFrmIds[dialogType], 0, 0, 0);
unsigned char* background = artLockFrameDataReturningSize(fid, &backgroundHandle, &backgroundWidth, &backgroundHeight);
if (background == NULL) {
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, gDialogBoxBackgroundFrmIds[dialogType], 0, 0, 0);
if (!backgroundFrmImage.lock(backgroundFid)) {
fontSetCurrent(savedFont);
return -1;
}
// Maintain original position in original resolution, otherwise center it.
if (screenGetWidth() != 640) x = (screenGetWidth() - backgroundWidth) / 2;
if (screenGetHeight() != 480) y = (screenGetHeight() - backgroundHeight) / 2;
int win = windowCreate(x, y, backgroundWidth, backgroundHeight, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
if (screenGetWidth() != 640) x = (screenGetWidth() - backgroundFrmImage.getWidth()) / 2;
if (screenGetHeight() != 480) y = (screenGetHeight() - backgroundFrmImage.getHeight()) / 2;
int win = windowCreate(x,
y,
backgroundFrmImage.getWidth(),
backgroundFrmImage.getHeight(),
256,
WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
if (win == -1) {
artUnlock(backgroundHandle);
fontSetCurrent(savedFont);
return -1;
}
unsigned char* windowBuf = windowGetBuffer(win);
memcpy(windowBuf, background, backgroundWidth * backgroundHeight);
memcpy(windowBuf, backgroundFrmImage.getData(), backgroundFrmImage.getWidth() * backgroundFrmImage.getHeight());
CacheEntry* doneBoxHandle = NULL;
unsigned char* doneBox = NULL;
int doneBoxWidth;
int doneBoxHeight;
CacheEntry* downButtonHandle = NULL;
unsigned char* downButton = NULL;
int downButtonWidth;
int downButtonHeight;
CacheEntry* upButtonHandle = NULL;
unsigned char* upButton = NULL;
FrmImage doneBoxFrmImage;
FrmImage buttonNormalFrmImage;
FrmImage buttonPressedFrmImage;
if ((flags & DIALOG_BOX_0x20) == 0) {
int doneBoxFid = buildFid(OBJ_TYPE_INTERFACE, 209, 0, 0, 0);
doneBox = artLockFrameDataReturningSize(doneBoxFid, &doneBoxHandle, &doneBoxWidth, &doneBoxHeight);
if (doneBox == NULL) {
artUnlock(backgroundHandle);
if (!doneBoxFrmImage.lock(doneBoxFid)) {
fontSetCurrent(savedFont);
windowDestroy(win);
return -1;
}
int downButtonFid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
downButton = artLockFrameDataReturningSize(downButtonFid, &downButtonHandle, &downButtonWidth, &downButtonHeight);
if (downButton == NULL) {
artUnlock(doneBoxHandle);
artUnlock(backgroundHandle);
int pressedFid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
if (!buttonPressedFrmImage.lock(pressedFid)) {
fontSetCurrent(savedFont);
windowDestroy(win);
return -1;
}
int upButtonFid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
upButton = artLockFrameData(upButtonFid, 0, 0, &upButtonHandle);
if (upButton == NULL) {
artUnlock(downButtonHandle);
artUnlock(doneBoxHandle);
artUnlock(backgroundHandle);
int normalFid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
if (!buttonNormalFrmImage.lock(normalFid)) {
fontSetCurrent(savedFont);
windowDestroy(win);
return -1;
}
int v27 = hasTwoButtons ? _doneX[dialogType] : (backgroundWidth - doneBoxWidth) / 2;
blitBufferToBuffer(doneBox, doneBoxWidth, doneBoxHeight, doneBoxWidth, windowBuf + backgroundWidth * _doneY[dialogType] + v27, backgroundWidth);
int v27 = hasTwoButtons
? _doneX[dialogType]
: (backgroundFrmImage.getWidth() - doneBoxFrmImage.getWidth()) / 2;
blitBufferToBuffer(doneBoxFrmImage.getData(),
doneBoxFrmImage.getWidth(),
doneBoxFrmImage.getHeight(),
doneBoxFrmImage.getWidth(),
windowBuf + backgroundFrmImage.getWidth() * _doneY[dialogType] + v27,
backgroundFrmImage.getWidth());
if (!messageListInit(&messageList)) {
artUnlock(upButtonHandle);
artUnlock(downButtonHandle);
artUnlock(doneBoxHandle);
artUnlock(backgroundHandle);
fontSetCurrent(savedFont);
windowDestroy(win);
return -1;
@@ -277,10 +265,6 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
sprintf(path, "%s%s", asc_5186C8, "DBOX.MSG");
if (!messageListLoad(&messageList, path)) {
artUnlock(upButtonHandle);
artUnlock(downButtonHandle);
artUnlock(doneBoxHandle);
artUnlock(backgroundHandle);
fontSetCurrent(savedFont);
// FIXME: Window is not removed.
return -1;
@@ -292,10 +276,26 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
// 101 - YES
messageListItem.num = (flags & DIALOG_BOX_YES_NO) == 0 ? 100 : 101;
if (messageListGetItem(&messageList, &messageListItem)) {
fontDrawText(windowBuf + backgroundWidth * (_doneY[dialogType] + 3) + v27 + 35, messageListItem.text, backgroundWidth, backgroundWidth, _colorTable[18979]);
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * (_doneY[dialogType] + 3) + v27 + 35,
messageListItem.text,
backgroundFrmImage.getWidth(),
backgroundFrmImage.getWidth(),
_colorTable[18979]);
}
int btn = buttonCreate(win, v27 + 13, _doneY[dialogType] + 4, downButtonWidth, downButtonHeight, -1, -1, -1, 500, upButton, downButton, NULL, BUTTON_FLAG_TRANSPARENT);
int btn = buttonCreate(win,
v27 + 13,
_doneY[dialogType] + 4,
buttonPressedFrmImage.getWidth(),
buttonPressedFrmImage.getHeight(),
-1,
-1,
-1,
500,
buttonNormalFrmImage.getData(),
buttonPressedFrmImage.getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (btn != -1) {
buttonSetCallbacks(btn, _gsound_red_butt_press, _gsound_red_butt_release);
}
@@ -311,61 +311,58 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
fontSetCurrent(103);
blitBufferToBufferTrans(doneBox,
doneBoxWidth,
doneBoxHeight,
doneBoxWidth,
windowBuf + backgroundWidth * _doneY[dialogType] + _doneX[dialogType] + doneBoxWidth + 24,
backgroundWidth);
blitBufferToBufferTrans(doneBoxFrmImage.getData(),
doneBoxFrmImage.getWidth(),
doneBoxFrmImage.getHeight(),
doneBoxFrmImage.getWidth(),
windowBuf + backgroundFrmImage.getWidth() * _doneY[dialogType] + _doneX[dialogType] + doneBoxFrmImage.getWidth() + 24,
backgroundFrmImage.getWidth());
fontDrawText(windowBuf + backgroundWidth * (_doneY[dialogType] + 3) + _doneX[dialogType] + doneBoxWidth + 59,
a8, backgroundWidth, backgroundWidth, _colorTable[18979]);
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * (_doneY[dialogType] + 3) + _doneX[dialogType] + doneBoxFrmImage.getWidth() + 59,
a8,
backgroundFrmImage.getWidth(),
backgroundFrmImage.getWidth(),
_colorTable[18979]);
int btn = buttonCreate(win,
doneBoxWidth + _doneX[dialogType] + 37,
doneBoxFrmImage.getWidth() + _doneX[dialogType] + 37,
_doneY[dialogType] + 4,
downButtonWidth,
downButtonHeight,
-1, -1, -1, 501, upButton, downButton, 0, BUTTON_FLAG_TRANSPARENT);
buttonPressedFrmImage.getWidth(),
buttonPressedFrmImage.getHeight(),
-1,
-1,
-1,
501,
buttonNormalFrmImage.getData(),
buttonPressedFrmImage.getData(),
0,
BUTTON_FLAG_TRANSPARENT);
if (btn != -1) {
buttonSetCallbacks(btn, _gsound_red_butt_press, _gsound_red_butt_release);
}
} else {
int doneBoxFid = buildFid(OBJ_TYPE_INTERFACE, 209, 0, 0, 0);
unsigned char* doneBox = artLockFrameDataReturningSize(doneBoxFid, &doneBoxHandle, &doneBoxWidth, &doneBoxHeight);
if (doneBox == NULL) {
artUnlock(backgroundHandle);
if (!doneBoxFrmImage.lock(doneBoxFid)) {
fontSetCurrent(savedFont);
windowDestroy(win);
return -1;
}
int downButtonFid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
unsigned char* downButton = artLockFrameDataReturningSize(downButtonFid, &downButtonHandle, &downButtonWidth, &downButtonHeight);
if (downButton == NULL) {
artUnlock(doneBoxHandle);
artUnlock(backgroundHandle);
int pressedFid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
if (!buttonPressedFrmImage.lock(pressedFid)) {
fontSetCurrent(savedFont);
windowDestroy(win);
return -1;
}
int upButtonFid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
unsigned char* upButton = artLockFrameData(upButtonFid, 0, 0, &upButtonHandle);
if (upButton == NULL) {
artUnlock(downButtonHandle);
artUnlock(doneBoxHandle);
artUnlock(backgroundHandle);
int normalFid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
if (!buttonNormalFrmImage.lock(normalFid)) {
fontSetCurrent(savedFont);
windowDestroy(win);
return -1;
}
if (!messageListInit(&messageList)) {
artUnlock(upButtonHandle);
artUnlock(downButtonHandle);
artUnlock(doneBoxHandle);
artUnlock(backgroundHandle);
fontSetCurrent(savedFont);
windowDestroy(win);
return -1;
@@ -375,38 +372,34 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
sprintf(path, "%s%s", asc_5186C8, "DBOX.MSG");
if (!messageListLoad(&messageList, path)) {
artUnlock(upButtonHandle);
artUnlock(downButtonHandle);
artUnlock(doneBoxHandle);
artUnlock(backgroundHandle);
fontSetCurrent(savedFont);
windowDestroy(win);
return -1;
}
blitBufferToBufferTrans(doneBox,
doneBoxWidth,
doneBoxHeight,
doneBoxWidth,
windowBuf + backgroundWidth * _doneY[dialogType] + _doneX[dialogType],
backgroundWidth);
blitBufferToBufferTrans(doneBoxFrmImage.getData(),
doneBoxFrmImage.getWidth(),
doneBoxFrmImage.getHeight(),
doneBoxFrmImage.getWidth(),
windowBuf + backgroundFrmImage.getWidth() * _doneY[dialogType] + _doneX[dialogType],
backgroundFrmImage.getWidth());
fontSetCurrent(103);
fontDrawText(windowBuf + backgroundWidth * (_doneY[dialogType] + 3) + _doneX[dialogType] + 35,
a8, backgroundWidth, backgroundWidth, _colorTable[18979]);
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * (_doneY[dialogType] + 3) + _doneX[dialogType] + 35,
a8, backgroundFrmImage.getWidth(), backgroundFrmImage.getWidth(), _colorTable[18979]);
int btn = buttonCreate(win,
_doneX[dialogType] + 13,
_doneY[dialogType] + 4,
downButtonWidth,
downButtonHeight,
buttonPressedFrmImage.getWidth(),
buttonPressedFrmImage.getHeight(),
-1,
-1,
-1,
501,
upButton,
downButton,
buttonNormalFrmImage.getData(),
buttonPressedFrmImage.getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (btn != -1) {
@@ -428,28 +421,44 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
if (hasTitle) {
if ((flags & DIALOG_BOX_NO_HORIZONTAL_CENTERING) != 0) {
fontDrawText(windowBuf + backgroundWidth * v23 + _xtable[dialogType], title, backgroundWidth, backgroundWidth, titleColor);
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + _xtable[dialogType],
title,
backgroundFrmImage.getWidth(),
backgroundFrmImage.getWidth(),
titleColor);
} else {
int length = fontGetStringWidth(title);
fontDrawText(windowBuf + backgroundWidth * v23 + (backgroundWidth - length) / 2, title, backgroundWidth, backgroundWidth, titleColor);
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + (backgroundFrmImage.getWidth() - length) / 2,
title,
backgroundFrmImage.getWidth(),
backgroundFrmImage.getWidth(),
titleColor);
}
v23 += fontGetLineHeight();
}
for (int v94 = 0; v94 < bodyLength; v94++) {
int len = fontGetStringWidth(body[v94]);
if (len <= backgroundWidth - 26) {
if (len <= backgroundFrmImage.getWidth() - 26) {
if ((flags & DIALOG_BOX_NO_HORIZONTAL_CENTERING) != 0) {
fontDrawText(windowBuf + backgroundWidth * v23 + _xtable[dialogType], body[v94], backgroundWidth, backgroundWidth, bodyColor);
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + _xtable[dialogType],
body[v94],
backgroundFrmImage.getWidth(),
backgroundFrmImage.getWidth(),
bodyColor);
} else {
int length = fontGetStringWidth(body[v94]);
fontDrawText(windowBuf + backgroundWidth * v23 + (backgroundWidth - length) / 2, body[v94], backgroundWidth, backgroundWidth, bodyColor);
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + (backgroundFrmImage.getWidth() - length) / 2,
body[v94],
backgroundFrmImage.getWidth(),
backgroundFrmImage.getWidth(),
bodyColor);
}
v23 += fontGetLineHeight();
} else {
short beginnings[WORD_WRAP_MAX_COUNT];
short count;
if (wordWrap(body[v94], backgroundWidth - 26, beginnings, &count) != 0) {
if (wordWrap(body[v94], backgroundFrmImage.getWidth() - 26, beginnings, &count) != 0) {
debugPrint("\nError: dialog_out");
}
@@ -464,10 +473,18 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
string[v51] = '\0';
if ((flags & DIALOG_BOX_NO_HORIZONTAL_CENTERING) != 0) {
fontDrawText(windowBuf + backgroundWidth * v23 + _xtable[dialogType], string, backgroundWidth, backgroundWidth, bodyColor);
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + _xtable[dialogType],
string,
backgroundFrmImage.getWidth(),
backgroundFrmImage.getWidth(),
bodyColor);
} else {
int length = fontGetStringWidth(string);
fontDrawText(windowBuf + backgroundWidth * v23 + (backgroundWidth - length) / 2, string, backgroundWidth, backgroundWidth, bodyColor);
fontDrawText(windowBuf + backgroundFrmImage.getWidth() * v23 + (backgroundFrmImage.getWidth() - length) / 2,
string,
backgroundFrmImage.getWidth(),
backgroundFrmImage.getWidth(),
bodyColor);
}
v23 += fontGetLineHeight();
}
@@ -503,13 +520,9 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
}
windowDestroy(win);
artUnlock(backgroundHandle);
fontSetCurrent(savedFont);
if (v86) {
artUnlock(doneBoxHandle);
artUnlock(downButtonHandle);
artUnlock(upButtonHandle);
messageListFree(&messageList);
}
@@ -536,48 +549,34 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
}
}
unsigned char* frmBuffers[FILE_DIALOG_FRM_COUNT];
CacheEntry* frmHandles[FILE_DIALOG_FRM_COUNT];
Size frmSizes[FILE_DIALOG_FRM_COUNT];
FrmImage frmImages[FILE_DIALOG_FRM_COUNT];
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
int fid = buildFid(OBJ_TYPE_INTERFACE, gLoadFileDialogFrmIds[index], 0, 0, 0);
frmBuffers[index] = artLockFrameDataReturningSize(fid, &(frmHandles[index]), &(frmSizes[index].width), &(frmSizes[index].height));
if (frmBuffers[index] == NULL) {
while (--index >= 0) {
artUnlock(frmHandles[index]);
}
if (!frmImages[index].lock(fid)) {
return -1;
}
}
int backgroundWidth = frmSizes[FILE_DIALOG_FRM_BACKGROUND].width;
int backgroundHeight = frmSizes[FILE_DIALOG_FRM_BACKGROUND].height;
int backgroundWidth = frmImages[FILE_DIALOG_FRM_BACKGROUND].getWidth();
int backgroundHeight = frmImages[FILE_DIALOG_FRM_BACKGROUND].getHeight();
// Maintain original position in original resolution, otherwise center it.
if (screenGetWidth() != 640) x = (screenGetWidth() - backgroundWidth) / 2;
if (screenGetHeight() != 480) y = (screenGetHeight() - backgroundHeight) / 2;
int win = windowCreate(x, y, backgroundWidth, backgroundHeight, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
if (win == -1) {
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
artUnlock(frmHandles[index]);
}
return -1;
}
unsigned char* windowBuffer = windowGetBuffer(win);
memcpy(windowBuffer, frmBuffers[FILE_DIALOG_FRM_BACKGROUND], backgroundWidth * backgroundHeight);
memcpy(windowBuffer, frmImages[FILE_DIALOG_FRM_BACKGROUND].getData(), backgroundWidth * backgroundHeight);
MessageList messageList;
MessageListItem messageListItem;
if (!messageListInit(&messageList)) {
windowDestroy(win);
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
artUnlock(frmHandles[index]);
}
return -1;
}
@@ -586,11 +585,6 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
if (!messageListLoad(&messageList, path)) {
windowDestroy(win);
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
artUnlock(frmHandles[index]);
}
return -1;
}
@@ -607,14 +601,14 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
int doneBtn = buttonCreate(win,
LOAD_FILE_DIALOG_DONE_BUTTON_X,
LOAD_FILE_DIALOG_DONE_BUTTON_Y,
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].width,
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].height,
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getWidth(),
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getHeight(),
-1,
-1,
-1,
500,
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL],
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED],
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (doneBtn != -1) {
@@ -624,14 +618,14 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
int cancelBtn = buttonCreate(win,
LOAD_FILE_DIALOG_CANCEL_BUTTON_X,
LOAD_FILE_DIALOG_CANCEL_BUTTON_Y,
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].width,
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].height,
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getWidth(),
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getHeight(),
-1,
-1,
-1,
501,
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL],
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED],
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (cancelBtn != -1) {
@@ -641,14 +635,14 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
int scrollUpBtn = buttonCreate(win,
FILE_DIALOG_SCROLL_BUTTON_X,
FILE_DIALOG_SCROLL_BUTTON_Y,
frmSizes[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].width,
frmSizes[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].height,
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getWidth(),
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getHeight(),
-1,
505,
506,
505,
frmBuffers[FILE_DIALOG_FRM_SCROLL_UP_ARROW_NORMAL],
frmBuffers[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED],
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (scrollUpBtn != -1) {
@@ -657,15 +651,15 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
int scrollDownButton = buttonCreate(win,
FILE_DIALOG_SCROLL_BUTTON_X,
FILE_DIALOG_SCROLL_BUTTON_Y + frmSizes[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].height,
frmSizes[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].width,
frmSizes[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].height,
FILE_DIALOG_SCROLL_BUTTON_Y + frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getHeight(),
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].getWidth(),
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].getHeight(),
-1,
503,
504,
503,
frmBuffers[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_NORMAL],
frmBuffers[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED],
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (scrollUpBtn != -1) {
@@ -888,10 +882,6 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
windowDestroy(win);
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
artUnlock(frmHandles[index]);
}
messageListFree(&messageList);
fontSetCurrent(oldFont);
@@ -918,48 +908,34 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
}
}
unsigned char* frmBuffers[FILE_DIALOG_FRM_COUNT];
CacheEntry* frmHandles[FILE_DIALOG_FRM_COUNT];
Size frmSizes[FILE_DIALOG_FRM_COUNT];
FrmImage frmImages[FILE_DIALOG_FRM_COUNT];
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
int fid = buildFid(OBJ_TYPE_INTERFACE, gSaveFileDialogFrmIds[index], 0, 0, 0);
frmBuffers[index] = artLockFrameDataReturningSize(fid, &(frmHandles[index]), &(frmSizes[index].width), &(frmSizes[index].height));
if (frmBuffers[index] == NULL) {
while (--index >= 0) {
artUnlock(frmHandles[index]);
}
if (!frmImages[index].lock(fid)) {
return -1;
}
}
int backgroundWidth = frmSizes[FILE_DIALOG_FRM_BACKGROUND].width;
int backgroundHeight = frmSizes[FILE_DIALOG_FRM_BACKGROUND].height;
int backgroundWidth = frmImages[FILE_DIALOG_FRM_BACKGROUND].getWidth();
int backgroundHeight = frmImages[FILE_DIALOG_FRM_BACKGROUND].getHeight();
// Maintain original position in original resolution, otherwise center it.
if (screenGetWidth() != 640) x = (screenGetWidth() - backgroundWidth) / 2;
if (screenGetHeight() != 480) y = (screenGetHeight() - backgroundHeight) / 2;
int win = windowCreate(x, y, backgroundWidth, backgroundHeight, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
if (win == -1) {
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
artUnlock(frmHandles[index]);
}
return -1;
}
unsigned char* windowBuffer = windowGetBuffer(win);
memcpy(windowBuffer, frmBuffers[FILE_DIALOG_FRM_BACKGROUND], backgroundWidth * backgroundHeight);
memcpy(windowBuffer, frmImages[FILE_DIALOG_FRM_BACKGROUND].getData(), backgroundWidth * backgroundHeight);
MessageList messageList;
MessageListItem messageListItem;
if (!messageListInit(&messageList)) {
windowDestroy(win);
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
artUnlock(frmHandles[index]);
}
return -1;
}
@@ -968,11 +944,6 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
if (!messageListLoad(&messageList, path)) {
windowDestroy(win);
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
artUnlock(frmHandles[index]);
}
return -1;
}
@@ -989,14 +960,14 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
int doneBtn = buttonCreate(win,
SAVE_FILE_DIALOG_DONE_BUTTON_X,
SAVE_FILE_DIALOG_DONE_BUTTON_Y,
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].width,
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].height,
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getWidth(),
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getHeight(),
-1,
-1,
-1,
500,
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL],
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED],
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (doneBtn != -1) {
@@ -1006,14 +977,14 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
int cancelBtn = buttonCreate(win,
SAVE_FILE_DIALOG_CANCEL_BUTTON_X,
SAVE_FILE_DIALOG_CANCEL_BUTTON_Y,
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].width,
frmSizes[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].height,
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getWidth(),
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getHeight(),
-1,
-1,
-1,
501,
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL],
frmBuffers[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED],
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_LITTLE_RED_BUTTON_PRESSED].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (cancelBtn != -1) {
@@ -1023,14 +994,14 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
int scrollUpBtn = buttonCreate(win,
FILE_DIALOG_SCROLL_BUTTON_X,
FILE_DIALOG_SCROLL_BUTTON_Y,
frmSizes[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].width,
frmSizes[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].height,
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getWidth(),
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getHeight(),
-1,
505,
506,
505,
frmBuffers[FILE_DIALOG_FRM_SCROLL_UP_ARROW_NORMAL],
frmBuffers[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED],
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (scrollUpBtn != -1) {
@@ -1039,15 +1010,15 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
int scrollDownButton = buttonCreate(win,
FILE_DIALOG_SCROLL_BUTTON_X,
FILE_DIALOG_SCROLL_BUTTON_Y + frmSizes[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].height,
frmSizes[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].width,
frmSizes[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].height,
FILE_DIALOG_SCROLL_BUTTON_Y + frmImages[FILE_DIALOG_FRM_SCROLL_UP_ARROW_PRESSED].getHeight(),
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].getWidth(),
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].getHeight(),
-1,
503,
504,
503,
frmBuffers[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_NORMAL],
frmBuffers[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED],
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_NORMAL].getData(),
frmImages[FILE_DIALOG_FRM_SCROLL_DOWN_ARROW_PRESSED].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (scrollUpBtn != -1) {
@@ -1092,7 +1063,7 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
char fileNameCopy[32];
strncpy(fileNameCopy, dest, 32);
int fileNameCopyLength = strlen(fileNameCopy);
size_t fileNameCopyLength = strlen(fileNameCopy);
fileNameCopy[fileNameCopyLength + 1] = '\0';
fileNameCopy[fileNameCopyLength] = ' ';
@@ -1374,11 +1345,6 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
}
windowDestroy(win);
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
artUnlock(frmHandles[index]);
}
messageListFree(&messageList);
fontSetCurrent(oldFont);
@@ -1403,3 +1369,5 @@ static void fileDialogRenderFileList(unsigned char* buffer, char** fileList, int
}
}
}
} // namespace fallout

View File

@@ -1,6 +1,8 @@
#ifndef DBOX_H
#define DBOX_H
namespace fallout {
typedef enum DialogBoxOptions {
DIALOG_BOX_LARGE = 0x01,
DIALOG_BOX_MEDIUM = 0x02,
@@ -14,4 +16,6 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLength, int x, int y, int flags);
int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLength, int x, int y, int flags);
} // namespace fallout
#endif /* DBOX_H */

View File

@@ -14,6 +14,8 @@
#include "platform_compat.h"
#include "window_manager_private.h"
namespace fallout {
static int _debug_puts(char* string);
static void _debug_clear();
static int _debug_mono(char* string);
@@ -317,3 +319,5 @@ void _debug_exit(void)
fclose(_fd);
}
}
} // namespace fallout

View File

@@ -1,6 +1,8 @@
#ifndef DEBUG_H
#define DEBUG_H
namespace fallout {
typedef int(DebugPrintProc)(char* string);
void _GNW_debug_init();
@@ -12,4 +14,6 @@ void _debug_register_func(DebugPrintProc* proc);
int debugPrint(const char* format, ...);
void _debug_exit(void);
} // namespace fallout
#endif /* DEBUG_H */

View File

@@ -9,6 +9,8 @@
#include "platform_compat.h"
namespace fallout {
// The size of decompression buffer for reading compressed [DFile]s.
#define DFILE_DECOMPRESSION_BUFFER_SIZE (0x400)
@@ -852,3 +854,5 @@ static void dfileUngetCompressed(DFile* stream, int ch)
stream->flags |= DFILE_HAS_COMPRESSED_UNGETC;
stream->position--;
}
} // namespace fallout

View File

@@ -7,6 +7,8 @@
#include "platform_compat.h"
namespace fallout {
typedef struct DBase DBase;
typedef struct DBaseEntry DBaseEntry;
typedef struct DFile DFile;
@@ -128,4 +130,6 @@ long dfileTell(DFile* stream);
void dfileRewind(DFile* stream);
int dfileEof(DFile* stream);
} // namespace fallout
#endif /* DFILE_H */

View File

@@ -9,6 +9,8 @@
#include "text_font.h"
#include "window_manager.h"
namespace fallout {
// 0x501623
const float flt_501623 = 31.0;
@@ -750,3 +752,5 @@ int _dialogGetMediaFlag()
{
return _mediaFlag;
}
} // namespace fallout

View File

@@ -3,6 +3,8 @@
#include "interpreter.h"
namespace fallout {
typedef void DialogFunc1(int win);
typedef void DialogFunc2(int win);
@@ -131,4 +133,6 @@ void _dialogRegisterWinDrawCallbacks(DialogFunc1* a1, DialogFunc2* a2);
int _dialogToggleMediaFlag(int a1);
int _dialogGetMediaFlag();
} // namespace fallout
#endif /* DIALOG_H */

View File

@@ -6,6 +6,8 @@
#include "platform_compat.h"
namespace fallout {
// NOTE: I guess this marker is used as a type discriminator for implementing
// nested dictionaries. That's why every dictionary-related function starts
// with a check for this value.
@@ -552,3 +554,5 @@ void dictionarySetMemoryProcs(MallocProc* mallocProc, ReallocProc* reallocProc,
gDictionaryFreeProc = dictionaryFreeDefaultImpl;
}
}
} // namespace fallout

View File

@@ -5,6 +5,8 @@
#include "memory_defs.h"
namespace fallout {
typedef int(DictionaryReadProc)(FILE* stream, void* buffer, unsigned int size, int a4);
typedef int(DictionaryWriteProc)(FILE* stream, void* buffer, unsigned int size, int a4);
@@ -63,4 +65,6 @@ int dictionaryWriteHeader(FILE* stream, Dictionary* dictionary);
int dictionaryWrite(FILE* stream, Dictionary* dictionary, int a3);
void dictionarySetMemoryProcs(MallocProc* mallocProc, ReallocProc* reallocProc, FreeProc* freeProc);
} // namespace fallout
#endif /* DICTIONARY_H */

View File

@@ -1,5 +1,7 @@
#include "dinput.h"
namespace fallout {
enum InputType {
INPUT_TYPE_MOUSE,
INPUT_TYPE_TOUCH,
@@ -237,3 +239,5 @@ void handleTouchEvent(SDL_Event* event)
gLastInputType = INPUT_TYPE_TOUCH;
}
}
} // namespace fallout

View File

@@ -3,6 +3,8 @@
#include <SDL.h>
namespace fallout {
typedef struct MouseData {
int x;
int y;
@@ -33,4 +35,6 @@ void keyboardDeviceFree();
void handleMouseEvent(SDL_Event* event);
void handleTouchEvent(SDL_Event* event);
} // namespace fallout
#endif /* DINPUT_H */

View File

@@ -18,6 +18,8 @@
#include "text_font.h"
#include "window_manager.h"
namespace fallout {
// The maximum number of lines display monitor can hold. Once this value
// is reached earlier messages are thrown away.
#define DISPLAY_MONITOR_LINES_CAPACITY (100)
@@ -468,3 +470,5 @@ static void consoleFileFlush()
gConsoleFileStream.flush();
}
}
} // namespace fallout

View File

@@ -1,6 +1,8 @@
#ifndef DISPLAY_MONITOR_H
#define DISPLAY_MONITOR_H
namespace fallout {
int displayMonitorInit();
int displayMonitorReset();
void displayMonitorExit();
@@ -8,4 +10,6 @@ void displayMonitorAddMessage(char* string);
void displayMonitorDisable();
void displayMonitorEnable();
} // namespace fallout
#endif /* DISPLAY_MONITOR_H */

View File

@@ -6,6 +6,8 @@
#include "core.h"
#include "mmx.h"
namespace fallout {
// 0x4D2FC0
void bufferDrawLine(unsigned char* buf, int pitch, int x1, int y1, int x2, int y2, int color)
{
@@ -326,3 +328,5 @@ void bufferOutline(unsigned char* buf, int width, int height, int pitch, int col
}
}
}
} // namespace fallout

View File

@@ -1,6 +1,8 @@
#ifndef DRAW_H
#define DRAW_H
namespace fallout {
void bufferDrawLine(unsigned char* buf, int pitch, int left, int top, int right, int bottom, int color);
void bufferDrawRect(unsigned char* buf, int a2, int a3, int a4, int a5, int a6, int a7);
void bufferDrawRectShadowed(unsigned char* buf, int a2, int a3, int a4, int a5, int a6, int a7, int a8);
@@ -14,4 +16,6 @@ void _lighten_buf(unsigned char* buf, int width, int height, int pitch);
void _swap_color_buf(unsigned char* buf, int width, int height, int pitch, int color1, int color2);
void bufferOutline(unsigned char* buf, int width, int height, int pitch, int a5);
} // namespace fallout
#endif /* DRAW_H */

View File

@@ -8,6 +8,8 @@
#include "game_config.h"
#include "platform_compat.h"
namespace fallout {
// 0x440DD0
void runElectronicRegistration()
{
@@ -45,3 +47,5 @@ void runElectronicRegistration()
}
}
}
} // namespace fallout

View File

@@ -1,6 +1,10 @@
#ifndef ELECTRONIC_REGISTRATION_H
#define ELECTRONIC_REGISTRATION_H
namespace fallout {
void runElectronicRegistration();
} // namespace fallout
#endif /* ELECTRONIC_REGISTRATION_H */

View File

@@ -20,15 +20,11 @@
#include "sfall_config.h"
#include "window_manager.h"
namespace fallout {
// The maximum number of elevator levels.
#define ELEVATOR_LEVEL_MAX (4)
// NOTE: There are two variables which hold background data used in the
// elevator window - [gElevatorBackgroundFrmData] and [gElevatorPanelFrmData].
// For unknown reason they are using -1 to denote that they are not set
// (instead of using NULL).
#define ELEVATOR_BACKGROUND_NULL ((unsigned char*)(-1))
// Max number of elevators that can be loaded from elevators.ini. This limit is
// emposed by Sfall.
#define ELEVATORS_MAX 50
@@ -320,47 +316,18 @@ static const char* gElevatorSoundEffects[ELEVATOR_LEVEL_MAX - 1][ELEVATOR_LEVEL_
},
};
// 0x570A2C
static Size gElevatorFrmSizes[ELEVATOR_FRM_COUNT];
// 0x570A44
static int gElevatorBackgroundFrmWidth;
// 0x570A48
static int gElevatorBackgroundFrmHeight;
// 0x570A4C
static int gElevatorPanelFrmWidth;
// 0x570A50
static int gElevatorPanelFrmHeight;
// 0x570A54
static int gElevatorWindow;
// 0x570A58
static CacheEntry* gElevatorFrmHandles[ELEVATOR_FRM_COUNT];
// 0x570A64
static CacheEntry* gElevatorBackgroundFrmHandle;
// 0x570A68
static CacheEntry* gElevatorPanelFrmHandle;
// 0x570A6C
static unsigned char* gElevatorWindowBuffer;
// 0x570A70
static bool gElevatorWindowIsoWasEnabled;
// 0x570A74
static unsigned char* gElevatorFrmData[ELEVATOR_FRM_COUNT];
// 0x570A80
static unsigned char* gElevatorBackgroundFrmData;
// 0x570A84
static unsigned char* gElevatorPanelFrmData;
static FrmImage _elevatorFrmImages[ELEVATOR_FRM_COUNT];
static FrmImage _elevatorBackgroundFrmImage;
static FrmImage _elevatorPanelFrmImage;
// Presents elevator dialog for player to pick a desired level.
//
@@ -411,15 +378,15 @@ int elevatorSelectLevel(int elevator, int* mapPtr, int* elevationPtr, int* tileP
debugPrint("\n the start elev level %d\n", *elevationPtr);
int v18 = (gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].width * gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].height) / 13;
int v18 = (_elevatorFrmImages[ELEVATOR_FRM_GAUGE].getWidth() * _elevatorFrmImages[ELEVATOR_FRM_GAUGE].getHeight()) / 13;
float v42 = 12.0f / (float)(gElevatorLevels[elevator] - 1);
blitBufferToBuffer(
gElevatorFrmData[ELEVATOR_FRM_GAUGE] + v18 * (int)((float)(*elevationPtr) * v42),
gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].width,
gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].height / 13,
gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].width,
gElevatorWindowBuffer + gElevatorBackgroundFrmWidth * 41 + 121,
gElevatorBackgroundFrmWidth);
_elevatorFrmImages[ELEVATOR_FRM_GAUGE].getData() + v18 * (int)((float)(*elevationPtr) * v42),
_elevatorFrmImages[ELEVATOR_FRM_GAUGE].getWidth(),
_elevatorFrmImages[ELEVATOR_FRM_GAUGE].getHeight() / 13,
_elevatorFrmImages[ELEVATOR_FRM_GAUGE].getWidth(),
gElevatorWindowBuffer + _elevatorBackgroundFrmImage.getWidth() * 41 + 121,
_elevatorBackgroundFrmImage.getWidth());
windowRefresh(gElevatorWindow);
bool done = false;
@@ -468,12 +435,12 @@ int elevatorSelectLevel(int elevator, int* mapPtr, int* elevationPtr, int* tileP
unsigned int tick = _get_time();
v44 += v43;
blitBufferToBuffer(
gElevatorFrmData[ELEVATOR_FRM_GAUGE] + v18 * (int)v44,
gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].width,
gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].height / 13,
gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].width,
gElevatorWindowBuffer + gElevatorBackgroundFrmWidth * 41 + 121,
gElevatorBackgroundFrmWidth);
_elevatorFrmImages[ELEVATOR_FRM_GAUGE].getData() + v18 * (int)v44,
_elevatorFrmImages[ELEVATOR_FRM_GAUGE].getWidth(),
_elevatorFrmImages[ELEVATOR_FRM_GAUGE].getHeight() / 13,
_elevatorFrmImages[ELEVATOR_FRM_GAUGE].getWidth(),
gElevatorWindowBuffer + _elevatorBackgroundFrmImage.getWidth() * 41 + 121,
_elevatorBackgroundFrmImage.getWidth());
windowRefresh(gElevatorWindow);
@@ -512,15 +479,14 @@ static int elevatorWindowInit(int elevator)
int index;
for (index = 0; index < ELEVATOR_FRM_COUNT; index++) {
int fid = buildFid(OBJ_TYPE_INTERFACE, gElevatorFrmIds[index], 0, 0, 0);
gElevatorFrmData[index] = artLockFrameDataReturningSize(fid, &(gElevatorFrmHandles[index]), &(gElevatorFrmSizes[index].width), &(gElevatorFrmSizes[index].height));
if (gElevatorFrmData[index] == NULL) {
if (!_elevatorFrmImages[index].lock(fid)) {
break;
}
}
if (index != ELEVATOR_FRM_COUNT) {
for (int reversedIndex = index - 1; reversedIndex >= 0; reversedIndex--) {
artUnlock(gElevatorFrmHandles[reversedIndex]);
_elevatorFrmImages[reversedIndex].unlock();
}
if (gElevatorWindowIsoWasEnabled) {
@@ -532,39 +498,27 @@ static int elevatorWindowInit(int elevator)
return -1;
}
gElevatorPanelFrmData = ELEVATOR_BACKGROUND_NULL;
gElevatorBackgroundFrmData = ELEVATOR_BACKGROUND_NULL;
const ElevatorBackground* elevatorBackground = &(gElevatorBackgrounds[elevator]);
bool backgroundsLoaded = true;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, elevatorBackground->backgroundFrmId, 0, 0, 0);
gElevatorBackgroundFrmData = artLockFrameDataReturningSize(backgroundFid, &gElevatorBackgroundFrmHandle, &gElevatorBackgroundFrmWidth, &gElevatorBackgroundFrmHeight);
if (gElevatorBackgroundFrmData != NULL) {
if (_elevatorBackgroundFrmImage.lock(backgroundFid)) {
if (elevatorBackground->panelFrmId != -1) {
int panelFid = buildFid(OBJ_TYPE_INTERFACE, elevatorBackground->panelFrmId, 0, 0, 0);
gElevatorPanelFrmData = artLockFrameDataReturningSize(panelFid, &gElevatorPanelFrmHandle, &gElevatorPanelFrmWidth, &gElevatorPanelFrmHeight);
if (gElevatorPanelFrmData == NULL) {
gElevatorPanelFrmData = ELEVATOR_BACKGROUND_NULL;
if (!_elevatorPanelFrmImage.lock(panelFid)) {
backgroundsLoaded = false;
}
}
} else {
gElevatorBackgroundFrmData = ELEVATOR_BACKGROUND_NULL;
backgroundsLoaded = false;
}
if (!backgroundsLoaded) {
if (gElevatorBackgroundFrmData != ELEVATOR_BACKGROUND_NULL) {
artUnlock(gElevatorBackgroundFrmHandle);
}
if (gElevatorPanelFrmData != ELEVATOR_BACKGROUND_NULL) {
artUnlock(gElevatorPanelFrmHandle);
}
_elevatorBackgroundFrmImage.unlock();
_elevatorPanelFrmImage.unlock();
for (int index = 0; index < ELEVATOR_FRM_COUNT; index++) {
artUnlock(gElevatorFrmHandles[index]);
_elevatorFrmImages[index].unlock();
}
if (gElevatorWindowIsoWasEnabled) {
@@ -576,26 +530,21 @@ static int elevatorWindowInit(int elevator)
return -1;
}
int elevatorWindowX = (screenGetWidth() - gElevatorBackgroundFrmWidth) / 2;
int elevatorWindowY = (screenGetHeight() - INTERFACE_BAR_HEIGHT - 1 - gElevatorBackgroundFrmHeight) / 2;
int elevatorWindowX = (screenGetWidth() - _elevatorBackgroundFrmImage.getWidth()) / 2;
int elevatorWindowY = (screenGetHeight() - INTERFACE_BAR_HEIGHT - 1 - _elevatorBackgroundFrmImage.getHeight()) / 2;
gElevatorWindow = windowCreate(
elevatorWindowX,
elevatorWindowY,
gElevatorBackgroundFrmWidth,
gElevatorBackgroundFrmHeight,
_elevatorBackgroundFrmImage.getWidth(),
_elevatorBackgroundFrmImage.getHeight(),
256,
WINDOW_FLAG_0x10 | WINDOW_FLAG_0x02);
if (gElevatorWindow == -1) {
if (gElevatorBackgroundFrmData != ELEVATOR_BACKGROUND_NULL) {
artUnlock(gElevatorBackgroundFrmHandle);
}
if (gElevatorPanelFrmData != ELEVATOR_BACKGROUND_NULL) {
artUnlock(gElevatorPanelFrmHandle);
}
_elevatorBackgroundFrmImage.unlock();
_elevatorPanelFrmImage.unlock();
for (int index = 0; index < ELEVATOR_FRM_COUNT; index++) {
artUnlock(gElevatorFrmHandles[index]);
_elevatorFrmImages[index].unlock();
}
if (gElevatorWindowIsoWasEnabled) {
@@ -608,15 +557,15 @@ static int elevatorWindowInit(int elevator)
}
gElevatorWindowBuffer = windowGetBuffer(gElevatorWindow);
memcpy(gElevatorWindowBuffer, (unsigned char*)gElevatorBackgroundFrmData, gElevatorBackgroundFrmWidth * gElevatorBackgroundFrmHeight);
memcpy(gElevatorWindowBuffer, _elevatorBackgroundFrmImage.getData(), _elevatorBackgroundFrmImage.getWidth() * _elevatorBackgroundFrmImage.getHeight());
if (gElevatorPanelFrmData != ELEVATOR_BACKGROUND_NULL) {
blitBufferToBuffer((unsigned char*)gElevatorPanelFrmData,
gElevatorPanelFrmWidth,
gElevatorPanelFrmHeight,
gElevatorPanelFrmWidth,
gElevatorWindowBuffer + gElevatorBackgroundFrmWidth * (gElevatorBackgroundFrmHeight - gElevatorPanelFrmHeight),
gElevatorBackgroundFrmWidth);
if (_elevatorPanelFrmImage.isLocked()) {
blitBufferToBuffer(_elevatorPanelFrmImage.getData(),
_elevatorPanelFrmImage.getWidth(),
_elevatorPanelFrmImage.getHeight(),
_elevatorPanelFrmImage.getWidth(),
gElevatorWindowBuffer + _elevatorBackgroundFrmImage.getWidth() * (_elevatorBackgroundFrmImage.getHeight() - _elevatorPanelFrmImage.getHeight()),
_elevatorBackgroundFrmImage.getWidth());
}
int y = 40;
@@ -624,14 +573,14 @@ static int elevatorWindowInit(int elevator)
int btn = buttonCreate(gElevatorWindow,
13,
y,
gElevatorFrmSizes[ELEVATOR_FRM_BUTTON_DOWN].width,
gElevatorFrmSizes[ELEVATOR_FRM_BUTTON_DOWN].height,
_elevatorFrmImages[ELEVATOR_FRM_BUTTON_DOWN].getWidth(),
_elevatorFrmImages[ELEVATOR_FRM_BUTTON_DOWN].getHeight(),
-1,
-1,
-1,
500 + level,
gElevatorFrmData[ELEVATOR_FRM_BUTTON_UP],
gElevatorFrmData[ELEVATOR_FRM_BUTTON_DOWN],
_elevatorFrmImages[ELEVATOR_FRM_BUTTON_UP].getData(),
_elevatorFrmImages[ELEVATOR_FRM_BUTTON_DOWN].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (btn != -1) {
@@ -648,16 +597,11 @@ static void elevatorWindowFree()
{
windowDestroy(gElevatorWindow);
if (gElevatorBackgroundFrmData != ELEVATOR_BACKGROUND_NULL) {
artUnlock(gElevatorBackgroundFrmHandle);
}
if (gElevatorPanelFrmData != ELEVATOR_BACKGROUND_NULL) {
artUnlock(gElevatorPanelFrmHandle);
}
_elevatorBackgroundFrmImage.unlock();
_elevatorPanelFrmImage.unlock();
for (int index = 0; index < ELEVATOR_FRM_COUNT; index++) {
artUnlock(gElevatorFrmHandles[index]);
_elevatorFrmImages[index].unlock();
}
scriptsEnable();
@@ -751,3 +695,5 @@ void elevatorsInit()
}
}
}
} // namespace fallout

View File

@@ -1,6 +1,8 @@
#ifndef ELEVATOR_H
#define ELEVATOR_H
namespace fallout {
typedef enum Elevator {
ELEVATOR_BROTHERHOOD_OF_STEEL_MAIN,
ELEVATOR_BROTHERHOOD_OF_STEEL_SURFACE,
@@ -22,4 +24,6 @@ int elevatorSelectLevel(int elevator, int* mapPtr, int* elevationPtr, int* tileP
void elevatorsInit();
} // namespace fallout
#endif /* ELEVATOR_H */

View File

@@ -33,6 +33,8 @@
#include "word_wrap.h"
#include "worldmap.h"
namespace fallout {
// The maximum number of subtitle lines per slide.
#define ENDGAME_ENDING_MAX_SUBTITLES (50)
@@ -1197,3 +1199,5 @@ char* endgameDeathEndingGetFileName()
return gEndgameDeathEndingFileName;
}
} // namespace fallout

View File

@@ -1,6 +1,8 @@
#ifndef ENDGAME_H
#define ENDGAME_H
namespace fallout {
typedef enum EndgameDeathEndingReason {
// Dude died.
ENDGAME_DEATH_ENDING_REASON_DEATH = 0,
@@ -18,4 +20,6 @@ int endgameDeathEndingExit();
void endgameSetupDeathEnding(int reason);
char* endgameDeathEndingGetFileName();
} // namespace fallout
#endif /* ENDGAME_H */

View File

@@ -7,6 +7,8 @@
#include "memory_manager.h"
#include "platform_compat.h"
namespace fallout {
typedef struct ExternalVariable {
char name[32];
char* programName;
@@ -343,3 +345,5 @@ void _exportClearAllVariables()
}
}
}
} // namespace fallout

View File

@@ -3,6 +3,8 @@
#include "interpreter.h"
namespace fallout {
int externalVariableSetValue(Program* program, const char* identifier, ProgramValue& value);
int externalVariableGetValue(Program* program, const char* name, ProgramValue& value);
int externalVariableCreate(Program* program, const char* identifier);
@@ -12,4 +14,6 @@ Program* externalProcedureGetProgram(const char* identifier, int* addressPtr, in
int externalProcedureCreate(Program* program, const char* identifier, int address, int argumentCount);
void _exportClearAllVariables();
} // namespace fallout
#endif /* EXPORT_H */

View File

@@ -5,6 +5,8 @@
#include <fpattern.h>
namespace fallout {
// 0x4E6380
bool fileFindFirst(const char* path, DirectoryFileFindData* findData)
{
@@ -95,3 +97,5 @@ bool findFindClose(DirectoryFileFindData* findData)
return true;
}
} // namespace fallout

View File

@@ -11,6 +11,8 @@
#include "platform_compat.h"
namespace fallout {
// NOTE: This structure is significantly different from what was in the
// original code. Watcom provides opendir/readdir/closedir implementations,
// that use Win32 FindFirstFile/FindNextFile under the hood, which in turn
@@ -65,4 +67,6 @@ static inline char* fileFindGetName(DirectoryFileFindData* findData)
#endif
}
} // namespace fallout
#endif /* FILE_FIND_H */

View File

@@ -11,6 +11,8 @@
#include "platform_compat.h"
namespace fallout {
static void fileCopy(const char* existingFilePath, const char* newFilePath);
// 0x452740
@@ -185,3 +187,5 @@ static void fileCopy(const char* existingFilePath, const char* newFilePath)
fclose(out);
}
}
} // namespace fallout

View File

@@ -1,8 +1,12 @@
#ifndef FILE_UTILS_H
#define FILE_UTILS_H
namespace fallout {
int fileCopyDecompressed(const char* existingFilePath, const char* newFilePath);
int fileCopyCompressed(const char* existingFilePath, const char* newFilePath);
int _gzdecompress_file(const char* existingFilePath, const char* newFilePath);
} // namespace fallout
#endif /* FILE_UTILS_H */

View File

@@ -10,6 +10,8 @@
// The maximum number of interface fonts.
#define INTERFACE_FONT_MAX (16)
namespace fallout {
typedef struct InterfaceFontGlyph {
short width;
short height;
@@ -405,3 +407,5 @@ static void interfaceFontByteSwapInt16(short* value)
{
interfaceFontByteSwapUInt16((unsigned short*)value);
}
} // namespace fallout

View File

@@ -3,9 +3,13 @@
#include "text_font.h"
namespace fallout {
extern FontManager gModernFontManager;
int interfaceFontsInit();
void interfaceFontsExit();
} // namespace fallout
#endif /* FONT_MANAGER_H */

View File

@@ -2,6 +2,8 @@
#include <SDL.h>
namespace fallout {
FpsLimiter::FpsLimiter(std::size_t fps)
: _fps(fps)
, _ticks(0)
@@ -19,3 +21,5 @@ void FpsLimiter::throttle() const
SDL_Delay(1000 / _fps - (SDL_GetTicks() - _ticks));
}
}
} // namespace fallout

View File

@@ -3,6 +3,8 @@
#include <cstddef>
namespace fallout {
class FpsLimiter {
public:
FpsLimiter(std::size_t fps = 60);
@@ -14,4 +16,6 @@ private:
std::size_t _ticks;
};
} // namespace fallout
#endif /* FPS_LIMITER_H */

View File

@@ -66,6 +66,8 @@
#include "window_manager.h"
#include "worldmap.h"
namespace fallout {
#define HELP_SCREEN_WIDTH (640)
#define HELP_SCREEN_HEIGHT (480)
@@ -1139,13 +1141,11 @@ static void showHelp()
if (win != -1) {
unsigned char* windowBuffer = windowGetBuffer(win);
if (windowBuffer != NULL) {
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 297, 0, 0, 0);
CacheEntry* backgroundHandle;
unsigned char* backgroundData = artLockFrameData(backgroundFid, 0, 0, &backgroundHandle);
if (backgroundData != NULL) {
if (backgroundFrmImage.lock(backgroundFid)) {
paletteSetEntries(gPaletteBlack);
blitBufferToBuffer(backgroundData, HELP_SCREEN_WIDTH, HELP_SCREEN_HEIGHT, HELP_SCREEN_WIDTH, windowBuffer, HELP_SCREEN_WIDTH);
artUnlock(backgroundHandle);
blitBufferToBuffer(backgroundFrmImage.getData(), HELP_SCREEN_WIDTH, HELP_SCREEN_HEIGHT, HELP_SCREEN_WIDTH, windowBuffer, HELP_SCREEN_WIDTH);
windowUnhide(win);
colorPaletteLoad("art\\intrface\\helpscrn.pal");
paletteSetEntries(_cmap);
@@ -1405,3 +1405,5 @@ int gameShowDeathDialog(const char* message)
return rc;
}
} // namespace fallout

View File

@@ -4,6 +4,8 @@
#include "game_vars.h"
#include "message.h"
namespace fallout {
typedef enum GameState {
GAME_STATE_0,
GAME_STATE_1,
@@ -39,4 +41,6 @@ int showQuitConfirmationDialog();
int gameShowDeathDialog(const char* message);
} // namespace fallout
#endif /* GAME_H */

View File

@@ -6,6 +6,8 @@
#include "main.h"
#include "platform_compat.h"
namespace fallout {
// A flag indicating if [gGameConfig] was initialized.
//
// 0x5186D0
@@ -181,3 +183,5 @@ bool gameConfigExit(bool shouldSave)
return result;
}
} // namespace fallout

View File

@@ -3,6 +3,8 @@
#include "config.h"
namespace fallout {
// The file name of the main config file.
#define GAME_CONFIG_FILE_NAME "fallout2.cfg"
@@ -120,4 +122,6 @@ bool gameConfigInit(bool isMapper, int argc, char** argv);
bool gameConfigSave();
bool gameConfigExit(bool shouldSave);
} // namespace fallout
#endif /* GAME_CONFIG_H */

View File

@@ -38,6 +38,8 @@
#include "tile.h"
#include "window_manager.h"
namespace fallout {
#define DIALOG_REVIEW_ENTRIES_CAPACITY 80
#define DIALOG_OPTION_ENTRIES_CAPACITY 30
@@ -272,25 +274,6 @@ static int _dialogue_just_started = 0;
// 0x5187F0
static int _dialogue_seconds_since_last_input = 0;
// 0x5187F4
static CacheEntry* gGameDialogReviewWindowButtonFrmHandles[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_COUNT] = {
INVALID_CACHE_ENTRY,
INVALID_CACHE_ENTRY,
INVALID_CACHE_ENTRY,
INVALID_CACHE_ENTRY,
INVALID_CACHE_ENTRY,
INVALID_CACHE_ENTRY,
};
// 0x51880C
static CacheEntry* _reviewBackKey = INVALID_CACHE_ENTRY;
// 0x518810
static CacheEntry* gGameDialogReviewWindowBackgroundFrmHandle = INVALID_CACHE_ENTRY;
// 0x518814
static unsigned char* gGameDialogReviewWindowBackgroundFrmData = NULL;
// 0x518818
static const int gGameDialogReviewWindowButtonWidths[GAME_DIALOG_REVIEW_WINDOW_BUTTON_COUNT] = {
35,
@@ -503,58 +486,9 @@ static int _control_buttons_start;
// 0x58F468
static int gGameDialogReviewWindowOldFont;
// 0x58F46C
static CacheEntry* gGameDialogRedButtonUpFrmHandle;
// 0x58F470
static int _gdialog_buttons[9];
// 0x58F494
static CacheEntry* gGameDialogUpperHighlightFrmHandle;
// 0x58F498
static CacheEntry* gGameDialogReviewButtonUpFrmHandle;
// 0x58F49C
static int gGameDialogLowerHighlightFrmHeight;
// 0x58F4A0
static CacheEntry* gGameDialogReviewButtonDownFrmHandle;
// 0x58F4A4
static unsigned char* gGameDialogRedButtonDownFrmData;
// 0x58F4A8
static int gGameDialogLowerHighlightFrmWidth;
// 0x58F4AC
static unsigned char* gGameDialogRedButtonUpFrmData;
// 0x58F4B0
static int gGameDialogUpperHighlightFrmWidth;
// Yellow highlight blick effect.
//
// 0x58F4B4
static Art* gGameDialogLowerHighlightFrm;
// 0x58F4B8
static int gGameDialogUpperHighlightFrmHeight;
// 0x58F4BC
static CacheEntry* gGameDialogRedButtonDownFrmHandle;
// 0x58F4C0
static CacheEntry* gGameDialogLowerHighlightFrmHandle;
// White highlight blick effect.
//
// This effect appears at the top-right corner on dialog display. Together with
// [gDialogLowerHighlight] it gives an effect of depth of the monitor.
//
// 0x58F4C4
static Art* gGameDialogUpperHighlightFrm;
// 0x58F4C8
static int _oldFont;
@@ -602,6 +536,15 @@ static unsigned int gGameDialogFidgetUpdateDelay;
// 0x596C38
static int gGameDialogFidgetFrmCurrentFrame;
static FrmImage _reviewBackgroundFrmImage;
static FrmImage _reviewFrmImages[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_COUNT];
static FrmImage _reviewButtonNormalFrmImage;
static FrmImage _reviewButtonPressedFrmImage;
static FrmImage _redButtonNormalFrmImage;
static FrmImage _redButtonPressedFrmImage;
static FrmImage _lowerHighlightFrmImage;
static FrmImage _upperHighlightFrmImage;
static int _gdialogReset();
static void gameDialogEndLips();
static int gdHide();
@@ -1346,32 +1289,28 @@ int gameDialogReviewWindowInit(int* win)
return -1;
}
FrmImage backgroundFrmImage;
int fid = buildFid(OBJ_TYPE_INTERFACE, 102, 0, 0, 0);
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &_reviewBackKey);
if (backgroundFrmData == NULL) {
if (!backgroundFrmImage.lock(fid)) {
windowDestroy(*win);
*win = -1;
return -1;
}
unsigned char* windowBuffer = windowGetBuffer(*win);
blitBufferToBuffer(backgroundFrmData,
blitBufferToBuffer(backgroundFrmImage.getData(),
GAME_DIALOG_REVIEW_WINDOW_WIDTH,
GAME_DIALOG_REVIEW_WINDOW_HEIGHT,
GAME_DIALOG_REVIEW_WINDOW_WIDTH,
windowBuffer,
GAME_DIALOG_REVIEW_WINDOW_WIDTH);
artUnlock(_reviewBackKey);
_reviewBackKey = INVALID_CACHE_ENTRY;
unsigned char* buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_COUNT];
backgroundFrmImage.unlock();
int index;
for (index = 0; index < GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_COUNT; index++) {
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameDialogReviewWindowButtonFrmIds[index], 0, 0, 0);
buttonFrmData[index] = artLockFrameData(fid, 0, 0, &(gGameDialogReviewWindowButtonFrmHandles[index]));
if (buttonFrmData[index] == NULL) {
if (!_reviewFrmImages[index].lock(fid)) {
break;
}
}
@@ -1390,8 +1329,8 @@ int gameDialogReviewWindowInit(int* win)
-1,
-1,
KEY_ARROW_UP,
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_UP_NORMAL],
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_UP_PRESSED],
_reviewFrmImages[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_UP_NORMAL].getData(),
_reviewFrmImages[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_UP_PRESSED].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (upBtn == -1) {
@@ -1410,8 +1349,8 @@ int gameDialogReviewWindowInit(int* win)
-1,
-1,
KEY_ARROW_DOWN,
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_DOWN_NORMAL],
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_DOWN_PRESSED],
_reviewFrmImages[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_DOWN_NORMAL].getData(),
_reviewFrmImages[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_DOWN_PRESSED].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (downBtn == -1) {
@@ -1430,8 +1369,8 @@ int gameDialogReviewWindowInit(int* win)
-1,
-1,
KEY_ESCAPE,
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_DONE_NORMAL],
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_DONE_PRESSED],
_reviewFrmImages[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_DONE_NORMAL].getData(),
_reviewFrmImages[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_DONE_PRESSED].getData(),
NULL,
BUTTON_FLAG_TRANSPARENT);
if (doneBtn == -1) {
@@ -1448,8 +1387,7 @@ int gameDialogReviewWindowInit(int* win)
tickersRemove(gameDialogTicker);
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 102, 0, 0, 0);
gGameDialogReviewWindowBackgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &gGameDialogReviewWindowBackgroundFrmHandle);
if (gGameDialogReviewWindowBackgroundFrmData == NULL) {
if (!_reviewBackgroundFrmImage.lock(backgroundFid)) {
gameDialogReviewWindowFree(win);
return -1;
}
@@ -1463,17 +1401,10 @@ int gameDialogReviewWindowFree(int* win)
tickersAdd(gameDialogTicker);
for (int index = 0; index < GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_COUNT; index++) {
if (gGameDialogReviewWindowButtonFrmHandles[index] != INVALID_CACHE_ENTRY) {
artUnlock(gGameDialogReviewWindowButtonFrmHandles[index]);
gGameDialogReviewWindowButtonFrmHandles[index] = INVALID_CACHE_ENTRY;
}
_reviewFrmImages[index].unlock();
}
if (gGameDialogReviewWindowBackgroundFrmHandle != INVALID_CACHE_ENTRY) {
artUnlock(gGameDialogReviewWindowBackgroundFrmHandle);
gGameDialogReviewWindowBackgroundFrmHandle = INVALID_CACHE_ENTRY;
gGameDialogReviewWindowBackgroundFrmData = NULL;
}
_reviewBackgroundFrmImage.unlock();
fontSetCurrent(gGameDialogReviewWindowOldFont);
@@ -1560,7 +1491,7 @@ void gameDialogReviewWindowUpdate(int win, int origin)
int width = GAME_DIALOG_WINDOW_WIDTH;
blitBufferToBuffer(
gGameDialogReviewWindowBackgroundFrmData + width * entriesRect.top + entriesRect.left,
_reviewBackgroundFrmImage.getData() + width * entriesRect.top + entriesRect.left,
width,
entriesRect.bottom - entriesRect.top + 15,
width,
@@ -1590,12 +1521,12 @@ void gameDialogReviewWindowUpdate(int win, int origin)
// NOTE: Uninline.
y = text_to_rect_wrapped(windowBuffer + 113,
&entriesRect,
replyText,
NULL,
fontGetLineHeight(),
640,
_colorTable[768] | 0x2000000);
&entriesRect,
replyText,
NULL,
fontGetLineHeight(),
640,
_colorTable[768] | 0x2000000);
// SFALL: Cosmetic fix to the dialog review interface to prevent the
// player name from being displayed at the bottom of the window when the
@@ -1623,12 +1554,12 @@ void gameDialogReviewWindowUpdate(int win, int origin)
// NOTE: Uninline.
y = text_to_rect_wrapped(windowBuffer + 113,
&entriesRect,
optionText,
NULL,
fontGetLineHeight(),
640,
_colorTable[15855] | 0x2000000);
&entriesRect,
optionText,
NULL,
fontGetLineHeight(),
640,
_colorTable[15855] | 0x2000000);
}
if (y >= 407) {
@@ -2945,7 +2876,7 @@ void _gdialog_scroll_subwin(int win, int a2, unsigned char* a3, unsigned char* a
} else {
rect.top = v18 * 10;
v7 = a6 % 10;
v9 += (GAME_DIALOG_WINDOW_WIDTH) * rect.top;
v9 += GAME_DIALOG_WINDOW_WIDTH * rect.top;
}
for (; v18 >= 0; v18--) {
@@ -3183,20 +3114,18 @@ int _gdialog_barter_create_win()
frmId = 111;
}
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
CacheEntry* backgroundHandle;
Art* backgroundFrm = artLock(backgroundFid, &backgroundHandle);
if (backgroundFrm == NULL) {
if (!backgroundFrmImage.lock(backgroundFid)) {
return -1;
}
unsigned char* backgroundData = artGetFrameData(backgroundFrm, 0, 0);
unsigned char* backgroundData = backgroundFrmImage.getData();
if (backgroundData == NULL) {
artUnlock(backgroundHandle);
return -1;
}
_dialogue_subwin_len = artGetHeight(backgroundFrm, 0, 0);
_dialogue_subwin_len = backgroundFrmImage.getHeight();
int barterWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
int barterWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len;
@@ -3207,7 +3136,6 @@ int _gdialog_barter_create_win()
256,
WINDOW_FLAG_0x02);
if (gGameDialogWindow == -1) {
artUnlock(backgroundHandle);
return -1;
}
@@ -3219,15 +3147,15 @@ int _gdialog_barter_create_win()
_gdialog_scroll_subwin(gGameDialogWindow, 1, backgroundData, windowBuffer, NULL, _dialogue_subwin_len, 0);
artUnlock(backgroundHandle);
backgroundFrmImage.unlock();
// TRADE
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 41, 163, 14, 14, -1, -1, -1, KEY_LOWERCASE_M, gGameDialogRedButtonUpFrmData, gGameDialogRedButtonDownFrmData, 0, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 41, 163, 14, 14, -1, -1, -1, KEY_LOWERCASE_M, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), 0, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[0] != -1) {
buttonSetCallbacks(_gdialog_buttons[0], _gsound_med_butt_press, _gsound_med_butt_release);
// TALK
_gdialog_buttons[1] = buttonCreate(gGameDialogWindow, 584, 162, 14, 14, -1, -1, -1, KEY_LOWERCASE_T, gGameDialogRedButtonUpFrmData, gGameDialogRedButtonDownFrmData, 0, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[1] = buttonCreate(gGameDialogWindow, 584, 162, 14, 14, -1, -1, -1, KEY_LOWERCASE_T, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), 0, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[1] != -1) {
buttonSetCallbacks(_gdialog_buttons[1], _gsound_med_butt_press, _gsound_med_butt_release);
@@ -3291,13 +3219,11 @@ void _gdialog_barter_destroy_win()
frmId = 111;
}
CacheEntry* backgroundFrmHandle;
int fid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
if (backgroundFrmData != NULL) {
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
if (backgroundFrmImage.lock(backgroundFid)) {
unsigned char* windowBuffer = windowGetBuffer(gGameDialogWindow);
_gdialog_scroll_subwin(gGameDialogWindow, 0, backgroundFrmData, windowBuffer, backgroundWindowBuffer, _dialogue_subwin_len, 0);
artUnlock(backgroundFrmHandle);
_gdialog_scroll_subwin(gGameDialogWindow, 0, backgroundFrmImage.getData(), windowBuffer, backgroundWindowBuffer, _dialogue_subwin_len, 0);
}
windowDestroy(gGameDialogWindow);
@@ -3342,20 +3268,19 @@ void _gdialog_barter_cleanup_tables()
// 0x448740
int partyMemberControlWindowInit()
{
CacheEntry* backgroundFrmHandle;
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 390, 0, 0, 0);
Art* backgroundFrm = artLock(backgroundFid, &backgroundFrmHandle);
if (backgroundFrm == NULL) {
if (!backgroundFrmImage.lock(backgroundFid)) {
return -1;
}
unsigned char* backgroundData = artGetFrameData(backgroundFrm, 0, 0);
unsigned char* backgroundData = backgroundFrmImage.getData();
if (backgroundData == NULL) {
partyMemberControlWindowFree();
return -1;
}
_dialogue_subwin_len = artGetHeight(backgroundFrm, 0, 0);
_dialogue_subwin_len = backgroundFrmImage.getHeight();
int controlWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
int controlWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len;
gGameDialogWindow = windowCreate(controlWindowX,
@@ -3373,10 +3298,10 @@ int partyMemberControlWindowInit()
unsigned char* src = windowGetBuffer(gGameDialogBackgroundWindow);
blitBufferToBuffer(src + (GAME_DIALOG_WINDOW_WIDTH) * (GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len), GAME_DIALOG_WINDOW_WIDTH, _dialogue_subwin_len, GAME_DIALOG_WINDOW_WIDTH, windowBuffer, GAME_DIALOG_WINDOW_WIDTH);
_gdialog_scroll_subwin(gGameDialogWindow, 1, backgroundData, windowBuffer, 0, _dialogue_subwin_len, 0);
artUnlock(backgroundFrmHandle);
backgroundFrmImage.unlock();
// TALK
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 593, 41, 14, 14, -1, -1, -1, KEY_ESCAPE, gGameDialogRedButtonUpFrmData, gGameDialogRedButtonDownFrmData, NULL, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 593, 41, 14, 14, -1, -1, -1, KEY_ESCAPE, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[0] == -1) {
partyMemberControlWindowFree();
return -1;
@@ -3384,7 +3309,7 @@ int partyMemberControlWindowInit()
buttonSetCallbacks(_gdialog_buttons[0], _gsound_med_butt_press, _gsound_med_butt_release);
// TRADE
_gdialog_buttons[1] = buttonCreate(gGameDialogWindow, 593, 97, 14, 14, -1, -1, -1, KEY_LOWERCASE_D, gGameDialogRedButtonUpFrmData, gGameDialogRedButtonDownFrmData, NULL, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[1] = buttonCreate(gGameDialogWindow, 593, 97, 14, 14, -1, -1, -1, KEY_LOWERCASE_D, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[1] == -1) {
partyMemberControlWindowFree();
return -1;
@@ -3392,7 +3317,7 @@ int partyMemberControlWindowInit()
buttonSetCallbacks(_gdialog_buttons[1], _gsound_med_butt_press, _gsound_med_butt_release);
// USE BEST WEAPON
_gdialog_buttons[2] = buttonCreate(gGameDialogWindow, 236, 15, 14, 14, -1, -1, -1, KEY_LOWERCASE_W, gGameDialogRedButtonUpFrmData, gGameDialogRedButtonDownFrmData, NULL, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[2] = buttonCreate(gGameDialogWindow, 236, 15, 14, 14, -1, -1, -1, KEY_LOWERCASE_W, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[2] == -1) {
partyMemberControlWindowFree();
return -1;
@@ -3400,7 +3325,7 @@ int partyMemberControlWindowInit()
buttonSetCallbacks(_gdialog_buttons[1], _gsound_med_butt_press, _gsound_med_butt_release);
// USE BEST ARMOR
_gdialog_buttons[3] = buttonCreate(gGameDialogWindow, 235, 46, 14, 14, -1, -1, -1, KEY_LOWERCASE_A, gGameDialogRedButtonUpFrmData, gGameDialogRedButtonDownFrmData, NULL, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[3] = buttonCreate(gGameDialogWindow, 235, 46, 14, 14, -1, -1, -1, KEY_LOWERCASE_A, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[3] == -1) {
partyMemberControlWindowFree();
return -1;
@@ -3518,12 +3443,10 @@ void partyMemberControlWindowFree()
}
// control.frm - party member control interface
CacheEntry* backgroundFrmHandle;
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 390, 0, 0, 0);
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
if (backgroundFrmData != NULL) {
_gdialog_scroll_subwin(gGameDialogWindow, 0, backgroundFrmData, windowGetBuffer(gGameDialogWindow), windowGetBuffer(gGameDialogBackgroundWindow) + (GAME_DIALOG_WINDOW_WIDTH) * (480 - _dialogue_subwin_len), _dialogue_subwin_len, 0);
artUnlock(backgroundFrmHandle);
if (backgroundFrmImage.lock(backgroundFid)) {
_gdialog_scroll_subwin(gGameDialogWindow, 0, backgroundFrmImage.getData(), windowGetBuffer(gGameDialogWindow), windowGetBuffer(gGameDialogBackgroundWindow) + (GAME_DIALOG_WINDOW_WIDTH) * (480 - _dialogue_subwin_len), _dialogue_subwin_len, 0);
}
windowDestroy(gGameDialogWindow);
@@ -3539,12 +3462,11 @@ void partyMemberControlWindowUpdate()
unsigned char* windowBuffer = windowGetBuffer(gGameDialogWindow);
int windowWidth = windowGetWidth(gGameDialogWindow);
CacheEntry* backgroundHandle;
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 390, 0, 0, 0);
Art* background = artLock(backgroundFid, &backgroundHandle);
if (background != NULL) {
int width = artGetWidth(background, 0, 0);
unsigned char* buffer = artGetFrameData(background, 0, 0);
if (!backgroundFrmImage.lock(backgroundFid)) {
int width = backgroundFrmImage.getWidth();
unsigned char* buffer = backgroundFrmImage.getData();
// Clear "Weapon Used:".
blitBufferToBuffer(buffer + width * 20 + 112, 110, fontGetLineHeight(), width, windowBuffer + windowWidth * 20 + 112, windowWidth);
@@ -3558,7 +3480,7 @@ void partyMemberControlWindowUpdate()
// Clear ?
blitBufferToBuffer(buffer + width * 80 + 232, 132, 106, width, windowBuffer + windowWidth * 80 + 232, windowWidth);
artUnlock(backgroundHandle);
backgroundFrmImage.unlock();
}
MessageListItem messageListItem;
@@ -3774,21 +3696,20 @@ int partyMemberCustomizationWindowInit()
return -1;
}
CacheEntry* backgroundFrmHandle;
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 391, 0, 0, 0);
Art* backgroundFrm = artLock(backgroundFid, &backgroundFrmHandle);
if (backgroundFrm == NULL) {
if (!backgroundFrmImage.lock(backgroundFid)) {
return -1;
}
unsigned char* backgroundFrmData = artGetFrameData(backgroundFrm, 0, 0);
unsigned char* backgroundFrmData = backgroundFrmImage.getData();
if (backgroundFrmData == NULL) {
// FIXME: Leaking background.
partyMemberCustomizationWindowFree();
return -1;
}
_dialogue_subwin_len = artGetHeight(backgroundFrm, 0, 0);
_dialogue_subwin_len = backgroundFrmImage.getHeight();
int customizationWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
int customizationWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len;
@@ -3813,9 +3734,9 @@ int partyMemberCustomizationWindowInit()
GAME_DIALOG_WINDOW_WIDTH);
_gdialog_scroll_subwin(gGameDialogWindow, 1, backgroundFrmData, windowBuffer, NULL, _dialogue_subwin_len, 0);
artUnlock(backgroundFrmHandle);
backgroundFrmImage.unlock();
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 593, 101, 14, 14, -1, -1, -1, 13, gGameDialogRedButtonUpFrmData, gGameDialogRedButtonDownFrmData, 0, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 593, 101, 14, 14, -1, -1, -1, 13, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), 0, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[0] == -1) {
partyMemberCustomizationWindowFree();
return -1;
@@ -3916,13 +3837,11 @@ void partyMemberCustomizationWindowFree()
}
}
CacheEntry* backgroundFrmHandle;
FrmImage backgroundFrmImage;
// custom.frm - party member control interface
int fid = buildFid(OBJ_TYPE_INTERFACE, 391, 0, 0, 0);
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
if (backgroundFrmData != NULL) {
_gdialog_scroll_subwin(gGameDialogWindow, 0, backgroundFrmData, windowGetBuffer(gGameDialogWindow), windowGetBuffer(gGameDialogBackgroundWindow) + (GAME_DIALOG_WINDOW_WIDTH) * (480 - _dialogue_subwin_len), _dialogue_subwin_len, 0);
artUnlock(backgroundFrmHandle);
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 391, 0, 0, 0);
if (backgroundFrmImage.lock(backgroundFid)) {
_gdialog_scroll_subwin(gGameDialogWindow, 0, backgroundFrmImage.getData(), windowGetBuffer(gGameDialogWindow), windowGetBuffer(gGameDialogBackgroundWindow) + (GAME_DIALOG_WINDOW_WIDTH) * (480 - _dialogue_subwin_len), _dialogue_subwin_len, 0);
}
windowDestroy(gGameDialogWindow);
@@ -3967,19 +3886,18 @@ void partyMemberCustomizationWindowUpdate()
unsigned char* windowBuffer = windowGetBuffer(gGameDialogWindow);
int windowWidth = windowGetWidth(gGameDialogWindow);
CacheEntry* backgroundHandle;
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 391, 0, 0, 0);
Art* background = artLock(backgroundFid, &backgroundHandle);
if (background == NULL) {
if (!backgroundFrmImage.lock(backgroundFid)) {
return;
}
int backgroundWidth = artGetWidth(background, 0, 0);
int backgroundHeight = artGetHeight(background, 0, 0);
unsigned char* backgroundData = artGetFrameData(background, 0, 0);
int backgroundWidth = backgroundFrmImage.getWidth();
int backgroundHeight = backgroundFrmImage.getHeight();
unsigned char* backgroundData = backgroundFrmImage.getData();
blitBufferToBuffer(backgroundData, backgroundWidth, backgroundHeight, backgroundWidth, windowBuffer, GAME_DIALOG_WINDOW_WIDTH);
artUnlock(backgroundHandle);
backgroundFrmImage.unlock();
MessageListItem messageListItem;
int num;
@@ -4075,42 +3993,39 @@ int _gdCustomSelect(int a1)
{
int oldFont = fontGetCurrent();
CacheEntry* backgroundFrmHandle;
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 419, 0, 0, 0);
Art* backgroundFrm = artLock(backgroundFid, &backgroundFrmHandle);
if (backgroundFrm == NULL) {
if (!backgroundFrmImage.lock(backgroundFid)) {
return -1;
}
int backgroundFrmWidth = artGetWidth(backgroundFrm, 0, 0);
int backgroundFrmHeight = artGetHeight(backgroundFrm, 0, 0);
int backgroundFrmWidth = backgroundFrmImage.getWidth();
int backgroundFrmHeight = backgroundFrmImage.getHeight();
int selectWindowX = (screenGetWidth() - backgroundFrmWidth) / 2;
int selectWindowY = (screenGetHeight() - backgroundFrmHeight) / 2;
int win = windowCreate(selectWindowX, selectWindowY, backgroundFrmWidth, backgroundFrmHeight, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
if (win == -1) {
artUnlock(backgroundFrmHandle);
return -1;
}
unsigned char* windowBuffer = windowGetBuffer(win);
unsigned char* backgroundFrmData = artGetFrameData(backgroundFrm, 0, 0);
blitBufferToBuffer(backgroundFrmData,
blitBufferToBuffer(backgroundFrmImage.getData(),
backgroundFrmWidth,
backgroundFrmHeight,
backgroundFrmWidth,
windowBuffer,
backgroundFrmWidth);
artUnlock(backgroundFrmHandle);
backgroundFrmImage.unlock();
int btn1 = buttonCreate(win, 70, 164, 14, 14, -1, -1, -1, KEY_RETURN, gGameDialogRedButtonUpFrmData, gGameDialogRedButtonDownFrmData, NULL, BUTTON_FLAG_TRANSPARENT);
int btn1 = buttonCreate(win, 70, 164, 14, 14, -1, -1, -1, KEY_RETURN, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
if (btn1 == -1) {
windowDestroy(win);
return -1;
}
int btn2 = buttonCreate(win, 176, 163, 14, 14, -1, -1, -1, KEY_ESCAPE, gGameDialogRedButtonUpFrmData, gGameDialogRedButtonDownFrmData, NULL, BUTTON_FLAG_TRANSPARENT);
int btn2 = buttonCreate(win, 176, 163, 14, 14, -1, -1, -1, KEY_ESCAPE, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
if (btn2 == -1) {
windowDestroy(win);
return -1;
@@ -4312,18 +4227,17 @@ int _gdialog_window_create()
_gdialog_buttons[index] = -1;
}
CacheEntry* backgroundFrmHandle;
FrmImage backgroundFrmImage;
// 389 - di_talkp.frm - dialog screen subwindow (party members)
// 99 - di_talk.frm - dialog screen subwindow (NPC's)
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, gGameDialogSpeakerIsPartyMember ? 389 : 99, 0, 0, 0);
Art* backgroundFrm = artLock(backgroundFid, &backgroundFrmHandle);
if (backgroundFrm == NULL) {
if (!backgroundFrmImage.lock(backgroundFid)) {
return -1;
}
unsigned char* backgroundFrmData = artGetFrameData(backgroundFrm, 0, 0);
unsigned char* backgroundFrmData = backgroundFrmImage.getData();
if (backgroundFrmData != NULL) {
_dialogue_subwin_len = artGetHeight(backgroundFrm, 0, 0);
_dialogue_subwin_len = backgroundFrmImage.getHeight();
int dialogSubwindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2;
int dialogSubwindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2 + GAME_DIALOG_WINDOW_HEIGHT - _dialogue_subwin_len;
@@ -4343,24 +4257,20 @@ int _gdialog_window_create()
_gdialog_scroll_subwin(gGameDialogWindow, 1, backgroundFrmData, v10, 0, _dialogue_subwin_len, 0);
}
artUnlock(backgroundFrmHandle);
// BARTER/TRADE
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 593, 41, 14, 14, -1, -1, -1, -1, gGameDialogRedButtonUpFrmData, gGameDialogRedButtonDownFrmData, NULL, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[0] = buttonCreate(gGameDialogWindow, 593, 41, 14, 14, -1, -1, -1, -1, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), NULL, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[0] != -1) {
buttonSetMouseCallbacks(_gdialog_buttons[0], NULL, NULL, NULL, gameDialogBarterButtonUpMouseUp);
buttonSetCallbacks(_gdialog_buttons[0], _gsound_med_butt_press, _gsound_med_butt_release);
// di_rest1.frm - dialog rest button up
int upFid = buildFid(OBJ_TYPE_INTERFACE, 97, 0, 0, 0);
unsigned char* reviewButtonUpData = artLockFrameData(upFid, 0, 0, &gGameDialogReviewButtonUpFrmHandle);
if (reviewButtonUpData != NULL) {
if (_reviewButtonNormalFrmImage.lock(upFid)) {
// di_rest2.frm - dialog rest button down
int downFid = buildFid(OBJ_TYPE_INTERFACE, 98, 0, 0, 0);
unsigned char* reivewButtonDownData = artLockFrameData(downFid, 0, 0, &gGameDialogReviewButtonDownFrmHandle);
if (reivewButtonDownData != NULL) {
if (_reviewButtonPressedFrmImage.lock(downFid)) {
// REVIEW
_gdialog_buttons[1] = buttonCreate(gGameDialogWindow, 13, 154, 51, 29, -1, -1, -1, -1, reviewButtonUpData, reivewButtonDownData, NULL, 0);
_gdialog_buttons[1] = buttonCreate(gGameDialogWindow, 13, 154, 51, 29, -1, -1, -1, -1, _reviewButtonNormalFrmImage.getData(), _reviewButtonPressedFrmImage.getData(), NULL, 0);
if (_gdialog_buttons[1] != -1) {
buttonSetMouseCallbacks(_gdialog_buttons[1], NULL, NULL, NULL, gameDialogReviewButtonOnMouseUp);
buttonSetCallbacks(_gdialog_buttons[1], _gsound_red_butt_press, _gsound_red_butt_release);
@@ -4371,7 +4281,7 @@ int _gdialog_window_create()
}
// COMBAT CONTROL
_gdialog_buttons[2] = buttonCreate(gGameDialogWindow, 593, 116, 14, 14, -1, -1, -1, -1, gGameDialogRedButtonUpFrmData, gGameDialogRedButtonDownFrmData, 0, BUTTON_FLAG_TRANSPARENT);
_gdialog_buttons[2] = buttonCreate(gGameDialogWindow, 593, 116, 14, 14, -1, -1, -1, -1, _redButtonNormalFrmImage.getData(), _redButtonPressedFrmImage.getData(), 0, BUTTON_FLAG_TRANSPARENT);
if (_gdialog_buttons[2] != -1) {
buttonSetMouseCallbacks(_gdialog_buttons[2], NULL, NULL, NULL, gameDialogCombatControlButtonOnMouseUp);
buttonSetCallbacks(_gdialog_buttons[2], _gsound_med_butt_press, _gsound_med_butt_release);
@@ -4384,10 +4294,10 @@ int _gdialog_window_create()
_gdialog_buttons[1] = -1;
}
artUnlock(gGameDialogReviewButtonDownFrmHandle);
_reviewButtonPressedFrmImage.unlock();
}
artUnlock(gGameDialogReviewButtonUpFrmHandle);
_reviewButtonNormalFrmImage.unlock();
}
buttonDestroy(_gdialog_buttons[0]);
@@ -4399,8 +4309,6 @@ int _gdialog_window_create()
}
}
artUnlock(backgroundFrmHandle);
return -1;
}
@@ -4416,8 +4324,8 @@ void _gdialog_window_destroy()
_gdialog_buttons[index] = -1;
}
artUnlock(gGameDialogReviewButtonDownFrmHandle);
artUnlock(gGameDialogReviewButtonUpFrmHandle);
_reviewButtonNormalFrmImage.unlock();
_reviewButtonPressedFrmImage.unlock();
int offset = (GAME_DIALOG_WINDOW_WIDTH) * (480 - _dialogue_subwin_len);
unsigned char* backgroundWindowBuffer = windowGetBuffer(gGameDialogBackgroundWindow) + offset;
@@ -4431,13 +4339,11 @@ void _gdialog_window_destroy()
frmId = 99;
}
CacheEntry* backgroundFrmHandle;
int fid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
if (backgroundFrmData != NULL) {
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
if (backgroundFrmImage.lock(backgroundFid)) {
unsigned char* windowBuffer = windowGetBuffer(gGameDialogWindow);
_gdialog_scroll_subwin(gGameDialogWindow, 0, backgroundFrmData, windowBuffer, backgroundWindowBuffer, _dialogue_subwin_len, 0);
artUnlock(backgroundFrmHandle);
_gdialog_scroll_subwin(gGameDialogWindow, 0, backgroundFrmImage.getData(), windowBuffer, backgroundWindowBuffer, _dialogue_subwin_len, 0);
windowDestroy(gGameDialogWindow);
_gdialog_window_created = 0;
gGameDialogWindow = -1;
@@ -4468,18 +4374,16 @@ static int talk_to_create_background_window()
// 0x44AB18
int gameDialogWindowRenderBackground()
{
CacheEntry* backgroundFrmHandle;
FrmImage backgroundFrmImage;
// alltlk.frm - dialog screen background
int fid = buildFid(OBJ_TYPE_INTERFACE, 103, 0, 0, 0);
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
if (backgroundFrmData == NULL) {
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 103, 0, 0, 0);
if (!backgroundFrmImage.lock(backgroundFid)) {
return -1;
}
int windowWidth = GAME_DIALOG_WINDOW_WIDTH;
unsigned char* windowBuffer = windowGetBuffer(gGameDialogBackgroundWindow);
blitBufferToBuffer(backgroundFrmData, windowWidth, 480, windowWidth, windowBuffer, windowWidth);
artUnlock(backgroundFrmHandle);
blitBufferToBuffer(backgroundFrmImage.getData(), windowWidth, 480, windowWidth, windowBuffer, windowWidth);
if (!_dialogue_just_started) {
windowRefresh(gGameDialogBackgroundWindow);
@@ -4500,25 +4404,22 @@ int _talkToRefreshDialogWindowRect(Rect* rect)
frmId = 99;
}
CacheEntry* backgroundFrmHandle;
int fid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
if (backgroundFrmData == NULL) {
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
if (!backgroundFrmImage.lock(backgroundFid)) {
return -1;
}
int offset = 640 * rect->top + rect->left;
unsigned char* windowBuffer = windowGetBuffer(gGameDialogWindow);
blitBufferToBuffer(backgroundFrmData + offset,
blitBufferToBuffer(backgroundFrmImage.getData() + offset,
rect->right - rect->left,
rect->bottom - rect->top,
GAME_DIALOG_WINDOW_WIDTH,
windowBuffer + offset,
GAME_DIALOG_WINDOW_WIDTH);
artUnlock(backgroundFrmHandle);
windowRefreshRect(gGameDialogWindow, rect);
return 0;
@@ -4559,23 +4460,19 @@ void gameDialogRenderTalkingHead(Art* headFrm, int frame)
_totalHotx = 0;
}
FrmImage backgroundFrmImage;
int backgroundFid = buildFid(OBJ_TYPE_BACKGROUND, gGameDialogBackground, 0, 0, 0);
CacheEntry* backgroundHandle;
Art* backgroundFrm = artLock(backgroundFid, &backgroundHandle);
if (backgroundFrm == NULL) {
if (!backgroundFrmImage.lock(backgroundFid)) {
debugPrint("\tError locking background in display...\n");
}
unsigned char* backgroundFrmData = artGetFrameData(backgroundFrm, 0, 0);
unsigned char* backgroundFrmData = backgroundFrmImage.getData();
if (backgroundFrmData != NULL) {
blitBufferToBuffer(backgroundFrmData, 388, 200, 388, gGameDialogDisplayBuffer, GAME_DIALOG_WINDOW_WIDTH);
} else {
debugPrint("\tError getting background data in display...\n");
}
artUnlock(backgroundHandle);
int width = artGetWidth(headFrm, frame, 0);
int height = artGetHeight(headFrm, frame, 0);
unsigned char* data = artGetFrameData(headFrm, frame, 0);
@@ -4640,11 +4537,27 @@ void gameDialogRenderTalkingHead(Art* headFrm, int frame)
unsigned char* dest = windowGetBuffer(gGameDialogBackgroundWindow);
unsigned char* data1 = artGetFrameData(gGameDialogUpperHighlightFrm, 0, 0);
gameDialogRenderHighlight(data1, gGameDialogUpperHighlightFrmWidth, gGameDialogUpperHighlightFrmHeight, gGameDialogUpperHighlightFrmWidth, dest, 426, 15, GAME_DIALOG_WINDOW_WIDTH, _light_BlendTable, _light_GrayTable);
gameDialogRenderHighlight(_upperHighlightFrmImage.getData(),
_upperHighlightFrmImage.getWidth(),
_upperHighlightFrmImage.getHeight(),
_upperHighlightFrmImage.getWidth(),
dest,
426,
15,
GAME_DIALOG_WINDOW_WIDTH,
_light_BlendTable,
_light_GrayTable);
unsigned char* data2 = artGetFrameData(gGameDialogLowerHighlightFrm, 0, 0);
gameDialogRenderHighlight(data2, gGameDialogLowerHighlightFrmWidth, gGameDialogLowerHighlightFrmHeight, gGameDialogLowerHighlightFrmWidth, dest, 129, 214 - gGameDialogLowerHighlightFrmHeight - 2, GAME_DIALOG_WINDOW_WIDTH, _dark_BlendTable, _dark_GrayTable);
gameDialogRenderHighlight(_lowerHighlightFrmImage.getData(),
_lowerHighlightFrmImage.getWidth(),
_lowerHighlightFrmImage.getHeight(),
_lowerHighlightFrmImage.getWidth(),
dest,
129,
214 - _lowerHighlightFrmImage.getHeight() - 2,
GAME_DIALOG_WINDOW_WIDTH,
_dark_BlendTable,
_dark_GrayTable);
for (int index = 0; index < 8; ++index) {
Rect* rect = &(_backgrndRects[index]);
@@ -4654,7 +4567,7 @@ void gameDialogRenderTalkingHead(Art* headFrm, int frame)
width,
rect->bottom - rect->top,
width,
dest + (GAME_DIALOG_WINDOW_WIDTH) * rect->top + rect->left,
dest + GAME_DIALOG_WINDOW_WIDTH * rect->top + rect->left,
GAME_DIALOG_WINDOW_WIDTH);
}
@@ -4680,15 +4593,11 @@ void gameDialogHighlightsInit()
// hilight1.frm - dialogue upper hilight
int upperHighlightFid = buildFid(OBJ_TYPE_INTERFACE, 115, 0, 0, 0);
gGameDialogUpperHighlightFrm = artLock(upperHighlightFid, &gGameDialogUpperHighlightFrmHandle);
gGameDialogUpperHighlightFrmWidth = artGetWidth(gGameDialogUpperHighlightFrm, 0, 0);
gGameDialogUpperHighlightFrmHeight = artGetHeight(gGameDialogUpperHighlightFrm, 0, 0);
_upperHighlightFrmImage.lock(upperHighlightFid);
// hilight2.frm - dialogue lower hilight
int lowerHighlightFid = buildFid(OBJ_TYPE_INTERFACE, 116, 0, 0, 0);
gGameDialogLowerHighlightFrm = artLock(lowerHighlightFid, &gGameDialogLowerHighlightFrmHandle);
gGameDialogLowerHighlightFrmWidth = artGetWidth(gGameDialogLowerHighlightFrm, 0, 0);
gGameDialogLowerHighlightFrmHeight = artGetHeight(gGameDialogLowerHighlightFrm, 0, 0);
_lowerHighlightFrmImage.lock(lowerHighlightFid);
}
// NOTE: Inlined.
@@ -4699,38 +4608,29 @@ static void gameDialogHighlightsExit()
_freeColorBlendTable(_colorTable[17969]);
_freeColorBlendTable(_colorTable[22187]);
artUnlock(gGameDialogUpperHighlightFrmHandle);
artUnlock(gGameDialogLowerHighlightFrmHandle);
_upperHighlightFrmImage.unlock();
_lowerHighlightFrmImage.unlock();
}
static void gameDialogRedButtonsInit()
{
// di_rdbt2.frm - dialog red button down
int pressedFid = buildFid(OBJ_TYPE_INTERFACE, 96, 0, 0, 0);
gGameDialogRedButtonUpFrmData = artLockFrameData(pressedFid, 0, 0, &gGameDialogRedButtonUpFrmHandle);
if (gGameDialogRedButtonUpFrmData == NULL) {
if (!_redButtonPressedFrmImage.lock(pressedFid)) {
gameDialogRedButtonsExit();
}
// di_rdbt1.frm - dialog red button up
int normalFid = buildFid(OBJ_TYPE_INTERFACE, 95, 0, 0, 0);
gGameDialogRedButtonDownFrmData = artLockFrameData(normalFid, 0, 0, &gGameDialogRedButtonDownFrmHandle);
if (gGameDialogRedButtonDownFrmData == NULL) {
if (!_redButtonNormalFrmImage.lock(normalFid)) {
gameDialogRedButtonsExit();
}
}
static void gameDialogRedButtonsExit()
{
if (gGameDialogRedButtonDownFrmHandle != NULL) {
artUnlock(gGameDialogRedButtonDownFrmHandle);
gGameDialogRedButtonDownFrmHandle = NULL;
gGameDialogRedButtonDownFrmData = NULL;
}
if (gGameDialogRedButtonUpFrmHandle != NULL) {
artUnlock(gGameDialogRedButtonUpFrmHandle);
gGameDialogRedButtonUpFrmHandle = NULL;
gGameDialogRedButtonUpFrmData = NULL;
}
_redButtonNormalFrmImage.unlock();
_redButtonPressedFrmImage.unlock();
}
} // namespace fallout

View File

@@ -4,6 +4,8 @@
#include "interpreter.h"
#include "obj_types.h"
namespace fallout {
extern Object* gGameDialogSpeaker;
extern bool gGameDialogSpeakerIsPartyMember;
extern int gGameDialogHeadFid;
@@ -37,4 +39,6 @@ void gameDialogSetBarterModifier(int modifier);
int gameDialogBarter(int modifier);
void _barter_end_to_talk_to();
} // namespace fallout
#endif /* GAME_DIALOG_H */

View File

@@ -6,6 +6,8 @@
#include "memory_defs.h"
#include "memory_manager.h"
namespace fallout {
static void* gameMemoryMalloc(size_t size);
static void* gameMemoryRealloc(void* ptr, size_t newSize);
static void gameMemoryFree(void* ptr);
@@ -37,3 +39,5 @@ static void gameMemoryFree(void* ptr)
{
internal_free(ptr);
}
} // namespace fallout

View File

@@ -1,6 +1,10 @@
#ifndef GAME_MEMORY_H
#define GAME_MEMORY_H
namespace fallout {
int gameMemoryInit();
} // namespace fallout
#endif /* GAME_MEMORY_H */

View File

@@ -27,6 +27,8 @@
#include "tile.h"
#include "window_manager.h"
namespace fallout {
typedef enum ScrollableDirections {
SCROLLABLE_W = 0x01,
SCROLLABLE_E = 0x02,
@@ -2454,3 +2456,5 @@ static void customMouseModeFrmsInit()
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_USE_SCIENCE_FRM_KEY, &(gGameMouseModeFrmIds[GAME_MOUSE_MODE_USE_SCIENCE]));
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_USE_REPAIR_FRM_KEY, &(gGameMouseModeFrmIds[GAME_MOUSE_MODE_USE_REPAIR]));
}
} // namespace fallout

View File

@@ -3,6 +3,8 @@
#include "obj_types.h"
namespace fallout {
typedef enum GameMouseMode {
GAME_MOUSE_MODE_MOVE,
GAME_MOUSE_MODE_ARROW,
@@ -99,4 +101,6 @@ int gameMouseHighlightActionMenuItemAtIndex(int menuItemIndex);
void gameMouseLoadItemHighlight();
void _gmouse_remove_item_outline(Object* object);
} // namespace fallout
#endif /* GAME_MOUSE_H */

View File

@@ -18,6 +18,8 @@
#include "text_font.h"
#include "window_manager.h"
namespace fallout {
#define GAME_MOVIE_WINDOW_WIDTH 640
#define GAME_MOVIE_WINDOW_HEIGHT 480
@@ -349,3 +351,5 @@ static char* gameMovieBuildSubtitlesFilePath(char* movieFilePath)
return gGameMovieSubtitlesFilePath;
}
} // namespace fallout

View File

@@ -3,6 +3,8 @@
#include "db.h"
namespace fallout {
typedef enum GameMovieFlags {
GAME_MOVIE_FADE_IN = 0x01,
GAME_MOVIE_FADE_OUT = 0x02,
@@ -40,4 +42,6 @@ void gameMovieFadeOut();
bool gameMovieIsSeen(int movie);
bool gameMovieIsPlaying();
} // namespace fallout
#endif /* GAME_MOVIE_H */

View File

@@ -2,6 +2,8 @@
#include "color.h"
namespace fallout {
// 0x44EBC0
int _HighRGB_(int a1)
{
@@ -23,3 +25,5 @@ int _HighRGB_(int a1)
return result;
}
} // namespace fallout

View File

@@ -1,6 +1,10 @@
#ifndef GAME_PALETTE_H
#define GAME_PALETTE_H
namespace fallout {
int _HighRGB_(int a1);
} // namespace fallout
#endif /* GAME_PALETTE_H */

View File

@@ -24,6 +24,8 @@
#include "window_manager.h"
#include "worldmap.h"
namespace fallout {
typedef enum SoundEffectActionType {
SOUND_EFFECT_ACTION_TYPE_ACTIVE,
SOUND_EFFECT_ACTION_TYPE_PASSIVE,
@@ -2148,3 +2150,5 @@ int ambientSoundEffectEventProcess(Object* a1, void* data)
return 0;
}
} // namespace fallout

View File

@@ -4,6 +4,8 @@
#include "obj_types.h"
#include "sound.h"
namespace fallout {
typedef enum WeaponSoundEffect {
WEAPON_SOUND_EFFECT_READY,
WEAPON_SOUND_EFFECT_ATTACK,
@@ -83,4 +85,6 @@ int soundPlayFile(const char* name);
int _gsound_sfx_q_start();
int ambientSoundEffectEventProcess(Object* a1, void* a2);
} // namespace fallout
#endif /* GAME_SOUND_H */

View File

@@ -1,6 +1,8 @@
#ifndef GAME_VARS_H
#define GAME_VARS_H
namespace fallout {
typedef enum GameGlobalVar {
GVAR_PLAYER_REPUTATION,
GVAR_CHILDKILLER_REPUTATION,
@@ -700,4 +702,6 @@ typedef enum GameGlobalVar {
GVAR_PATCH_INVAIDITATOR,
} GameGlobalVar;
} // namespace fallout
#endif /* GAME_VARS_H */

View File

@@ -6,6 +6,8 @@
#include "memory.h"
namespace fallout {
// 0x51DEF4
static RectListNode* _rectList = NULL;
@@ -183,3 +185,5 @@ int rectIntersection(const Rect* s1, const Rect* s2, Rect* r)
return -1;
}
} // namespace fallout

View File

@@ -1,6 +1,8 @@
#ifndef GEOMETRY_H
#define GEOMETRY_H
namespace fallout {
typedef struct Point {
int x;
int y;
@@ -56,4 +58,6 @@ static inline void rectOffset(Rect* rect, int dx, int dy)
rect->bottom += dy;
}
} // namespace fallout
#endif /* GEOMETRY_H */

View File

@@ -5,6 +5,8 @@
#include "debug.h"
#include "memory.h"
namespace fallout {
static void _InitTree();
static void _InsertNode(int a1);
static void _DeleteNode(int a1);
@@ -382,3 +384,5 @@ int graphDecompress(unsigned char* src, unsigned char* dest, int length)
return 0;
}
} // namespace fallout

View File

@@ -1,7 +1,11 @@
#ifndef GRAPH_LIB_H
#define GRAPH_LIB_H
namespace fallout {
int graphCompress(unsigned char* a1, unsigned char* a2, int a3);
int graphDecompress(unsigned char* a1, unsigned char* a2, int a3);
} // namespace fallout
#endif /* GRAPH_LIB_H */

View File

@@ -4,6 +4,8 @@
#include "color.h"
namespace fallout {
// 0x596D90
static unsigned char _GreyTable[256];
@@ -40,3 +42,5 @@ void grayscalePaletteApply(unsigned char* buffer, int width, int height, int pit
ptr += skip;
}
}
} // namespace fallout

View File

@@ -1,7 +1,11 @@
#ifndef GRAYSCALE_H
#define GRAYSCALE_H
namespace fallout {
void grayscalePaletteUpdate(int a1, int a2);
void grayscalePaletteApply(unsigned char* surface, int width, int height, int pitch);
} // namespace fallout
#endif /* GRAYSCALE_H */

Some files were not shown because too many files have changed in this diff Show More