Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| df5bceaf2a | |||
| 66d46bd8a5 | |||
| 28a433ea76 | |||
| 2c69834a12 | |||
| 00ee53efca | |||
| 4989cf6d5a | |||
| 0d5aa705f0 | |||
| 307b032118 | |||
| ab8279078e | |||
| b7ac80e684 | |||
| 6064a4bc79 | |||
| e41a4b8e16 | |||
| 39057fd1fb |
+10
-1
@@ -2,14 +2,23 @@
|
||||
*.c text eol=lf
|
||||
*.cc text eol=lf
|
||||
*.cmake text eol=lf
|
||||
*.gradle text eol=lf
|
||||
*.h text eol=lf
|
||||
*.md text eol=lf
|
||||
*.java text eol=lf
|
||||
*.json text eol=lf
|
||||
*.md text eol=lf
|
||||
*.plist text eol=lf
|
||||
*.pro text eol=lf
|
||||
*.properties text eol=lf
|
||||
*.xml text eol=lf
|
||||
*.yml text eol=lf
|
||||
.clang-format text eol=lf
|
||||
.editorconfig text eol=lf
|
||||
.gitattributes text eol=lf
|
||||
.gitignore text eol=lf
|
||||
gradlew text eol=lf
|
||||
CMakeLists.txt text eol=lf
|
||||
LICENSE text eol=lf
|
||||
|
||||
# Force CRLF
|
||||
*.bat text eol=crlf
|
||||
|
||||
@@ -2,19 +2,12 @@ name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/ci-build.yml'
|
||||
- 'src/**.cc'
|
||||
- 'src/**.h'
|
||||
- '**/CMakeLists.txt'
|
||||
- '**/*.cmake'
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/ci-build.yml'
|
||||
- 'src/**.cc'
|
||||
- 'src/**.h'
|
||||
- '**/CMakeLists.txt'
|
||||
- '**/*.cmake'
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@@ -38,6 +31,49 @@ jobs:
|
||||
- name: cppcheck
|
||||
run: cppcheck --std=c++17 src/
|
||||
|
||||
android:
|
||||
name: Android
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 11
|
||||
cache: gradle
|
||||
|
||||
- name: Cache cmake build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: os/android/app/.cxx
|
||||
key: android-cmake-v1
|
||||
|
||||
- name: Setup signing config
|
||||
run: |
|
||||
cd os/android
|
||||
echo "$KEYSTORE_FILE_BASE64" | base64 --decode > debug.keystore
|
||||
echo "$KEYSTORE_PROPERTIES_FILE_BASE64" | base64 --decode > debug-keystore.properties
|
||||
env:
|
||||
KEYSTORE_FILE_BASE64: ${{ secrets.ANDROID_DEBUG_KEYSTORE_FILE_BASE64 }}
|
||||
KEYSTORE_PROPERTIES_FILE_BASE64: ${{ secrets.ANDROID_DEBUG_KEYSTORE_PROPERTIES_FILE_BASE64 }}
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cd os/android
|
||||
./gradlew assembleDebug
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fallout2-ce-debug.apk
|
||||
path: os/android/app/build/outputs/apk/debug/app-debug.apk
|
||||
retention-days: 7
|
||||
|
||||
linux:
|
||||
name: Linux (${{ matrix.arch }})
|
||||
|
||||
|
||||
@@ -10,6 +10,51 @@ defaults:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
android:
|
||||
name: Android
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 11
|
||||
cache: gradle
|
||||
|
||||
- name: Cache cmake build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: os/android/app/.cxx
|
||||
key: android-cmake-v1
|
||||
|
||||
- name: Setup signing config
|
||||
run: |
|
||||
cd os/android
|
||||
echo "$KEYSTORE_FILE_BASE64" | base64 --decode > release.keystore
|
||||
echo "$KEYSTORE_PROPERTIES_FILE_BASE64" | base64 --decode > release-keystore.properties
|
||||
env:
|
||||
KEYSTORE_FILE_BASE64: ${{ secrets.ANDROID_RELEASE_KEYSTORE_FILE_BASE64 }}
|
||||
KEYSTORE_PROPERTIES_FILE_BASE64: ${{ secrets.ANDROID_RELEASE_KEYSTORE_PROPERTIES_FILE_BASE64 }}
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cd os/android
|
||||
./gradlew assembleRelease
|
||||
|
||||
- name: Upload
|
||||
run: |
|
||||
cd os/android/app/build/outputs/apk/release
|
||||
cp app-release.apk fallout2-ce-android.apk
|
||||
gh release upload ${{ github.ref_name }} fallout2-ce-android.apk
|
||||
rm fallout2-ce-android.apk
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
linux:
|
||||
name: Linux (${{ matrix.arch }})
|
||||
|
||||
|
||||
@@ -170,6 +170,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||
"src/palette.h"
|
||||
"src/party_member.cc"
|
||||
"src/party_member.h"
|
||||
"src/pcx.cc"
|
||||
"src/pcx.h"
|
||||
"src/perk_defs.h"
|
||||
"src/perk.cc"
|
||||
"src/perk.h"
|
||||
|
||||
@@ -34,6 +34,16 @@ $ sudo apt install libsdl2-2.0-0
|
||||
|
||||
- Run `fallout2-ce.app`.
|
||||
|
||||
### Android
|
||||
|
||||
> **NOTE**: Fallout 2 was designed with mouse in mind. There are many controls that require precise cursor positioning, which is not possible with fingers. When playing on Android you'll use fingers to move mouse cursor, not a character, or a map. Double tap to "click" left mouse button in the current cursor position, triple tap to "click" right mouse button. It might feel awkward at first, but it's super handy - you can play with just a thumb. This is not set in stone and might change in the future.
|
||||
|
||||
- Use Windows installation as a base - it contains data assets needed to play. Copy `Fallout2` folder to your device, for example to `Downloads`. You need `master.dat`, `critter.dat`, `patch000.dat`, and `data` folder.
|
||||
|
||||
- Download `fallout2-ce.apk` and copy it to your device. Open it with file explorer, follow instructions (install from unknown source).
|
||||
|
||||
- When you run the game for the first time it will immediately present file picker. Select the folder from the first step. Wait until this data is copied. There is no fancy importing interface (yet), just wait for about 30 seconds. The game will start automatically.
|
||||
|
||||
## Contributing
|
||||
|
||||
Integrating Sfall goodies is the top priority. Quality of life updates are OK too. Please no large scale refactorings at this time as we need to reconcile changes from Reference Edition, which will make this process slow and error-prone. In any case open up an issue with your suggestion or to notify other people that something is being worked on.
|
||||
|
||||
@@ -7,3 +7,7 @@
|
||||
/.idea/navEditor.xml
|
||||
/.idea/workspace.xml
|
||||
/local.properties
|
||||
/debug-keystore.properties
|
||||
/debug.keystore
|
||||
/release-keystore.properties
|
||||
/release.keystore
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
/.cxx
|
||||
/build
|
||||
|
||||
# TODO: Cleanup root .gitignore
|
||||
!/src/debug
|
||||
|
||||
@@ -26,10 +26,49 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
// Override default debug signing config to make sure every CI runner
|
||||
// uses the same key for painless updates.
|
||||
def debugKeystorePropertiesFile = rootProject.file('debug-keystore.properties')
|
||||
if (debugKeystorePropertiesFile.exists()) {
|
||||
def debugKeystoreProperties = new Properties()
|
||||
debugKeystoreProperties.load(new FileInputStream(debugKeystorePropertiesFile))
|
||||
|
||||
debug {
|
||||
storeFile rootProject.file(debugKeystoreProperties.getProperty('storeFile'))
|
||||
storePassword debugKeystoreProperties.getProperty('storePassword')
|
||||
keyAlias debugKeystoreProperties.getProperty('keyAlias')
|
||||
keyPassword debugKeystoreProperties.getProperty('keyPassword')
|
||||
}
|
||||
}
|
||||
|
||||
def releaseKeystoreProperties = new Properties()
|
||||
def releaseKeystorePropertiesFile = rootProject.file('release-keystore.properties')
|
||||
if (releaseKeystorePropertiesFile.exists()) {
|
||||
releaseKeystoreProperties.load(new FileInputStream(releaseKeystorePropertiesFile))
|
||||
|
||||
release {
|
||||
storeFile rootProject.file(releaseKeystoreProperties.getProperty('storeFile'))
|
||||
storePassword releaseKeystoreProperties.getProperty('storePassword')
|
||||
keyAlias releaseKeystoreProperties.getProperty('keyAlias')
|
||||
keyPassword releaseKeystoreProperties.getProperty('keyPassword')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
// Prevents signing keys clashes between debug and release versions
|
||||
// for painless development.
|
||||
applicationIdSuffix '.debug'
|
||||
}
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
|
||||
// Release signing config is optional and might not be present in CI
|
||||
// builds, hence `findByName`.
|
||||
signingConfig signingConfigs.findByName('release')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,4 +96,5 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'androidx.documentfile:documentfile:1.0.1'
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">Fallout 2 (Debug)</string>
|
||||
</resources>
|
||||
@@ -92,6 +92,10 @@
|
||||
</intent-filter>
|
||||
-->
|
||||
</activity>
|
||||
|
||||
<activity android:name=".ImportActivity"
|
||||
android:theme="@style/AppTheme">
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.alexbatalov.fallout2ce;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class ImportActivity extends Activity {
|
||||
private static final int IMPORT_REQUEST_CODE = 1;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
startActivityForResult(intent, IMPORT_REQUEST_CODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent resultData) {
|
||||
if (requestCode == IMPORT_REQUEST_CODE) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
final Uri treeUri = resultData.getData();
|
||||
if (treeUri != null) {
|
||||
final DocumentFile treeDocument = DocumentFile.fromTreeUri(this, treeUri);
|
||||
if (treeDocument != null) {
|
||||
copyRecursively(treeDocument, getExternalFilesDir(null));
|
||||
|
||||
final Intent intent = new Intent(this, MainActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finish();
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, resultData);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean copyRecursively(DocumentFile src, File dest) {
|
||||
final DocumentFile[] documentFiles = src.listFiles();
|
||||
for (final DocumentFile documentFile : documentFiles) {
|
||||
if (documentFile.isFile()) {
|
||||
if (!copyFile(documentFile, new File(dest, documentFile.getName()))) {
|
||||
return false;
|
||||
}
|
||||
} else if (documentFile.isDirectory()) {
|
||||
final File subdirectory = new File(dest, documentFile.getName());
|
||||
if (!subdirectory.exists()) {
|
||||
subdirectory.mkdir();
|
||||
}
|
||||
|
||||
if (!copyRecursively(documentFile, subdirectory)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean copyFile(DocumentFile src, File dest) {
|
||||
try {
|
||||
final InputStream inputStream = getContentResolver().openInputStream(src.getUri());
|
||||
final OutputStream outputStream = new FileOutputStream(dest);
|
||||
|
||||
final byte[] buffer = new byte[16384];
|
||||
int bytesRead;
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
|
||||
inputStream.close();
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,47 @@
|
||||
package com.alexbatalov.fallout2ce;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import org.libsdl.app.SDLActivity;
|
||||
|
||||
public class MainActivity extends SDLActivity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
// Needed to initialize `files` folder (and make it publicly accessible
|
||||
// for file managers) for user to upload assets.
|
||||
getExternalFilesDir(null);
|
||||
import java.io.File;
|
||||
|
||||
public class MainActivity extends SDLActivity {
|
||||
private boolean noExit = false;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
final File externalFilesDir = getExternalFilesDir(null);
|
||||
|
||||
final File configFile = new File(externalFilesDir, "fallout2.cfg");
|
||||
if (!configFile.exists()) {
|
||||
final File masterDatFile = new File(externalFilesDir, "master.dat");
|
||||
final File critterDatFile = new File(externalFilesDir, "critter.dat");
|
||||
if (!masterDatFile.exists() || !critterDatFile.exists()) {
|
||||
final Intent intent = new Intent(this, ImportActivity.class);
|
||||
startActivity(intent);
|
||||
|
||||
noExit = true;
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
if (!noExit) {
|
||||
// Needed to make sure libc calls exit handlers, which releases
|
||||
// in-game resources.
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getLibraries() {
|
||||
return new String[]{
|
||||
"fallout2-ce",
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">Fallout 2 Community Edition</string>
|
||||
<string name="app_name">Fallout 2</string>
|
||||
</resources>
|
||||
|
||||
+249
-256
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -16,7 +16,7 @@ bool _can_see(Object* a1, Object* a2);
|
||||
bool _action_explode_running();
|
||||
int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object* a5, bool a6);
|
||||
int actionTalk(Object* a1, Object* a2);
|
||||
void _action_dmg(int tile, int elevation, int minDamage, int maxDamage, int damageType, bool animated, bool bypassArmor);
|
||||
void actionDamage(int tile, int elevation, int minDamage, int maxDamage, int damageType, bool animated, bool bypassArmor);
|
||||
bool actionCheckPush(Object* a1, Object* a2);
|
||||
int actionPush(Object* a1, Object* a2);
|
||||
int _action_can_talk_to(Object* a1, Object* a2);
|
||||
|
||||
+868
-484
File diff suppressed because it is too large
Load Diff
+39
-54
@@ -3,36 +3,14 @@
|
||||
|
||||
#include "combat_defs.h"
|
||||
#include "obj_types.h"
|
||||
#include "sound.h"
|
||||
|
||||
typedef enum AnimKind {
|
||||
ANIM_KIND_OBJ_MOVE_TO_OBJ = 0,
|
||||
ANIM_KIND_OBJ_MOVE_TO_TILE = 1,
|
||||
ANIM_KIND_2 = 2,
|
||||
ANIM_KIND_KNOCKDOWN = 3,
|
||||
ANIM_KIND_ANIMATE = 4,
|
||||
ANIM_KIND_ANIMATE_REVERSE = 5,
|
||||
ANIM_KIND_6 = 6,
|
||||
ANIM_KIND_SET_ROTATION_TO_TILE = 7,
|
||||
ANIM_KIND_ROTATE_CLOCKWISE = 8,
|
||||
ANIM_KIND_ROTATE_COUNTER_CLOCKWISE = 9,
|
||||
ANIM_KIND_HIDE = 10,
|
||||
ANIM_KIND_EXEC = 11,
|
||||
ANIM_KIND_EXEC_2 = 12,
|
||||
ANIM_KIND_14 = 14,
|
||||
ANIM_KIND_15 = 15,
|
||||
ANIM_KIND_16 = 16,
|
||||
ANIM_KIND_17 = 17,
|
||||
ANIM_KIND_18 = 18,
|
||||
ANIM_KIND_19 = 19,
|
||||
ANIM_KIND_20 = 20,
|
||||
ANIM_KIND_23 = 23,
|
||||
ANIM_KIND_24 = 24,
|
||||
ANIM_KIND_ANIMATE_FOREVER = 25,
|
||||
ANIM_KIND_26 = 26,
|
||||
ANIM_KIND_27 = 27,
|
||||
ANIM_KIND_28 = 28,
|
||||
} AnimKind;
|
||||
typedef enum AnimationRequestOptions {
|
||||
ANIMATION_REQUEST_UNRESERVED = 0x01,
|
||||
ANIMATION_REQUEST_RESERVED = 0x02,
|
||||
ANIMATION_REQUEST_NO_STAND = 0x04,
|
||||
ANIMATION_REQUEST_0x100 = 0x100,
|
||||
ANIMATION_REQUEST_INSIGNIFICANT = 0x200,
|
||||
} AnimationRequestOptions;
|
||||
|
||||
// Basic animations: 0-19
|
||||
// Knockdown and death: 20-35
|
||||
@@ -112,9 +90,13 @@ typedef enum AnimationType {
|
||||
LAST_SF_DEATH_ANIM = ANIM_FALL_FRONT_BLOOD_SF,
|
||||
} AnimationType;
|
||||
|
||||
typedef int AnimationProc(Object*, Object*);
|
||||
typedef int AnimationSoundProc(Sound*);
|
||||
typedef int AnimationProc2(Object*, Object*, void*);
|
||||
#define FID_ANIM_TYPE(value) ((value) & 0xFF0000) >> 16
|
||||
|
||||
// Signature of animation callback accepting 2 parameters.
|
||||
typedef int(AnimationCallback)(void* a1, void* a2);
|
||||
|
||||
// Signature of animation callback accepting 3 parameters.
|
||||
typedef int(AnimationCallback3)(void* a1, void* a2, void* a3);
|
||||
|
||||
typedef struct STRUCT_530014_28 {
|
||||
int tile;
|
||||
@@ -133,28 +115,31 @@ int _register_priority(int a1);
|
||||
int reg_anim_clear(Object* a1);
|
||||
int reg_anim_end();
|
||||
int animationIsBusy(Object* a1);
|
||||
int reg_anim_obj_move_to_obj(Object* a1, Object* a2, int actionPoints, int delay);
|
||||
int reg_anim_obj_run_to_obj(Object* owner, Object* destination, int actionPoints, int delay);
|
||||
int reg_anim_obj_move_to_tile(Object* obj, int tile_num, int elev, int actionPoints, int delay);
|
||||
int reg_anim_obj_run_to_tile(Object* obj, int tile_num, int elev, int actionPoints, int delay);
|
||||
int reg_anim_2(Object* obj, int tile_num, int elev, int a4, int a5);
|
||||
int reg_anim_knockdown(Object* obj, int tile, int elev, int anim, int delay);
|
||||
int reg_anim_animate(Object* obj, int anim, int delay);
|
||||
int reg_anim_animate_reverse(Object* obj, int anim, int delay);
|
||||
int reg_anim_6(Object* obj, int anim, int delay);
|
||||
int reg_anim_set_rotation_to_tile(Object* owner, int tile);
|
||||
int reg_anim_rotate_clockwise(Object* obj);
|
||||
int reg_anim_rotate_counter_clockwise(Object* obj);
|
||||
int reg_anim_hide(Object* obj);
|
||||
int reg_anim_11_0(Object* a1, Object* a2, AnimationProc* proc, int delay);
|
||||
int reg_anim_12(Object* a1, Object* a2, void* a3, AnimationProc2* proc, int delay);
|
||||
int reg_anim_11_1(Object* a1, Object* a2, AnimationProc* proc, int delay);
|
||||
int reg_anim_15(Object* obj, int a2, int a3);
|
||||
int reg_anim_17(Object* obj, int fid, int a3);
|
||||
int reg_anim_18(Object* obj, int a2, int a3);
|
||||
int reg_anim_update_light(Object* obj, int fid, int a3);
|
||||
int reg_anim_play_sfx(Object* obj, const char* a2, int a3);
|
||||
int reg_anim_animate_forever(Object* obj, int a2, int a3);
|
||||
int animationRegisterMoveToObject(Object* owner, Object* destination, int actionPoints, int delay);
|
||||
int animationRegisterRunToObject(Object* owner, Object* destination, int actionPoints, int delay);
|
||||
int animationRegisterMoveToTile(Object* owner, int tile, int elevation, int actionPoints, int delay);
|
||||
int animationRegisterRunToTile(Object* owner, int tile, int elevation, int actionPoints, int delay);
|
||||
int animationRegisterMoveToTileStraight(Object* object, int tile, int elevation, int anim, int delay);
|
||||
int animationRegisterMoveToTileStraightAndWaitForComplete(Object* owner, int tile, int elev, int anim, int delay);
|
||||
int animationRegisterAnimate(Object* owner, int anim, int delay);
|
||||
int animationRegisterAnimateReversed(Object* owner, int anim, int delay);
|
||||
int animationRegisterAnimateAndHide(Object* owner, int anim, int delay);
|
||||
int animationRegisterRotateToTile(Object* owner, int tile);
|
||||
int animationRegisterRotateClockwise(Object* owner);
|
||||
int animationRegisterRotateCounterClockwise(Object* owner);
|
||||
int animationRegisterHideObject(Object* object);
|
||||
int animationRegisterHideObjectForced(Object* object);
|
||||
int animationRegisterCallback(void* a1, void* a2, AnimationCallback* proc, int delay);
|
||||
int animationRegisterCallback3(void* a1, void* a2, void* a3, AnimationCallback3* proc, int delay);
|
||||
int animationRegisterCallbackForced(void* a1, void* a2, AnimationCallback* proc, int delay);
|
||||
int animationRegisterSetFlag(Object* object, int flag, int delay);
|
||||
int animationRegisterUnsetFlag(Object* object, int flag, int delay);
|
||||
int animationRegisterSetFid(Object* owner, int fid, int delay);
|
||||
int animationRegisterTakeOutWeapon(Object* owner, int weaponAnimationCode, int delay);
|
||||
int animationRegisterSetLightDistance(Object* owner, int lightDistance, int delay);
|
||||
int animationRegisterToggleOutline(Object* object, bool outline, int delay);
|
||||
int animationRegisterPlaySoundEffect(Object* owner, const char* soundEffectName, int delay);
|
||||
int animationRegisterAnimateForever(Object* owner, int anim, int delay);
|
||||
int reg_anim_26(int a1, int a2);
|
||||
int _make_path(Object* object, int from, int to, unsigned char* a4, int a5);
|
||||
int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotations, int a5, PathBuilderCallback* callback);
|
||||
|
||||
+247
-212
@@ -3,6 +3,7 @@
|
||||
#include "animation.h"
|
||||
#include "debug.h"
|
||||
#include "draw.h"
|
||||
#include "game.h"
|
||||
#include "game_config.h"
|
||||
#include "memory.h"
|
||||
#include "object.h"
|
||||
@@ -126,10 +127,8 @@ static int* gArtCritterFidShoudRunData;
|
||||
int artInit()
|
||||
{
|
||||
char path[COMPAT_MAX_PATH];
|
||||
int i;
|
||||
File* stream;
|
||||
char str[200];
|
||||
char *ptr, *curr;
|
||||
char string[200];
|
||||
|
||||
int cacheSize;
|
||||
if (!configGetInt(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_ART_CACHE_SIZE_KEY, &cacheSize)) {
|
||||
@@ -147,20 +146,20 @@ int artInit()
|
||||
gArtLanguageInitialized = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < 11; i++) {
|
||||
gArtListDescriptions[i].flags = 0;
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[i].name, gArtListDescriptions[i].name);
|
||||
for (int objectType = 0; objectType < OBJ_TYPE_COUNT; objectType++) {
|
||||
gArtListDescriptions[objectType].flags = 0;
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[objectType].name, gArtListDescriptions[objectType].name);
|
||||
|
||||
if (artReadList(path, &(gArtListDescriptions[i].fileNames), &(gArtListDescriptions[i].fileNamesLength)) != 0) {
|
||||
if (artReadList(path, &(gArtListDescriptions[objectType].fileNames), &(gArtListDescriptions[objectType].fileNamesLength)) != 0) {
|
||||
debugPrint("art_read_lst failed in art_init\n");
|
||||
cacheFree(&gArtCache);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
_anon_alias = (int*)internal_malloc(sizeof(*_anon_alias) * gArtListDescriptions[1].fileNamesLength);
|
||||
_anon_alias = (int*)internal_malloc(sizeof(*_anon_alias) * gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength);
|
||||
if (_anon_alias == NULL) {
|
||||
gArtListDescriptions[1].fileNamesLength = 0;
|
||||
gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength = 0;
|
||||
debugPrint("Out of memory for anon_alias in art_init\n");
|
||||
cacheFree(&gArtCache);
|
||||
return -1;
|
||||
@@ -168,17 +167,17 @@ int artInit()
|
||||
|
||||
gArtCritterFidShoudRunData = (int*)internal_malloc(sizeof(*gArtCritterFidShoudRunData) * gArtListDescriptions[1].fileNamesLength);
|
||||
if (gArtCritterFidShoudRunData == NULL) {
|
||||
gArtListDescriptions[1].fileNamesLength = 0;
|
||||
gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength = 0;
|
||||
debugPrint("Out of memory for artCritterFidShouldRunData in art_init\n");
|
||||
cacheFree(&gArtCache);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < gArtListDescriptions[1].fileNamesLength; i++) {
|
||||
gArtCritterFidShoudRunData[i] = 0;
|
||||
for (int critterIndex = 0; critterIndex < gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength; critterIndex++) {
|
||||
gArtCritterFidShoudRunData[critterIndex] = 0;
|
||||
}
|
||||
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[1].name, gArtListDescriptions[1].name);
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[OBJ_TYPE_CRITTER].name, gArtListDescriptions[OBJ_TYPE_CRITTER].name);
|
||||
|
||||
stream = fileOpen(path, "rt");
|
||||
if (stream == NULL) {
|
||||
@@ -206,75 +205,70 @@ int artInit()
|
||||
tribalMaleFileName = gDefaultTribalMaleFileName;
|
||||
}
|
||||
|
||||
char *tribalFemaleFileName = NULL;
|
||||
char* tribalFemaleFileName = NULL;
|
||||
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_TRIBAL_FEMALE_KEY, &tribalFemaleFileName);
|
||||
if (tribalFemaleFileName == NULL || tribalFemaleFileName[0] == '\0') {
|
||||
tribalFemaleFileName = gDefaultTribalFemaleFileName;
|
||||
}
|
||||
|
||||
ptr = gArtListDescriptions[1].fileNames;
|
||||
for (i = 0; i < gArtListDescriptions[1].fileNamesLength; i++) {
|
||||
if (compat_stricmp(ptr, jumpsuitMaleFileName) == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_MALE] = i;
|
||||
} else if (compat_stricmp(ptr, jumpsuitFemaleFileName) == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_FEMALE] = i;
|
||||
char* critterFileNames = gArtListDescriptions[OBJ_TYPE_CRITTER].fileNames;
|
||||
for (int critterIndex = 0; critterIndex < gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength; critterIndex++) {
|
||||
if (compat_stricmp(critterFileNames, "hmjmps") == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_MALE] = critterIndex;
|
||||
} else if (compat_stricmp(critterFileNames, "hfjmps") == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_FEMALE] = critterIndex;
|
||||
}
|
||||
|
||||
if (compat_stricmp(ptr, tribalMaleFileName) == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_MALE] = i;
|
||||
_art_vault_guy_num = i;
|
||||
} else if (compat_stricmp(ptr, tribalFemaleFileName) == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_FEMALE] = i;
|
||||
if (compat_stricmp(critterFileNames, "hmwarr") == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_MALE] = critterIndex;
|
||||
_art_vault_guy_num = critterIndex;
|
||||
} else if (compat_stricmp(critterFileNames, "hfprim") == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_FEMALE] = critterIndex;
|
||||
}
|
||||
|
||||
ptr += 13;
|
||||
critterFileNames += 13;
|
||||
}
|
||||
|
||||
for (i = 0; i < gArtListDescriptions[1].fileNamesLength; i++) {
|
||||
if (!fileReadString(str, sizeof(str), stream)) {
|
||||
for (int critterIndex = 0; critterIndex < gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength; critterIndex++) {
|
||||
if (!fileReadString(string, sizeof(string), stream)) {
|
||||
break;
|
||||
}
|
||||
|
||||
ptr = str;
|
||||
curr = ptr;
|
||||
while (*curr != '\0' && *curr != ',') {
|
||||
curr++;
|
||||
}
|
||||
char* sep1 = strchr(string, ',');
|
||||
if (sep1 != NULL) {
|
||||
_anon_alias[critterIndex] = atoi(sep1 + 1);
|
||||
|
||||
if (*curr != '\0') {
|
||||
_anon_alias[i] = atoi(curr + 1);
|
||||
|
||||
ptr = curr + 1;
|
||||
curr = ptr;
|
||||
while (*curr != '\0' && *curr != ',') {
|
||||
curr++;
|
||||
char* sep2 = strchr(sep1 + 1, ',');
|
||||
if (sep2 != NULL) {
|
||||
gArtCritterFidShoudRunData[critterIndex] = atoi(sep2 + 1);
|
||||
} else {
|
||||
gArtCritterFidShoudRunData[critterIndex] = 0;
|
||||
}
|
||||
|
||||
gArtCritterFidShoudRunData[i] = *curr != '\0' ? atoi(ptr) : 0;
|
||||
} else {
|
||||
_anon_alias[i] = _art_vault_guy_num;
|
||||
gArtCritterFidShoudRunData[i] = 1;
|
||||
_anon_alias[critterIndex] = _art_vault_guy_num;
|
||||
gArtCritterFidShoudRunData[critterIndex] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
ptr = gArtListDescriptions[4].fileNames;
|
||||
for (i = 0; i < gArtListDescriptions[4].fileNamesLength; i++) {
|
||||
if (compat_stricmp(ptr, "grid001.frm") == 0) {
|
||||
_art_mapper_blank_tile = i;
|
||||
char* tileFileNames = gArtListDescriptions[OBJ_TYPE_TILE].fileNames;
|
||||
for (int tileIndex = 0; tileIndex < gArtListDescriptions[OBJ_TYPE_TILE].fileNamesLength; tileIndex++) {
|
||||
if (compat_stricmp(tileFileNames, "grid001.frm") == 0) {
|
||||
_art_mapper_blank_tile = tileIndex;
|
||||
}
|
||||
tileFileNames += 13;
|
||||
}
|
||||
|
||||
gHeadDescriptions = (HeadDescription*)internal_malloc(sizeof(HeadDescription) * gArtListDescriptions[8].fileNamesLength);
|
||||
gHeadDescriptions = (HeadDescription*)internal_malloc(sizeof(*gHeadDescriptions) * gArtListDescriptions[OBJ_TYPE_HEAD].fileNamesLength);
|
||||
if (gHeadDescriptions == NULL) {
|
||||
gArtListDescriptions[8].fileNamesLength = 0;
|
||||
gArtListDescriptions[OBJ_TYPE_HEAD].fileNamesLength = 0;
|
||||
debugPrint("Out of memory for head_info in art_init\n");
|
||||
cacheFree(&gArtCache);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[8].name, gArtListDescriptions[8].name);
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[OBJ_TYPE_HEAD].name, gArtListDescriptions[OBJ_TYPE_HEAD].name);
|
||||
|
||||
stream = fileOpen(path, "rt");
|
||||
if (stream == NULL) {
|
||||
@@ -283,46 +277,42 @@ int artInit()
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < gArtListDescriptions[8].fileNamesLength; i++) {
|
||||
if (!fileReadString(str, sizeof(str), stream)) {
|
||||
for (int headIndex = 0; headIndex < gArtListDescriptions[OBJ_TYPE_HEAD].fileNamesLength; headIndex++) {
|
||||
if (!fileReadString(string, sizeof(string), stream)) {
|
||||
break;
|
||||
}
|
||||
|
||||
ptr = str;
|
||||
curr = ptr;
|
||||
while (*curr != '\0' && *curr != ',') {
|
||||
curr++;
|
||||
char* sep1 = strchr(string, ',');
|
||||
if (sep1 != NULL) {
|
||||
*sep1 = '\0';
|
||||
} else {
|
||||
sep1 = string;
|
||||
}
|
||||
|
||||
if (*curr != '\0') {
|
||||
ptr = curr + 1;
|
||||
curr = ptr;
|
||||
while (*curr != '\0' && *curr != ',') {
|
||||
curr++;
|
||||
}
|
||||
|
||||
if (*curr != '\0') {
|
||||
gHeadDescriptions[i].goodFidgetCount = atoi(ptr);
|
||||
|
||||
ptr = curr + 1;
|
||||
curr = ptr;
|
||||
while (*curr != '\0' && *curr != ',') {
|
||||
curr++;
|
||||
}
|
||||
|
||||
if (*curr != '\0') {
|
||||
gHeadDescriptions[i].neutralFidgetCount = atoi(ptr);
|
||||
|
||||
ptr = curr + 1;
|
||||
curr = strpbrk(ptr, " ,;\t\n");
|
||||
if (curr != NULL) {
|
||||
*curr = '\0';
|
||||
}
|
||||
|
||||
gHeadDescriptions[i].badFidgetCount = atoi(ptr);
|
||||
}
|
||||
}
|
||||
char* sep2 = strchr(sep1, ',');
|
||||
if (sep2 != NULL) {
|
||||
*sep2 = '\0';
|
||||
} else {
|
||||
sep2 = sep1;
|
||||
}
|
||||
|
||||
gHeadDescriptions[headIndex].goodFidgetCount = atoi(sep1 + 1);
|
||||
|
||||
char* sep3 = strchr(sep2, ',');
|
||||
if (sep3 != NULL) {
|
||||
*sep3 = '\0';
|
||||
} else {
|
||||
sep3 = sep2;
|
||||
}
|
||||
|
||||
gHeadDescriptions[headIndex].neutralFidgetCount = atoi(sep2 + 1);
|
||||
|
||||
char* sep4 = strpbrk(sep3 + 1, " ,;\t\n");
|
||||
if (sep4 != NULL) {
|
||||
*sep4 = '\0';
|
||||
}
|
||||
|
||||
gHeadDescriptions[headIndex].badFidgetCount = atoi(sep3 + 1);
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
@@ -357,19 +347,19 @@ void artExit()
|
||||
// 0x418F1C
|
||||
char* artGetObjectTypeName(int objectType)
|
||||
{
|
||||
return objectType >= 0 && objectType < OBJ_TYPE_COUNT ? gArtListDescriptions[objectType].name : NULL;
|
||||
return objectType >= OBJ_TYPE_ITEM && objectType < OBJ_TYPE_COUNT ? gArtListDescriptions[objectType].name : NULL;
|
||||
}
|
||||
|
||||
// 0x418F34
|
||||
int artIsObjectTypeHidden(int objectType)
|
||||
{
|
||||
return objectType >= 0 && objectType < OBJ_TYPE_COUNT ? gArtListDescriptions[objectType].flags & 1 : 0;
|
||||
return objectType >= OBJ_TYPE_ITEM && objectType < OBJ_TYPE_COUNT ? gArtListDescriptions[objectType].flags & 1 : 0;
|
||||
}
|
||||
|
||||
// 0x418F7C
|
||||
int artGetFidgetCount(int headFid)
|
||||
{
|
||||
if ((headFid & 0xF000000) >> 24 != OBJ_TYPE_HEAD) {
|
||||
if (FID_TYPE(headFid) != OBJ_TYPE_HEAD) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -522,15 +512,15 @@ int artCacheFlush()
|
||||
}
|
||||
|
||||
// 0x4192B0
|
||||
int artCopyFileName(int type, int id, char* dest)
|
||||
int artCopyFileName(int objectType, int id, char* dest)
|
||||
{
|
||||
ArtListDescription* ptr;
|
||||
|
||||
if (type < 0 && type >= 11) {
|
||||
if (objectType < OBJ_TYPE_ITEM && objectType >= OBJ_TYPE_COUNT) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr = &(gArtListDescriptions[type]);
|
||||
ptr = &(gArtListDescriptions[objectType]);
|
||||
|
||||
if (id >= ptr->fileNamesLength) {
|
||||
return -1;
|
||||
@@ -622,7 +612,7 @@ char* artBuildFilePath(int fid)
|
||||
|
||||
v10 = (fid & 0x70000000) >> 28;
|
||||
|
||||
v1 = _art_alias_fid(fid);
|
||||
v1 = artAliasFid(fid);
|
||||
if (v1 != -1) {
|
||||
v2 = v1;
|
||||
}
|
||||
@@ -630,15 +620,15 @@ char* artBuildFilePath(int fid)
|
||||
*_art_name = '\0';
|
||||
|
||||
v3 = v2 & 0xFFF;
|
||||
v4 = (v2 & 0xFF0000) >> 16;
|
||||
v4 = FID_ANIM_TYPE(v2);
|
||||
v5 = (v2 & 0xF000) >> 12;
|
||||
type = (v2 & 0xF000000) >> 24;
|
||||
type = FID_TYPE(v2);
|
||||
|
||||
if (v3 >= gArtListDescriptions[type].fileNamesLength) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (type < 0 || type >= 11) {
|
||||
if (type < OBJ_TYPE_ITEM || type >= OBJ_TYPE_COUNT) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -669,44 +659,40 @@ char* artBuildFilePath(int fid)
|
||||
|
||||
// art_read_lst
|
||||
// 0x419664
|
||||
static int artReadList(const char* path, char** out_arr, int* out_count)
|
||||
static int artReadList(const char* path, char** artListPtr, int* artListSizePtr)
|
||||
{
|
||||
File* stream;
|
||||
char str[200];
|
||||
char* arr;
|
||||
int count;
|
||||
char* brk;
|
||||
|
||||
stream = fileOpen(path, "rt");
|
||||
File* stream = fileOpen(path, "rt");
|
||||
if (stream == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
while (fileReadString(str, sizeof(str), stream)) {
|
||||
int count = 0;
|
||||
char string[200];
|
||||
while (fileReadString(string, sizeof(string), stream)) {
|
||||
count++;
|
||||
}
|
||||
|
||||
fileSeek(stream, 0, SEEK_SET);
|
||||
|
||||
*out_count = count;
|
||||
*artListSizePtr = count;
|
||||
|
||||
arr = (char*)internal_malloc(13 * count);
|
||||
*out_arr = arr;
|
||||
if (arr == NULL) {
|
||||
goto err;
|
||||
char* artList = (char*)internal_malloc(13 * count);
|
||||
*artListPtr = artList;
|
||||
if (artList == NULL) {
|
||||
fileClose(stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (fileReadString(str, sizeof(str), stream)) {
|
||||
brk = strpbrk(str, " ,;\r\t\n");
|
||||
while (fileReadString(string, sizeof(string), stream)) {
|
||||
char* brk = strpbrk(string, " ,;\r\t\n");
|
||||
if (brk != NULL) {
|
||||
*brk = '\0';
|
||||
}
|
||||
|
||||
strncpy(arr, str, 12);
|
||||
arr[12] = '\0';
|
||||
strncpy(artList, string, 12);
|
||||
artList[12] = '\0';
|
||||
|
||||
arr += 13;
|
||||
artList += 13;
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
@@ -864,34 +850,24 @@ ArtFrame* artGetFrame(Art* art, int frame, int rotation)
|
||||
// 0x4198C8
|
||||
bool artExists(int fid)
|
||||
{
|
||||
int v3;
|
||||
bool result;
|
||||
bool result = false;
|
||||
int oldDb = -1;
|
||||
|
||||
v3 = -1;
|
||||
result = false;
|
||||
|
||||
if ((fid & 0xF000000) >> 24 == 1) {
|
||||
v3 = _db_current(1);
|
||||
// _db_current(_critter_db_handle);
|
||||
_db_current(0);
|
||||
if (FID_TYPE(fid) == OBJ_TYPE_CRITTER) {
|
||||
oldDb = _db_current(1);
|
||||
_db_current(_critter_db_handle);
|
||||
}
|
||||
|
||||
char* filePath = artBuildFilePath(fid);
|
||||
if (filePath == NULL) {
|
||||
goto out;
|
||||
if (filePath != NULL) {
|
||||
int fileSize;
|
||||
if (dbGetFileSize(filePath, &fileSize) != -1) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
int fileSize;
|
||||
if (dbGetFileSize(filePath, &fileSize) == -1) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = true;
|
||||
|
||||
out:
|
||||
|
||||
if (v3 != -1) {
|
||||
_db_current(v3);
|
||||
if (oldDb != -1) {
|
||||
_db_current(oldDb);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -923,7 +899,7 @@ int _art_alias_num(int index)
|
||||
// 0x4199AC
|
||||
int artCritterFidShouldRun(int fid)
|
||||
{
|
||||
if ((fid & 0xF000000) >> 24 == 1) {
|
||||
if (FID_TYPE(fid) == OBJ_TYPE_CRITTER) {
|
||||
return gArtCritterFidShoudRunData[fid & 0xFFF];
|
||||
}
|
||||
|
||||
@@ -931,64 +907,61 @@ int artCritterFidShouldRun(int fid)
|
||||
}
|
||||
|
||||
// 0x4199D4
|
||||
int _art_alias_fid(int fid)
|
||||
int artAliasFid(int fid)
|
||||
{
|
||||
int v2;
|
||||
int v3;
|
||||
int result;
|
||||
int type = FID_TYPE(fid);
|
||||
int anim = FID_ANIM_TYPE(fid);
|
||||
if (type == OBJ_TYPE_CRITTER) {
|
||||
if (anim == ANIM_ELECTRIFY
|
||||
|| anim == ANIM_BURNED_TO_NOTHING
|
||||
|| anim == ANIM_ELECTRIFIED_TO_NOTHING
|
||||
|| anim == ANIM_ELECTRIFY_SF
|
||||
|| anim == ANIM_BURNED_TO_NOTHING_SF
|
||||
|| anim == ANIM_ELECTRIFIED_TO_NOTHING_SF
|
||||
|| anim == ANIM_FIRE_DANCE
|
||||
|| anim == ANIM_CALLED_SHOT_PIC) {
|
||||
// NOTE: Original code is slightly different. It uses many mutually
|
||||
// mirrored bitwise operators. Probably result of some macros for
|
||||
// getting/setting individual bits on fid.
|
||||
return (fid & 0x70000000) | ((anim << 16) & 0xFF0000) | 0x1000000 | (fid & 0xF000) | (_anon_alias[fid & 0xFFF] & 0xFFF);
|
||||
}
|
||||
}
|
||||
|
||||
v2 = (fid & 0xF000000) >> 24;
|
||||
v3 = (fid & 0xFF0000) >> 16;
|
||||
|
||||
if (v2 != 1 || v3 != 27 && v3 != 29 && v3 != 30 && v3 != 55 && v3 != 57 && v3 != 58 && v3 != 33 && v3 != 64)
|
||||
result = -1;
|
||||
else
|
||||
result = ((fid & 0x70000000) >> 28 << 28) & 0x70000000 | (v3 << 16) & 0xFF0000 | 0x1000000 | (((fid & 0xF000) >> 12) << 12) & 0xF000 | _anon_alias[fid & 0xFFF] & 0xFFF;
|
||||
|
||||
return result;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 0x419A78
|
||||
static int artCacheGetFileSizeImpl(int fid, int* sizePtr)
|
||||
{
|
||||
int v4;
|
||||
char* str;
|
||||
char* ptr;
|
||||
int result;
|
||||
char path[COMPAT_MAX_PATH];
|
||||
bool loaded;
|
||||
int fileSize;
|
||||
int oldDb = -1;
|
||||
int result = -1;
|
||||
|
||||
v4 = -1;
|
||||
result = -1;
|
||||
|
||||
if ((fid & 0xF000000) >> 24 == 1) {
|
||||
v4 = _db_current(1);
|
||||
// _db_current(_critter_db_handle);
|
||||
_db_current(0);
|
||||
if (FID_TYPE(fid) == OBJ_TYPE_CRITTER) {
|
||||
oldDb = _db_current(1);
|
||||
_db_current(_critter_db_handle);
|
||||
}
|
||||
|
||||
str = artBuildFilePath(fid);
|
||||
if (str != NULL) {
|
||||
loaded = false;
|
||||
char* artFilePath = artBuildFilePath(fid);
|
||||
if (artFilePath != NULL) {
|
||||
int fileSize;
|
||||
bool loaded = false;
|
||||
|
||||
if (gArtLanguageInitialized) {
|
||||
ptr = str;
|
||||
while (*ptr != '\0' && *ptr != '\\') {
|
||||
ptr++;
|
||||
char* pch = strchr(artFilePath, '\\');
|
||||
if (pch == NULL) {
|
||||
pch = artFilePath;
|
||||
}
|
||||
|
||||
if (*ptr == '\0') {
|
||||
ptr = str;
|
||||
}
|
||||
char localizedPath[COMPAT_MAX_PATH];
|
||||
sprintf(localizedPath, "art\\%s\\%s", gArtLanguage, pch);
|
||||
|
||||
sprintf(path, "art\\%s\\%s", gArtLanguage, ptr);
|
||||
if (dbGetFileSize(path, &fileSize) == 0) {
|
||||
if (dbGetFileSize(localizedPath, &fileSize) == 0) {
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!loaded) {
|
||||
if (dbGetFileSize(str, &fileSize) == 0) {
|
||||
if (dbGetFileSize(artFilePath, &fileSize) == 0) {
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
@@ -999,8 +972,8 @@ static int artCacheGetFileSizeImpl(int fid, int* sizePtr)
|
||||
}
|
||||
}
|
||||
|
||||
if (v4 != -1) {
|
||||
_db_current(v4);
|
||||
if (oldDb != -1) {
|
||||
_db_current(oldDb);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -1009,43 +982,33 @@ static int artCacheGetFileSizeImpl(int fid, int* sizePtr)
|
||||
// 0x419B78
|
||||
static int artCacheReadDataImpl(int fid, int* sizePtr, unsigned char* data)
|
||||
{
|
||||
int v4;
|
||||
char* str;
|
||||
char* ptr;
|
||||
int result;
|
||||
char path[COMPAT_MAX_PATH];
|
||||
bool loaded;
|
||||
int oldDb = -1;
|
||||
int result = -1;
|
||||
|
||||
v4 = -1;
|
||||
result = -1;
|
||||
|
||||
if ((fid & 0xF000000) >> 24 == 1) {
|
||||
v4 = _db_current(1);
|
||||
// _db_current(_critter_db_handle);
|
||||
_db_current(0);
|
||||
if (FID_TYPE(fid) == OBJ_TYPE_CRITTER) {
|
||||
oldDb = _db_current(1);
|
||||
_db_current(_critter_db_handle);
|
||||
}
|
||||
|
||||
str = artBuildFilePath(fid);
|
||||
if (str != NULL) {
|
||||
loaded = false;
|
||||
char* artFileName = artBuildFilePath(fid);
|
||||
if (artFileName != NULL) {
|
||||
bool loaded = false;
|
||||
if (gArtLanguageInitialized) {
|
||||
ptr = str;
|
||||
while (*ptr != '\0' && *ptr != '\\') {
|
||||
ptr++;
|
||||
char* pch = strchr(artFileName, '\\');
|
||||
if (pch == NULL) {
|
||||
pch = artFileName;
|
||||
}
|
||||
|
||||
if (*ptr == '\0') {
|
||||
ptr = str;
|
||||
}
|
||||
char localizedPath[COMPAT_MAX_PATH];
|
||||
sprintf(localizedPath, "art\\%s\\%s", gArtLanguage, pch);
|
||||
|
||||
sprintf(path, "art\\%s\\%s", gArtLanguage, ptr);
|
||||
if (artRead(str, data) == 0) {
|
||||
if (artRead(localizedPath, data) == 0) {
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!loaded) {
|
||||
if (artRead(str, data) == 0) {
|
||||
if (artRead(artFileName, data) == 0) {
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
@@ -1057,8 +1020,8 @@ static int artCacheReadDataImpl(int fid, int* sizePtr, unsigned char* data)
|
||||
}
|
||||
}
|
||||
|
||||
if (v4 != -1) {
|
||||
_db_current(v4);
|
||||
if (oldDb != -1) {
|
||||
_db_current(oldDb);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -1071,7 +1034,7 @@ static void artCacheFreeImpl(void* ptr)
|
||||
}
|
||||
|
||||
// 0x419C88
|
||||
int buildFid(int objectType, int a2, int anim, int a3, int rotation)
|
||||
int buildFid(int objectType, int frmId, int animType, int a3, int rotation)
|
||||
{
|
||||
int v7, v8, v9, v10;
|
||||
|
||||
@@ -1081,13 +1044,13 @@ int buildFid(int objectType, int a2, int anim, int a3, int rotation)
|
||||
goto zero;
|
||||
}
|
||||
|
||||
if (anim == 33 || anim < 20 || anim > 35) {
|
||||
if (animType == ANIM_FIRE_DANCE || animType < ANIM_FALL_BACK || animType > ANIM_FALL_FRONT_BLOOD) {
|
||||
goto zero;
|
||||
}
|
||||
|
||||
v7 = ((a3 << 12) & 0xF000) | (anim << 16) & 0xFF0000 | 0x1000000;
|
||||
v8 = (rotation << 28) & 0x70000000 | v7;
|
||||
v9 = a2 & 0xFFF;
|
||||
v7 = ((a3 << 12) & 0xF000) | ((animType << 16) & 0xFF0000) | 0x1000000;
|
||||
v8 = ((rotation << 28) & 0x70000000) | v7;
|
||||
v9 = frmId & 0xFFF;
|
||||
|
||||
if (artExists(v9 | v8) != 0) {
|
||||
goto out;
|
||||
@@ -1108,7 +1071,7 @@ zero:
|
||||
|
||||
out:
|
||||
|
||||
return (v10 << 28) & 0x70000000 | (objectType << 24) | (anim << 16) & 0xFF0000 | (a3 << 12) & 0xF000 | a2 & 0xFFF;
|
||||
return ((v10 << 28) & 0x70000000) | (objectType << 24) | ((animType << 16) & 0xFF0000) | ((a3 << 12) & 0xF000) | (frmId & 0xFFF);
|
||||
}
|
||||
|
||||
// 0x419D60
|
||||
@@ -1172,3 +1135,75 @@ int artRead(const char* path, unsigned char* data)
|
||||
fileClose(stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x41A070
|
||||
int artWriteFrameData(unsigned char* data, File* stream, int count)
|
||||
{
|
||||
unsigned char* ptr = data;
|
||||
for (int index = 0; index < count; index++) {
|
||||
ArtFrame* frame = (ArtFrame*)ptr;
|
||||
|
||||
if (fileWriteInt16(stream, frame->width) == -1) return -1;
|
||||
if (fileWriteInt16(stream, frame->height) == -1) return -1;
|
||||
if (fileWriteInt32(stream, frame->size) == -1) return -1;
|
||||
if (fileWriteInt16(stream, frame->x) == -1) return -1;
|
||||
if (fileWriteInt16(stream, frame->y) == -1) return -1;
|
||||
if (fileWrite(ptr + sizeof(ArtFrame), frame->size, 1, stream) != 1) return -1;
|
||||
|
||||
ptr += sizeof(ArtFrame) + frame->size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x41A138
|
||||
int artWriteHeader(Art* art, File* stream)
|
||||
{
|
||||
if (fileWriteInt32(stream, art->field_0) == -1) return -1;
|
||||
if (fileWriteInt16(stream, art->framesPerSecond) == -1) return -1;
|
||||
if (fileWriteInt16(stream, art->actionFrame) == -1) return -1;
|
||||
if (fileWriteInt16(stream, art->frameCount) == -1) return -1;
|
||||
if (fileWriteInt16List(stream, art->xOffsets, ROTATION_COUNT) == -1) return -1;
|
||||
if (fileWriteInt16List(stream, art->yOffsets, ROTATION_COUNT) == -1) return -1;
|
||||
if (fileWriteInt32List(stream, art->dataOffsets, ROTATION_COUNT) == -1) return -1;
|
||||
if (fileWriteInt32(stream, art->field_3A) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x41A1E8
|
||||
int artWrite(const char* path, unsigned char* data)
|
||||
{
|
||||
if (data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
File* stream = fileOpen(path, "wb");
|
||||
if (stream == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Art* art = (Art*)data;
|
||||
if (artWriteHeader(art, stream) == -1) {
|
||||
fileClose(stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int index = 0; index < ROTATION_COUNT; index++) {
|
||||
if (index == 0 || art->dataOffsets[index - 1] != art->dataOffsets[index]) {
|
||||
if (artWriteFrameData(data + sizeof(Art) + art->dataOffsets[index], stream, art->frameCount) != 0) {
|
||||
fileClose(stream);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ unsigned char* artLockFrameData(int fid, int frame, int direction, CacheEntry**
|
||||
unsigned char* artLockFrameDataReturningSize(int fid, CacheEntry** out_cache_entry, int* widthPtr, int* heightPtr);
|
||||
int artUnlock(CacheEntry* cache_entry);
|
||||
int artCacheFlush();
|
||||
int artCopyFileName(int a1, int a2, char* a3);
|
||||
int artCopyFileName(int objectType, int a2, char* a3);
|
||||
int _art_get_code(int a1, int a2, char* a3, char* a4);
|
||||
char* artBuildFilePath(int a1);
|
||||
int artGetFramesPerSecond(Art* art);
|
||||
@@ -144,8 +144,9 @@ bool artExists(int fid);
|
||||
bool _art_fid_valid(int fid);
|
||||
int _art_alias_num(int a1);
|
||||
int artCritterFidShouldRun(int a1);
|
||||
int _art_alias_fid(int a1);
|
||||
int buildFid(int a1, int a2, int a3, int a4, int a5);
|
||||
int artAliasFid(int fid);
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
||||
+3
-3
@@ -302,7 +302,7 @@ void automapShow(bool isInGame, bool isUsingScanner)
|
||||
unsigned char* frmData[AUTOMAP_FRM_COUNT];
|
||||
CacheEntry* frmHandle[AUTOMAP_FRM_COUNT];
|
||||
for (int index = 0; index < AUTOMAP_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, frmIds[index], 0, 0, 0);
|
||||
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) {
|
||||
@@ -482,7 +482,7 @@ static void automapRenderInMapWindow(int window, int elevation, unsigned char* b
|
||||
continue;
|
||||
}
|
||||
|
||||
int objectType = (object->fid & 0xF000000) >> 24;
|
||||
int objectType = FID_TYPE(object->fid);
|
||||
unsigned char objectColor;
|
||||
|
||||
if ((flags & AUTOMAP_IN_GAME) != 0) {
|
||||
@@ -1048,7 +1048,7 @@ static void _decode_map_data(int elevation)
|
||||
if (object->tile != -1 && (object->flags & OBJECT_SEEN) != 0) {
|
||||
int contentType;
|
||||
|
||||
int objectType = (object->fid & 0xF000000) >> 24;
|
||||
int objectType = FID_TYPE(object->fid);
|
||||
if (objectType == OBJ_TYPE_SCENERY && object->pid != PROTO_ID_0x2000158) {
|
||||
contentType = 2;
|
||||
} else if (objectType == OBJ_TYPE_WALL) {
|
||||
|
||||
+1
-1
@@ -5,8 +5,8 @@
|
||||
#include "sound.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// The initial number of cache entries in new cache.
|
||||
|
||||
@@ -1275,7 +1275,7 @@ static int characterEditorWindowInit()
|
||||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, (gCharacterEditorIsCreationMode ? 169 : 177), 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, (gCharacterEditorIsCreationMode ? 169 : 177), 0, 0, 0);
|
||||
gCharacterEditorWindowBackgroundBuffer = artLockFrameDataReturningSize(fid, &gCharacterEditorWindowBackgroundHandle, &(gCharacterEditorFrmSize[0].width), &(gCharacterEditorFrmSize[0].height));
|
||||
if (gCharacterEditorWindowBackgroundBuffer == NULL) {
|
||||
messageListFree(&gCharacterEditorMessageList);
|
||||
@@ -1296,7 +1296,7 @@ static int characterEditorWindowInit()
|
||||
soundContinueAll();
|
||||
|
||||
for (i = 0; i < EDITOR_GRAPHIC_COUNT; i++) {
|
||||
fid = buildFid(6, gCharacterEditorFrmIds[i], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, gCharacterEditorFrmIds[i], 0, 0, 0);
|
||||
gCharacterEditorFrmData[i] = artLockFrameDataReturningSize(fid, &(gCharacterEditorFrmHandle[i]), &(gCharacterEditorFrmSize[i].width), &(gCharacterEditorFrmSize[i].height));
|
||||
if (gCharacterEditorFrmData[i] == NULL) {
|
||||
break;
|
||||
@@ -4892,7 +4892,7 @@ static int characterEditorDrawCardWithOptions(int graphicId, const char* name, c
|
||||
short beginnings[WORD_WRAP_MAX_COUNT];
|
||||
short beginningsCount;
|
||||
|
||||
fid = buildFid(10, graphicId, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_SKILLDEX, graphicId, 0, 0, 0);
|
||||
buf = artLockFrameDataReturningSize(fid, &graphicHandle, &(size.width), &(size.height));
|
||||
if (buf == NULL) {
|
||||
return -1;
|
||||
@@ -5744,7 +5744,7 @@ static int perkDialogShow()
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundWidth;
|
||||
int backgroundHeight;
|
||||
int fid = buildFid(6, 86, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 86, 0, 0, 0);
|
||||
gPerkDialogBackgroundBuffer = artLockFrameDataReturningSize(fid, &backgroundFrmHandle, &backgroundWidth, &backgroundHeight);
|
||||
if (gPerkDialogBackgroundBuffer == NULL) {
|
||||
debugPrint("\n *** Error running perks dialog window ***\n");
|
||||
@@ -5956,7 +5956,7 @@ static int perkDialogHandleInput(int count, void (*refreshProc)())
|
||||
soundPlayFile("ib1p1xx1");
|
||||
rc = 1;
|
||||
} else if (keyCode == 501) {
|
||||
mouseGetPositionInWindow(gPerkDialogWindow , &gCharacterEditorMouseX, &gCharacterEditorMouseY);
|
||||
mouseGetPositionInWindow(gPerkDialogWindow, &gCharacterEditorMouseX, &gCharacterEditorMouseY);
|
||||
gPerkDialogCurrentLine = (gCharacterEditorMouseY - PERK_WINDOW_LIST_Y) / v16;
|
||||
if (gPerkDialogCurrentLine >= 0) {
|
||||
if (count - 1 < gPerkDialogCurrentLine)
|
||||
@@ -6526,7 +6526,7 @@ static int perkDialogOptionCompare(const void* a1, const void* a2)
|
||||
// 0x43DB54
|
||||
static int perkDialogDrawCard(int frmId, const char* name, const char* rank, char* description)
|
||||
{
|
||||
int fid = buildFid(10, frmId, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_SKILLDEX, frmId, 0, 0, 0);
|
||||
|
||||
CacheEntry* handle;
|
||||
int width;
|
||||
@@ -6611,7 +6611,7 @@ static int perkDialogDrawCard(int frmId, const char* name, const char* rank, cha
|
||||
strcpy(gPerkDialogCardTitle, name);
|
||||
gPerkDialogCardFrmId = frmId;
|
||||
gPerkDialogCardDrawn = true;
|
||||
|
||||
|
||||
artUnlock(handle);
|
||||
|
||||
return 0;
|
||||
|
||||
+14
-14
@@ -299,7 +299,7 @@ static bool characterSelectorWindowInit()
|
||||
}
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
backgroundFid = buildFid(6, 174, 0, 0, 0);
|
||||
backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 174, 0, 0, 0);
|
||||
backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -328,13 +328,13 @@ static bool characterSelectorWindowInit()
|
||||
int fid;
|
||||
|
||||
// Setup "Previous" button.
|
||||
fid = buildFid(6, 122, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 122, 0, 0, 0);
|
||||
gCharacterSelectorWindowPreviousButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowPreviousButtonUpFrmHandle);
|
||||
if (gCharacterSelectorWindowPreviousButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 123, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 123, 0, 0, 0);
|
||||
gCharacterSelectorWindowPreviousButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowPreviousButtonDownFrmHandle);
|
||||
if (gCharacterSelectorWindowPreviousButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -360,13 +360,13 @@ static bool characterSelectorWindowInit()
|
||||
buttonSetCallbacks(gCharacterSelectorWindowPreviousButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
// Setup "Next" button.
|
||||
fid = buildFid(6, 124, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 124, 0, 0, 0);
|
||||
gCharacterSelectorWindowNextButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowNextButtonUpFrmHandle);
|
||||
if (gCharacterSelectorWindowNextButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 125, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 125, 0, 0, 0);
|
||||
gCharacterSelectorWindowNextButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowNextButtonDownFrmHandle);
|
||||
if (gCharacterSelectorWindowNextButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -392,13 +392,13 @@ static bool characterSelectorWindowInit()
|
||||
buttonSetCallbacks(gCharacterSelectorWindowNextButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
// Setup "Take" button.
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
gCharacterSelectorWindowTakeButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowTakeButtonUpFrmHandle);
|
||||
if (gCharacterSelectorWindowTakeButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
gCharacterSelectorWindowTakeButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowTakeButtonDownFrmHandle);
|
||||
if (gCharacterSelectorWindowTakeButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -424,12 +424,12 @@ static bool characterSelectorWindowInit()
|
||||
buttonSetCallbacks(gCharacterSelectorWindowTakeButton, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||
|
||||
// Setup "Modify" button.
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
gCharacterSelectorWindowModifyButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowModifyButtonUpFrmHandle);
|
||||
if (gCharacterSelectorWindowModifyButtonUpFrmData == NULL)
|
||||
goto err;
|
||||
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
gCharacterSelectorWindowModifyButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowModifyButtonDownFrmHandle);
|
||||
if (gCharacterSelectorWindowModifyButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -455,13 +455,13 @@ static bool characterSelectorWindowInit()
|
||||
buttonSetCallbacks(gCharacterSelectorWindowModifyButton, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||
|
||||
// Setup "Create" button.
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
gCharacterSelectorWindowCreateButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowCreateButtonUpFrmHandle);
|
||||
if (gCharacterSelectorWindowCreateButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
gCharacterSelectorWindowCreateButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowCreateButtonDownFrmHandle);
|
||||
if (gCharacterSelectorWindowCreateButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -487,13 +487,13 @@ static bool characterSelectorWindowInit()
|
||||
buttonSetCallbacks(gCharacterSelectorWindowCreateButton, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||
|
||||
// Setup "Back" button.
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
gCharacterSelectorWindowBackButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowBackButtonUpFrmHandle);
|
||||
if (gCharacterSelectorWindowBackButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
gCharacterSelectorWindowBackButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowBackButtonDownFrmHandle);
|
||||
if (gCharacterSelectorWindowBackButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -688,7 +688,7 @@ static bool characterSelectorWindowRenderFace()
|
||||
bool success = false;
|
||||
|
||||
CacheEntry* faceFrmHandle;
|
||||
int faceFid = buildFid(6, gPremadeCharacterDescriptions[gCurrentPremadeCharacter].face, 0, 0, 0);
|
||||
int faceFid = buildFid(OBJ_TYPE_INTERFACE, gPremadeCharacterDescriptions[gCurrentPremadeCharacter].face, 0, 0, 0);
|
||||
Art* frm = artLock(faceFid, &faceFrmHandle);
|
||||
if (frm != NULL) {
|
||||
unsigned char* data = artGetFrameData(frm, 0, 0);
|
||||
|
||||
+80
-2
@@ -2,11 +2,19 @@
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define COLOR_PALETTE_STACK_CAPACITY 16
|
||||
|
||||
typedef struct ColorPaletteStackEntry {
|
||||
unsigned char mappedColors[256];
|
||||
unsigned char cmap[768];
|
||||
unsigned char colorTable[32768];
|
||||
} ColorPaletteStackEntry;
|
||||
|
||||
static int colorPaletteFileOpen(const char* filePath, int flags);
|
||||
static int colorPaletteFileRead(int fd, void* buffer, size_t size);
|
||||
static int colorPaletteFileClose(int fd);
|
||||
@@ -25,6 +33,12 @@ static char _aColor_cNoError[] = "color.c: No errors\n";
|
||||
// 0x50F95C
|
||||
static char _aColor_cColorTa[] = "color.c: color table not found\n";
|
||||
|
||||
// 0x50F984
|
||||
static char _aColor_cColorpa[] = "color.c: colorpalettestack overflow";
|
||||
|
||||
// 0x50F9AC
|
||||
static char aColor_cColor_0[] = "color.c: colorpalettestack underflow";
|
||||
|
||||
// 0x51DF10
|
||||
static char* _errorStr = _aColor_cNoError;
|
||||
|
||||
@@ -54,6 +68,9 @@ unsigned char _cmap[768] = {
|
||||
0x3F, 0x3F, 0x3F
|
||||
};
|
||||
|
||||
// 0x673050
|
||||
static ColorPaletteStackEntry* gColorPaletteStack[COLOR_PALETTE_STACK_CAPACITY];
|
||||
|
||||
// 0x673090
|
||||
unsigned char _systemCmap[256 * 3];
|
||||
|
||||
@@ -78,6 +95,9 @@ unsigned char _colorMixMulTable[65536];
|
||||
// 0x6A38D0
|
||||
unsigned char _colorTable[32768];
|
||||
|
||||
// 0x6AB8D0
|
||||
static int gColorPaletteStackSize;
|
||||
|
||||
// 0x6AB928
|
||||
static ColorPaletteFileReadProc* gColorPaletteFileReadProc;
|
||||
|
||||
@@ -572,6 +592,60 @@ void colorSetBrightness(double value)
|
||||
_setSystemPalette(_systemCmap);
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4C8828
|
||||
bool colorPushColorPalette()
|
||||
{
|
||||
if (gColorPaletteStackSize >= COLOR_PALETTE_STACK_CAPACITY) {
|
||||
_errorStr = _aColor_cColorpa;
|
||||
return false;
|
||||
}
|
||||
|
||||
ColorPaletteStackEntry* entry = (ColorPaletteStackEntry*)malloc(sizeof(*entry));
|
||||
gColorPaletteStack[gColorPaletteStackSize] = entry;
|
||||
|
||||
memcpy(entry->mappedColors, _mappedColor, sizeof(_mappedColor));
|
||||
memcpy(entry->cmap, _cmap, sizeof(_cmap));
|
||||
memcpy(entry->colorTable, _colorTable, sizeof(_colorTable));
|
||||
|
||||
gColorPaletteStackSize++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4C88E0
|
||||
bool colorPopColorPalette()
|
||||
{
|
||||
if (gColorPaletteStackSize == 0) {
|
||||
_errorStr = aColor_cColor_0;
|
||||
return false;
|
||||
}
|
||||
|
||||
gColorPaletteStackSize--;
|
||||
|
||||
ColorPaletteStackEntry* entry = gColorPaletteStack[gColorPaletteStackSize];
|
||||
|
||||
memcpy(_mappedColor, entry->mappedColors, sizeof(_mappedColor));
|
||||
memcpy(_cmap, entry->cmap, sizeof(_cmap));
|
||||
memcpy(_colorTable, entry->colorTable, sizeof(_colorTable));
|
||||
|
||||
free(entry);
|
||||
gColorPaletteStack[gColorPaletteStackSize] = NULL;
|
||||
|
||||
_setIntensityTables();
|
||||
|
||||
for (int index = 0; index < 256; index++) {
|
||||
_setMixTableColor(index);
|
||||
}
|
||||
|
||||
_rebuildColorBlendTables();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x4C89CC
|
||||
bool _initColors()
|
||||
{
|
||||
@@ -599,5 +673,9 @@ void _colorsClose()
|
||||
_freeColorBlendTable(index);
|
||||
}
|
||||
|
||||
// TODO: Incomplete.
|
||||
for (int index = 0; index < gColorPaletteStackSize; index++) {
|
||||
free(gColorPaletteStack[index]);
|
||||
}
|
||||
|
||||
gColorPaletteStackSize = 0;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ unsigned char* _getColorBlendTable(int ch);
|
||||
void _freeColorBlendTable(int a1);
|
||||
void colorPaletteSetMemoryProcs(MallocProc* mallocProc, ReallocProc* reallocProc, FreeProc* freeProc);
|
||||
void colorSetBrightness(double value);
|
||||
bool colorPushColorPalette();
|
||||
bool colorPopColorPalette();
|
||||
bool _initColors();
|
||||
void _colorsClose();
|
||||
|
||||
|
||||
+117
-114
@@ -46,8 +46,15 @@
|
||||
#define CALLED_SHOT_WINDOW_WIDTH (504)
|
||||
#define CALLED_SHOT_WINDOW_HEIGHT (309)
|
||||
|
||||
typedef struct CombatAiInfo {
|
||||
Object* friendlyDead;
|
||||
Object* lastTarget;
|
||||
Object* lastItem;
|
||||
int lastMove;
|
||||
} CombatAiInfo;
|
||||
|
||||
static bool _combat_safety_invalidate_weapon_func(Object* critter, Object* weapon, int hitMode, Object* a4, int* a5, Object* a6);
|
||||
static int _combatCopyAIInfo(int a1, int a2);
|
||||
static int aiInfoCopy(int srcIndex, int destIndex);
|
||||
static void _combat_begin(Object* a1);
|
||||
static void _combat_begin_extra(Object* a1);
|
||||
static void _combat_over();
|
||||
@@ -96,7 +103,7 @@ int _combatNumTurns = 0;
|
||||
unsigned int gCombatState = COMBAT_STATE_0x02;
|
||||
|
||||
// 0x510948
|
||||
static STRUCT_510948* _aiInfoList = NULL;
|
||||
static CombatAiInfo* _aiInfoList = NULL;
|
||||
|
||||
// 0x51094C
|
||||
static STRUCT_664980* _gcsd = NULL;
|
||||
@@ -1989,7 +1996,6 @@ int _find_cid(int a1, int cid, Object** critterList, int critterListLength)
|
||||
int combatLoad(File* stream)
|
||||
{
|
||||
int v14;
|
||||
STRUCT_510948* ptr;
|
||||
int a2;
|
||||
Object* obj;
|
||||
int v24;
|
||||
@@ -2001,7 +2007,7 @@ int combatLoad(File* stream)
|
||||
if (!isInCombat()) {
|
||||
obj = objectFindFirst();
|
||||
while (obj != NULL) {
|
||||
if (obj->pid >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (obj->data.critter.combat.whoHitMeCid == -1) {
|
||||
obj->data.critter.combat.whoHitMe = NULL;
|
||||
}
|
||||
@@ -2071,42 +2077,42 @@ int combatLoad(File* stream)
|
||||
internal_free(_aiInfoList);
|
||||
}
|
||||
|
||||
_aiInfoList = (STRUCT_510948*)internal_malloc(sizeof(*_aiInfoList) * _list_total);
|
||||
_aiInfoList = (CombatAiInfo*)internal_malloc(sizeof(*_aiInfoList) * _list_total);
|
||||
if (_aiInfoList == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (v14 = 0; v14 < _list_total; v14++) {
|
||||
ptr = &(_aiInfoList[v14]);
|
||||
CombatAiInfo* aiInfo = &(_aiInfoList[v14]);
|
||||
|
||||
if (fileReadInt32(stream, &a2) == -1) return -1;
|
||||
|
||||
if (a2 == -1) {
|
||||
ptr->field_0 = 0;
|
||||
aiInfo->friendlyDead = NULL;
|
||||
} else {
|
||||
ptr->field_0 = objectFindById(a2);
|
||||
if (ptr->field_0 == NULL) return -1;
|
||||
aiInfo->friendlyDead = objectFindById(a2);
|
||||
if (aiInfo->friendlyDead == NULL) return -1;
|
||||
}
|
||||
|
||||
if (fileReadInt32(stream, &a2) == -1) return -1;
|
||||
|
||||
if (a2 == -1) {
|
||||
ptr->field_4 = 0;
|
||||
aiInfo->lastTarget = NULL;
|
||||
} else {
|
||||
ptr->field_4 = objectFindById(a2);
|
||||
if (ptr->field_4 == NULL) return -1;
|
||||
aiInfo->lastTarget = objectFindById(a2);
|
||||
if (aiInfo->lastTarget == NULL) return -1;
|
||||
}
|
||||
|
||||
if (fileReadInt32(stream, &a2) == -1) return -1;
|
||||
|
||||
if (a2 == -1) {
|
||||
ptr->field_8 = 0;
|
||||
aiInfo->lastItem = NULL;
|
||||
} else {
|
||||
ptr->field_8 = objectFindById(a2);
|
||||
if (ptr->field_8 == NULL) return -1;
|
||||
aiInfo->lastItem = objectFindById(a2);
|
||||
if (aiInfo->lastItem == NULL) return -1;
|
||||
}
|
||||
|
||||
if (fileReadInt32(stream, &(ptr->field_C)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(aiInfo->lastMove)) == -1) return -1;
|
||||
}
|
||||
|
||||
_combat_begin_extra(gDude);
|
||||
@@ -2138,12 +2144,12 @@ int combatSave(File* stream)
|
||||
}
|
||||
|
||||
for (int index = 0; index < _list_total; index++) {
|
||||
STRUCT_510948* ptr = &(_aiInfoList[index]);
|
||||
CombatAiInfo* aiInfo = &(_aiInfoList[index]);
|
||||
|
||||
if (fileWriteInt32(stream, ptr->field_0 != NULL ? ptr->field_0->id : -1) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->field_4 != NULL ? ptr->field_4->id : -1) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->field_8 != NULL ? ptr->field_8->id : -1) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->field_C) == -1) return -1;
|
||||
if (fileWriteInt32(stream, aiInfo->friendlyDead != NULL ? aiInfo->friendlyDead->id : -1) == -1) return -1;
|
||||
if (fileWriteInt32(stream, aiInfo->lastTarget != NULL ? aiInfo->lastTarget->id : -1) == -1) return -1;
|
||||
if (fileWriteInt32(stream, aiInfo->lastItem != NULL ? aiInfo->lastItem->id : -1) == -1) return -1;
|
||||
if (fileWriteInt32(stream, aiInfo->lastMove) == -1) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -2283,24 +2289,21 @@ void _combat_data_init(Object* obj)
|
||||
}
|
||||
|
||||
// 0x421850
|
||||
static int _combatCopyAIInfo(int a1, int a2)
|
||||
static int aiInfoCopy(int srcIndex, int destIndex)
|
||||
{
|
||||
STRUCT_510948* v3;
|
||||
STRUCT_510948* v4;
|
||||
CombatAiInfo* src = &_aiInfoList[srcIndex];
|
||||
CombatAiInfo* dest = &_aiInfoList[destIndex];
|
||||
|
||||
v3 = &_aiInfoList[a1];
|
||||
v4 = &_aiInfoList[a2];
|
||||
|
||||
v4->field_0 = v3->field_0;
|
||||
v4->field_4 = v3->field_4;
|
||||
v4->field_8 = v3->field_8;
|
||||
v4->field_C = v3->field_C;
|
||||
dest->friendlyDead = src->friendlyDead;
|
||||
dest->lastTarget = src->lastTarget;
|
||||
dest->lastItem = src->lastItem;
|
||||
dest->lastMove = src->lastMove;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x421880
|
||||
Object* _combatAIInfoGetFriendlyDead(Object* obj)
|
||||
Object* aiInfoGetFriendlyDead(Object* obj)
|
||||
{
|
||||
if (!isInCombat()) {
|
||||
return NULL;
|
||||
@@ -2314,11 +2317,11 @@ Object* _combatAIInfoGetFriendlyDead(Object* obj)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _aiInfoList[obj->cid].field_0;
|
||||
return _aiInfoList[obj->cid].friendlyDead;
|
||||
}
|
||||
|
||||
// 0x4218AC
|
||||
int _combatAIInfoSetFriendlyDead(Object* a1, Object* a2)
|
||||
int aiInfoSetFriendlyDead(Object* a1, Object* a2)
|
||||
{
|
||||
if (!isInCombat()) {
|
||||
return 0;
|
||||
@@ -2336,13 +2339,13 @@ int _combatAIInfoSetFriendlyDead(Object* a1, Object* a2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
_aiInfoList[a1->cid].field_0 = a2;
|
||||
_aiInfoList[a1->cid].friendlyDead = a2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x4218EC
|
||||
Object* _combatAIInfoGetLastTarget(Object* obj)
|
||||
Object* aiInfoGetLastTarget(Object* obj)
|
||||
{
|
||||
if (!isInCombat()) {
|
||||
return NULL;
|
||||
@@ -2356,11 +2359,11 @@ Object* _combatAIInfoGetLastTarget(Object* obj)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _aiInfoList[obj->cid].field_4;
|
||||
return _aiInfoList[obj->cid].lastTarget;
|
||||
}
|
||||
|
||||
// 0x421918
|
||||
int _combatAIInfoSetLastTarget(Object* a1, Object* a2)
|
||||
int aiInfoSetLastTarget(Object* a1, Object* a2)
|
||||
{
|
||||
if (!isInCombat()) {
|
||||
return 0;
|
||||
@@ -2382,13 +2385,13 @@ int _combatAIInfoSetLastTarget(Object* a1, Object* a2)
|
||||
a2 = NULL;
|
||||
}
|
||||
|
||||
_aiInfoList[a1->cid].field_4 = a2;
|
||||
_aiInfoList[a1->cid].lastTarget = a2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x42196C
|
||||
Object* _combatAIInfoGetLastItem(Object* obj)
|
||||
Object* aiInfoGetLastItem(Object* obj)
|
||||
{
|
||||
int v1;
|
||||
|
||||
@@ -2405,11 +2408,11 @@ Object* _combatAIInfoGetLastItem(Object* obj)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _aiInfoList[v1].field_8;
|
||||
return _aiInfoList[v1].lastItem;
|
||||
}
|
||||
|
||||
// 0x421998
|
||||
int _combatAIInfoSetLastItem(Object* obj, Object* a2)
|
||||
int aiInfoSetLastItem(Object* obj, Object* a2)
|
||||
{
|
||||
int v2;
|
||||
|
||||
@@ -2426,7 +2429,7 @@ int _combatAIInfoSetLastItem(Object* obj, Object* a2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
_aiInfoList[v2].field_8 = NULL;
|
||||
_aiInfoList[v2].lastItem = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2446,24 +2449,24 @@ static void _combat_begin(Object* a1)
|
||||
_list_total = objectListCreate(-1, _combat_elev, OBJ_TYPE_CRITTER, &_combat_list);
|
||||
_list_noncom = _list_total;
|
||||
_list_com = 0;
|
||||
_aiInfoList = (STRUCT_510948*)internal_malloc(sizeof(*_aiInfoList) * _list_total);
|
||||
_aiInfoList = (CombatAiInfo*)internal_malloc(sizeof(*_aiInfoList) * _list_total);
|
||||
if (_aiInfoList == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int index = 0; index < _list_total; index++) {
|
||||
STRUCT_510948* ptr = &(_aiInfoList[index]);
|
||||
ptr->field_0 = NULL;
|
||||
ptr->field_4 = NULL;
|
||||
ptr->field_8 = NULL;
|
||||
ptr->field_C = 0;
|
||||
CombatAiInfo* aiInfo = &(_aiInfoList[index]);
|
||||
aiInfo->friendlyDead = NULL;
|
||||
aiInfo->lastTarget = NULL;
|
||||
aiInfo->lastItem = NULL;
|
||||
aiInfo->lastMove = 0;
|
||||
}
|
||||
|
||||
Object* v1 = NULL;
|
||||
for (int index = 0; index < _list_total; index++) {
|
||||
Object* critter = _combat_list[index];
|
||||
CritterCombatData* combatData = &(critter->data.critter.combat);
|
||||
combatData->maneuver &= 0x01;
|
||||
combatData->maneuver &= CRITTER_MANEUVER_0x01;
|
||||
combatData->damageLastTurn = 0;
|
||||
combatData->whoHitMe = NULL;
|
||||
combatData->ap = 0;
|
||||
@@ -2471,7 +2474,7 @@ static void _combat_begin(Object* a1)
|
||||
|
||||
// NOTE: Not sure about this code, field_C is already reset.
|
||||
if (isInCombat() && critter != NULL && index != -1) {
|
||||
_aiInfoList[index].field_C = 0;
|
||||
_aiInfoList[index].lastMove = 0;
|
||||
}
|
||||
|
||||
scriptSetObjects(critter->sid, NULL, NULL);
|
||||
@@ -2495,16 +2498,16 @@ static void _combat_begin(Object* a1)
|
||||
_gmouse_enable_scrolling();
|
||||
|
||||
if (v1 != NULL && !_isLoadingGame()) {
|
||||
int fid = buildFid((v1->fid & 0xF000000) >> 24,
|
||||
int fid = buildFid(FID_TYPE(v1->fid),
|
||||
100,
|
||||
(v1->fid & 0xFF0000) >> 16,
|
||||
FID_ANIM_TYPE(v1->fid),
|
||||
(v1->fid & 0xF000) >> 12,
|
||||
(v1->fid & 0x70000000) >> 28);
|
||||
|
||||
reg_anim_clear(v1);
|
||||
reg_anim_begin(2);
|
||||
reg_anim_animate(v1, 6, -1);
|
||||
reg_anim_17(v1, fid, -1);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterAnimate(v1, ANIM_UP_STAIRS_RIGHT, -1);
|
||||
animationRegisterSetFid(v1, fid, -1);
|
||||
reg_anim_end();
|
||||
|
||||
while (animationIsBusy(v1)) {
|
||||
@@ -2536,7 +2539,7 @@ static void _combat_begin_extra(Object* a1)
|
||||
// 0x421D50
|
||||
void _combat_update_critter_outline_for_los(Object* critter, bool a2)
|
||||
{
|
||||
if (critter->pid >> 24 != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2636,7 +2639,7 @@ static void _combat_over()
|
||||
for (int index = 0; index < _list_noncom + _list_com; index++) {
|
||||
Object* critter = _combat_list[index];
|
||||
critter->data.critter.combat.damageLastTurn = 0;
|
||||
critter->data.critter.combat.maneuver = 0;
|
||||
critter->data.critter.combat.maneuver = CRITTER_MANEUVER_NONE;
|
||||
}
|
||||
|
||||
for (int index = 0; index < _list_total; index++) {
|
||||
@@ -2649,15 +2652,15 @@ static void _combat_over()
|
||||
scriptSetFixedParam(critter->sid, 0);
|
||||
|
||||
if (critter->pid == 0x1000098 && !critterIsDead(critter) && !_isLoadingGame()) {
|
||||
int fid = buildFid((critter->fid & 0xF000000) >> 24,
|
||||
int fid = buildFid(FID_TYPE(critter->fid),
|
||||
99,
|
||||
(critter->fid & 0xFF0000) >> 16,
|
||||
FID_ANIM_TYPE(critter->fid),
|
||||
(critter->fid & 0xF000) >> 12,
|
||||
(critter->fid & 0x70000000) >> 28);
|
||||
reg_anim_clear(critter);
|
||||
reg_anim_begin(2);
|
||||
reg_anim_animate(critter, 6, -1);
|
||||
reg_anim_17(critter, fid, -1);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterAnimate(critter, ANIM_UP_STAIRS_RIGHT, -1);
|
||||
animationRegisterSetFid(critter, fid, -1);
|
||||
reg_anim_end();
|
||||
|
||||
while (animationIsBusy(critter)) {
|
||||
@@ -2766,7 +2769,7 @@ static void _combat_add_noncoms()
|
||||
for (int index = _list_com; index < _list_com + _list_noncom; index++) {
|
||||
Object* obj = _combat_list[index];
|
||||
if (_combatai_want_to_join(obj)) {
|
||||
obj->data.critter.combat.maneuver = 0;
|
||||
obj->data.critter.combat.maneuver = CRITTER_MANEUVER_NONE;
|
||||
|
||||
Object** objectPtr1 = &(_combat_list[index]);
|
||||
Object** objectPtr2 = &(_combat_list[_list_com]);
|
||||
@@ -3056,7 +3059,7 @@ static void _combat_set_move_all()
|
||||
|
||||
if (isInCombat()) {
|
||||
if (object->cid != -1) {
|
||||
_aiInfoList[object->cid].field_C = 0;
|
||||
_aiInfoList[object->cid].lastMove = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3330,7 +3333,7 @@ void attackInit(Attack* attack, Object* attacker, Object* defender, int hitMode,
|
||||
int _combat_attack(Object* a1, Object* a2, int hitMode, int hitLocation)
|
||||
{
|
||||
if (a1 != gDude && hitMode == HIT_MODE_PUNCH && randomBetween(1, 4) == 1) {
|
||||
int fid = buildFid(1, a1->fid & 0xFFF, ANIM_KICK_LEG, (a1->fid & 0xF000) >> 12, (a1->fid & 0x70000000) >> 28);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, a1->fid & 0xFFF, ANIM_KICK_LEG, (a1->fid & 0xF000) >> 12, (a1->fid & 0x70000000) >> 28);
|
||||
if (artExists(fid)) {
|
||||
hitMode = HIT_MODE_KICK;
|
||||
}
|
||||
@@ -3393,7 +3396,7 @@ int _combat_attack(Object* a1, Object* a2, int hitMode, int hitLocation)
|
||||
|
||||
_combat_call_display = 1;
|
||||
_combat_cleanup_enabled = 1;
|
||||
_combatAIInfoSetLastTarget(a1, a2);
|
||||
aiInfoSetLastTarget(a1, a2);
|
||||
debugPrint("running attack...\n");
|
||||
|
||||
return 0;
|
||||
@@ -3422,7 +3425,7 @@ static bool _check_ranged_miss(Attack* attack)
|
||||
_make_straight_path_func(attack->attacker, curr, to, NULL, &critter, 32, _obj_shoot_blocking_at);
|
||||
if (critter != NULL) {
|
||||
if ((critter->flags & OBJECT_SHOOT_THRU) == 0) {
|
||||
if ((critter->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(critter->fid) != OBJ_TYPE_CRITTER) {
|
||||
roll = ROLL_SUCCESS;
|
||||
break;
|
||||
}
|
||||
@@ -3472,14 +3475,14 @@ static int _shoot_along_path(Attack* attack, int a2, int a3, int anim)
|
||||
|
||||
Object* critter = attack->attacker;
|
||||
while (critter != NULL) {
|
||||
if (v5 <= 0 && anim != ANIM_FIRE_CONTINUOUS || v7 == a2 || attack->extrasLength >= 6) {
|
||||
if ((v5 <= 0 && anim != ANIM_FIRE_CONTINUOUS) || v7 == a2 || attack->extrasLength >= 6) {
|
||||
break;
|
||||
}
|
||||
|
||||
_make_straight_path_func(attack->attacker, v7, a2, NULL, &critter, 32, _obj_shoot_blocking_at);
|
||||
|
||||
if (critter != NULL) {
|
||||
if (((critter->fid & 0xF000000) >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(critter->fid) != OBJ_TYPE_CRITTER) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3619,7 +3622,7 @@ static int _compute_spray(Attack* attack, int accuracy, int* a3, int* a4, int an
|
||||
int v28 = _tile_num_beyond(attack->attacker->tile, v26, range);
|
||||
*a3 += _shoot_along_path(attack, v28, v30, anim);
|
||||
|
||||
if (roll != ROLL_FAILURE || *a3 <= 0 && attack->extrasLength <= 0) {
|
||||
if (roll != ROLL_FAILURE || (*a3 <= 0 && attack->extrasLength <= 0)) {
|
||||
if (roll >= ROLL_SUCCESS && *a3 == 0 && attack->extrasLength == 0) {
|
||||
roll = ROLL_FAILURE;
|
||||
}
|
||||
@@ -3809,7 +3812,7 @@ static int attackCompute(Attack* attack)
|
||||
|
||||
// compute_explosion_on_extras
|
||||
// 0x423C10
|
||||
void _compute_explosion_on_extras(Attack* attack, int a2, int a3, int a4)
|
||||
void _compute_explosion_on_extras(Attack* attack, int a2, bool isGrenade, int a4)
|
||||
{
|
||||
Object* attacker;
|
||||
|
||||
@@ -3852,9 +3855,9 @@ void _compute_explosion_on_extras(Attack* attack, int a2, int a3, int a4)
|
||||
}
|
||||
} else {
|
||||
v22++;
|
||||
if (a3 && _item_w_grenade_dmg_radius(attack->weapon) < v22) {
|
||||
if (isGrenade && _item_w_grenade_dmg_radius(attack->weapon) < v22) {
|
||||
v5 = -1;
|
||||
} else if (a3 || _item_w_rocket_dmg_radius(attack->weapon) >= v22) {
|
||||
} else if (isGrenade || _item_w_rocket_dmg_radius(attack->weapon) >= v22) {
|
||||
v5 = tileGetTileInDirection(v19, ROTATION_NE, 1);
|
||||
} else {
|
||||
v5 = -1;
|
||||
@@ -3869,13 +3872,13 @@ void _compute_explosion_on_extras(Attack* attack, int a2, int a3, int a4)
|
||||
break;
|
||||
}
|
||||
|
||||
Object* v11 = _obj_blocking_at(attacker, v5, attack->attacker->elevation);
|
||||
if (v11 != NULL
|
||||
&& (v11->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER
|
||||
&& (v11->data.critter.combat.results & DAM_DEAD) == 0
|
||||
&& (v11->flags & OBJECT_SHOOT_THRU) == 0
|
||||
&& !_combat_is_shot_blocked(v11, v11->tile, tile, NULL, NULL)) {
|
||||
if (v11 == attack->attacker) {
|
||||
Object* obstacle = _obj_blocking_at(attacker, v5, attack->attacker->elevation);
|
||||
if (obstacle != NULL
|
||||
&& FID_TYPE(obstacle->fid) == OBJ_TYPE_CRITTER
|
||||
&& (obstacle->data.critter.combat.results & DAM_DEAD) == 0
|
||||
&& (obstacle->flags & OBJECT_SHOOT_THRU) == 0
|
||||
&& !_combat_is_shot_blocked(obstacle, obstacle->tile, tile, NULL, NULL)) {
|
||||
if (obstacle == attack->attacker) {
|
||||
attack->attackerFlags &= ~DAM_HIT;
|
||||
attackComputeDamage(attack, 1, 2);
|
||||
attack->attackerFlags |= DAM_HIT;
|
||||
@@ -3883,15 +3886,15 @@ void _compute_explosion_on_extras(Attack* attack, int a2, int a3, int a4)
|
||||
} else {
|
||||
int index;
|
||||
for (index = 0; index < attack->extrasLength; index++) {
|
||||
if (attack->extras[index] == v11) {
|
||||
if (attack->extras[index] == obstacle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == attack->extrasLength) {
|
||||
attack->extrasHitLocation[index] = HIT_LOCATION_TORSO;
|
||||
attack->extras[index] = v11;
|
||||
attackInit(&_explosion_ctd, attack->attacker, v11, attack->hitMode, HIT_LOCATION_TORSO);
|
||||
attack->extras[index] = obstacle;
|
||||
attackInit(&_explosion_ctd, attack->attacker, obstacle, attack->hitMode, HIT_LOCATION_TORSO);
|
||||
if (!a4) {
|
||||
_explosion_ctd.attackerFlags |= DAM_HIT;
|
||||
attackComputeDamage(&_explosion_ctd, 1, 2);
|
||||
@@ -3911,11 +3914,11 @@ void _compute_explosion_on_extras(Attack* attack, int a2, int a3, int a4)
|
||||
static int attackComputeCriticalHit(Attack* attack)
|
||||
{
|
||||
Object* defender = attack->defender;
|
||||
if (defender != NULL && _critter_flag_check(defender->pid, 1024)) {
|
||||
if (defender != NULL && _critter_flag_check(defender->pid, CRITTER_FLAG_0x400)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (defender != NULL && (defender->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (defender != NULL && PID_TYPE(defender->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -3999,7 +4002,7 @@ static int _attackFindInvalidFlags(Object* critter, Object* item)
|
||||
{
|
||||
int flags = 0;
|
||||
|
||||
if (critter != NULL && (critter->pid >> 24) == OBJ_TYPE_CRITTER && _critter_flag_check(critter->pid, 64)) {
|
||||
if (critter != NULL && PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER && _critter_flag_check(critter->pid, CRITTER_FLAG_0x40)) {
|
||||
flags |= DAM_DROP;
|
||||
}
|
||||
|
||||
@@ -4015,7 +4018,7 @@ static int attackComputeCriticalFailure(Attack* attack)
|
||||
{
|
||||
attack->attackerFlags |= DAM_HIT;
|
||||
|
||||
if (attack->attacker != NULL && _critter_flag_check(attack->attacker->pid, 1024)) {
|
||||
if (attack->attacker != NULL && _critter_flag_check(attack->attacker->pid, CRITTER_FLAG_0x400)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4141,7 +4144,7 @@ static int attackDetermineToHit(Object* attacker, int tile, Object* defender, in
|
||||
Object* weapon = critterGetWeaponForHitMode(attacker, hitMode);
|
||||
|
||||
bool targetIsCritter = defender != NULL
|
||||
? ((defender->fid & 0xF000000) >> 24) == OBJ_TYPE_CRITTER
|
||||
? FID_TYPE(defender->fid) == OBJ_TYPE_CRITTER
|
||||
: false;
|
||||
|
||||
bool isRangedWeapon = false;
|
||||
@@ -4323,7 +4326,7 @@ static int attackDetermineToHit(Object* attacker, int tile, Object* defender, in
|
||||
}
|
||||
|
||||
// 0x4247B8
|
||||
static void attackComputeDamage(Attack* attack, int ammoQuantity, int a3)
|
||||
static void attackComputeDamage(Attack* attack, int ammoQuantity, int bonusDamageMultiplier)
|
||||
{
|
||||
int* damagePtr;
|
||||
Object* critter;
|
||||
@@ -4344,7 +4347,7 @@ static void attackComputeDamage(Attack* attack, int ammoQuantity, int a3)
|
||||
|
||||
*damagePtr = 0;
|
||||
|
||||
if ((critter->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(critter->fid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4398,7 +4401,7 @@ static void attackComputeDamage(Attack* attack, int ammoQuantity, int a3)
|
||||
damageResistance = 0;
|
||||
}
|
||||
|
||||
int damageMultiplier = a3 * weaponGetAmmoDamageMultiplier(attack->weapon);
|
||||
int damageMultiplier = bonusDamageMultiplier * weaponGetAmmoDamageMultiplier(attack->weapon);
|
||||
int damageDivisor = weaponGetAmmoDamageDivisor(attack->weapon);
|
||||
|
||||
for (int index = 0; index < ammoQuantity; index++) {
|
||||
@@ -4447,8 +4450,8 @@ static void attackComputeDamage(Attack* attack, int ammoQuantity, int a3)
|
||||
if (knockbackDistancePtr != NULL
|
||||
&& (critter->flags & OBJECT_MULTIHEX) == 0
|
||||
&& (damageType == DAMAGE_TYPE_EXPLOSION || attack->weapon == NULL || weaponGetAttackTypeForHitMode(attack->weapon, attack->hitMode) == ATTACK_TYPE_MELEE)
|
||||
&& (critter->pid >> 24) == OBJ_TYPE_CRITTER
|
||||
&& _critter_flag_check(critter->pid, 0x4000) == 0) {
|
||||
&& PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER
|
||||
&& _critter_flag_check(critter->pid, CRITTER_FLAG_0x4000) == 0) {
|
||||
bool shouldKnockback = true;
|
||||
bool hasStonewall = false;
|
||||
if (critter == gDude) {
|
||||
@@ -4488,7 +4491,7 @@ void attackComputeDeathFlags(Attack* attack)
|
||||
void _apply_damage(Attack* attack, bool animated)
|
||||
{
|
||||
Object* attacker = attack->attacker;
|
||||
bool attackerIsCritter = attacker != NULL && (attacker->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER;
|
||||
bool attackerIsCritter = attacker != NULL && FID_TYPE(attacker->fid) == OBJ_TYPE_CRITTER;
|
||||
bool v5 = attack->defender != attack->oops;
|
||||
|
||||
if (attackerIsCritter && (attacker->data.critter.combat.results & DAM_DEAD) != 0) {
|
||||
@@ -4503,7 +4506,7 @@ void _apply_damage(Attack* attack, bool animated)
|
||||
}
|
||||
|
||||
Object* defender = attack->defender;
|
||||
bool defenderIsCritter = defender != NULL && (defender->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER;
|
||||
bool defenderIsCritter = defender != NULL && FID_TYPE(defender->fid) == OBJ_TYPE_CRITTER;
|
||||
|
||||
if (!defenderIsCritter && !v5) {
|
||||
bool v9 = objectIsPartyMember(attack->defender) && objectIsPartyMember(attack->attacker) ? false : true;
|
||||
@@ -4549,7 +4552,7 @@ void _apply_damage(Attack* attack, bool animated)
|
||||
|
||||
for (int index = 0; index < attack->extrasLength; index++) {
|
||||
Object* obj = attack->extras[index];
|
||||
if ((obj->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER && (obj->data.critter.combat.results & DAM_DEAD) == 0) {
|
||||
if (FID_TYPE(obj->fid) == OBJ_TYPE_CRITTER && (obj->data.critter.combat.results & DAM_DEAD) == 0) {
|
||||
_set_new_results(obj, attack->extrasFlags[index]);
|
||||
|
||||
if (defenderIsCritter) {
|
||||
@@ -4579,8 +4582,8 @@ void _apply_damage(Attack* attack, bool animated)
|
||||
// 0x424EE8
|
||||
static void _check_for_death(Object* object, int damage, int* flags)
|
||||
{
|
||||
if (object == NULL || !_critter_flag_check(object->pid, 0x0400)) {
|
||||
if (object == NULL || (object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (object == NULL || !_critter_flag_check(object->pid, CRITTER_FLAG_0x400)) {
|
||||
if (object == NULL || PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (damage > 0) {
|
||||
if (critterGetHitPoints(object) - damage <= 0) {
|
||||
*flags |= DAM_DEAD;
|
||||
@@ -4597,15 +4600,15 @@ static void _set_new_results(Object* critter, int flags)
|
||||
return;
|
||||
}
|
||||
|
||||
if (((critter->fid & 0xF000000) >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(critter->fid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_critter_flag_check(critter->pid, 0x0400)) {
|
||||
if (_critter_flag_check(critter->pid, CRITTER_FLAG_0x400)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4635,11 +4638,11 @@ static void _damage_object(Object* a1, int damage, bool animated, int a4, Object
|
||||
return;
|
||||
}
|
||||
|
||||
if ((a1->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(a1->fid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_critter_flag_check(a1->pid, 1024)) {
|
||||
if (_critter_flag_check(a1->pid, CRITTER_FLAG_0x400)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4670,7 +4673,7 @@ static void _damage_object(Object* a1, int damage, bool animated, int a4, Object
|
||||
|
||||
if (a1 != gDude) {
|
||||
Object* whoHitMe = a1->data.critter.combat.whoHitMe;
|
||||
if (whoHitMe == gDude || whoHitMe != NULL && whoHitMe->data.critter.combat.team == gDude->data.critter.combat.team) {
|
||||
if (whoHitMe == gDude || (whoHitMe != NULL && whoHitMe->data.critter.combat.team == gDude->data.critter.combat.team)) {
|
||||
bool scriptOverrides = false;
|
||||
Script* scr;
|
||||
if (scriptGetScript(a1->sid, &scr) != -1) {
|
||||
@@ -4764,7 +4767,7 @@ void _combat_display(Attack* attack)
|
||||
&& attack->oops != NULL
|
||||
&& attack->defender != attack->oops
|
||||
&& (attack->attackerFlags & DAM_HIT) != 0) {
|
||||
if ((attack->defender->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(attack->defender->fid) == OBJ_TYPE_CRITTER) {
|
||||
if (attack->oops == gDude) {
|
||||
// 608 (male) - Oops! %s was hit instead of you!
|
||||
// 708 (female) - Oops! %s was hit instead of you!
|
||||
@@ -4820,7 +4823,7 @@ void _combat_display(Attack* attack)
|
||||
if (v21 != NULL && (v21->data.critter.combat.results & DAM_DEAD) == 0) {
|
||||
text[0] = '\0';
|
||||
|
||||
if ((v21->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(v21->fid) == OBJ_TYPE_CRITTER) {
|
||||
if (attack->defenderHitLocation == HIT_LOCATION_TORSO) {
|
||||
if ((attack->attackerFlags & DAM_CRITICAL) != 0) {
|
||||
switch (attack->defenderDamage) {
|
||||
@@ -5233,7 +5236,7 @@ static void _combat_standup(Object* a1)
|
||||
static void _print_tohit(unsigned char* dest, int destPitch, int accuracy)
|
||||
{
|
||||
CacheEntry* numbersFrmHandle;
|
||||
int numbersFrmFid = buildFid(6, 82, 0, 0, 0);
|
||||
int numbersFrmFid = buildFid(OBJ_TYPE_INTERFACE, 82, 0, 0, 0);
|
||||
unsigned char* numbersFrmData = artLockFrameData(numbersFrmFid, 0, 0, &numbersFrmHandle);
|
||||
if (numbersFrmData == NULL) {
|
||||
return;
|
||||
@@ -5325,7 +5328,7 @@ static int calledShotSelectHitLocation(Object* critter, int* hitLocation, int hi
|
||||
|
||||
unsigned char* windowBuffer = windowGetBuffer(gCalledShotWindow);
|
||||
|
||||
fid = buildFid(6, 118, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 118, 0, 0, 0);
|
||||
data = artLockFrameData(fid, 0, 0, &handle);
|
||||
if (data == NULL) {
|
||||
windowDestroy(gCalledShotWindow);
|
||||
@@ -5335,14 +5338,14 @@ static int calledShotSelectHitLocation(Object* critter, int* hitLocation, int hi
|
||||
blitBufferToBuffer(data, CALLED_SHOT_WINDOW_WIDTH, CALLED_SHOT_WINDOW_HEIGHT, CALLED_SHOT_WINDOW_WIDTH, windowBuffer, CALLED_SHOT_WINDOW_WIDTH);
|
||||
artUnlock(handle);
|
||||
|
||||
fid = buildFid(1, critter->fid & 0xFFF, ANIM_CALLED_SHOT_PIC, 0, 0);
|
||||
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);
|
||||
}
|
||||
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
|
||||
CacheEntry* upHandle;
|
||||
unsigned char* up = artLockFrameData(fid, 0, 0, &upHandle);
|
||||
@@ -5351,7 +5354,7 @@ static int calledShotSelectHitLocation(Object* critter, int* hitLocation, int hi
|
||||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
|
||||
CacheEntry* downHandle;
|
||||
unsigned char* down = artLockFrameData(fid, 0, 0, &downHandle);
|
||||
@@ -5710,7 +5713,7 @@ bool _combat_is_shot_blocked(Object* a1, int from, int to, Object* a4, int* a5)
|
||||
while (obstacle != NULL && current != to) {
|
||||
_make_straight_path_func(a1, current, to, 0, &obstacle, 32, _obj_shoot_blocking_at);
|
||||
if (obstacle != NULL) {
|
||||
if ((obstacle->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER && obstacle != a4) {
|
||||
if (FID_TYPE(obstacle->fid) != OBJ_TYPE_CRITTER && obstacle != a4) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -5791,7 +5794,7 @@ void _combat_delete_critter(Object* obj)
|
||||
|
||||
while (i < (_list_total - 1)) {
|
||||
_combat_list[i] = _combat_list[i + 1];
|
||||
_combatCopyAIInfo(i + 1, i);
|
||||
aiInfoCopy(i + 1, i);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -1,8 +1,8 @@
|
||||
#ifndef COMBAT_H
|
||||
#define COMBAT_H
|
||||
|
||||
#include "db.h"
|
||||
#include "combat_defs.h"
|
||||
#include "db.h"
|
||||
#include "obj_types.h"
|
||||
#include "proto_types.h"
|
||||
|
||||
@@ -21,12 +21,12 @@ bool _combat_safety_invalidate_weapon(Object* a1, Object* a2, int hitMode, Objec
|
||||
bool _combatTestIncidentalHit(Object* a1, Object* a2, Object* a3, Object* a4);
|
||||
Object* _combat_whose_turn();
|
||||
void _combat_data_init(Object* obj);
|
||||
Object* _combatAIInfoGetFriendlyDead(Object* obj);
|
||||
int _combatAIInfoSetFriendlyDead(Object* a1, Object* a2);
|
||||
Object* _combatAIInfoGetLastTarget(Object* obj);
|
||||
int _combatAIInfoSetLastTarget(Object* a1, Object* a2);
|
||||
Object* _combatAIInfoGetLastItem(Object* obj);
|
||||
int _combatAIInfoSetLastItem(Object* obj, Object* a2);
|
||||
Object* aiInfoGetFriendlyDead(Object* obj);
|
||||
int aiInfoSetFriendlyDead(Object* a1, Object* a2);
|
||||
Object* aiInfoGetLastTarget(Object* obj);
|
||||
int aiInfoSetLastTarget(Object* a1, Object* a2);
|
||||
Object* aiInfoGetLastItem(Object* obj);
|
||||
int aiInfoSetLastItem(Object* obj, Object* a2);
|
||||
void _combat_update_critter_outline_for_los(Object* critter, bool a2);
|
||||
void _combat_over_from_load();
|
||||
void _combat_give_exps(int exp_points);
|
||||
@@ -35,7 +35,7 @@ void _combat(STRUCT_664980* attack);
|
||||
void attackInit(Attack* attack, Object* a2, Object* a3, int a4, int a5);
|
||||
int _combat_attack(Object* a1, Object* a2, int a3, int a4);
|
||||
int _combat_bullet_start(const Object* a1, const Object* a2);
|
||||
void _compute_explosion_on_extras(Attack* attack, int a2, int a3, int a4);
|
||||
void _compute_explosion_on_extras(Attack* attack, int a2, bool isGrenade, int a4);
|
||||
int _determine_to_hit(Object* a1, Object* a2, int hitLocation, int hitMode);
|
||||
int _determine_to_hit_no_range(Object* a1, Object* a2, int a3, int a4, unsigned char* a5);
|
||||
int _determine_to_hit_from_tile(Object* a1, int a2, Object* a3, int a4, int a5);
|
||||
|
||||
+98
-98
@@ -72,19 +72,19 @@ typedef struct AiPacket {
|
||||
char* general_type;
|
||||
} AiPacket;
|
||||
|
||||
typedef struct STRUCT_832 {
|
||||
Object* field_0;
|
||||
Object* field_4;
|
||||
Object* field_8[100];
|
||||
int field_198[100];
|
||||
int field_328;
|
||||
int field_32C;
|
||||
int field_330;
|
||||
int field_334;
|
||||
int* field_338;
|
||||
int field_33C;
|
||||
int field_340;
|
||||
} STRUCT_832;
|
||||
typedef struct AiRetargetData {
|
||||
Object* source;
|
||||
Object* target;
|
||||
Object* critterList[100];
|
||||
int ratingList[100];
|
||||
int critterCount;
|
||||
int sourceTeam;
|
||||
int sourceRating;
|
||||
bool notSameTile;
|
||||
int* tiles;
|
||||
int currentTileIndex;
|
||||
int sourceIntelligence;
|
||||
} AiRetargetData;
|
||||
|
||||
static void _parse_hurt_str(char* str, int* out_value);
|
||||
static int _cai_match_str_to_list(const char* str, const char** list, int count, int* out_value);
|
||||
@@ -114,8 +114,8 @@ static Object* _ai_search_environ(Object* critter, int itemType);
|
||||
static Object* _ai_retrieve_object(Object* a1, Object* a2);
|
||||
static int _ai_pick_hit_mode(Object* a1, Object* a2, Object* a3);
|
||||
static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a4);
|
||||
static int _cai_retargetTileFromFriendlyFire(Object* a1, Object* a2, int* a3);
|
||||
static int _cai_retargetTileFromFriendlyFireSubFunc(STRUCT_832* a1, int a2);
|
||||
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 int _ai_switch_weapons(Object* a1, int* hitMode, Object** weapon, Object* a4);
|
||||
static int _ai_called_shot(Object* a1, Object* a2, int a3);
|
||||
@@ -568,7 +568,7 @@ int aiLoad(File* stream)
|
||||
{
|
||||
for (int index = 0; index < gPartyMemberDescriptionsLength; index++) {
|
||||
int pid = gPartyMemberPids[index];
|
||||
if (pid != -1 && (pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (pid != -1 && PID_TYPE(pid) == OBJ_TYPE_CRITTER) {
|
||||
Proto* proto;
|
||||
if (protoGetProto(pid, &proto) == -1) {
|
||||
return -1;
|
||||
@@ -589,7 +589,7 @@ int aiSave(File* stream)
|
||||
{
|
||||
for (int index = 0; index < gPartyMemberDescriptionsLength; index++) {
|
||||
int pid = gPartyMemberPids[index];
|
||||
if (pid != -1 && (pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (pid != -1 && PID_TYPE(pid) == OBJ_TYPE_CRITTER) {
|
||||
Proto* proto;
|
||||
if (protoGetProto(pid, &proto) == -1) {
|
||||
return -1;
|
||||
@@ -897,9 +897,9 @@ int aiSetDisposition(Object* obj, int disposition)
|
||||
// 0x428398
|
||||
static int _ai_magic_hands(Object* critter, Object* item, int num)
|
||||
{
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
|
||||
reg_anim_animate(critter, ANIM_MAGIC_HANDS_MIDDLE, 0);
|
||||
animationRegisterAnimate(critter, ANIM_MAGIC_HANDS_MIDDLE, 0);
|
||||
|
||||
if (reg_anim_end() == 0) {
|
||||
if (isInCombat()) {
|
||||
@@ -939,7 +939,7 @@ static int _ai_check_drugs(Object* critter)
|
||||
int v25 = 0;
|
||||
int v28 = 0;
|
||||
int v29 = 0;
|
||||
Object* v3 = _combatAIInfoGetLastItem(critter);
|
||||
Object* v3 = aiInfoGetLastItem(critter);
|
||||
if (v3 == NULL) {
|
||||
AiPacket* ai = aiGetPacket(critter);
|
||||
if (ai == NULL) {
|
||||
@@ -1045,7 +1045,7 @@ static int _ai_check_drugs(Object* critter)
|
||||
critter->data.critter.combat.ap -= 2;
|
||||
}
|
||||
|
||||
if (ai->chem_use == CHEM_USE_SOMETIMES || ai->chem_use == CHEM_USE_ANYTIME && v29 >= 2) {
|
||||
if (ai->chem_use == CHEM_USE_SOMETIMES || (ai->chem_use == CHEM_USE_ANYTIME && v29 >= 2)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1054,7 +1054,7 @@ static int _ai_check_drugs(Object* critter)
|
||||
}
|
||||
}
|
||||
|
||||
if (v3 != NULL || !v28 && v25 == 1) {
|
||||
if (v3 != NULL || (!v28 && v25 == 1)) {
|
||||
do {
|
||||
if (v3 == NULL) {
|
||||
v3 = _ai_search_environ(critter, ITEM_TYPE_DRUG);
|
||||
@@ -1128,9 +1128,9 @@ static void _ai_run_away(Object* a1, Object* a2)
|
||||
}
|
||||
|
||||
if (actionPoints > 0) {
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
_combatai_msg(a1, NULL, AI_MESSAGE_TYPE_RUN, 0);
|
||||
reg_anim_obj_run_to_tile(a1, destination, a1->elevation, combatData->ap, 0);
|
||||
animationRegisterRunToTile(a1, destination, a1->elevation, combatData->ap, 0);
|
||||
if (reg_anim_end() == 0) {
|
||||
_combat_turn_run();
|
||||
}
|
||||
@@ -1175,8 +1175,8 @@ static int _ai_move_away(Object* a1, Object* a2, int a3)
|
||||
}
|
||||
|
||||
if (actionPoints > 0) {
|
||||
reg_anim_begin(2);
|
||||
reg_anim_obj_move_to_tile(a1, destination, a1->elevation, actionPoints, 0);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterMoveToTile(a1, destination, a1->elevation, actionPoints, 0);
|
||||
if (reg_anim_end() == 0) {
|
||||
_combat_turn_run();
|
||||
}
|
||||
@@ -1325,7 +1325,7 @@ static Object* _ai_find_nearest_team(Object* a1, Object* a2, int a3)
|
||||
|
||||
for (i = 0; i < _curr_crit_num; i++) {
|
||||
obj = _curr_crit_list[i];
|
||||
if (a1 != obj && !(obj->data.critter.combat.results & 0x80) && ((a3 & 0x02) && a2->data.critter.combat.team != obj->data.critter.combat.team || (a3 & 0x01) && a2->data.critter.combat.team == obj->data.critter.combat.team)) {
|
||||
if (a1 != obj && !(obj->data.critter.combat.results & 0x80) && (((a3 & 0x02) && a2->data.critter.combat.team != obj->data.critter.combat.team) || ((a3 & 0x01) && a2->data.critter.combat.team == obj->data.critter.combat.team))) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
@@ -1353,8 +1353,8 @@ static Object* _ai_find_nearest_team_in_combat(Object* a1, Object* a2, int a3)
|
||||
Object* obj = _curr_crit_list[index];
|
||||
if (obj != a1
|
||||
&& (obj->data.critter.combat.results & DAM_DEAD) == 0
|
||||
&& ((a3 & 0x02) != 0 && team != obj->data.critter.combat.team
|
||||
|| (a3 & 0x01) != 0 && team == obj->data.critter.combat.team)) {
|
||||
&& (((a3 & 0x02) != 0 && team != obj->data.critter.combat.team)
|
||||
|| ((a3 & 0x01) != 0 && team == obj->data.critter.combat.team))) {
|
||||
if (obj->data.critter.combat.whoHitMe != NULL) {
|
||||
return obj;
|
||||
}
|
||||
@@ -1467,7 +1467,7 @@ static Object* _ai_danger_source(Object* a1)
|
||||
attackWho = aiGetPacket(a1)->attack_who;
|
||||
switch (attackWho) {
|
||||
case ATTACK_WHO_WHOMEVER_ATTACKING_ME: {
|
||||
Object* candidate = _combatAIInfoGetLastTarget(gDude);
|
||||
Object* candidate = aiInfoGetLastTarget(gDude);
|
||||
if (candidate == NULL || a1->data.critter.combat.team == candidate->data.critter.combat.team) {
|
||||
break;
|
||||
}
|
||||
@@ -1560,8 +1560,8 @@ int _caiSetupTeamCombat(Object* a1, Object* a2)
|
||||
|
||||
obj = objectFindFirstAtElevation(a1->elevation);
|
||||
while (obj != NULL) {
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER && obj != gDude) {
|
||||
obj->data.critter.combat.maneuver |= 0x01;
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER && obj != gDude) {
|
||||
obj->data.critter.combat.maneuver |= CRITTER_MANEUVER_0x01;
|
||||
}
|
||||
obj = objectFindNextAtElevation();
|
||||
}
|
||||
@@ -1719,7 +1719,7 @@ static Object* _ai_best_weapon(Object* attacker, Object* weapon1, Object* weapon
|
||||
avgDamage1 = (maxDamage - minDamage) / 2;
|
||||
if (_item_w_area_damage_radius(weapon1, HIT_MODE_RIGHT_WEAPON_PRIMARY) > 0 && defender != NULL) {
|
||||
attack.weapon = weapon1;
|
||||
_compute_explosion_on_extras(&attack, 0, _item_w_is_grenade(weapon1), 1);
|
||||
_compute_explosion_on_extras(&attack, 0, weaponIsGrenade(weapon1), 1);
|
||||
avgDamage1 *= attack.extrasLength + 1;
|
||||
}
|
||||
|
||||
@@ -1763,7 +1763,7 @@ static Object* _ai_best_weapon(Object* attacker, Object* weapon1, Object* weapon
|
||||
avgDamage2 = (maxDamage - minDamage) / 2;
|
||||
if (_item_w_area_damage_radius(weapon2, HIT_MODE_RIGHT_WEAPON_PRIMARY) > 0 && defender != NULL) {
|
||||
attack.weapon = weapon2;
|
||||
_compute_explosion_on_extras(&attack, 0, _item_w_is_grenade(weapon2), 1);
|
||||
_compute_explosion_on_extras(&attack, 0, weaponIsGrenade(weapon2), 1);
|
||||
avgDamage2 *= attack.extrasLength + 1;
|
||||
}
|
||||
|
||||
@@ -1842,7 +1842,7 @@ static bool _ai_can_use_weapon(Object* critter, Object* weapon, int hitMode)
|
||||
int rotation = critter->rotation + 1;
|
||||
int animationCode = weaponGetAnimationCode(weapon);
|
||||
int v9 = weaponGetAnimationForHitMode(weapon, hitMode);
|
||||
int fid = buildFid(1, critter->fid & 0xFFF, v9, animationCode, rotation);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, v9, animationCode, rotation);
|
||||
if (!artExists(fid)) {
|
||||
return false;
|
||||
}
|
||||
@@ -2086,7 +2086,7 @@ static Object* _ai_retrieve_object(Object* a1, Object* a2)
|
||||
a2 = NULL;
|
||||
}
|
||||
|
||||
_combatAIInfoSetLastItem(v3, a2);
|
||||
aiInfoSetLastItem(v3, a2);
|
||||
|
||||
return v3;
|
||||
}
|
||||
@@ -2194,7 +2194,7 @@ static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a
|
||||
return -1;
|
||||
}
|
||||
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
|
||||
if (a4) {
|
||||
_combatai_msg(a1, NULL, AI_MESSAGE_TYPE_MOVE, 0);
|
||||
@@ -2214,7 +2214,7 @@ static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a
|
||||
_moveBlockObj = NULL;
|
||||
if (pathfinderFindPath(a1, a1->tile, a2->tile, NULL, 0, _obj_ai_blocking_at) == 0
|
||||
&& _moveBlockObj != NULL
|
||||
&& (_moveBlockObj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
&& PID_TYPE(_moveBlockObj->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (shouldUnhide) {
|
||||
a2->flags &= ~OBJECT_HIDDEN;
|
||||
}
|
||||
@@ -2240,15 +2240,15 @@ static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a
|
||||
|
||||
if (actionPoints >= critterGetStat(a1, STAT_MAXIMUM_ACTION_POINTS) / 2 && artCritterFidShouldRun(a1->fid)) {
|
||||
if ((a2->flags & OBJECT_MULTIHEX) != 0) {
|
||||
reg_anim_obj_run_to_obj(a1, a2, actionPoints, 0);
|
||||
animationRegisterRunToObject(a1, a2, actionPoints, 0);
|
||||
} else {
|
||||
reg_anim_obj_run_to_tile(a1, tile, a1->elevation, actionPoints, 0);
|
||||
animationRegisterRunToTile(a1, tile, a1->elevation, actionPoints, 0);
|
||||
}
|
||||
} else {
|
||||
if ((a2->flags & OBJECT_MULTIHEX) != 0) {
|
||||
reg_anim_obj_move_to_obj(a1, a2, actionPoints, 0);
|
||||
animationRegisterMoveToObject(a1, a2, actionPoints, 0);
|
||||
} else {
|
||||
reg_anim_obj_move_to_tile(a1, tile, a1->elevation, actionPoints, 0);
|
||||
animationRegisterMoveToTile(a1, tile, a1->elevation, actionPoints, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2262,21 +2262,21 @@ static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a
|
||||
}
|
||||
|
||||
// 0x42A1D4
|
||||
static int _cai_retargetTileFromFriendlyFire(Object* a1, Object* a2, int* a3)
|
||||
static int _cai_retargetTileFromFriendlyFire(Object* source, Object* target, int* tilePtr)
|
||||
{
|
||||
if (a1 == NULL) {
|
||||
if (source == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a2 == NULL) {
|
||||
if (target == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a3 == NULL) {
|
||||
if (tilePtr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*a3 == -1) {
|
||||
if (*tilePtr == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2286,16 +2286,16 @@ static int _cai_retargetTileFromFriendlyFire(Object* a1, Object* a2, int* a3)
|
||||
|
||||
int tiles[32];
|
||||
|
||||
STRUCT_832 v1;
|
||||
v1.field_0 = a1;
|
||||
v1.field_4 = a2;
|
||||
v1.field_32C = a1->data.critter.combat.team;
|
||||
v1.field_330 = _combatai_rating(a1);
|
||||
v1.field_328 = 0;
|
||||
v1.field_338 = tiles;
|
||||
v1.field_334 = *a3 != a1->tile;
|
||||
v1.field_33C = 0;
|
||||
v1.field_340 = critterGetStat(a1, STAT_INTELLIGENCE);
|
||||
AiRetargetData aiRetargetData;
|
||||
aiRetargetData.source = source;
|
||||
aiRetargetData.target = target;
|
||||
aiRetargetData.sourceTeam = source->data.critter.combat.team;
|
||||
aiRetargetData.sourceRating = _combatai_rating(source);
|
||||
aiRetargetData.critterCount = 0;
|
||||
aiRetargetData.tiles = tiles;
|
||||
aiRetargetData.notSameTile = *tilePtr != source->tile;
|
||||
aiRetargetData.currentTileIndex = 0;
|
||||
aiRetargetData.sourceIntelligence = critterGetStat(source, STAT_INTELLIGENCE);
|
||||
|
||||
for (int index = 0; index < 32; index++) {
|
||||
tiles[index] = -1;
|
||||
@@ -2304,23 +2304,23 @@ static int _cai_retargetTileFromFriendlyFire(Object* a1, Object* a2, int* a3)
|
||||
for (int index = 0; index < _curr_crit_num; index++) {
|
||||
Object* obj = _curr_crit_list[index];
|
||||
if ((obj->data.critter.combat.results & DAM_DEAD) == 0
|
||||
&& obj->data.critter.combat.team == v1.field_32C
|
||||
&& _combatAIInfoGetLastTarget(obj) == v1.field_4
|
||||
&& obj != v1.field_0) {
|
||||
int v10 = _combatai_rating(obj);
|
||||
if (v10 >= v1.field_330) {
|
||||
v1.field_8[v1.field_328] = obj;
|
||||
v1.field_198[v1.field_328] = v10;
|
||||
v1.field_328 += 1;
|
||||
&& obj->data.critter.combat.team == aiRetargetData.sourceTeam
|
||||
&& aiInfoGetLastTarget(obj) == aiRetargetData.target
|
||||
&& obj != aiRetargetData.source) {
|
||||
int rating = _combatai_rating(obj);
|
||||
if (rating >= aiRetargetData.sourceRating) {
|
||||
aiRetargetData.critterList[aiRetargetData.critterCount] = obj;
|
||||
aiRetargetData.ratingList[aiRetargetData.critterCount] = rating;
|
||||
aiRetargetData.critterCount += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_combat_obj = a1;
|
||||
_combat_obj = source;
|
||||
|
||||
qsort(v1.field_8, v1.field_328, sizeof(*v1.field_8), _compare_nearer);
|
||||
qsort(aiRetargetData.critterList, aiRetargetData.critterCount, sizeof(*aiRetargetData.critterList), _compare_nearer);
|
||||
|
||||
if (_cai_retargetTileFromFriendlyFireSubFunc(&v1, *a3) == 0) {
|
||||
if (_cai_retargetTileFromFriendlyFireSubFunc(&aiRetargetData, *tilePtr) == 0) {
|
||||
int minDistance = 99999;
|
||||
int minDistanceIndex = -1;
|
||||
|
||||
@@ -2330,8 +2330,8 @@ static int _cai_retargetTileFromFriendlyFire(Object* a1, Object* a2, int* a3)
|
||||
break;
|
||||
}
|
||||
|
||||
if (_obj_blocking_at(NULL, tile, a1->elevation) == 0) {
|
||||
int distance = tileDistanceBetween(*a3, tile);
|
||||
if (_obj_blocking_at(NULL, tile, source->elevation) == 0) {
|
||||
int distance = tileDistanceBetween(*tilePtr, tile);
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance;
|
||||
minDistanceIndex = index;
|
||||
@@ -2340,7 +2340,7 @@ static int _cai_retargetTileFromFriendlyFire(Object* a1, Object* a2, int* a3)
|
||||
}
|
||||
|
||||
if (minDistanceIndex != -1) {
|
||||
*a3 = tiles[minDistanceIndex];
|
||||
*tilePtr = tiles[minDistanceIndex];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2348,24 +2348,24 @@ static int _cai_retargetTileFromFriendlyFire(Object* a1, Object* a2, int* a3)
|
||||
}
|
||||
|
||||
// 0x42A410
|
||||
static int _cai_retargetTileFromFriendlyFireSubFunc(STRUCT_832* a1, int tile)
|
||||
static int _cai_retargetTileFromFriendlyFireSubFunc(AiRetargetData* aiRetargetData, int tile)
|
||||
{
|
||||
if (a1->field_340 <= 0) {
|
||||
if (aiRetargetData->sourceIntelligence <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int distance = 1;
|
||||
|
||||
for (int index = 0; index < a1->field_328; index++) {
|
||||
Object* obj = a1->field_8[index];
|
||||
if (_cai_attackWouldIntersect(obj, a1->field_4, a1->field_0, tile, &distance)) {
|
||||
for (int index = 0; index < aiRetargetData->critterCount; index++) {
|
||||
Object* obj = aiRetargetData->critterList[index];
|
||||
if (_cai_attackWouldIntersect(obj, aiRetargetData->target, aiRetargetData->source, tile, &distance)) {
|
||||
debugPrint("In the way!");
|
||||
|
||||
a1->field_338[a1->field_33C] = tileGetTileInDirection(tile, (obj->rotation + 1) % ROTATION_COUNT, distance);
|
||||
a1->field_338[a1->field_33C + 1] = tileGetTileInDirection(tile, (obj->rotation + 5) % ROTATION_COUNT, distance);
|
||||
aiRetargetData->tiles[aiRetargetData->currentTileIndex] = tileGetTileInDirection(tile, (obj->rotation + 1) % ROTATION_COUNT, distance);
|
||||
aiRetargetData->tiles[aiRetargetData->currentTileIndex + 1] = tileGetTileInDirection(tile, (obj->rotation + 5) % ROTATION_COUNT, distance);
|
||||
|
||||
a1->field_340 -= 2;
|
||||
a1->field_33C += 2;
|
||||
aiRetargetData->sourceIntelligence -= 2;
|
||||
aiRetargetData->currentTileIndex += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2490,8 +2490,8 @@ static int _ai_attack(Object* a1, Object* a2, int a3)
|
||||
return -1;
|
||||
}
|
||||
|
||||
reg_anim_begin(2);
|
||||
reg_anim_set_rotation_to_tile(a1, a2->tile);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterRotateToTile(a1, a2->tile);
|
||||
reg_anim_end();
|
||||
_combat_turn_run();
|
||||
|
||||
@@ -2527,7 +2527,7 @@ static int _ai_try_attack(Object* a1, Object* a2)
|
||||
if (weapon == NULL) {
|
||||
if (critterGetBodyType(a2) != BODY_TYPE_BIPED
|
||||
|| ((a2->fid & 0xF000) >> 12 != 0)
|
||||
|| !artExists(buildFid(1, a1->fid & 0xFFF, ANIM_THROW_PUNCH, 0, a1->rotation + 1))
|
||||
|| !artExists(buildFid(OBJ_TYPE_CRITTER, a1->fid & 0xFFF, ANIM_THROW_PUNCH, 0, a1->rotation + 1))
|
||||
|| _combat_safety_invalidate_weapon(a1, weapon, HIT_MODE_RIGHT_WEAPON_PRIMARY, a2, &v31)) {
|
||||
_ai_switch_weapons(a1, &hitMode, &weapon, a2);
|
||||
}
|
||||
@@ -2813,8 +2813,8 @@ int _cai_perform_distance_prefs(Object* a1, Object* a2)
|
||||
|
||||
int tile = a1->tile;
|
||||
if (_cai_retargetTileFromFriendlyFire(a1, a2, &tile) == 0 && tile != a1->tile) {
|
||||
reg_anim_begin(2);
|
||||
reg_anim_obj_move_to_tile(a1, tile, a1->elevation, a1->data.critter.combat.ap, 0);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterMoveToTile(a1, tile, a1->elevation, a1->data.critter.combat.ap, 0);
|
||||
if (reg_anim_end() != 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -2884,10 +2884,10 @@ void _combat_ai(Object* a1, Object* a2)
|
||||
&& (a1->data.critter.combat.results & DAM_DEAD) == 0
|
||||
&& a1->data.critter.combat.ap != 0
|
||||
&& objectGetDistanceBetween(a1, a2) > ai->max_dist) {
|
||||
Object* v13 = _combatAIInfoGetFriendlyDead(a1);
|
||||
Object* v13 = aiInfoGetFriendlyDead(a1);
|
||||
if (v13 != NULL) {
|
||||
_ai_move_away(a1, v13, 10);
|
||||
_combatAIInfoSetFriendlyDead(a1, NULL);
|
||||
aiInfoSetFriendlyDead(a1, NULL);
|
||||
} else {
|
||||
int perception = critterGetStat(a1, STAT_PERCEPTION);
|
||||
if (!_ai_find_friend(a1, perception * 2, 5)) {
|
||||
@@ -2900,10 +2900,10 @@ void _combat_ai(Object* a1, Object* a2)
|
||||
Object* whoHitMe = combatData->whoHitMe;
|
||||
if (whoHitMe != NULL) {
|
||||
if ((whoHitMe->data.critter.combat.results & DAM_DEAD) == 0 && combatData->damageLastTurn > 0) {
|
||||
Object* v16 = _combatAIInfoGetFriendlyDead(a1);
|
||||
Object* v16 = aiInfoGetFriendlyDead(a1);
|
||||
if (v16 != NULL) {
|
||||
_ai_move_away(a1, v16, 10);
|
||||
_combatAIInfoSetFriendlyDead(a1, NULL);
|
||||
aiInfoSetFriendlyDead(a1, NULL);
|
||||
} else {
|
||||
const char* name = critterGetName(a1);
|
||||
debugPrint("%s: FLEEING: Somebody is shooting at me that I can't see!");
|
||||
@@ -2913,11 +2913,11 @@ void _combat_ai(Object* a1, Object* a2)
|
||||
}
|
||||
}
|
||||
|
||||
Object* v18 = _combatAIInfoGetFriendlyDead(a1);
|
||||
Object* v18 = aiInfoGetFriendlyDead(a1);
|
||||
if (v18 != NULL) {
|
||||
_ai_move_away(a1, v18, 10);
|
||||
if (objectGetDistanceBetween(a1, v18) >= 10) {
|
||||
_combatAIInfoSetFriendlyDead(a1, NULL);
|
||||
aiInfoSetFriendlyDead(a1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3017,7 +3017,7 @@ bool _combatai_want_to_stop(Object* a1)
|
||||
// 0x42B504
|
||||
int critterSetTeam(Object* obj, int team)
|
||||
{
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3036,7 +3036,7 @@ int critterSetTeam(Object* obj, int team)
|
||||
}
|
||||
}
|
||||
|
||||
_combatAIInfoSetLastTarget(obj, NULL);
|
||||
aiInfoSetLastTarget(obj, NULL);
|
||||
|
||||
if (isInCombat()) {
|
||||
bool outlineWasEnabled = obj->outline != 0 && (obj->outline & OUTLINE_DISABLED) == 0;
|
||||
@@ -3065,7 +3065,7 @@ int critterSetTeam(Object* obj, int team)
|
||||
// 0x42B5D4
|
||||
int critterSetAiPacket(Object* object, int aiPacket)
|
||||
{
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -3087,7 +3087,7 @@ int critterSetAiPacket(Object* object, int aiPacket)
|
||||
// 0x42B634
|
||||
int _combatai_msg(Object* a1, Attack* attack, int type, int delay)
|
||||
{
|
||||
if ((a1->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(a1->pid) != OBJ_TYPE_CRITTER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -3162,7 +3162,7 @@ int _combatai_msg(Object* a1, Attack* attack, int type, int delay)
|
||||
strncpy(string, messageListItem.text, 259);
|
||||
|
||||
// TODO: Get rid of casts.
|
||||
return reg_anim_11_0(a1, (Object*)type, (AnimationProc*)_ai_print_msg, delay);
|
||||
return animationRegisterCallback(a1, (void*)type, (AnimationCallback*)_ai_print_msg, delay);
|
||||
}
|
||||
|
||||
// 0x42B80C
|
||||
@@ -3245,7 +3245,7 @@ static int _combatai_rating(Object* obj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((obj->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(obj->fid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3408,7 +3408,7 @@ void _combatai_notify_onlookers(Object* a1)
|
||||
if ((a1->data.critter.combat.results & DAM_DEAD) != 0) {
|
||||
if (!objectCanHearObject(obj, obj->data.critter.combat.whoHitMe)) {
|
||||
debugPrint("\nSomebody Died and I don't know why! Run!!!");
|
||||
_combatAIInfoSetFriendlyDead(obj, a1);
|
||||
aiInfoSetFriendlyDead(obj, a1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,13 +84,6 @@ typedef enum HitLocation {
|
||||
HIT_LOCATION_SPECIFIC_COUNT = HIT_LOCATION_COUNT - 1,
|
||||
} HitLocation;
|
||||
|
||||
typedef struct STRUCT_510948 {
|
||||
Object* field_0;
|
||||
Object* field_4;
|
||||
Object* field_8;
|
||||
int field_C;
|
||||
} STRUCT_510948;
|
||||
|
||||
typedef struct STRUCT_664980 {
|
||||
Object* attacker;
|
||||
Object* defender;
|
||||
|
||||
+31
-57
@@ -81,25 +81,20 @@ bool configParseCommandLineArguments(Config* config, int argc, char** argv)
|
||||
}
|
||||
|
||||
for (int arg = 0; arg < argc; arg++) {
|
||||
char* pch = argv[arg];
|
||||
char* pch;
|
||||
char* string = argv[arg];
|
||||
|
||||
// Find opening bracket.
|
||||
while (*pch != '\0' && *pch != '[') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch == '\0') {
|
||||
pch = strchr(string, '[');
|
||||
if (pch == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char* sectionKey = pch + 1;
|
||||
|
||||
// Find closing bracket.
|
||||
while (*pch != '\0' && *pch != ']') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch == '\0') {
|
||||
pch = strchr(sectionKey, ']');
|
||||
if (pch == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -189,7 +184,7 @@ bool configSetString(Config* config, const char* sectionKey, const char* key, co
|
||||
}
|
||||
|
||||
// 0x42C05C
|
||||
bool configGetInt(Config* config, const char* sectionKey, const char* key, int* valuePtr, unsigned char base /* = 0 */ )
|
||||
bool configGetInt(Config* config, const char* sectionKey, const char* key, int* valuePtr, unsigned char base /* = 0 */)
|
||||
{
|
||||
if (valuePtr == NULL) {
|
||||
return false;
|
||||
@@ -233,36 +228,30 @@ bool configGetIntList(Config* config, const char* sectionKey, const char* key, i
|
||||
}
|
||||
|
||||
char temp[CONFIG_FILE_MAX_LINE_LENGTH];
|
||||
strncpy(temp, string, CONFIG_FILE_MAX_LINE_LENGTH - 1);
|
||||
string = strncpy(temp, string, CONFIG_FILE_MAX_LINE_LENGTH - 1);
|
||||
|
||||
char* beginning = temp;
|
||||
char* pch = beginning;
|
||||
while (*pch != '\0') {
|
||||
if (*pch == ',') {
|
||||
*pch = '\0';
|
||||
|
||||
*arr++ = atoi(beginning);
|
||||
|
||||
*pch = ',';
|
||||
|
||||
pch++;
|
||||
beginning = pch;
|
||||
|
||||
count--;
|
||||
|
||||
if (count < 0) {
|
||||
break;
|
||||
}
|
||||
while (1) {
|
||||
char* pch = strchr(string, ',');
|
||||
if (pch == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
pch++;
|
||||
count--;
|
||||
if (count == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
*pch = '\0';
|
||||
*arr++ = atoi(string);
|
||||
string = pch + 1;
|
||||
}
|
||||
|
||||
if (count <= 1) {
|
||||
*arr = atoi(beginning);
|
||||
*arr = atoi(string);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 0x42C160
|
||||
@@ -383,30 +372,19 @@ static bool configParseLine(Config* config, char* string)
|
||||
char* pch;
|
||||
|
||||
// Find comment marker and truncate the string.
|
||||
pch = string;
|
||||
while (*pch != '\0' && *pch != ';') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch != '\0') {
|
||||
pch = strchr(string, ';');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
}
|
||||
|
||||
// Find opening bracket.
|
||||
pch = string;
|
||||
while (*pch != '\0' && *pch != '[') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch == '[') {
|
||||
pch = strchr(string, '[');
|
||||
if (pch != NULL) {
|
||||
char* sectionKey = pch + 1;
|
||||
|
||||
// Find closing bracket.
|
||||
while (*pch != '\0' && *pch != ']') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch == ']') {
|
||||
pch = strchr(sectionKey, ']');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
strcpy(gConfigLastSectionKey, sectionKey);
|
||||
return configTrimString(gConfigLastSectionKey);
|
||||
@@ -435,12 +413,8 @@ static bool configParseKeyValue(char* string, char* key, char* value)
|
||||
}
|
||||
|
||||
// Find equals character.
|
||||
char* pch = string;
|
||||
while (*pch != '\0' && *pch != '=') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch == '\0') {
|
||||
char* pch = strchr(string, '=');
|
||||
if (pch == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+374
-144
@@ -1,8 +1,8 @@
|
||||
#include "core.h"
|
||||
|
||||
#include "audio_engine.h"
|
||||
#include "config.h"
|
||||
#include "color.h"
|
||||
#include "config.h"
|
||||
#include "dinput.h"
|
||||
#include "draw.h"
|
||||
#include "interface.h"
|
||||
@@ -13,9 +13,9 @@
|
||||
#include "window_manager.h"
|
||||
#include "window_manager_private.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
// NOT USED.
|
||||
void (*_idle_func)() = NULL;
|
||||
@@ -116,39 +116,48 @@ int gModifierKeysState = 0;
|
||||
int (*_kb_scan_to_ascii)() = keyboardDequeueLogicalKeyCode;
|
||||
|
||||
// 0x51E2F0
|
||||
STRUCT_51E2F0* _vcr_buffer = NULL;
|
||||
VcrEntry* _vcr_buffer = NULL;
|
||||
|
||||
// number of entries in _vcr_buffer
|
||||
// 0x51E2F4
|
||||
int _vcr_buffer_index = 0;
|
||||
|
||||
// 0x51E2F8
|
||||
int _vcr_state = 2;
|
||||
unsigned int gVcrState = VCR_STATE_TURNED_OFF;
|
||||
|
||||
// 0x51E2FC
|
||||
int _vcr_time = 0;
|
||||
unsigned int _vcr_time = 0;
|
||||
|
||||
// 0x51E300
|
||||
int _vcr_counter = 0;
|
||||
unsigned int _vcr_counter = 0;
|
||||
|
||||
// 0x51E304
|
||||
int _vcr_terminate_flags = 0;
|
||||
unsigned int gVcrTerminateFlags = 0;
|
||||
|
||||
// 0x51E308
|
||||
int _vcr_terminated_condition = 0;
|
||||
int gVcrPlaybackCompletionReason = VCR_PLAYBACK_COMPLETION_REASON_NONE;
|
||||
|
||||
// 0x51E30C
|
||||
int _vcr_start_time = 0;
|
||||
unsigned int _vcr_start_time = 0;
|
||||
|
||||
// 0x51E310
|
||||
int _vcr_registered_atexit = 0;
|
||||
|
||||
// 0x51E314
|
||||
File* _vcr_file = NULL;
|
||||
File* gVcrFile = NULL;
|
||||
|
||||
// 0x51E318
|
||||
int _vcr_buffer_end = 0;
|
||||
|
||||
// 0x51E31C
|
||||
VcrPlaybackCompletionCallback* gVcrPlaybackCompletionCallback = NULL;
|
||||
|
||||
// 0x51E320
|
||||
unsigned int gVcrRequestedTerminationFlags = 0;
|
||||
|
||||
// 0x51E324
|
||||
int gVcrOldKeyboardLayout = 0;
|
||||
|
||||
// A map of SDL_SCANCODE_* constants normalized for QWERTY keyboard.
|
||||
//
|
||||
// 0x6ABC70
|
||||
@@ -355,6 +364,9 @@ int gKeyboardLayout;
|
||||
// 0x6AD93C
|
||||
unsigned char gPressedPhysicalKeysCount;
|
||||
|
||||
// 0x6AD940
|
||||
VcrEntry stru_6AD940;
|
||||
|
||||
SDL_Window* gSdlWindow = NULL;
|
||||
SDL_Surface* gSdlSurface = NULL;
|
||||
SDL_Renderer* gSdlRenderer = NULL;
|
||||
@@ -446,7 +458,7 @@ void _process_bk()
|
||||
|
||||
tickersExecute();
|
||||
|
||||
if (_vcr_update() != 3) {
|
||||
if (vcrUpdate() != 3) {
|
||||
_mouse_info();
|
||||
}
|
||||
|
||||
@@ -629,31 +641,37 @@ void pauseGame()
|
||||
// 0x4C8E38
|
||||
int pauseHandlerDefaultImpl()
|
||||
{
|
||||
int len;
|
||||
int v1;
|
||||
int v2;
|
||||
int win;
|
||||
unsigned char* buf;
|
||||
int v6;
|
||||
int v7;
|
||||
int windowWidth = fontGetStringWidth("Paused") + 32;
|
||||
int windowHeight = 3 * fontGetLineHeight() + 16;
|
||||
|
||||
len = fontGetStringWidth("Paused") + 32;
|
||||
v1 = fontGetLineHeight();
|
||||
v2 = 3 * v1 + 16;
|
||||
|
||||
win = windowCreate((_scr_size.right - _scr_size.left + 1 - len) / 2, (_scr_size.bottom - _scr_size.top + 1 - v2) / 2, len, v2, 256, 20);
|
||||
int win = windowCreate((rectGetWidth(&_scr_size) - windowWidth) / 2,
|
||||
(rectGetHeight(&_scr_size) - windowHeight) / 2,
|
||||
windowWidth,
|
||||
windowHeight,
|
||||
256,
|
||||
WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
|
||||
if (win == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
windowDrawBorder(win);
|
||||
buf = windowGetBuffer(win);
|
||||
fontDrawText(buf + 8 * len + 16, "Paused", len, len, _colorTable[31744]);
|
||||
|
||||
v6 = v2 - 8 - v1;
|
||||
v7 = fontGetStringWidth("Done");
|
||||
// TODO: Incomplete.
|
||||
// _win_register_text_button(win, (len - v7 - 16) / 2, v6 - 6, -1, -1, -1, 27, "Done", 0);
|
||||
unsigned char* windowBuffer = windowGetBuffer(win);
|
||||
fontDrawText(windowBuffer + 8 * windowWidth + 16,
|
||||
"Paused",
|
||||
windowWidth,
|
||||
windowWidth,
|
||||
_colorTable[31744]);
|
||||
|
||||
_win_register_text_button(win,
|
||||
(windowWidth - fontGetStringWidth("Done") - 16) / 2,
|
||||
windowHeight - 8 - fontGetLineHeight() - 6,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
KEY_ESCAPE,
|
||||
"Done",
|
||||
0);
|
||||
|
||||
windowRefresh(win);
|
||||
|
||||
@@ -720,7 +738,7 @@ int screenshotHandlerDefaultImpl(int width, int height, unsigned char* data, uns
|
||||
|
||||
for (index = 0; index < 100000; index++) {
|
||||
sprintf(fileName, "scr%.5d.bmp", index);
|
||||
|
||||
|
||||
stream = compat_fopen(fileName, "rb");
|
||||
if (stream == NULL) {
|
||||
break;
|
||||
@@ -784,7 +802,7 @@ int screenshotHandlerDefaultImpl(int width, int height, unsigned char* data, uns
|
||||
// biCompression
|
||||
intValue = 0;
|
||||
fwrite(&intValue, sizeof(intValue), 1, stream);
|
||||
|
||||
|
||||
// biSizeImage
|
||||
intValue = 0;
|
||||
fwrite(&intValue, sizeof(intValue), 1, stream);
|
||||
@@ -1254,6 +1272,11 @@ void _GNW95_process_message()
|
||||
// The data is accumulated in SDL itself and will be processed
|
||||
// in `_mouse_info`.
|
||||
break;
|
||||
case SDL_FINGERDOWN:
|
||||
case SDL_FINGERMOTION:
|
||||
case SDL_FINGERUP:
|
||||
handleTouchFingerEvent(&(e.tfinger));
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
if (!keyboardIsDisabled()) {
|
||||
@@ -1324,10 +1347,10 @@ void _GNW95_process_key(KeyboardData* data)
|
||||
{
|
||||
data->key = gNormalizedQwertyKeys[data->key];
|
||||
|
||||
if (_vcr_state == 1) {
|
||||
if (_vcr_terminate_flags & 1) {
|
||||
_vcr_terminated_condition = 2;
|
||||
_vcr_stop();
|
||||
if (gVcrState == VCR_STATE_PLAYING) {
|
||||
if ((gVcrTerminateFlags & VCR_TERMINATE_ON_KEY_PRESS) != 0) {
|
||||
gVcrPlaybackCompletionReason = VCR_PLAYBACK_COMPLETION_REASON_TERMINATED;
|
||||
vcrStop();
|
||||
}
|
||||
} else {
|
||||
STRUCT_6ABF50* ptr = &(_GNW95_key_time_stamps[data->key]);
|
||||
@@ -1643,10 +1666,11 @@ void _mouse_info()
|
||||
x = (int)(x * gMouseSensitivity);
|
||||
y = (int)(y * gMouseSensitivity);
|
||||
|
||||
if (_vcr_state == 1) {
|
||||
if (((_vcr_terminate_flags & 4) && buttons) || ((_vcr_terminate_flags & 2) && (x || y))) {
|
||||
_vcr_terminated_condition = 2;
|
||||
_vcr_stop();
|
||||
if (gVcrState == VCR_STATE_PLAYING) {
|
||||
if (((gVcrTerminateFlags & VCR_TERMINATE_ON_MOUSE_PRESS) != 0 && buttons != 0)
|
||||
|| ((gVcrTerminateFlags & VCR_TERMINATE_ON_MOUSE_MOVE) != 0 && (x != 0 || y != 0))) {
|
||||
gVcrPlaybackCompletionReason = VCR_PLAYBACK_COMPLETION_REASON_TERMINATED;
|
||||
vcrStop();
|
||||
return;
|
||||
}
|
||||
x = 0;
|
||||
@@ -1665,18 +1689,18 @@ void _mouse_simulate_input(int delta_x, int delta_y, int buttons)
|
||||
}
|
||||
|
||||
if (delta_x || delta_y || buttons != gMouseButtonsState) {
|
||||
if (_vcr_state == 0) {
|
||||
if (_vcr_buffer_index == 4095) {
|
||||
_vcr_dump_buffer();
|
||||
if (gVcrState == 0) {
|
||||
if (_vcr_buffer_index == VCR_BUFFER_CAPACITY - 1) {
|
||||
vcrDump();
|
||||
}
|
||||
|
||||
STRUCT_51E2F0* ptr = &(_vcr_buffer[_vcr_buffer_index]);
|
||||
ptr->type = 3;
|
||||
ptr->field_4 = _vcr_time;
|
||||
ptr->field_8 = _vcr_counter;
|
||||
ptr->dx = delta_x;
|
||||
ptr->dy = delta_y;
|
||||
ptr->buttons = buttons;
|
||||
VcrEntry* vcrEntry = &(_vcr_buffer[_vcr_buffer_index]);
|
||||
vcrEntry->type = VCR_ENTRY_TYPE_MOUSE_EVENT;
|
||||
vcrEntry->time = _vcr_time;
|
||||
vcrEntry->counter = _vcr_counter;
|
||||
vcrEntry->mouseEvent.dx = delta_x;
|
||||
vcrEntry->mouseEvent.dy = delta_y;
|
||||
vcrEntry->mouseEvent.buttons = buttons;
|
||||
|
||||
_vcr_buffer_index++;
|
||||
}
|
||||
@@ -1996,10 +2020,10 @@ int _GNW95_init_mode_ex(int width, int height, int bpp)
|
||||
_zero_mem = _GNW95_zero_vid_mem;
|
||||
_mouse_blit = _GNW95_ShowRect;
|
||||
} else {
|
||||
_zero_mem = NULL;
|
||||
_mouse_blit = _GNW95_MouseShowRect16;
|
||||
_mouse_blit_trans = _GNW95_MouseShowTransRect16;
|
||||
_scr_blit = _GNW95_ShowRect16;
|
||||
_zero_mem = NULL;
|
||||
_mouse_blit = _GNW95_MouseShowRect16;
|
||||
_mouse_blit_trans = _GNW95_MouseShowTransRect16;
|
||||
_scr_blit = _GNW95_ShowRect16;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -2036,7 +2060,7 @@ int _GNW95_init_window(int width, int height, bool fullscreen)
|
||||
if (gSdlRenderer == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
if (SDL_RenderSetLogicalSize(gSdlRenderer, width, height) != 0) {
|
||||
goto err;
|
||||
}
|
||||
@@ -2214,7 +2238,7 @@ void directDrawSetPaletteInRange(unsigned char* palette, int start, int count)
|
||||
void directDrawSetPalette(unsigned char* palette)
|
||||
{
|
||||
if (gSdlSurface != NULL && gSdlSurface->format->palette != NULL) {
|
||||
SDL_Color colors[256];
|
||||
SDL_Color colors[256];
|
||||
|
||||
for (int index = 0; index < 256; index++) {
|
||||
colors[index].r = palette[index * 3] << 2;
|
||||
@@ -2251,7 +2275,6 @@ void directDrawSetPalette(unsigned char* palette)
|
||||
windowRefreshAll(&_scr_size);
|
||||
}
|
||||
|
||||
|
||||
if (_update_palette_func != NULL) {
|
||||
_update_palette_func();
|
||||
}
|
||||
@@ -2555,13 +2578,14 @@ int keyboardGetLayout()
|
||||
// TODO: Key type is likely short.
|
||||
void _kb_simulate_key(KeyboardData* data)
|
||||
{
|
||||
if (_vcr_state == 0) {
|
||||
if (_vcr_buffer_index != 4095) {
|
||||
STRUCT_51E2F0* ptr = &(_vcr_buffer[_vcr_buffer_index]);
|
||||
ptr->type = 2;
|
||||
ptr->type_2_field_C = data->key & 0xFFFF;
|
||||
ptr->field_4 = _vcr_time;
|
||||
ptr->field_8 = _vcr_counter;
|
||||
if (gVcrState == 0) {
|
||||
if (_vcr_buffer_index != VCR_BUFFER_CAPACITY - 1) {
|
||||
VcrEntry* vcrEntry = &(_vcr_buffer[_vcr_buffer_index]);
|
||||
vcrEntry->type = VCR_ENTRY_TYPE_KEYBOARD_EVENT;
|
||||
vcrEntry->keyboardEvent.key = data->key & 0xFFFF;
|
||||
vcrEntry->time = _vcr_time;
|
||||
vcrEntry->counter = _vcr_counter;
|
||||
|
||||
_vcr_buffer_index++;
|
||||
}
|
||||
}
|
||||
@@ -4359,9 +4383,9 @@ int keyboardPeekEvent(int index, KeyboardEvent** keyboardEventPtr)
|
||||
}
|
||||
|
||||
// 0x4D2680
|
||||
bool _vcr_record(const char* fileName)
|
||||
bool vcrRecord(const char* fileName)
|
||||
{
|
||||
if (_vcr_state != 2) {
|
||||
if (gVcrState != VCR_STATE_TURNED_OFF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4369,77 +4393,260 @@ bool _vcr_record(const char* fileName)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_vcr_buffer != NULL) {
|
||||
// NOTE: Uninline.
|
||||
if (!vcrInitBuffer()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_vcr_buffer = (STRUCT_51E2F0*)internal_malloc(sizeof(*_vcr_buffer) * 4096);
|
||||
if (_vcr_buffer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_vcr_clear_buffer();
|
||||
|
||||
_vcr_file = fileOpen(fileName, "wb");
|
||||
if (_vcr_file == NULL) {
|
||||
if (_vcr_buffer != NULL) {
|
||||
_vcr_clear_buffer();
|
||||
internal_free(_vcr_buffer);
|
||||
_vcr_buffer = NULL;
|
||||
}
|
||||
gVcrFile = fileOpen(fileName, "wb");
|
||||
if (gVcrFile == NULL) {
|
||||
// NOTE: Uninline.
|
||||
vcrFreeBuffer();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_vcr_registered_atexit == 0) {
|
||||
_vcr_registered_atexit = atexit(_vcr_stop);
|
||||
_vcr_registered_atexit = atexit(vcrStop);
|
||||
}
|
||||
|
||||
STRUCT_51E2F0* entry = &(_vcr_buffer[_vcr_buffer_index]);
|
||||
entry->type = 1;
|
||||
entry->field_4 = 0;
|
||||
entry->field_8 = 0;
|
||||
entry->type_1_field_14 = keyboardGetLayout();
|
||||
VcrEntry* vcrEntry = &(_vcr_buffer[_vcr_buffer_index]);
|
||||
vcrEntry->type = VCR_ENTRY_TYPE_INITIAL_STATE;
|
||||
vcrEntry->time = 0;
|
||||
vcrEntry->counter = 0;
|
||||
vcrEntry->initial.keyboardLayout = keyboardGetLayout();
|
||||
|
||||
while (mouseGetEvent() != 0) {
|
||||
_mouse_info();
|
||||
}
|
||||
|
||||
mouseGetPosition(&(entry->type_1_field_C), &(entry->type_1_field_10));
|
||||
mouseGetPosition(&(vcrEntry->initial.mouseX), &(vcrEntry->initial.mouseY));
|
||||
|
||||
_vcr_counter = 1;
|
||||
_vcr_buffer_index++;
|
||||
_vcr_start_time = _get_time();
|
||||
keyboardReset();
|
||||
_vcr_state = 0;
|
||||
|
||||
gVcrState = VCR_STATE_RECORDING;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x4D27EC
|
||||
bool vcrPlay(const char* fileName, unsigned int terminationFlags, VcrPlaybackCompletionCallback* callback)
|
||||
{
|
||||
if (gVcrState != VCR_STATE_TURNED_OFF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fileName == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
if (!vcrInitBuffer()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
gVcrFile = fileOpen(fileName, "rb");
|
||||
if (gVcrFile == NULL) {
|
||||
// NOTE: Uninline.
|
||||
vcrFreeBuffer();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vcrLoad()) {
|
||||
fileClose(gVcrFile);
|
||||
// NOTE: Uninline.
|
||||
vcrFreeBuffer();
|
||||
return false;
|
||||
}
|
||||
|
||||
while (mouseGetEvent() != 0) {
|
||||
_mouse_info();
|
||||
}
|
||||
|
||||
keyboardReset();
|
||||
|
||||
gVcrRequestedTerminationFlags = terminationFlags;
|
||||
gVcrPlaybackCompletionCallback = callback;
|
||||
gVcrPlaybackCompletionReason = VCR_PLAYBACK_COMPLETION_REASON_COMPLETED;
|
||||
gVcrTerminateFlags = 0;
|
||||
_vcr_counter = 0;
|
||||
_vcr_time = 0;
|
||||
_vcr_start_time = _get_time();
|
||||
gVcrState = VCR_STATE_PLAYING;
|
||||
stru_6AD940.time = 0;
|
||||
stru_6AD940.counter = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x4D28F4
|
||||
void _vcr_stop()
|
||||
void vcrStop()
|
||||
{
|
||||
if (_vcr_state == 0 || _vcr_state == 1) {
|
||||
_vcr_state |= 0x80000000;
|
||||
if (gVcrState == VCR_STATE_RECORDING || gVcrState == VCR_STATE_PLAYING) {
|
||||
gVcrState |= VCR_STATE_STOP_REQUESTED;
|
||||
}
|
||||
|
||||
keyboardReset();
|
||||
}
|
||||
|
||||
// 0x4D2918
|
||||
int _vcr_status()
|
||||
int vcrGetState()
|
||||
{
|
||||
return _vcr_state;
|
||||
return gVcrState;
|
||||
}
|
||||
|
||||
// 0x4D2930
|
||||
int _vcr_update()
|
||||
int vcrUpdate()
|
||||
{
|
||||
// TODO: Incomplete.
|
||||
if ((gVcrState & VCR_STATE_STOP_REQUESTED) != 0) {
|
||||
gVcrState &= ~VCR_STATE_STOP_REQUESTED;
|
||||
|
||||
switch (gVcrState) {
|
||||
case VCR_STATE_RECORDING:
|
||||
vcrDump();
|
||||
|
||||
fileClose(gVcrFile);
|
||||
gVcrFile = NULL;
|
||||
|
||||
// NOTE: Uninline.
|
||||
vcrFreeBuffer();
|
||||
|
||||
break;
|
||||
case VCR_STATE_PLAYING:
|
||||
fileClose(gVcrFile);
|
||||
gVcrFile = NULL;
|
||||
|
||||
// NOTE: Uninline.
|
||||
vcrFreeBuffer();
|
||||
|
||||
keyboardSetLayout(gVcrOldKeyboardLayout);
|
||||
|
||||
if (gVcrPlaybackCompletionCallback != NULL) {
|
||||
gVcrPlaybackCompletionCallback(gVcrPlaybackCompletionReason);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
gVcrState = VCR_STATE_TURNED_OFF;
|
||||
}
|
||||
|
||||
switch (gVcrState) {
|
||||
case VCR_STATE_RECORDING:
|
||||
_vcr_counter++;
|
||||
_vcr_time = getTicksSince(_vcr_start_time);
|
||||
if (_vcr_buffer_index == VCR_BUFFER_CAPACITY - 1) {
|
||||
vcrDump();
|
||||
}
|
||||
break;
|
||||
case VCR_STATE_PLAYING:
|
||||
if (_vcr_buffer_index < _vcr_buffer_end || vcrLoad()) {
|
||||
VcrEntry* vcrEntry = &(_vcr_buffer[_vcr_buffer_index]);
|
||||
if (stru_6AD940.counter < vcrEntry->counter) {
|
||||
if (vcrEntry->time > stru_6AD940.time) {
|
||||
unsigned int delay = stru_6AD940.time;
|
||||
delay += (_vcr_counter - stru_6AD940.counter)
|
||||
* (vcrEntry->time - stru_6AD940.time)
|
||||
/ (vcrEntry->counter - stru_6AD940.counter);
|
||||
|
||||
while (getTicksSince(_vcr_start_time) < delay) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_vcr_counter++;
|
||||
|
||||
int rc = 0;
|
||||
while (_vcr_counter >= _vcr_buffer[_vcr_buffer_index].counter) {
|
||||
_vcr_time = getTicksSince(_vcr_start_time);
|
||||
if (_vcr_time > _vcr_buffer[_vcr_buffer_index].time + 5
|
||||
|| _vcr_time < _vcr_buffer[_vcr_buffer_index].time - 5) {
|
||||
_vcr_start_time += _vcr_time - _vcr_buffer[_vcr_buffer_index].time;
|
||||
}
|
||||
|
||||
switch (_vcr_buffer[_vcr_buffer_index].type) {
|
||||
case VCR_ENTRY_TYPE_INITIAL_STATE:
|
||||
gVcrState = VCR_STATE_TURNED_OFF;
|
||||
gVcrOldKeyboardLayout = keyboardGetLayout();
|
||||
keyboardSetLayout(_vcr_buffer[_vcr_buffer_index].initial.keyboardLayout);
|
||||
while (mouseGetEvent() != 0) {
|
||||
_mouse_info();
|
||||
}
|
||||
gVcrState = VCR_ENTRY_TYPE_INITIAL_STATE;
|
||||
mouseHideCursor();
|
||||
_mouse_set_position(_vcr_buffer[_vcr_buffer_index].initial.mouseX, _vcr_buffer[_vcr_buffer_index].initial.mouseY);
|
||||
mouseShowCursor();
|
||||
keyboardReset();
|
||||
gVcrTerminateFlags = gVcrRequestedTerminationFlags;
|
||||
_vcr_start_time = _get_time();
|
||||
_vcr_counter = 0;
|
||||
break;
|
||||
case VCR_ENTRY_TYPE_KEYBOARD_EVENT:
|
||||
if (1) {
|
||||
KeyboardData keyboardData;
|
||||
keyboardData.key = _vcr_buffer[_vcr_buffer_index].keyboardEvent.key;
|
||||
_kb_simulate_key(&keyboardData);
|
||||
}
|
||||
break;
|
||||
case VCR_ENTRY_TYPE_MOUSE_EVENT:
|
||||
rc = 3;
|
||||
_mouse_simulate_input(_vcr_buffer[_vcr_buffer_index].mouseEvent.dx, _vcr_buffer[_vcr_buffer_index].mouseEvent.dy, _vcr_buffer[_vcr_buffer_index].mouseEvent.buttons);
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(&stru_6AD940, &(_vcr_buffer[_vcr_buffer_index]), sizeof(stru_6AD940));
|
||||
_vcr_buffer_index++;
|
||||
}
|
||||
|
||||
return rc;
|
||||
} else {
|
||||
// NOTE: Uninline.
|
||||
vcrStop();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Inlined.
|
||||
//
|
||||
// 0x4D2C64
|
||||
bool vcrInitBuffer()
|
||||
{
|
||||
if (_vcr_buffer == NULL) {
|
||||
_vcr_buffer = (VcrEntry*)internal_malloc(sizeof(*_vcr_buffer) * VCR_BUFFER_CAPACITY);
|
||||
if (_vcr_buffer == NULL) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
vcrClear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOTE: Inlined.
|
||||
//
|
||||
// 0x4D2C98
|
||||
bool vcrFreeBuffer()
|
||||
{
|
||||
if (_vcr_buffer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
vcrClear();
|
||||
|
||||
internal_free(_vcr_buffer);
|
||||
_vcr_buffer = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x4D2CD0
|
||||
bool _vcr_clear_buffer()
|
||||
bool vcrClear()
|
||||
{
|
||||
if (_vcr_buffer == NULL) {
|
||||
return false;
|
||||
@@ -4451,81 +4658,104 @@ bool _vcr_clear_buffer()
|
||||
}
|
||||
|
||||
// 0x4D2CF0
|
||||
int _vcr_dump_buffer()
|
||||
bool vcrDump()
|
||||
{
|
||||
if (!_vcr_buffer || !_vcr_file) {
|
||||
return 0;
|
||||
if (_vcr_buffer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gVcrFile == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int index = 0; index < _vcr_buffer_index; index++) {
|
||||
if (_vcr_save_record(&(_vcr_buffer[index]), _vcr_file)) {
|
||||
_vcr_buffer_index = 0;
|
||||
return 1;
|
||||
if (!vcrWriteEntry(&(_vcr_buffer[index]), gVcrFile)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
// NOTE: Uninline.
|
||||
if (!vcrClear()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x4D2D74
|
||||
bool vcrLoad()
|
||||
{
|
||||
if (gVcrFile == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
if (!vcrClear()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (_vcr_buffer_end = 0; _vcr_buffer_end < VCR_BUFFER_CAPACITY; _vcr_buffer_end++) {
|
||||
if (!vcrReadEntry(&(_vcr_buffer[_vcr_buffer_end]), gVcrFile)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_vcr_buffer_end == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x4D2E00
|
||||
bool _vcr_save_record(STRUCT_51E2F0* ptr, File* stream)
|
||||
bool vcrWriteEntry(VcrEntry* vcrEntry, File* stream)
|
||||
{
|
||||
if (_db_fwriteLong(stream, ptr->type) == -1) goto err;
|
||||
if (_db_fwriteLong(stream, ptr->field_4) == -1) goto err;
|
||||
if (_db_fwriteLong(stream, ptr->field_8) == -1) goto err;
|
||||
|
||||
switch (ptr->type) {
|
||||
case 1:
|
||||
if (_db_fwriteLong(stream, ptr->type_1_field_C) == -1) goto err;
|
||||
if (_db_fwriteLong(stream, ptr->type_1_field_10) == -1) goto err;
|
||||
if (_db_fwriteLong(stream, ptr->type_1_field_14) == -1) goto err;
|
||||
if (fileWriteUInt32(stream, vcrEntry->type) == -1) return false;
|
||||
if (fileWriteUInt32(stream, vcrEntry->time) == -1) return false;
|
||||
if (fileWriteUInt32(stream, vcrEntry->counter) == -1) return false;
|
||||
|
||||
switch (vcrEntry->type) {
|
||||
case VCR_ENTRY_TYPE_INITIAL_STATE:
|
||||
if (fileWriteInt32(stream, vcrEntry->initial.mouseX) == -1) return false;
|
||||
if (fileWriteInt32(stream, vcrEntry->initial.mouseY) == -1) return false;
|
||||
if (fileWriteInt32(stream, vcrEntry->initial.keyboardLayout) == -1) return false;
|
||||
return true;
|
||||
case 2:
|
||||
if (fileWriteInt16(stream, ptr->type_2_field_C) == -1) goto err;
|
||||
|
||||
case VCR_ENTRY_TYPE_KEYBOARD_EVENT:
|
||||
if (fileWriteInt16(stream, vcrEntry->keyboardEvent.key) == -1) return false;
|
||||
return true;
|
||||
case 3:
|
||||
if (_db_fwriteLong(stream, ptr->dx) == -1) goto err;
|
||||
if (_db_fwriteLong(stream, ptr->dy) == -1) goto err;
|
||||
if (_db_fwriteLong(stream, ptr->buttons) == -1) goto err;
|
||||
|
||||
case VCR_ENTRY_TYPE_MOUSE_EVENT:
|
||||
if (fileWriteInt32(stream, vcrEntry->mouseEvent.dx) == -1) return false;
|
||||
if (fileWriteInt32(stream, vcrEntry->mouseEvent.dy) == -1) return false;
|
||||
if (fileWriteInt32(stream, vcrEntry->mouseEvent.buttons) == -1) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
err:
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 0x4D2EE4
|
||||
bool _vcr_load_record(STRUCT_51E2F0* ptr, File* stream)
|
||||
bool vcrReadEntry(VcrEntry* vcrEntry, File* stream)
|
||||
{
|
||||
if (_db_freadInt(stream, &(ptr->type)) == -1) goto err;
|
||||
if (_db_freadInt(stream, &(ptr->field_4)) == -1) goto err;
|
||||
if (_db_freadInt(stream, &(ptr->field_8)) == -1) goto err;
|
||||
|
||||
switch (ptr->type) {
|
||||
case 1:
|
||||
if (_db_freadInt(stream, &(ptr->type_1_field_C)) == -1) goto err;
|
||||
if (_db_freadInt(stream, &(ptr->type_1_field_10)) == -1) goto err;
|
||||
if (_db_freadInt(stream, &(ptr->type_1_field_14)) == -1) goto err;
|
||||
if (fileReadUInt32(stream, &(vcrEntry->type)) == -1) return false;
|
||||
if (fileReadUInt32(stream, &(vcrEntry->time)) == -1) return false;
|
||||
if (fileReadUInt32(stream, &(vcrEntry->counter)) == -1) return false;
|
||||
|
||||
switch (vcrEntry->type) {
|
||||
case VCR_ENTRY_TYPE_INITIAL_STATE:
|
||||
if (fileReadInt32(stream, &(vcrEntry->initial.mouseX)) == -1) return false;
|
||||
if (fileReadInt32(stream, &(vcrEntry->initial.mouseY)) == -1) return false;
|
||||
if (fileReadInt32(stream, &(vcrEntry->initial.keyboardLayout)) == -1) return false;
|
||||
return true;
|
||||
case 2:
|
||||
if (fileReadInt16(stream, &(ptr->type_2_field_C)) == -1) goto err;
|
||||
|
||||
case VCR_ENTRY_TYPE_KEYBOARD_EVENT:
|
||||
if (fileReadInt16(stream, &(vcrEntry->keyboardEvent.key)) == -1) return false;
|
||||
return true;
|
||||
case 3:
|
||||
if (_db_freadInt(stream, &(ptr->dx)) == -1) goto err;
|
||||
if (_db_freadInt(stream, &(ptr->dy)) == -1) goto err;
|
||||
if (_db_freadInt(stream, &(ptr->buttons)) == -1) goto err;
|
||||
|
||||
case VCR_ENTRY_TYPE_MOUSE_EVENT:
|
||||
if (fileReadInt32(stream, &(vcrEntry->mouseEvent.dx)) == -1) return false;
|
||||
if (fileReadInt32(stream, &(vcrEntry->mouseEvent.dy)) == -1) return false;
|
||||
if (fileReadInt32(stream, &(vcrEntry->mouseEvent.buttons)) == -1) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
err:
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+75
-28
@@ -360,6 +360,44 @@ typedef enum KeyboardLayout {
|
||||
KEYBOARD_LAYOUT_SPANISH,
|
||||
} KeyboardLayout;
|
||||
|
||||
#define VCR_BUFFER_CAPACITY 4096
|
||||
|
||||
typedef enum VcrState {
|
||||
VCR_STATE_RECORDING,
|
||||
VCR_STATE_PLAYING,
|
||||
VCR_STATE_TURNED_OFF,
|
||||
} VcrState;
|
||||
|
||||
#define VCR_STATE_STOP_REQUESTED 0x80000000
|
||||
|
||||
typedef enum VcrTerminationFlags {
|
||||
// Specifies that VCR playback should stop if any key is pressed.
|
||||
VCR_TERMINATE_ON_KEY_PRESS = 0x01,
|
||||
|
||||
// Specifies that VCR playback should stop if mouse is mouved.
|
||||
VCR_TERMINATE_ON_MOUSE_MOVE = 0x02,
|
||||
|
||||
// Specifies that VCR playback should stop if any mouse button is pressed.
|
||||
VCR_TERMINATE_ON_MOUSE_PRESS = 0x04,
|
||||
} VcrTerminationFlags;
|
||||
|
||||
typedef enum VcrPlaybackCompletionReason {
|
||||
VCR_PLAYBACK_COMPLETION_REASON_NONE = 0,
|
||||
|
||||
// Indicates that VCR playback completed normally.
|
||||
VCR_PLAYBACK_COMPLETION_REASON_COMPLETED = 1,
|
||||
|
||||
// Indicates that VCR playback terminated according to termination flags.
|
||||
VCR_PLAYBACK_COMPLETION_REASON_TERMINATED = 2,
|
||||
} VcrPlaybackCompletionReason;
|
||||
|
||||
typedef enum VcrEntryType {
|
||||
VCR_ENTRY_TYPE_NONE = 0,
|
||||
VCR_ENTRY_TYPE_INITIAL_STATE = 1,
|
||||
VCR_ENTRY_TYPE_KEYBOARD_EVENT = 2,
|
||||
VCR_ENTRY_TYPE_MOUSE_EVENT = 3,
|
||||
} VcrEntryType;
|
||||
|
||||
typedef struct STRUCT_6ABF50 {
|
||||
// Time when appropriate key was pressed down or -1 if it's up.
|
||||
int tick;
|
||||
@@ -383,26 +421,26 @@ typedef struct TickerListNode {
|
||||
struct TickerListNode* next;
|
||||
} TickerListNode;
|
||||
|
||||
typedef struct STRUCT_51E2F0 {
|
||||
int type;
|
||||
int field_4;
|
||||
int field_8;
|
||||
typedef struct VcrEntry {
|
||||
unsigned int type;
|
||||
unsigned int time;
|
||||
unsigned int counter;
|
||||
union {
|
||||
struct {
|
||||
int type_1_field_C; // mouse x
|
||||
int type_1_field_10; // mouse y
|
||||
int type_1_field_14; // keyboard layout
|
||||
};
|
||||
int mouseX;
|
||||
int mouseY;
|
||||
int keyboardLayout;
|
||||
} initial;
|
||||
struct {
|
||||
short type_2_field_C;
|
||||
};
|
||||
short key;
|
||||
} keyboardEvent;
|
||||
struct {
|
||||
int dx;
|
||||
int dy;
|
||||
int buttons;
|
||||
};
|
||||
} mouseEvent;
|
||||
};
|
||||
} STRUCT_51E2F0;
|
||||
} VcrEntry;
|
||||
|
||||
typedef struct LogicalKeyEntry {
|
||||
short field_0;
|
||||
@@ -420,6 +458,7 @@ typedef struct KeyboardEvent {
|
||||
|
||||
typedef int(PauseHandler)();
|
||||
typedef int(ScreenshotHandler)(int width, int height, unsigned char* buffer, unsigned char* palette);
|
||||
typedef void(VcrPlaybackCompletionCallback)(int reason);
|
||||
|
||||
extern void (*_idle_func)();
|
||||
extern void (*_focus_func)(int);
|
||||
@@ -448,17 +487,20 @@ extern int gKeyboardEventQueueReadIndex;
|
||||
extern short word_51E2E8;
|
||||
extern int gModifierKeysState;
|
||||
extern int (*_kb_scan_to_ascii)();
|
||||
extern STRUCT_51E2F0* _vcr_buffer;
|
||||
extern VcrEntry* _vcr_buffer;
|
||||
extern int _vcr_buffer_index;
|
||||
extern int _vcr_state;
|
||||
extern int _vcr_time;
|
||||
extern int _vcr_counter;
|
||||
extern int _vcr_terminate_flags;
|
||||
extern int _vcr_terminated_condition;
|
||||
extern int _vcr_start_time;
|
||||
extern unsigned int gVcrState;
|
||||
extern unsigned int _vcr_time;
|
||||
extern unsigned int _vcr_counter;
|
||||
extern unsigned int gVcrTerminateFlags;
|
||||
extern int gVcrPlaybackCompletionReason;
|
||||
extern unsigned int _vcr_start_time;
|
||||
extern int _vcr_registered_atexit;
|
||||
extern File* _vcr_file;
|
||||
extern File* gVcrFile;
|
||||
extern int _vcr_buffer_end;
|
||||
extern VcrPlaybackCompletionCallback* gVcrPlaybackCompletionCallback;
|
||||
extern unsigned int gVcrRequestedTerminationFlags;
|
||||
extern int gVcrOldKeyboardLayout;
|
||||
|
||||
extern int gNormalizedQwertyKeys[SDL_NUM_SCANCODES];
|
||||
extern InputEvent gInputEventQueue[40];
|
||||
@@ -520,6 +562,7 @@ extern unsigned int _kb_idle_start_time;
|
||||
extern KeyboardEvent gLastKeyboardEvent;
|
||||
extern int gKeyboardLayout;
|
||||
extern unsigned char gPressedPhysicalKeysCount;
|
||||
extern VcrEntry stru_6AD940;
|
||||
|
||||
extern SDL_Window* gSdlWindow;
|
||||
extern SDL_Surface* gSdlSurface;
|
||||
@@ -621,14 +664,18 @@ void keyboardBuildItalianConfiguration();
|
||||
void keyboardBuildSpanishConfiguration();
|
||||
void _kb_init_lock_status();
|
||||
int keyboardPeekEvent(int index, KeyboardEvent** keyboardEventPtr);
|
||||
bool _vcr_record(const char* fileName);
|
||||
void _vcr_stop();
|
||||
int _vcr_status();
|
||||
int _vcr_update();
|
||||
bool _vcr_clear_buffer();
|
||||
int _vcr_dump_buffer();
|
||||
bool _vcr_save_record(STRUCT_51E2F0* ptr, File* stream);
|
||||
bool _vcr_load_record(STRUCT_51E2F0* ptr, File* stream);
|
||||
bool vcrRecord(const char* fileName);
|
||||
bool vcrPlay(const char* fileName, unsigned int terminationFlags, VcrPlaybackCompletionCallback* callback);
|
||||
void vcrStop();
|
||||
int vcrGetState();
|
||||
int vcrUpdate();
|
||||
bool vcrInitBuffer();
|
||||
bool vcrFreeBuffer();
|
||||
bool vcrClear();
|
||||
bool vcrDump();
|
||||
bool vcrLoad();
|
||||
bool vcrWriteEntry(VcrEntry* ptr, File* stream);
|
||||
bool vcrReadEntry(VcrEntry* ptr, File* stream);
|
||||
|
||||
int screenGetWidth();
|
||||
int screenGetHeight();
|
||||
|
||||
+35
-35
@@ -276,18 +276,18 @@ void dudeResetName()
|
||||
// 0x42D18C
|
||||
int critterGetHitPoints(Object* critter)
|
||||
{
|
||||
return (critter->pid >> 24) == OBJ_TYPE_CRITTER ? critter->data.critter.hp : 0;
|
||||
return PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER ? critter->data.critter.hp : 0;
|
||||
}
|
||||
|
||||
// 0x42D1A4
|
||||
int critterAdjustHitPoints(Object* critter, int a2)
|
||||
int critterAdjustHitPoints(Object* critter, int hp)
|
||||
{
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int maximumHp = critterGetStat(critter, STAT_MAXIMUM_HIT_POINTS);
|
||||
int newHp = critter->data.critter.hp + a2;
|
||||
int newHp = critter->data.critter.hp + hp;
|
||||
|
||||
critter->data.critter.hp = newHp;
|
||||
if (maximumHp >= newHp) {
|
||||
@@ -304,7 +304,7 @@ int critterAdjustHitPoints(Object* critter, int a2)
|
||||
// 0x42D1F8
|
||||
int critterGetPoison(Object* critter)
|
||||
{
|
||||
return (critter->pid >> 24) == OBJ_TYPE_CRITTER ? critter->data.critter.poison : 0;
|
||||
return PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER ? critter->data.critter.poison : 0;
|
||||
}
|
||||
|
||||
// Adjust critter's current poison by specified amount.
|
||||
@@ -396,7 +396,7 @@ int poisonEventProcess(Object* obj, void* data)
|
||||
// 0x42D38C
|
||||
int critterGetRadiation(Object* obj)
|
||||
{
|
||||
return (obj->pid >> 24) == OBJ_TYPE_CRITTER ? obj->data.critter.radiation : 0;
|
||||
return PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER ? obj->data.critter.radiation : 0;
|
||||
}
|
||||
|
||||
// 0x42D3A4
|
||||
@@ -416,7 +416,7 @@ int critterAdjustRadiation(Object* obj, int amount)
|
||||
}
|
||||
|
||||
if (amount > 0) {
|
||||
proto->critter.data.flags |= 0x02;
|
||||
proto->critter.data.flags |= CRITTER_FLAG_0x2;
|
||||
}
|
||||
|
||||
if (amount > 0) {
|
||||
@@ -483,7 +483,7 @@ int _critter_check_rads(Object* obj)
|
||||
|
||||
Proto* proto;
|
||||
protoGetProto(obj->pid, &proto);
|
||||
if ((proto->critter.data.flags & 0x02) == 0) {
|
||||
if ((proto->critter.data.flags & CRITTER_FLAG_0x2) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -521,10 +521,10 @@ int _critter_check_rads(Object* obj)
|
||||
|
||||
radiationEvent->radiationLevel = radiationLevel;
|
||||
radiationEvent->isHealing = 0;
|
||||
queueAddEvent(36000 * randomBetween(4, 18), obj, radiationEvent, EVENT_TYPE_RADIATION);
|
||||
queueAddEvent(GAME_TIME_TICKS_PER_HOUR * randomBetween(4, 18), obj, radiationEvent, EVENT_TYPE_RADIATION);
|
||||
}
|
||||
|
||||
proto->critter.data.flags &= ~(0x02);
|
||||
proto->critter.data.flags &= ~(CRITTER_FLAG_0x2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -657,7 +657,7 @@ int radiationEventWrite(File* stream, void* data)
|
||||
// 0x42D82C
|
||||
int critterGetDamageType(Object* obj)
|
||||
{
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -723,7 +723,7 @@ int critterGetKillType(Object* obj)
|
||||
return KILL_TYPE_MAN;
|
||||
}
|
||||
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -766,7 +766,7 @@ char* killTypeGetDescription(int killType)
|
||||
// 0x42D9F4
|
||||
int _critter_heal_hours(Object* critter, int a2)
|
||||
{
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -788,7 +788,7 @@ static int _critterClearObjDrugs(Object* obj, void* data)
|
||||
// 0x42DA64
|
||||
void critterKill(Object* critter, int anim, bool a3)
|
||||
{
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -800,20 +800,20 @@ void critterKill(Object* critter, int anim, bool a3)
|
||||
bool shouldChangeFid = false;
|
||||
int fid;
|
||||
if (_critter_is_prone(critter)) {
|
||||
int current = (critter->fid & 0xFF0000) >> 16;
|
||||
int current = FID_ANIM_TYPE(critter->fid);
|
||||
if (current == ANIM_FALL_BACK || current == ANIM_FALL_FRONT) {
|
||||
bool back = false;
|
||||
if (current == ANIM_FALL_BACK) {
|
||||
back = true;
|
||||
} else {
|
||||
fid = buildFid(1, critter->fid & 0xFFF, ANIM_FALL_FRONT_SF, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, ANIM_FALL_FRONT_SF, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
if (!artExists(fid)) {
|
||||
back = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (back) {
|
||||
fid = buildFid(1, critter->fid & 0xFFF, ANIM_FALL_BACK_SF, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, ANIM_FALL_BACK_SF, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
}
|
||||
|
||||
shouldChangeFid = true;
|
||||
@@ -828,12 +828,12 @@ void critterKill(Object* critter, int anim, bool a3)
|
||||
anim = LAST_SF_DEATH_ANIM;
|
||||
}
|
||||
|
||||
fid = buildFid(1, critter->fid & 0xFFF, anim, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, anim, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
_obj_fix_violence_settings(&fid);
|
||||
if (!artExists(fid)) {
|
||||
debugPrint("\nError: Critter Kill: Can't match fid!");
|
||||
|
||||
fid = buildFid(1, critter->fid & 0xFFF, ANIM_FALL_BACK_BLOOD_SF, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, ANIM_FALL_BACK_BLOOD_SF, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
_obj_fix_violence_settings(&fid);
|
||||
}
|
||||
|
||||
@@ -850,7 +850,7 @@ void critterKill(Object* critter, int anim, bool a3)
|
||||
rectUnion(&updatedRect, &tempRect, &updatedRect);
|
||||
}
|
||||
|
||||
if (!_critter_flag_check(critter->pid, 2048)) {
|
||||
if (!_critter_flag_check(critter->pid, CRITTER_FLAG_0x800)) {
|
||||
critter->flags |= OBJECT_NO_BLOCK;
|
||||
_obj_toggle_flat(critter, &tempRect);
|
||||
}
|
||||
@@ -902,7 +902,7 @@ bool critterIsActive(Object* critter)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -924,7 +924,7 @@ bool critterIsDead(Object* critter)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -946,7 +946,7 @@ bool critterIsCrippled(Object* critter)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -960,15 +960,15 @@ bool _critter_is_prone(Object* critter)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int anim = (critter->fid & 0xFF0000) >> 16;
|
||||
int anim = FID_ANIM_TYPE(critter->fid);
|
||||
|
||||
return (critter->data.critter.combat.results & (DAM_KNOCKED_OUT | DAM_KNOCKED_DOWN)) != 0
|
||||
|| anim >= FIRST_KNOCKDOWN_AND_DEATH_ANIM && anim <= LAST_KNOCKDOWN_AND_DEATH_ANIM
|
||||
|| anim >= FIRST_SF_DEATH_ANIM && anim <= LAST_SF_DEATH_ANIM;
|
||||
|| (anim >= FIRST_KNOCKDOWN_AND_DEATH_ANIM && anim <= LAST_KNOCKDOWN_AND_DEATH_ANIM)
|
||||
|| (anim >= FIRST_SF_DEATH_ANIM && anim <= LAST_SF_DEATH_ANIM);
|
||||
}
|
||||
|
||||
// critter_body_type
|
||||
@@ -980,7 +980,7 @@ int critterGetBodyType(Object* critter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1236,7 +1236,7 @@ int knockoutEventProcess(Object* obj, void* data)
|
||||
// 0x42E460
|
||||
int _critter_wake_clear(Object* obj, void* data)
|
||||
{
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1246,7 +1246,7 @@ int _critter_wake_clear(Object* obj, void* data)
|
||||
|
||||
obj->data.critter.combat.results &= ~(DAM_KNOCKED_OUT | DAM_KNOCKED_DOWN);
|
||||
|
||||
int fid = buildFid((obj->fid & 0xF000000) >> 24, obj->fid & 0xFFF, ANIM_STAND, (obj->fid & 0xF000) >> 12, obj->rotation + 1);
|
||||
int fid = buildFid(FID_TYPE(obj->fid), obj->fid & 0xFFF, ANIM_STAND, (obj->fid & 0xF000) >> 12, obj->rotation + 1);
|
||||
objectSetFid(obj, fid, 0);
|
||||
|
||||
return 0;
|
||||
@@ -1259,12 +1259,12 @@ int _critter_set_who_hit_me(Object* a1, Object* a2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a2 != NULL && ((a2->fid & 0xF000000) >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (a2 != NULL && FID_TYPE(a2->fid) != OBJ_TYPE_CRITTER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((a1->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (a2 == NULL || a1->data.critter.combat.team != a2->data.critter.combat.team || statRoll(a1, STAT_INTELLIGENCE, -1, NULL) < 2 && (!objectIsPartyMember(a1) || !objectIsPartyMember(a2))) {
|
||||
if (PID_TYPE(a1->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (a2 == NULL || a1->data.critter.combat.team != a2->data.critter.combat.team || (statRoll(a1, STAT_INTELLIGENCE, -1, NULL) < 2 && (!objectIsPartyMember(a1) || !objectIsPartyMember(a2)))) {
|
||||
a1->data.critter.combat.whoHitMe = a2;
|
||||
if (a2 == gDude) {
|
||||
reactionSetValue(a1, -3);
|
||||
@@ -1319,7 +1319,7 @@ bool _critter_can_obj_dude_rest()
|
||||
// 0x42E62C
|
||||
int critterGetMovementPointCostAdjustedForCrippledLegs(Object* critter, int actionPoints)
|
||||
{
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1358,7 +1358,7 @@ bool _critter_flag_check(int pid, int flag)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ void critterProtoDataCopy(CritterProtoData* dest, CritterProtoData* src);
|
||||
int dudeSetName(const char* name);
|
||||
void dudeResetName();
|
||||
int critterGetHitPoints(Object* critter);
|
||||
int critterAdjustHitPoints(Object* critter, int amount);
|
||||
int critterAdjustHitPoints(Object* critter, int hp);
|
||||
int critterGetPoison(Object* critter);
|
||||
int critterAdjustPoison(Object* obj, int amount);
|
||||
int poisonEventProcess(Object* obj, void* data);
|
||||
|
||||
+188
-3
@@ -1,10 +1,195 @@
|
||||
#include "datafile.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "color.h"
|
||||
#include "db.h"
|
||||
#include "memory_manager.h"
|
||||
#include "pcx.h"
|
||||
#include "platform_compat.h"
|
||||
|
||||
// 0x5184AC
|
||||
DatafileLoader* gDatafileLoader = NULL;
|
||||
|
||||
// 0x5184B0
|
||||
DatafileNameMangler* gDatafileNameMangler = datafileDefaultNameManglerImpl;
|
||||
|
||||
// 0x56D7E0
|
||||
unsigned char _pal[768];
|
||||
unsigned char gDatafilePalette[768];
|
||||
|
||||
// 0x42EE70
|
||||
char* datafileDefaultNameManglerImpl(char* path)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x42EE74
|
||||
void datafileSetNameMangler(DatafileNameMangler* mangler)
|
||||
{
|
||||
gDatafileNameMangler = mangler;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x42EE7C
|
||||
void datafileSetLoader(DatafileLoader* loader)
|
||||
{
|
||||
gDatafileLoader = loader;
|
||||
}
|
||||
|
||||
// 0x42EE84
|
||||
void sub_42EE84(unsigned char* data, unsigned char* palette, int width, int height)
|
||||
{
|
||||
unsigned char indexedPalette[256];
|
||||
|
||||
indexedPalette[0] = 0;
|
||||
for (int index = 1; index < 256; index++) {
|
||||
// TODO: Check.
|
||||
int r = palette[index * 3 + 2] >> 3;
|
||||
int g = palette[index * 3 + 1] >> 3;
|
||||
int b = palette[index * 3] >> 3;
|
||||
int colorTableIndex = (r << 10) | (g << 5) | b;
|
||||
indexedPalette[index] = _colorTable[colorTableIndex];
|
||||
}
|
||||
|
||||
int size = width * height;
|
||||
for (int index = 0; index < size; index++) {
|
||||
data[index] = indexedPalette[data[index]];
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x42EEF8
|
||||
void sub_42EEF8(unsigned char* data, unsigned char* palette, int width, int height)
|
||||
{
|
||||
unsigned char indexedPalette[256];
|
||||
|
||||
indexedPalette[0] = 0;
|
||||
for (int index = 1; index < 256; index++) {
|
||||
// TODO: Check.
|
||||
int r = palette[index * 3 + 2] >> 1;
|
||||
int g = palette[index * 3 + 1] >> 1;
|
||||
int b = palette[index * 3] >> 1;
|
||||
int colorTableIndex = (r << 10) | (g << 5) | b;
|
||||
indexedPalette[index] = _colorTable[colorTableIndex];
|
||||
}
|
||||
|
||||
int size = width * height;
|
||||
for (int index = 0; index < size; index++) {
|
||||
data[index] = indexedPalette[data[index]];
|
||||
}
|
||||
}
|
||||
|
||||
// 0x42EF60
|
||||
unsigned char* datafileReadRaw(char* path, int* widthPtr, int* heightPtr)
|
||||
{
|
||||
char* mangledPath = gDatafileNameMangler(path);
|
||||
char* dot = strrchr(mangledPath, '.');
|
||||
if (dot != NULL) {
|
||||
if (compat_stricmp(dot + 1, "pcx")) {
|
||||
return pcxRead(mangledPath, widthPtr, heightPtr, gDatafilePalette);
|
||||
}
|
||||
}
|
||||
|
||||
if (gDatafileLoader != NULL) {
|
||||
return gDatafileLoader(mangledPath, gDatafilePalette, widthPtr, heightPtr);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 0x42EFCC
|
||||
unsigned char* datafileRead(char* path, int* widthPtr, int* heightPtr)
|
||||
{
|
||||
unsigned char* v1 = datafileReadRaw(path, widthPtr, heightPtr);
|
||||
if (v1 != NULL) {
|
||||
sub_42EE84(v1, gDatafilePalette, *widthPtr, *heightPtr);
|
||||
}
|
||||
return v1;
|
||||
}
|
||||
|
||||
// NOTE: Unused
|
||||
//
|
||||
// 0x42EFF4
|
||||
unsigned char* sub_42EFF4(char* path)
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
unsigned char* v3 = datafileReadRaw(path, &width, &height);
|
||||
if (v3 != NULL) {
|
||||
internal_free_safe(v3, __FILE__, __LINE__); // "..\\int\\DATAFILE.C", 148
|
||||
return gDatafilePalette;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x42F024
|
||||
void sub_42F024(unsigned char* data, int* widthPtr, int* heightPtr)
|
||||
{
|
||||
int width = *widthPtr;
|
||||
int height = *heightPtr;
|
||||
unsigned char* temp = (unsigned char*)internal_malloc_safe(width * height, __FILE__, __LINE__); // "..\\int\\DATAFILE.C", 157
|
||||
|
||||
// NOTE: Original code does not initialize `x`.
|
||||
int y = 0;
|
||||
int x = 0;
|
||||
unsigned char* src1 = data;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
if (*src1 == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned char* src2 = src1;
|
||||
for (x = 0; x < width; x++) {
|
||||
if (*src2 == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
*temp++ = *src2++;
|
||||
}
|
||||
|
||||
src1 += width;
|
||||
}
|
||||
|
||||
memcpy(data, temp, x * y);
|
||||
internal_free_safe(temp, __FILE__, __LINE__); // // "..\\int\\DATAFILE.C", 171
|
||||
}
|
||||
|
||||
// 0x42F0E4
|
||||
unsigned char* _datafileGetPalette()
|
||||
unsigned char* datafileGetPalette()
|
||||
{
|
||||
return _pal;
|
||||
return gDatafilePalette;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x42F0EC
|
||||
unsigned char* datafileLoad(char* path, int* sizePtr)
|
||||
{
|
||||
const char* mangledPath = gDatafileNameMangler(path);
|
||||
File* stream = fileOpen(mangledPath, "rb");
|
||||
if (stream == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int size = fileGetSize(stream);
|
||||
unsigned char* data = (unsigned char*)internal_malloc_safe(size, __FILE__, __LINE__); // "..\\int\\DATAFILE.C", 185
|
||||
if (data == NULL) {
|
||||
// NOTE: This code is unreachable, internal_malloc_safe never fails.
|
||||
// Otherwise it leaks stream.
|
||||
*sizePtr = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fileRead(data, 1, size, stream);
|
||||
fileClose(stream);
|
||||
*sizePtr = size;
|
||||
return data;
|
||||
}
|
||||
|
||||
+18
-2
@@ -1,8 +1,24 @@
|
||||
#ifndef DATAFILE_H
|
||||
#define DATAFILE_H
|
||||
|
||||
extern unsigned char _pal[768];
|
||||
typedef unsigned char*(DatafileLoader)(char* path, unsigned char* palette, int* widthPtr, int* heightPtr);
|
||||
typedef char*(DatafileNameMangler)(char* path);
|
||||
|
||||
unsigned char* _datafileGetPalette();
|
||||
extern DatafileLoader* gDatafileLoader;
|
||||
extern DatafileNameMangler* gDatafileNameMangler;
|
||||
|
||||
extern unsigned char gDatafilePalette[768];
|
||||
|
||||
char* datafileDefaultNameManglerImpl(char* path);
|
||||
void datafileSetNameMangler(DatafileNameMangler* mangler);
|
||||
void datafileSetLoader(DatafileLoader* loader);
|
||||
void sub_42EE84(unsigned char* data, unsigned char* palette, int width, int height);
|
||||
void sub_42EEF8(unsigned char* data, unsigned char* palette, int width, int height);
|
||||
unsigned char* datafileReadRaw(char* path, int* widthPtr, int* heightPtr);
|
||||
unsigned char* datafileRead(char* path, int* widthPtr, int* heightPtr);
|
||||
unsigned char* sub_42EFF4(char* path);
|
||||
void sub_42F024(unsigned char* data, int* widthPtr, int* heightPtr);
|
||||
unsigned char* datafileGetPalette();
|
||||
unsigned char* datafileLoad(char* path, int* sizePtr);
|
||||
|
||||
#endif /* DATAFILE_H */
|
||||
|
||||
@@ -638,7 +638,7 @@ int fileNameListInit(const char* pattern, char*** fileNameListPtr, int a3, int a
|
||||
}
|
||||
}
|
||||
|
||||
bool v1 = *pattern == '*';
|
||||
bool isWildcard = *pattern == '*';
|
||||
|
||||
for (int index = 0; index < fileNamesLength; index += 1) {
|
||||
const char* name = xlist->fileNames[index];
|
||||
@@ -647,16 +647,7 @@ int fileNameListInit(const char* pattern, char*** fileNameListPtr, int a3, int a
|
||||
char extension[COMPAT_MAX_EXT];
|
||||
compat_splitpath(name, NULL, dir, fileName, extension);
|
||||
|
||||
bool v2 = false;
|
||||
if (v1) {
|
||||
char* pch = dir;
|
||||
while (*pch != '\0' && *pch != '\\') {
|
||||
pch++;
|
||||
}
|
||||
v2 = *pch != '\0';
|
||||
}
|
||||
|
||||
if (!v2) {
|
||||
if (!isWildcard || *dir == '\0' || strchr(dir, '\\') == NULL) {
|
||||
// NOTE: Quick and dirty fix to buffer overflow. See RE to
|
||||
// understand the problem.
|
||||
char path[COMPAT_MAX_PATH];
|
||||
|
||||
+11
-12
@@ -196,7 +196,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
||||
CacheEntry* backgroundHandle;
|
||||
int backgroundWidth;
|
||||
int backgroundHeight;
|
||||
int fid = buildFid(6, gDialogBoxBackgroundFrmIds[dialogType], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gDialogBoxBackgroundFrmIds[dialogType], 0, 0, 0);
|
||||
unsigned char* background = artLockFrameDataReturningSize(fid, &backgroundHandle, &backgroundWidth, &backgroundHeight);
|
||||
if (background == NULL) {
|
||||
fontSetCurrent(savedFont);
|
||||
@@ -230,7 +230,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
||||
unsigned char* upButton = NULL;
|
||||
|
||||
if ((flags & DIALOG_BOX_0x20) == 0) {
|
||||
int doneBoxFid = buildFid(6, 209, 0, 0, 0);
|
||||
int doneBoxFid = buildFid(OBJ_TYPE_INTERFACE, 209, 0, 0, 0);
|
||||
doneBox = artLockFrameDataReturningSize(doneBoxFid, &doneBoxHandle, &doneBoxWidth, &doneBoxHeight);
|
||||
if (doneBox == NULL) {
|
||||
artUnlock(backgroundHandle);
|
||||
@@ -239,7 +239,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
||||
return -1;
|
||||
}
|
||||
|
||||
int downButtonFid = buildFid(6, 9, 0, 0, 0);
|
||||
int downButtonFid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
downButton = artLockFrameDataReturningSize(downButtonFid, &downButtonHandle, &downButtonWidth, &downButtonHeight);
|
||||
if (downButton == NULL) {
|
||||
artUnlock(doneBoxHandle);
|
||||
@@ -249,7 +249,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
||||
return -1;
|
||||
}
|
||||
|
||||
int upButtonFid = buildFid(6, 8, 0, 0, 0);
|
||||
int upButtonFid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
upButton = artLockFrameData(upButtonFid, 0, 0, &upButtonHandle);
|
||||
if (upButton == NULL) {
|
||||
artUnlock(downButtonHandle);
|
||||
@@ -331,7 +331,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
||||
buttonSetCallbacks(btn, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||
}
|
||||
} else {
|
||||
int doneBoxFid = buildFid(6, 209, 0, 0, 0);
|
||||
int doneBoxFid = buildFid(OBJ_TYPE_INTERFACE, 209, 0, 0, 0);
|
||||
unsigned char* doneBox = artLockFrameDataReturningSize(doneBoxFid, &doneBoxHandle, &doneBoxWidth, &doneBoxHeight);
|
||||
if (doneBox == NULL) {
|
||||
artUnlock(backgroundHandle);
|
||||
@@ -340,7 +340,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
||||
return -1;
|
||||
}
|
||||
|
||||
int downButtonFid = buildFid(6, 9, 0, 0, 0);
|
||||
int downButtonFid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
unsigned char* downButton = artLockFrameDataReturningSize(downButtonFid, &downButtonHandle, &downButtonWidth, &downButtonHeight);
|
||||
if (downButton == NULL) {
|
||||
artUnlock(doneBoxHandle);
|
||||
@@ -350,7 +350,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
||||
return -1;
|
||||
}
|
||||
|
||||
int upButtonFid = buildFid(6, 8, 0, 0, 0);
|
||||
int upButtonFid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
unsigned char* upButton = artLockFrameData(upButtonFid, 0, 0, &upButtonHandle);
|
||||
if (upButton == NULL) {
|
||||
artUnlock(downButtonHandle);
|
||||
@@ -517,7 +517,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
||||
}
|
||||
|
||||
// 0x41DE90
|
||||
int showLoadFileDialog(char *title, char** fileList, char* dest, int fileListLength, int x, int y, int flags)
|
||||
int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLength, int x, int y, int flags)
|
||||
{
|
||||
int oldFont = fontGetCurrent();
|
||||
|
||||
@@ -541,7 +541,7 @@ int showLoadFileDialog(char *title, char** fileList, char* dest, int fileListLen
|
||||
Size frmSizes[FILE_DIALOG_FRM_COUNT];
|
||||
|
||||
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, gLoadFileDialogFrmIds[index], 0, 0, 0);
|
||||
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) {
|
||||
@@ -551,7 +551,6 @@ int showLoadFileDialog(char *title, char** fileList, char* dest, int fileListLen
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int backgroundWidth = frmSizes[FILE_DIALOG_FRM_BACKGROUND].width;
|
||||
int backgroundHeight = frmSizes[FILE_DIALOG_FRM_BACKGROUND].height;
|
||||
|
||||
@@ -922,7 +921,7 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
|
||||
Size frmSizes[FILE_DIALOG_FRM_COUNT];
|
||||
|
||||
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, gSaveFileDialogFrmIds[index], 0, 0, 0);
|
||||
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) {
|
||||
@@ -1090,7 +1089,7 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
|
||||
|
||||
char fileNameCopy[32];
|
||||
strncpy(fileNameCopy, dest, 32);
|
||||
|
||||
|
||||
int fileNameCopyLength = strlen(fileNameCopy);
|
||||
fileNameCopy[fileNameCopyLength + 1] = '\0';
|
||||
fileNameCopy[fileNameCopyLength] = ' ';
|
||||
|
||||
+45
-26
@@ -76,7 +76,7 @@ int dword_56DB6C;
|
||||
int dword_56DB70;
|
||||
|
||||
// 0x56DB74
|
||||
int _rand2plus;
|
||||
char* off_56DB74;
|
||||
|
||||
// 0x56DB7C
|
||||
int dword_56DB7C;
|
||||
@@ -91,7 +91,7 @@ int dword_56DB84;
|
||||
int dword_56DB88;
|
||||
|
||||
// 0x56DB8C
|
||||
int dword_56DB8C;
|
||||
char* off_56DB8C;
|
||||
|
||||
// 0x56DB90
|
||||
int _replyPlaying;
|
||||
@@ -127,16 +127,16 @@ int dword_56DBB8;
|
||||
int dword_56DBBC;
|
||||
|
||||
// 0x56DBC0
|
||||
void* off_56DBC0;
|
||||
char* off_56DBC0;
|
||||
|
||||
// 0x56DBC4
|
||||
void* off_56DBC4;
|
||||
char* off_56DBC4;
|
||||
|
||||
// 0x56DBC8
|
||||
void* off_56DBC8;
|
||||
char* off_56DBC8;
|
||||
|
||||
// 0x56DBCC
|
||||
void* off_56DBCC;
|
||||
char* off_56DBCC;
|
||||
|
||||
// 0x56DBD0
|
||||
char* gDialogReplyTitle;
|
||||
@@ -151,16 +151,16 @@ int dword_56DBD8;
|
||||
int dword_56DBDC;
|
||||
|
||||
// 0x56DBE0
|
||||
void* off_56DBE0;
|
||||
char* off_56DBE0;
|
||||
|
||||
// 0x56DBE4
|
||||
void* off_56DBE4;
|
||||
char* off_56DBE4;
|
||||
|
||||
// 0x56DBE8
|
||||
void* off_56DBE8;
|
||||
char* off_56DBE8;
|
||||
|
||||
// 0x56DBEC
|
||||
void* off_56DBEC;
|
||||
char* off_56DBEC;
|
||||
|
||||
// 0x42F434
|
||||
STRUCT_56DAE0_FIELD_4* _getReply()
|
||||
@@ -191,7 +191,7 @@ void _replyAddOption(const char* a1, const char* a2, int a3)
|
||||
|
||||
v18 = _getReply();
|
||||
v17 = v18->field_14 - 1;
|
||||
v18->field_C[v17].field_8 = 2;
|
||||
v18->field_C[v17].kind = 2;
|
||||
|
||||
if (a1 != NULL) {
|
||||
v14 = (char*)internal_malloc_safe(strlen(a1) + 1, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 805
|
||||
@@ -204,9 +204,9 @@ void _replyAddOption(const char* a1, const char* a2, int a3)
|
||||
if (a2 != NULL) {
|
||||
v15 = (char*)internal_malloc_safe(strlen(a2) + 1, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 810
|
||||
strcpy(v15, a2);
|
||||
v18->field_C[v17].field_4 = v15;
|
||||
v18->field_C[v17].string = v15;
|
||||
} else {
|
||||
v18->field_C[v17].field_4 = NULL;
|
||||
v18->field_C[v17].string = NULL;
|
||||
}
|
||||
|
||||
v18->field_C[v17].field_18 = widgetGetFont();
|
||||
@@ -215,7 +215,7 @@ void _replyAddOption(const char* a1, const char* a2, int a3)
|
||||
}
|
||||
|
||||
// 0x42F624
|
||||
void _replyAddOptionProc(const char* a1, const char* a2, int a3)
|
||||
void _replyAddOptionProc(const char* a1, int a2, int a3)
|
||||
{
|
||||
STRUCT_56DAE0_FIELD_4* v5;
|
||||
int v13;
|
||||
@@ -224,7 +224,7 @@ void _replyAddOptionProc(const char* a1, const char* a2, int a3)
|
||||
v5 = _getReply();
|
||||
v13 = v5->field_14 - 1;
|
||||
|
||||
v5->field_C[v13].field_8 = 1;
|
||||
v5->field_C[v13].kind = 1;
|
||||
|
||||
if (a1 != NULL) {
|
||||
v11 = (char*)internal_malloc_safe(strlen(a1) + 1, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 830
|
||||
@@ -234,7 +234,7 @@ void _replyAddOptionProc(const char* a1, const char* a2, int a3)
|
||||
v5->field_C[v13].field_0 = NULL;
|
||||
}
|
||||
|
||||
v5->field_C[v13].field_4 = (char*)a2;
|
||||
v5->field_C[v13].proc = a2;
|
||||
|
||||
v5->field_C[v13].field_18 = widgetGetFont();
|
||||
v5->field_C[v13].field_1A = word_56DB60;
|
||||
@@ -248,9 +248,9 @@ void _optionFree(STRUCT_56DAE0_FIELD_4_FIELD_C* a1)
|
||||
internal_free_safe(a1->field_0, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 844
|
||||
}
|
||||
|
||||
if (a1->field_8 == 2) {
|
||||
if (a1->field_4 != NULL) {
|
||||
internal_free_safe(a1->field_4, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 846
|
||||
if (a1->kind == 2) {
|
||||
if (a1->string != NULL) {
|
||||
internal_free_safe(a1->string, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 846
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -503,7 +503,7 @@ int _dialogOption(const char* a1, const char* a2)
|
||||
}
|
||||
|
||||
// 0x430F38
|
||||
int _dialogOptionProc(const char* a1, const char* a2)
|
||||
int _dialogOptionProc(const char* a1, int a2)
|
||||
{
|
||||
if (_dialog[_tods].field_C == -1) {
|
||||
return 1;
|
||||
@@ -514,6 +514,20 @@ int _dialogOptionProc(const char* a1, const char* a2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x430FD4
|
||||
int sub_430FD4(const char* a1, const char* a2, int timeout)
|
||||
{
|
||||
// TODO: Incomplete.
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 0x431088
|
||||
int sub_431088(int a1)
|
||||
{
|
||||
// TODO: Incomplete.
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 0x431184
|
||||
int _dialogGetExitPoint()
|
||||
{
|
||||
@@ -533,24 +547,24 @@ int _dialogQuit()
|
||||
}
|
||||
|
||||
// 0x4311B8
|
||||
int dialogSetOptionWindow(int a1, int a2, int a3, int a4, int a5)
|
||||
int dialogSetOptionWindow(int a1, int a2, int a3, int a4, char* a5)
|
||||
{
|
||||
dword_56DB6C = a1;
|
||||
dword_56DB70 = a2;
|
||||
dword_56DB64 = a3;
|
||||
dword_56DB68 = a4;
|
||||
_rand2plus = a5;
|
||||
off_56DB74 = a5;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x4311E0
|
||||
int dialogSetReplyWindow(int a1, int a2, int a3, int a4, int a5)
|
||||
int dialogSetReplyWindow(int a1, int a2, int a3, int a4, char* a5)
|
||||
{
|
||||
dword_56DB84 = a1;
|
||||
dword_56DB88 = a2;
|
||||
dword_56DB7C = a3;
|
||||
dword_56DB80 = a4;
|
||||
dword_56DB8C = a5;
|
||||
off_56DB8C = a5;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -565,7 +579,7 @@ int dialogSetBorder(int a1, int a2)
|
||||
}
|
||||
|
||||
// 0x431218
|
||||
int _dialogSetScrollUp(int a1, int a2, void* a3, void* a4, void* a5, void* a6, int a7)
|
||||
int _dialogSetScrollUp(int a1, int a2, char* a3, char* a4, char* a5, char* a6, int a7)
|
||||
{
|
||||
_upButton = a1;
|
||||
dword_56DBD8 = a2;
|
||||
@@ -596,7 +610,7 @@ int _dialogSetScrollUp(int a1, int a2, void* a3, void* a4, void* a5, void* a6, i
|
||||
}
|
||||
|
||||
// 0x4312C0
|
||||
int _dialogSetScrollDown(int a1, int a2, void* a3, void* a4, void* a5, void* a6, int a7)
|
||||
int _dialogSetScrollDown(int a1, int a2, char* a3, char* a4, char* a5, char* a6, int a7)
|
||||
{
|
||||
_downButton = a1;
|
||||
dword_56DBB8 = a2;
|
||||
@@ -666,6 +680,11 @@ int _dialogSetOptionFlags(int flags)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 0x431430
|
||||
void dialogInit()
|
||||
{
|
||||
}
|
||||
|
||||
// 0x431434
|
||||
void _dialogClose()
|
||||
{
|
||||
|
||||
+24
-18
@@ -8,8 +8,11 @@ typedef void DialogFunc2(int win);
|
||||
|
||||
typedef struct STRUCT_56DAE0_FIELD_4_FIELD_C {
|
||||
char* field_0;
|
||||
char* field_4;
|
||||
int field_8;
|
||||
union {
|
||||
int proc;
|
||||
char* string;
|
||||
};
|
||||
int kind;
|
||||
int field_C;
|
||||
int field_10;
|
||||
int field_14;
|
||||
@@ -60,12 +63,12 @@ extern int dword_56DB64;
|
||||
extern int dword_56DB68;
|
||||
extern int dword_56DB6C;
|
||||
extern int dword_56DB70;
|
||||
extern int _rand2plus;
|
||||
extern char* off_56DB74;
|
||||
extern int dword_56DB7C;
|
||||
extern int dword_56DB80;
|
||||
extern int dword_56DB84;
|
||||
extern int dword_56DB88;
|
||||
extern int dword_56DB8C;
|
||||
extern char* off_56DB8C;
|
||||
extern int _replyPlaying;
|
||||
extern int _replyWin;
|
||||
extern int gDialogReplyColorG;
|
||||
@@ -77,22 +80,22 @@ extern int gDialogOptionColorR;
|
||||
extern int _downButton;
|
||||
extern int dword_56DBB8;
|
||||
extern int dword_56DBBC;
|
||||
extern void* off_56DBC0;
|
||||
extern void* off_56DBC4;
|
||||
extern void* off_56DBC8;
|
||||
extern void* off_56DBCC;
|
||||
extern char* off_56DBC0;
|
||||
extern char* off_56DBC4;
|
||||
extern char* off_56DBC8;
|
||||
extern char* off_56DBCC;
|
||||
extern char* gDialogReplyTitle;
|
||||
extern int _upButton;
|
||||
extern int dword_56DBD8;
|
||||
extern int dword_56DBDC;
|
||||
extern void* off_56DBE0;
|
||||
extern void* off_56DBE4;
|
||||
extern void* off_56DBE8;
|
||||
extern void* off_56DBEC;
|
||||
extern char* off_56DBE0;
|
||||
extern char* off_56DBE4;
|
||||
extern char* off_56DBE8;
|
||||
extern char* off_56DBEC;
|
||||
|
||||
STRUCT_56DAE0_FIELD_4* _getReply();
|
||||
void _replyAddOption(const char* a1, const char* a2, int a3);
|
||||
void _replyAddOptionProc(const char* a1, const char* a2, int a3);
|
||||
void _replyAddOptionProc(const char* a1, int a2, int a3);
|
||||
void _optionFree(STRUCT_56DAE0_FIELD_4_FIELD_C* a1);
|
||||
void _replyFree();
|
||||
int _endDialog();
|
||||
@@ -107,18 +110,21 @@ int _dialogGotoReply(const char* a1);
|
||||
int dialogSetReplyTitle(const char* a1);
|
||||
int _dialogReply(const char* a1, const char* a2);
|
||||
int _dialogOption(const char* a1, const char* a2);
|
||||
int _dialogOptionProc(const char* a1, const char* a2);
|
||||
int _dialogOptionProc(const char* a1, int a2);
|
||||
int sub_430FD4(const char* a1, const char* a2, int timeout);
|
||||
int sub_431088(int a1);
|
||||
int _dialogGetExitPoint();
|
||||
int _dialogQuit();
|
||||
int dialogSetOptionWindow(int a1, int a2, int a3, int a4, int a5);
|
||||
int dialogSetReplyWindow(int a1, int a2, int a3, int a4, int a5);
|
||||
int dialogSetOptionWindow(int a1, int a2, int a3, int a4, char* a5);
|
||||
int dialogSetReplyWindow(int a1, int a2, int a3, int a4, char* a5);
|
||||
int dialogSetBorder(int a1, int a2);
|
||||
int _dialogSetScrollUp(int a1, int a2, void* a3, void* a4, void* a5, void* a6, int a7);
|
||||
int _dialogSetScrollDown(int a1, int a2, void* a3, void* a4, void* a5, void* a6, int a7);
|
||||
int _dialogSetScrollUp(int a1, int a2, char* a3, char* a4, char* a5, char* a6, int a7);
|
||||
int _dialogSetScrollDown(int a1, int a2, char* a3, char* a4, char* a5, char* a6, int a7);
|
||||
int dialogSetOptionSpacing(int value);
|
||||
int dialogSetOptionColor(float a1, float a2, float a3);
|
||||
int dialogSetReplyColor(float a1, float a2, float a3);
|
||||
int _dialogSetOptionFlags(int flags);
|
||||
void dialogInit();
|
||||
void _dialogClose();
|
||||
int _dialogGetDialogDepth();
|
||||
void _dialogRegisterWinDrawCallbacks(DialogFunc1* a1, DialogFunc2* a2);
|
||||
|
||||
+249
-12
@@ -44,24 +44,19 @@ static void dictionaryFreeDefaultImpl(void* ptr)
|
||||
}
|
||||
|
||||
// 0x4D9BA8
|
||||
int dictionaryInit(Dictionary* dictionary, int initialCapacity, size_t valueSize, void* a4)
|
||||
int dictionaryInit(Dictionary* dictionary, int initialCapacity, size_t valueSize, DictionaryIO* io)
|
||||
{
|
||||
dictionary->entriesCapacity = initialCapacity;
|
||||
dictionary->valueSize = valueSize;
|
||||
dictionary->entriesLength = 0;
|
||||
|
||||
if (a4 != NULL) {
|
||||
// NOTE: There is some structure pointed by [a4] with 5 fields. They are
|
||||
// either memcopied or assigned one by one into field_10 - field_20
|
||||
// respectively. This parameter is always NULL, so I doubt it's possible
|
||||
// to understand it's meaning. There are some hints in the unused
|
||||
// functions though.
|
||||
assert(false && "Not implemented");
|
||||
if (io != NULL) {
|
||||
memcpy(&(dictionary->io), io, sizeof(*io));
|
||||
} else {
|
||||
dictionary->field_10 = 0;
|
||||
dictionary->field_14 = 0;
|
||||
dictionary->field_18 = 0;
|
||||
dictionary->field_1C = 0;
|
||||
dictionary->io.readProc = NULL;
|
||||
dictionary->io.writeProc = NULL;
|
||||
dictionary->io.field_8 = 0;
|
||||
dictionary->io.field_C = 0;
|
||||
}
|
||||
|
||||
int rc = 0;
|
||||
@@ -302,6 +297,248 @@ int dictionaryRemoveValue(Dictionary* dictionary, const char* key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4D9F84
|
||||
int dictionaryCopy(Dictionary* dest, Dictionary* src)
|
||||
{
|
||||
if (src->marker != DICTIONARY_MARKER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dictionaryInit(dest, src->entriesCapacity, src->valueSize, &(src->io)) != 0) {
|
||||
// FIXME: Should return -1, as we were unable to initialize dictionary.
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int index = 0; index < src->entriesLength; index++) {
|
||||
DictionaryEntry* entry = &(src->entries[index]);
|
||||
if (dictionaryAddValue(dest, entry->key, entry->value) == -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4DA090
|
||||
int dictionaryReadInt(FILE* stream, int* valuePtr)
|
||||
{
|
||||
int ch;
|
||||
int value;
|
||||
|
||||
ch = fgetc(stream);
|
||||
if (ch == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = (ch & 0xFF);
|
||||
|
||||
ch = fgetc(stream);
|
||||
if (ch == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = (value << 8) | (ch & 0xFF);
|
||||
|
||||
ch = fgetc(stream);
|
||||
if (ch == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = (value << 8) | (ch & 0xFF);
|
||||
|
||||
ch = fgetc(stream);
|
||||
if (ch == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = (value << 8) | (ch & 0xFF);
|
||||
|
||||
*valuePtr = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4DA0F4
|
||||
int dictionaryReadHeader(FILE* stream, Dictionary* dictionary)
|
||||
{
|
||||
int value;
|
||||
|
||||
if (dictionaryReadInt(stream, &value) != 0) return -1;
|
||||
dictionary->entriesLength = value;
|
||||
|
||||
if (dictionaryReadInt(stream, &value) != 0) return -1;
|
||||
dictionary->entriesCapacity = value;
|
||||
|
||||
if (dictionaryReadInt(stream, &value) != 0) return -1;
|
||||
dictionary->valueSize = value;
|
||||
|
||||
// NOTE: Originally reads `values` pointer.
|
||||
if (dictionaryReadInt(stream, &value) != 0) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4DA158
|
||||
int dictionaryLoad(FILE* stream, Dictionary* dictionary, int a3)
|
||||
{
|
||||
if (dictionary->marker != DICTIONARY_MARKER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int index = 0; index < dictionary->entriesLength; index++) {
|
||||
DictionaryEntry* entry = &(dictionary->entries[index]);
|
||||
if (entry->key != NULL) {
|
||||
gDictionaryFreeProc(entry->key);
|
||||
}
|
||||
|
||||
if (entry->value != NULL) {
|
||||
gDictionaryFreeProc(entry->value);
|
||||
}
|
||||
}
|
||||
|
||||
if (dictionary->entries != NULL) {
|
||||
gDictionaryFreeProc(dictionary->entries);
|
||||
}
|
||||
|
||||
if (dictionaryReadHeader(stream, dictionary) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dictionary->entries = NULL;
|
||||
|
||||
if (dictionary->entriesCapacity <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
dictionary->entries = (DictionaryEntry*)gDictionaryMallocProc(sizeof(*dictionary->entries) * dictionary->entriesCapacity);
|
||||
if (dictionary->entries == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int index = 0; index < dictionary->entriesLength; index++) {
|
||||
DictionaryEntry* entry = &(dictionary->entries[index]);
|
||||
entry->key = NULL;
|
||||
entry->value = NULL;
|
||||
}
|
||||
|
||||
if (dictionary->entriesLength <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int index = 0; index < dictionary->entriesLength; index++) {
|
||||
DictionaryEntry* entry = &(dictionary->entries[index]);
|
||||
int keyLength = fgetc(stream);
|
||||
if (keyLength == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
entry->key = (char*)gDictionaryMallocProc(keyLength + 1);
|
||||
if (entry->key == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fgets(entry->key, keyLength, stream) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dictionary->valueSize != 0) {
|
||||
entry->value = gDictionaryMallocProc(dictionary->valueSize);
|
||||
if (entry->value == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dictionary->io.readProc != NULL) {
|
||||
if (dictionary->io.readProc(stream, entry->value, dictionary->valueSize, a3) != 0) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (fread(entry->value, dictionary->valueSize, 1, stream) != 1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4DA2EC
|
||||
int dictionaryWriteInt(FILE* stream, int value)
|
||||
{
|
||||
if (fputc((value >> 24) & 0xFF, stream) == -1) return -1;
|
||||
if (fputc((value >> 16) & 0xFF, stream) == -1) return -1;
|
||||
if (fputc((value >> 8) & 0xFF, stream) == -1) return -1;
|
||||
if (fputc(value & 0xFF, stream) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4DA360
|
||||
int dictionaryWriteHeader(FILE* stream, Dictionary* dictionary)
|
||||
{
|
||||
if (dictionaryWriteInt(stream, dictionary->entriesLength) != 0) return -1;
|
||||
if (dictionaryWriteInt(stream, dictionary->entriesCapacity) != 0) return -1;
|
||||
if (dictionaryWriteInt(stream, dictionary->valueSize) != 0) return -1;
|
||||
// NOTE: Originally writes `entries` pointer.
|
||||
if (dictionaryWriteInt(stream, 0) != 0) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4DA3A4
|
||||
int dictionaryWrite(FILE* stream, Dictionary* dictionary, int a3)
|
||||
{
|
||||
if (dictionary->marker != DICTIONARY_MARKER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dictionaryWriteHeader(stream, dictionary) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int index = 0; index < dictionary->entriesLength; index++) {
|
||||
DictionaryEntry* entry = &(dictionary->entries[index]);
|
||||
int keyLength = strlen(entry->key);
|
||||
if (fputc(keyLength, stream) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fputs(entry->key, stream) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dictionary->io.writeProc != NULL) {
|
||||
if (dictionary->valueSize != 0) {
|
||||
if (dictionary->io.writeProc(stream, entry->value, dictionary->valueSize, a3) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dictionary->valueSize != 0) {
|
||||
if (fwrite(entry->value, dictionary->valueSize, 1, stream) != 1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x4DA498
|
||||
void dictionarySetMemoryProcs(MallocProc* mallocProc, ReallocProc* reallocProc, FreeProc* freeProc)
|
||||
{
|
||||
|
||||
+24
-6
@@ -3,6 +3,20 @@
|
||||
|
||||
#include "memory_defs.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef int(DictionaryReadProc)(FILE* stream, void* buffer, unsigned int size, int a4);
|
||||
typedef int(DictionaryWriteProc)(FILE* stream, void* buffer, unsigned int size, int a4);
|
||||
|
||||
// NOTE: Last unnamed fields are likely seek, tell, and filelength.
|
||||
typedef struct DictionaryIO {
|
||||
DictionaryReadProc* readProc;
|
||||
DictionaryWriteProc* writeProc;
|
||||
int field_8;
|
||||
int field_C;
|
||||
int field_10;
|
||||
} DictionaryIO;
|
||||
|
||||
// A tuple containing individual key-value pair of a dictionary.
|
||||
typedef struct DictionaryEntry {
|
||||
char* key;
|
||||
@@ -27,22 +41,26 @@ typedef struct Dictionary {
|
||||
// The size of the dictionary values in bytes.
|
||||
size_t valueSize;
|
||||
|
||||
int field_10;
|
||||
int field_14;
|
||||
int field_18;
|
||||
int field_1C;
|
||||
int field_20;
|
||||
// IO callbacks.
|
||||
DictionaryIO io;
|
||||
|
||||
// The array of key-value pairs.
|
||||
DictionaryEntry* entries;
|
||||
} Dictionary;
|
||||
|
||||
int dictionaryInit(Dictionary* dictionary, int initialCapacity, size_t valueSize, void* a4);
|
||||
int dictionaryInit(Dictionary* dictionary, int initialCapacity, size_t valueSize, DictionaryIO* io);
|
||||
int dictionarySetCapacity(Dictionary* dictionary, int newCapacity);
|
||||
int dictionaryFree(Dictionary* dictionary);
|
||||
int dictionaryGetIndexByKey(Dictionary* dictionary, const char* key);
|
||||
int dictionaryAddValue(Dictionary* dictionary, const char* key, const void* value);
|
||||
int dictionaryRemoveValue(Dictionary* dictionary, const char* key);
|
||||
int dictionaryCopy(Dictionary* dest, Dictionary* src);
|
||||
int dictionaryReadInt(FILE* stream, int* valuePtr);
|
||||
int dictionaryReadHeader(FILE* stream, Dictionary* dictionary);
|
||||
int dictionaryLoad(FILE* stream, Dictionary* dictionary, int a3);
|
||||
int dictionaryWriteInt(FILE* stream, int value);
|
||||
int dictionaryWriteHeader(FILE* stream, Dictionary* dictionary);
|
||||
int dictionaryWrite(FILE* stream, Dictionary* dictionary, int a3);
|
||||
void dictionarySetMemoryProcs(MallocProc* mallocProc, ReallocProc* reallocProc, FreeProc* freeProc);
|
||||
|
||||
#endif /* DICTIONARY_H */
|
||||
|
||||
+87
-1
@@ -1,6 +1,18 @@
|
||||
#include "dinput.h"
|
||||
|
||||
#include <SDL.h>
|
||||
static int gTouchMouseLastX = 0;
|
||||
static int gTouchMouseLastY = 0;
|
||||
static int gTouchMouseDeltaX = 0;
|
||||
static int gTouchMouseDeltaY = 0;
|
||||
|
||||
static int gTouchFingers = 0;
|
||||
static unsigned int gTouchGestureLastTouchDownTimestamp = 0;
|
||||
static unsigned int gTouchGestureLastTouchUpTimestamp = 0;
|
||||
static int gTouchGestureTaps = 0;
|
||||
static bool gTouchGestureHandled = false;
|
||||
|
||||
extern int screenGetWidth();
|
||||
extern int screenGetHeight();
|
||||
|
||||
// 0x4E0400
|
||||
bool directInputInit()
|
||||
@@ -47,9 +59,42 @@ bool mouseDeviceUnacquire()
|
||||
// 0x4E053C
|
||||
bool mouseDeviceGetData(MouseData* mouseState)
|
||||
{
|
||||
#if __ANDROID__
|
||||
mouseState->x = gTouchMouseDeltaX;
|
||||
mouseState->y = gTouchMouseDeltaY;
|
||||
mouseState->buttons[0] = 0;
|
||||
mouseState->buttons[1] = 0;
|
||||
gTouchMouseDeltaX = 0;
|
||||
gTouchMouseDeltaY = 0;
|
||||
|
||||
if (gTouchFingers == 0) {
|
||||
if (SDL_GetTicks() - gTouchGestureLastTouchUpTimestamp > 150) {
|
||||
if (!gTouchGestureHandled) {
|
||||
if (gTouchGestureTaps == 2) {
|
||||
mouseState->buttons[0] = 1;
|
||||
gTouchGestureHandled = true;
|
||||
} else if (gTouchGestureTaps == 3) {
|
||||
mouseState->buttons[1] = 1;
|
||||
gTouchGestureHandled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (gTouchFingers == 1) {
|
||||
if (SDL_GetTicks() - gTouchGestureLastTouchDownTimestamp > 150) {
|
||||
if (gTouchGestureTaps == 1) {
|
||||
mouseState->buttons[0] = 1;
|
||||
gTouchGestureHandled = true;
|
||||
} else if (gTouchGestureTaps == 2) {
|
||||
mouseState->buttons[1] = 1;
|
||||
gTouchGestureHandled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
Uint32 buttons = SDL_GetRelativeMouseState(&(mouseState->x), &(mouseState->y));
|
||||
mouseState->buttons[0] = (buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0;
|
||||
mouseState->buttons[1] = (buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -100,3 +145,44 @@ bool keyboardDeviceInit()
|
||||
void keyboardDeviceFree()
|
||||
{
|
||||
}
|
||||
|
||||
void handleTouchFingerEvent(SDL_TouchFingerEvent* event)
|
||||
{
|
||||
int windowWidth = screenGetWidth();
|
||||
int windowHeight = screenGetHeight();
|
||||
|
||||
if (event->type == SDL_FINGERDOWN) {
|
||||
gTouchFingers++;
|
||||
|
||||
gTouchMouseLastX = (int)(event->x * windowWidth);
|
||||
gTouchMouseLastY = (int)(event->y * windowHeight);
|
||||
gTouchMouseDeltaX = 0;
|
||||
gTouchMouseDeltaY = 0;
|
||||
|
||||
if (event->timestamp - gTouchGestureLastTouchDownTimestamp > 250) {
|
||||
gTouchGestureTaps = 0;
|
||||
gTouchGestureHandled = false;
|
||||
}
|
||||
|
||||
gTouchGestureLastTouchDownTimestamp = event->timestamp;
|
||||
} else if (event->type == SDL_FINGERMOTION) {
|
||||
int prevX = gTouchMouseLastX;
|
||||
int prevY = gTouchMouseLastY;
|
||||
gTouchMouseLastX = (int)(event->x * windowWidth);
|
||||
gTouchMouseLastY = (int)(event->y * windowHeight);
|
||||
gTouchMouseDeltaX += gTouchMouseLastX - prevX;
|
||||
gTouchMouseDeltaY += gTouchMouseLastY - prevY;
|
||||
} else if (event->type == SDL_FINGERUP) {
|
||||
gTouchFingers--;
|
||||
|
||||
int prevX = gTouchMouseLastX;
|
||||
int prevY = gTouchMouseLastY;
|
||||
gTouchMouseLastX = (int)(event->x * windowWidth);
|
||||
gTouchMouseLastY = (int)(event->y * windowHeight);
|
||||
gTouchMouseDeltaX += gTouchMouseLastX - prevX;
|
||||
gTouchMouseDeltaY += gTouchMouseLastY - prevY;
|
||||
|
||||
gTouchGestureTaps++;
|
||||
gTouchGestureLastTouchUpTimestamp = event->timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef DINPUT_H
|
||||
#define DINPUT_H
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
typedef struct MouseData {
|
||||
int x;
|
||||
int y;
|
||||
@@ -26,4 +28,6 @@ void mouseDeviceFree();
|
||||
bool keyboardDeviceInit();
|
||||
void keyboardDeviceFree();
|
||||
|
||||
void handleTouchFingerEvent(SDL_TouchFingerEvent* event);
|
||||
|
||||
#endif /* DINPUT_H */
|
||||
|
||||
@@ -105,7 +105,7 @@ int displayMonitorInit()
|
||||
}
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundFid = buildFid(6, 16, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 16, 0, 0, 0);
|
||||
Art* backgroundFrm = artLock(backgroundFid, &backgroundFrmHandle);
|
||||
if (backgroundFrm == NULL) {
|
||||
internal_free(gDisplayMonitorBackgroundFrmData);
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#ifndef DRAW_H
|
||||
#define DRAW_H
|
||||
|
||||
void bufferDrawLine(unsigned char* buf, int pitch, int left, int top, int right, int bottom, int color);
|
||||
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);
|
||||
void blitBufferToBufferStretch(unsigned char* src, int srcWidth, int srcHeight, int srcPitch, unsigned char* dest, int destWidth, int destHeight, int destPitch);
|
||||
|
||||
+3
-3
@@ -503,7 +503,7 @@ static int elevatorWindowInit(int elevator)
|
||||
|
||||
int index;
|
||||
for (index = 0; index < ELEVATOR_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, gElevatorFrmIds[index], 0, 0, 0);
|
||||
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) {
|
||||
break;
|
||||
@@ -530,11 +530,11 @@ static int elevatorWindowInit(int elevator)
|
||||
const ElevatorBackground* elevatorBackground = &(gElevatorBackgrounds[elevator]);
|
||||
bool backgroundsLoaded = true;
|
||||
|
||||
int backgroundFid = buildFid(6, elevatorBackground->backgroundFrmId, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, elevatorBackground->backgroundFrmId, 0, 0, 0);
|
||||
gElevatorBackgroundFrmData = artLockFrameDataReturningSize(backgroundFid, &gElevatorBackgroundFrmHandle, &gElevatorBackgroundFrmWidth, &gElevatorBackgroundFrmHeight);
|
||||
if (gElevatorBackgroundFrmData != NULL) {
|
||||
if (elevatorBackground->panelFrmId != -1) {
|
||||
int panelFid = buildFid(6, elevatorBackground->panelFrmId, 0, 0, 0);
|
||||
int panelFid = buildFid(OBJ_TYPE_INTERFACE, elevatorBackground->panelFrmId, 0, 0, 0);
|
||||
gElevatorPanelFrmData = artLockFrameDataReturningSize(panelFid, &gElevatorPanelFrmHandle, &gElevatorPanelFrmWidth, &gElevatorPanelFrmHeight);
|
||||
if (gElevatorPanelFrmData == NULL) {
|
||||
gElevatorPanelFrmData = ELEVATOR_BACKGROUND_NULL;
|
||||
|
||||
+7
-15
@@ -217,7 +217,7 @@ void endgamePlaySlideshow()
|
||||
if (ending->art_num == 327) {
|
||||
endgameEndingRenderPanningScene(ending->direction, ending->voiceOverBaseName);
|
||||
} else {
|
||||
int fid = buildFid(6, ending->art_num, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, ending->art_num, 0, 0, 0);
|
||||
endgameEndingRenderStaticScene(fid, ending->voiceOverBaseName);
|
||||
}
|
||||
}
|
||||
@@ -309,7 +309,7 @@ static int endgameEndingHandleContinuePlaying()
|
||||
// 0x43FBDC
|
||||
static void endgameEndingRenderPanningScene(int direction, const char* narratorFileName)
|
||||
{
|
||||
int fid = buildFid(6, 327, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 327, 0, 0, 0);
|
||||
|
||||
CacheEntry* backgroundHandle;
|
||||
Art* background = artLock(fid, &backgroundHandle);
|
||||
@@ -441,7 +441,7 @@ static void endgameEndingRenderStaticScene(int fid, const char* narratorFileName
|
||||
blitBufferToBuffer(backgroundData, ENDGAME_ENDING_WINDOW_WIDTH, ENDGAME_ENDING_WINDOW_HEIGHT, ENDGAME_ENDING_WINDOW_WIDTH, gEndgameEndingSlideshowWindowBuffer, ENDGAME_ENDING_WINDOW_WIDTH);
|
||||
windowRefresh(gEndgameEndingSlideshowWindow);
|
||||
|
||||
endgameEndingLoadPalette((fid & 0xF000000) >> 24, fid & 0xFFF);
|
||||
endgameEndingLoadPalette(FID_TYPE(fid), fid & 0xFFF);
|
||||
|
||||
endgameEndingVoiceOverInit(narratorFileName);
|
||||
|
||||
@@ -746,23 +746,15 @@ static int endgameEndingSubtitlesLoad(const char* filePath)
|
||||
char* pch;
|
||||
|
||||
// Find and clamp string at EOL.
|
||||
pch = string;
|
||||
while (*pch != '\0' && *pch != '\n') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch != '\0') {
|
||||
pch = strchr(string, '\n');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
}
|
||||
|
||||
// Find separator. The value before separator is ignored (as opposed to
|
||||
// movie subtitles, where the value before separator is a timing).
|
||||
pch = string;
|
||||
while (*pch != '\0' && *pch != ':') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch != '\0') {
|
||||
pch = strchr(string, ':');
|
||||
if (pch != NULL) {
|
||||
if (gEndgameEndingSubtitlesLength < ENDGAME_ENDING_MAX_SUBTITLES) {
|
||||
gEndgameEndingSubtitles[gEndgameEndingSubtitlesLength] = internal_strdup(pch + 1);
|
||||
gEndgameEndingSubtitlesLength++;
|
||||
|
||||
+6
-7
@@ -176,12 +176,11 @@ int externalVariableSetValue(Program* program, const char* name, ProgramValue& p
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
|
||||
if ((exportedVariable->value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
||||
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 169
|
||||
}
|
||||
|
||||
if ((programValue.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
|
||||
if ((programValue.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
||||
if (program != NULL) {
|
||||
const char* stringValue = programGetString(program, programValue.opcode, programValue.integerValue);
|
||||
exportedVariable->value.opcode = VALUE_TYPE_DYNAMIC_STRING;
|
||||
@@ -204,7 +203,7 @@ int externalVariableGetValue(Program* program, const char* name, ProgramValue& v
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
|
||||
if ((exportedVariable->value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
||||
value.opcode = exportedVariable->value.opcode;
|
||||
value.integerValue = programPushString(program, exportedVariable->stringValue);
|
||||
} else {
|
||||
@@ -225,7 +224,7 @@ int externalVariableCreate(Program* program, const char* identifier)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
|
||||
if ((exportedVariable->value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
||||
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 234
|
||||
}
|
||||
} else {
|
||||
@@ -261,7 +260,7 @@ void _removeProgramReferences(Program* program)
|
||||
// 0x44152C
|
||||
void _initExport()
|
||||
{
|
||||
_interpretRegisterProgramDeleteCallback(_removeProgramReferences);
|
||||
intLibRegisterProgramDeleteCallback(_removeProgramReferences);
|
||||
}
|
||||
|
||||
// 0x441538
|
||||
@@ -328,7 +327,7 @@ void _exportClearAllVariables()
|
||||
for (int index = 0; index < 1013; index++) {
|
||||
ExternalVariable* exportedVariable = &(gExternalVariables[index]);
|
||||
if (exportedVariable->name[0] != '\0') {
|
||||
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
|
||||
if ((exportedVariable->value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
||||
if (exportedVariable->stringValue != NULL) {
|
||||
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 387
|
||||
}
|
||||
|
||||
+25
-37
@@ -720,14 +720,14 @@ int gameHandleKey(int eventCode, bool isInCombatMode)
|
||||
case KEY_COMMA:
|
||||
case KEY_LESS:
|
||||
if (reg_anim_begin(0) == 0) {
|
||||
reg_anim_rotate_counter_clockwise(gDude);
|
||||
animationRegisterRotateCounterClockwise(gDude);
|
||||
reg_anim_end();
|
||||
}
|
||||
break;
|
||||
case KEY_DOT:
|
||||
case KEY_GREATER:
|
||||
if (reg_anim_begin(0) == 0) {
|
||||
reg_anim_rotate_clockwise(gDude);
|
||||
animationRegisterRotateClockwise(gDude);
|
||||
reg_anim_end();
|
||||
}
|
||||
break;
|
||||
@@ -930,68 +930,56 @@ static int gameLoadGlobalVars()
|
||||
}
|
||||
|
||||
// 0x443CE8
|
||||
int globalVarsRead(const char* path, const char* section, int* out_vars_num, int** out_vars)
|
||||
int globalVarsRead(const char* path, const char* section, int* variablesListLengthPtr, int** variablesListPtr)
|
||||
{
|
||||
File* stream;
|
||||
char str[258];
|
||||
char* ch;
|
||||
|
||||
_inven_reset_dude();
|
||||
|
||||
stream = fileOpen(path, "rt");
|
||||
File* stream = fileOpen(path, "rt");
|
||||
if (stream == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*out_vars_num != 0) {
|
||||
internal_free(*out_vars);
|
||||
*out_vars = NULL;
|
||||
*out_vars_num = 0;
|
||||
if (*variablesListLengthPtr != 0) {
|
||||
internal_free(*variablesListPtr);
|
||||
*variablesListPtr = NULL;
|
||||
*variablesListLengthPtr = 0;
|
||||
}
|
||||
|
||||
char string[260];
|
||||
if (section != NULL) {
|
||||
while (fileReadString(str, sizeof(str), stream)) {
|
||||
if (strncmp(str, section, 16) == 0) {
|
||||
while (fileReadString(string, 258, stream)) {
|
||||
if (strncmp(string, section, 16) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (fileReadString(str, sizeof(str), stream)) {
|
||||
if (str[0] == '\n') {
|
||||
while (fileReadString(string, 258, stream)) {
|
||||
if (string[0] == '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str[0] == '/' && str[1] == '/') {
|
||||
if (string[0] == '/' && string[1] == '/') {
|
||||
continue;
|
||||
}
|
||||
|
||||
ch = str;
|
||||
|
||||
while (*ch != '\0' && *ch != ';') {
|
||||
ch++;
|
||||
char* semicolon = strchr(string, ';');
|
||||
if (semicolon != NULL) {
|
||||
*semicolon = '\0';
|
||||
}
|
||||
|
||||
if (*ch != '\0') {
|
||||
*ch = '\0';
|
||||
}
|
||||
*variablesListLengthPtr = *variablesListLengthPtr + 1;
|
||||
*variablesListPtr = (int*)internal_realloc(*variablesListPtr, sizeof(int) * *variablesListLengthPtr);
|
||||
|
||||
*out_vars_num = *out_vars_num + 1;
|
||||
*out_vars = (int*)internal_realloc(*out_vars, sizeof(int) * *out_vars_num);
|
||||
|
||||
if (*out_vars == NULL) {
|
||||
if (*variablesListPtr == NULL) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ch = str;
|
||||
while (*ch != '\0' && *ch != '=') {
|
||||
ch++;
|
||||
}
|
||||
|
||||
if (*ch != '\0') {
|
||||
sscanf(ch + 1, "%d", *out_vars + *out_vars_num - 1);
|
||||
char* equals = strchr(string, '=');
|
||||
if (equals != NULL) {
|
||||
sscanf(equals + 1, "%d", *variablesListPtr + *variablesListLengthPtr - 1);
|
||||
} else {
|
||||
*out_vars[*out_vars_num - 1] = 0;
|
||||
*variablesListPtr[*variablesListLengthPtr - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1098,7 +1086,7 @@ static void showHelp()
|
||||
if (win != -1) {
|
||||
unsigned char* windowBuffer = windowGetBuffer(win);
|
||||
if (windowBuffer != NULL) {
|
||||
int backgroundFid = buildFid(6, 297, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 297, 0, 0, 0);
|
||||
CacheEntry* backgroundHandle;
|
||||
unsigned char* backgroundData = artLockFrameData(backgroundFid, 0, 0, &backgroundHandle);
|
||||
if (backgroundData != NULL) {
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ void gameUiEnable();
|
||||
bool gameUiIsDisabled();
|
||||
int gameGetGlobalVar(int var);
|
||||
int gameSetGlobalVar(int var, int value);
|
||||
int globalVarsRead(const char* path, const char* section, int* out_vars_num, int** out_vars);
|
||||
int globalVarsRead(const char* path, const char* section, int* variablesListLengthPtr, int** variablesListPtr);
|
||||
int _game_state();
|
||||
int _game_state_request(int a1);
|
||||
void _game_state_update();
|
||||
|
||||
+59
-59
@@ -717,7 +717,7 @@ void gameDialogEnter(Object* a1, int a2)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((a1->pid >> 24) != OBJ_TYPE_ITEM && (a1->sid >> 24) != SCRIPT_TYPE_SPATIAL) {
|
||||
if (PID_TYPE(a1->pid) != OBJ_TYPE_ITEM && SID_TYPE(a1->sid) != SCRIPT_TYPE_SPATIAL) {
|
||||
MessageListItem messageListItem;
|
||||
|
||||
int rc = _action_can_talk_to(gDude, a1);
|
||||
@@ -915,9 +915,9 @@ int _gdialogInitFromScript(int headFid, int reaction)
|
||||
gGameDialogSpeakerIsPartyMember = objectIsPartyMember(gGameDialogSpeaker);
|
||||
_oldFont = fontGetCurrent();
|
||||
fontSetCurrent(101);
|
||||
dialogSetReplyWindow(135, 225, 379, 58, 0);
|
||||
dialogSetReplyWindow(135, 225, 379, 58, NULL);
|
||||
dialogSetReplyColor(0.3f, 0.3f, 0.3f);
|
||||
dialogSetOptionWindow(127, 335, 393, 117, 0);
|
||||
dialogSetOptionWindow(127, 335, 393, 117, NULL);
|
||||
dialogSetOptionColor(0.2f, 0.2f, 0.2f);
|
||||
dialogSetReplyTitle(NULL);
|
||||
_dialogRegisterWinDrawCallbacks(_demo_copy_title, _demo_copy_options);
|
||||
@@ -930,7 +930,7 @@ int _gdialogInitFromScript(int headFid, int reaction)
|
||||
gameMouseSetCursor(MOUSE_CURSOR_ARROW);
|
||||
textObjectsReset();
|
||||
|
||||
if ((gGameDialogSpeaker->pid >> 24) != OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(gGameDialogSpeaker->pid) != OBJ_TYPE_ITEM) {
|
||||
_tile_scroll_to(gGameDialogSpeaker->tile, 2);
|
||||
}
|
||||
|
||||
@@ -970,7 +970,7 @@ int _gdialogExitFromScript()
|
||||
dialogReviewEntriesClear();
|
||||
tickersRemove(gameDialogTicker);
|
||||
|
||||
if (gGameDialogSpeaker->pid >> 24 != OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(gGameDialogSpeaker->pid) != OBJ_TYPE_ITEM) {
|
||||
if (gGameDialogOldDudeTile != gDude->tile) {
|
||||
gGameDialogOldCenterTile = gDude->tile;
|
||||
}
|
||||
@@ -1298,7 +1298,7 @@ int gameDialogReviewWindowInit(int* win)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fid = buildFid(6, 102, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 102, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &_reviewBackKey);
|
||||
if (backgroundFrmData == NULL) {
|
||||
windowDestroy(*win);
|
||||
@@ -1318,10 +1318,10 @@ int gameDialogReviewWindowInit(int* win)
|
||||
_reviewBackKey = INVALID_CACHE_ENTRY;
|
||||
|
||||
unsigned char* buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_COUNT];
|
||||
|
||||
|
||||
int index;
|
||||
for (index = 0; index < GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, gGameDialogReviewWindowButtonFrmIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameDialogReviewWindowButtonFrmIds[index], 0, 0, 0);
|
||||
buttonFrmData[index] = artLockFrameData(fid, 0, 0, &(gGameDialogReviewWindowButtonFrmHandles[index]));
|
||||
if (buttonFrmData[index] == NULL) {
|
||||
break;
|
||||
@@ -1360,11 +1360,11 @@ int gameDialogReviewWindowInit(int* win)
|
||||
gGameDialogReviewWindowButtonHeights[GAME_DIALOG_REVIEW_WINDOW_BUTTON_SCROLL_DOWN],
|
||||
-1,
|
||||
-1,
|
||||
-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],
|
||||
NULL,
|
||||
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_DOWN_PRESSED],
|
||||
NULL,
|
||||
BUTTON_FLAG_TRANSPARENT);
|
||||
if (downBtn == -1) {
|
||||
gameDialogReviewWindowFree(win);
|
||||
@@ -1373,18 +1373,18 @@ int gameDialogReviewWindowInit(int* win)
|
||||
|
||||
buttonSetCallbacks(downBtn, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
int doneBtn = buttonCreate(*win,
|
||||
499,
|
||||
398,
|
||||
gGameDialogReviewWindowButtonWidths[GAME_DIALOG_REVIEW_WINDOW_BUTTON_DONE],
|
||||
int doneBtn = buttonCreate(*win,
|
||||
499,
|
||||
398,
|
||||
gGameDialogReviewWindowButtonWidths[GAME_DIALOG_REVIEW_WINDOW_BUTTON_DONE],
|
||||
gGameDialogReviewWindowButtonHeights[GAME_DIALOG_REVIEW_WINDOW_BUTTON_DONE],
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
KEY_ESCAPE,
|
||||
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_DONE_NORMAL],
|
||||
-1,
|
||||
-1,
|
||||
KEY_ESCAPE,
|
||||
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_DONE_NORMAL],
|
||||
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_DONE_PRESSED],
|
||||
NULL,
|
||||
NULL,
|
||||
BUTTON_FLAG_TRANSPARENT);
|
||||
if (doneBtn == -1) {
|
||||
gameDialogReviewWindowFree(win);
|
||||
@@ -1399,7 +1399,7 @@ int gameDialogReviewWindowInit(int* win)
|
||||
|
||||
tickersRemove(gameDialogTicker);
|
||||
|
||||
int backgroundFid = buildFid(6, 102, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 102, 0, 0, 0);
|
||||
gGameDialogReviewWindowBackgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &gGameDialogReviewWindowBackgroundFrmHandle);
|
||||
if (gGameDialogReviewWindowBackgroundFrmData == NULL) {
|
||||
gameDialogReviewWindowFree(win);
|
||||
@@ -1691,7 +1691,7 @@ int gameDialogSetReviewOptionText(const char* string)
|
||||
// 0x446288
|
||||
int _gdProcessInit()
|
||||
{
|
||||
int upBtn;
|
||||
int upBtn;
|
||||
int downBtn;
|
||||
int optionsWindowX;
|
||||
int optionsWindowY;
|
||||
@@ -1735,14 +1735,14 @@ int _gdProcessInit()
|
||||
}
|
||||
|
||||
// di_rdbt2.frm - dialog red button down
|
||||
fid = buildFid(6, 96, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 96, 0, 0, 0);
|
||||
gGameDialogRedButtonUpFrmData = artLockFrameData(fid, 0, 0, &gGameDialogRedButtonUpFrmHandle);
|
||||
if (gGameDialogRedButtonUpFrmData == NULL) {
|
||||
goto err_3;
|
||||
}
|
||||
|
||||
// di_rdbt1.frm - dialog red button up
|
||||
fid = buildFid(6, 95, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 95, 0, 0, 0);
|
||||
gGameDialogRedButtonDownFrmData = artLockFrameData(fid, 0, 0, &gGameDialogRedButtonDownFrmHandle);
|
||||
if (gGameDialogRedButtonDownFrmData == NULL) {
|
||||
goto err_3;
|
||||
@@ -3010,7 +3010,7 @@ int gameDialogDrawText(unsigned char* buffer, Rect* rect, char* string, int* a4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (*end == ' ') {
|
||||
*end = '\0';
|
||||
}
|
||||
@@ -3127,7 +3127,7 @@ int _gdialog_barter_create_win()
|
||||
frmId = 111;
|
||||
}
|
||||
|
||||
int backgroundFid = buildFid(6, frmId, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
|
||||
CacheEntry* backgroundHandle;
|
||||
Art* backgroundFrm = artLock(backgroundFid, &backgroundHandle);
|
||||
if (backgroundFrm == NULL) {
|
||||
@@ -3236,7 +3236,7 @@ void _gdialog_barter_destroy_win()
|
||||
}
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int fid = buildFid(6, frmId, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData != NULL) {
|
||||
unsigned char* windowBuffer = windowGetBuffer(gGameDialogWindow);
|
||||
@@ -3287,7 +3287,7 @@ void _gdialog_barter_cleanup_tables()
|
||||
int partyMemberControlWindowInit()
|
||||
{
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundFid = buildFid(6, 390, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 390, 0, 0, 0);
|
||||
Art* backgroundFrm = artLock(backgroundFid, &backgroundFrmHandle);
|
||||
if (backgroundFrm == NULL) {
|
||||
return -1;
|
||||
@@ -3359,7 +3359,7 @@ int partyMemberControlWindowInit()
|
||||
GameDialogButtonData* buttonData = &(gGameDialogDispositionButtonsData[index]);
|
||||
int fid;
|
||||
|
||||
fid = buildFid(6, buttonData->upFrmId, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, buttonData->upFrmId, 0, 0, 0);
|
||||
Art* upButtonFrm = artLock(fid, &(buttonData->upFrmHandle));
|
||||
if (upButtonFrm == NULL) {
|
||||
partyMemberControlWindowFree();
|
||||
@@ -3370,7 +3370,7 @@ int partyMemberControlWindowInit()
|
||||
int height = artGetHeight(upButtonFrm, 0, 0);
|
||||
unsigned char* upButtonFrmData = artGetFrameData(upButtonFrm, 0, 0);
|
||||
|
||||
fid = buildFid(6, buttonData->downFrmId, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, buttonData->downFrmId, 0, 0, 0);
|
||||
Art* downButtonFrm = artLock(fid, &(buttonData->downFrmHandle));
|
||||
if (downButtonFrm == NULL) {
|
||||
partyMemberControlWindowFree();
|
||||
@@ -3379,7 +3379,7 @@ int partyMemberControlWindowInit()
|
||||
|
||||
unsigned char* downButtonFrmData = artGetFrameData(downButtonFrm, 0, 0);
|
||||
|
||||
fid = buildFid(6, buttonData->disabledFrmId, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, buttonData->disabledFrmId, 0, 0, 0);
|
||||
Art* disabledButtonFrm = artLock(fid, &(buttonData->disabledFrmHandle));
|
||||
if (disabledButtonFrm == NULL) {
|
||||
partyMemberControlWindowFree();
|
||||
@@ -3394,14 +3394,14 @@ int partyMemberControlWindowInit()
|
||||
buttonData->x,
|
||||
buttonData->y,
|
||||
width,
|
||||
height,
|
||||
height,
|
||||
-1,
|
||||
-1,
|
||||
buttonData->keyCode,
|
||||
-1,
|
||||
upButtonFrmData,
|
||||
-1,
|
||||
buttonData->keyCode,
|
||||
-1,
|
||||
upButtonFrmData,
|
||||
downButtonFrmData,
|
||||
NULL,
|
||||
NULL,
|
||||
BUTTON_FLAG_TRANSPARENT | BUTTON_FLAG_0x04 | BUTTON_FLAG_0x01);
|
||||
if (_gdialog_buttons[v21] == -1) {
|
||||
partyMemberControlWindowFree();
|
||||
@@ -3463,7 +3463,7 @@ void partyMemberControlWindowFree()
|
||||
|
||||
// control.frm - party member control interface
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundFid = buildFid(6, 390, 0, 0, 0);
|
||||
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);
|
||||
@@ -3484,7 +3484,7 @@ void partyMemberControlWindowUpdate()
|
||||
int windowWidth = windowGetWidth(gGameDialogWindow);
|
||||
|
||||
CacheEntry* backgroundHandle;
|
||||
int backgroundFid = buildFid(6, 390, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 390, 0, 0, 0);
|
||||
Art* background = artLock(backgroundFid, &backgroundHandle);
|
||||
if (background != NULL) {
|
||||
int width = artGetWidth(background, 0, 0);
|
||||
@@ -3523,7 +3523,7 @@ void partyMemberControlWindowUpdate()
|
||||
|
||||
// Render preview.
|
||||
CacheEntry* previewHandle;
|
||||
int previewFid = buildFid((gGameDialogSpeaker->fid & 0xF000000) >> 24, gGameDialogSpeaker->fid & 0xFFF, ANIM_STAND, (gGameDialogSpeaker->fid & 0xF000) >> 12, ROTATION_SW);
|
||||
int previewFid = buildFid(FID_TYPE(gGameDialogSpeaker->fid), gGameDialogSpeaker->fid & 0xFFF, ANIM_STAND, (gGameDialogSpeaker->fid & 0xF000) >> 12, ROTATION_SW);
|
||||
Art* preview = artLock(previewFid, &previewHandle);
|
||||
if (preview != NULL) {
|
||||
int width = artGetWidth(preview, 0, ROTATION_SW);
|
||||
@@ -3603,7 +3603,7 @@ int _gdPickAIUpdateMsg(Object* critter)
|
||||
// 0x449330
|
||||
int _gdCanBarter()
|
||||
{
|
||||
if ((gGameDialogSpeaker->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(gGameDialogSpeaker->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -3612,7 +3612,7 @@ int _gdCanBarter()
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (proto->critter.data.flags & 0x02) {
|
||||
if (proto->critter.data.flags & CRITTER_FLAG_0x2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -3724,7 +3724,7 @@ int partyMemberCustomizationWindowInit()
|
||||
}
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundFid = buildFid(6, 391, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 391, 0, 0, 0);
|
||||
Art* backgroundFrm = artLock(backgroundFid, &backgroundFrmHandle);
|
||||
if (backgroundFrm == NULL) {
|
||||
return -1;
|
||||
@@ -3778,7 +3778,7 @@ int partyMemberCustomizationWindowInit()
|
||||
for (int index = 0; index < PARTY_MEMBER_CUSTOMIZATION_OPTION_COUNT; index++) {
|
||||
GameDialogButtonData* buttonData = &(_custom_button_info[index]);
|
||||
|
||||
int upButtonFid = buildFid(6, buttonData->upFrmId, 0, 0, 0);
|
||||
int upButtonFid = buildFid(OBJ_TYPE_INTERFACE, buttonData->upFrmId, 0, 0, 0);
|
||||
Art* upButtonFrm = artLock(upButtonFid, &(buttonData->upFrmHandle));
|
||||
if (upButtonFrm == NULL) {
|
||||
partyMemberCustomizationWindowFree();
|
||||
@@ -3789,7 +3789,7 @@ int partyMemberCustomizationWindowInit()
|
||||
int height = artGetHeight(upButtonFrm, 0, 0);
|
||||
unsigned char* upButtonFrmData = artGetFrameData(upButtonFrm, 0, 0);
|
||||
|
||||
int downButtonFid = buildFid(6, buttonData->downFrmId, 0, 0, 0);
|
||||
int downButtonFid = buildFid(OBJ_TYPE_INTERFACE, buttonData->downFrmId, 0, 0, 0);
|
||||
Art* downButtonFrm = artLock(downButtonFid, &(buttonData->downFrmHandle));
|
||||
if (downButtonFrm == NULL) {
|
||||
partyMemberCustomizationWindowFree();
|
||||
@@ -3867,7 +3867,7 @@ void partyMemberCustomizationWindowFree()
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
// custom.frm - party member control interface
|
||||
int fid = buildFid(6, 391, 0, 0, 0);
|
||||
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);
|
||||
@@ -3917,7 +3917,7 @@ void partyMemberCustomizationWindowUpdate()
|
||||
int windowWidth = windowGetWidth(gGameDialogWindow);
|
||||
|
||||
CacheEntry* backgroundHandle;
|
||||
int backgroundFid = buildFid(6, 391, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 391, 0, 0, 0);
|
||||
Art* background = artLock(backgroundFid, &backgroundHandle);
|
||||
if (background == NULL) {
|
||||
return;
|
||||
@@ -4025,7 +4025,7 @@ int _gdCustomSelect(int a1)
|
||||
int oldFont = fontGetCurrent();
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundFid = buildFid(6, 419, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 419, 0, 0, 0);
|
||||
Art* backgroundFrm = artLock(backgroundFid, &backgroundFrmHandle);
|
||||
if (backgroundFrm == NULL) {
|
||||
return -1;
|
||||
@@ -4208,7 +4208,7 @@ void _gdCustomUpdateSetting(int option, int value)
|
||||
// 0x44A52C
|
||||
void gameDialogBarterButtonUpMouseUp(int btn, int keyCode)
|
||||
{
|
||||
if ((gGameDialogSpeaker->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(gGameDialogSpeaker->pid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4219,7 +4219,7 @@ void gameDialogBarterButtonUpMouseUp(int btn, int keyCode)
|
||||
|
||||
Proto* proto;
|
||||
protoGetProto(gGameDialogSpeaker->pid, &proto);
|
||||
if (proto->critter.data.flags & 2) {
|
||||
if (proto->critter.data.flags & CRITTER_FLAG_0x2) {
|
||||
if (gGameDialogLipSyncStarted) {
|
||||
if (soundIsPlaying(gLipsData.sound)) {
|
||||
gameDialogEndLips();
|
||||
@@ -4269,7 +4269,7 @@ int _gdialog_window_create()
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
// 389 - di_talkp.frm - dialog screen subwindow (party members)
|
||||
// 99 - di_talk.frm - dialog screen subwindow (NPC's)
|
||||
int backgroundFid = buildFid(6, gGameDialogSpeakerIsPartyMember ? 389 : 99, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, gGameDialogSpeakerIsPartyMember ? 389 : 99, 0, 0, 0);
|
||||
Art* backgroundFrm = artLock(backgroundFid, &backgroundFrmHandle);
|
||||
if (backgroundFrm == NULL) {
|
||||
return -1;
|
||||
@@ -4306,11 +4306,11 @@ int _gdialog_window_create()
|
||||
buttonSetCallbacks(_gdialog_buttons[0], _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
// di_rest1.frm - dialog rest button up
|
||||
int upFid = buildFid(6, 97, 0, 0, 0);
|
||||
int upFid = buildFid(OBJ_TYPE_INTERFACE, 97, 0, 0, 0);
|
||||
unsigned char* reviewButtonUpData = artLockFrameData(upFid, 0, 0, &gGameDialogReviewButtonUpFrmHandle);
|
||||
if (reviewButtonUpData != NULL) {
|
||||
// di_rest2.frm - dialog rest button down
|
||||
int downFid = buildFid(6, 98, 0, 0, 0);
|
||||
int downFid = buildFid(OBJ_TYPE_INTERFACE, 98, 0, 0, 0);
|
||||
unsigned char* reivewButtonDownData = artLockFrameData(downFid, 0, 0, &gGameDialogReviewButtonDownFrmHandle);
|
||||
if (reivewButtonDownData != NULL) {
|
||||
// REVIEW
|
||||
@@ -4386,7 +4386,7 @@ void _gdialog_window_destroy()
|
||||
}
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int fid = buildFid(6, frmId, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData != NULL) {
|
||||
unsigned char* windowBuffer = windowGetBuffer(gGameDialogWindow);
|
||||
@@ -4403,7 +4403,7 @@ int gameDialogWindowRenderBackground()
|
||||
{
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
// alltlk.frm - dialog screen background
|
||||
int fid = buildFid(6, 103, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 103, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData == NULL) {
|
||||
return -1;
|
||||
@@ -4434,7 +4434,7 @@ int _talkToRefreshDialogWindowRect(Rect* rect)
|
||||
}
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int fid = buildFid(6, frmId, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData == NULL) {
|
||||
return -1;
|
||||
@@ -4550,7 +4550,7 @@ void gameDialogRenderTalkingHead(Art* headFrm, int frame)
|
||||
unsigned char* src = windowGetBuffer(gIsoWindow);
|
||||
|
||||
// Usually rendering functions use `screenGetWidth`/`screenGetHeight` to
|
||||
// determine rendering position. However in this case `windowGetHeight`
|
||||
// determine rendering position. However in this case `windowGetHeight`
|
||||
// is a must because isometric window's height can either include
|
||||
// interface bar or not. Offset is updated accordingly (332 -> 232, the
|
||||
// missing 100 is interface bar height, which is already accounted for
|
||||
@@ -4612,13 +4612,13 @@ void gameDialogPrepareHighlights()
|
||||
_dark_BlendTable = _getColorBlendTable(_colorTable[22187]);
|
||||
|
||||
// hilight1.frm - dialogue upper hilight
|
||||
int upperHighlightFid = buildFid(6, 115, 0, 0, 0);
|
||||
int upperHighlightFid = buildFid(OBJ_TYPE_INTERFACE, 115, 0, 0, 0);
|
||||
gGameDialogUpperHighlightFrm = artLock(upperHighlightFid, &gGameDialogUpperHighlightFrmHandle);
|
||||
gGameDialogUpperHighlightFrmWidth = artGetWidth(gGameDialogUpperHighlightFrm, 0, 0);
|
||||
gGameDialogUpperHighlightFrmHeight = artGetHeight(gGameDialogUpperHighlightFrm, 0, 0);
|
||||
|
||||
// hilight2.frm - dialogue lower hilight
|
||||
int lowerHighlightFid = buildFid(6, 116, 0, 0, 0);
|
||||
int lowerHighlightFid = buildFid(OBJ_TYPE_INTERFACE, 116, 0, 0, 0);
|
||||
gGameDialogLowerHighlightFrm = artLock(lowerHighlightFid, &gGameDialogLowerHighlightFrmHandle);
|
||||
gGameDialogLowerHighlightFrmWidth = artGetWidth(gGameDialogLowerHighlightFrm, 0, 0);
|
||||
gGameDialogLowerHighlightFrmHeight = artGetHeight(gGameDialogLowerHighlightFrm, 0, 0);
|
||||
|
||||
+37
-37
@@ -648,7 +648,7 @@ void gameMouseRefresh()
|
||||
if (pointedObject != NULL) {
|
||||
int primaryAction = -1;
|
||||
|
||||
switch ((pointedObject->fid & 0xF000000) >> 24) {
|
||||
switch (FID_TYPE(pointedObject->fid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
primaryAction = GAME_MOUSE_ACTION_MENU_ITEM_USE;
|
||||
if (gGameMouseItemHighlightEnabled) {
|
||||
@@ -670,7 +670,7 @@ void gameMouseRefresh()
|
||||
primaryAction = GAME_MOUSE_ACTION_MENU_ITEM_TALK;
|
||||
}
|
||||
} else {
|
||||
if (_critter_flag_check(pointedObject->pid, 32)) {
|
||||
if (_critter_flag_check(pointedObject->pid, CRITTER_FLAG_0x20)) {
|
||||
primaryAction = GAME_MOUSE_ACTION_MENU_ITEM_LOOK;
|
||||
} else {
|
||||
primaryAction = GAME_MOUSE_ACTION_MENU_ITEM_USE;
|
||||
@@ -693,7 +693,7 @@ void gameMouseRefresh()
|
||||
if (primaryAction != -1) {
|
||||
if (gameMouseRenderPrimaryAction(mouseX, mouseY, primaryAction, _scr_size.right - _scr_size.left + 1, _scr_size.bottom - _scr_size.top - 99) == 0) {
|
||||
Rect tmp;
|
||||
int fid = buildFid(6, 282, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 282, 0, 0, 0);
|
||||
if (objectSetFid(gGameMouseHexCursor, fid, &tmp) == 0) {
|
||||
tileWindowRefreshRect(&tmp, gElevation);
|
||||
}
|
||||
@@ -715,7 +715,7 @@ void gameMouseRefresh()
|
||||
}
|
||||
|
||||
if (pointedObject != NULL) {
|
||||
bool pointedObjectIsCritter = (pointedObject->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER;
|
||||
bool pointedObjectIsCritter = FID_TYPE(pointedObject->fid) == OBJ_TYPE_CRITTER;
|
||||
|
||||
int combatLooks = 0;
|
||||
configGetInt(&gGameConfig, GAME_CONFIG_PREFERENCES_KEY, GAME_CONFIG_COMBAT_LOOKS_KEY, &combatLooks);
|
||||
@@ -756,7 +756,7 @@ void gameMouseRefresh()
|
||||
|
||||
if (gameMouseRenderAccuracy(formattedAccuracy, color) == 0) {
|
||||
Rect tmp;
|
||||
int fid = buildFid(6, 284, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 284, 0, 0, 0);
|
||||
if (objectSetFid(gGameMouseHexCursor, fid, &tmp) == 0) {
|
||||
tileWindowRefreshRect(&tmp, gElevation);
|
||||
}
|
||||
@@ -825,7 +825,7 @@ void gameMouseRefresh()
|
||||
gGameMouseLastY = mouseY;
|
||||
|
||||
if (!_gmouse_mapper_mode) {
|
||||
int fid = buildFid(6, 0, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 0, 0, 0, 0);
|
||||
gameMouseSetBouncingCursorFid(fid);
|
||||
}
|
||||
|
||||
@@ -936,13 +936,13 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
|
||||
if (gGameMouseMode == GAME_MOUSE_MODE_ARROW) {
|
||||
Object* v5 = gameMouseGetObjectUnderCursor(-1, true, gElevation);
|
||||
if (v5 != NULL) {
|
||||
switch ((v5->fid & 0xF000000) >> 24) {
|
||||
switch (FID_TYPE(v5->fid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
actionPickUp(gDude, v5);
|
||||
break;
|
||||
case OBJ_TYPE_CRITTER:
|
||||
if (v5 == gDude) {
|
||||
if (((gDude->fid & 0xFF0000) >> 16) == ANIM_STAND) {
|
||||
if (FID_ANIM_TYPE(gDude->fid) == ANIM_STAND) {
|
||||
Rect a1;
|
||||
if (objectRotateClockwise(v5, &a1) == 0) {
|
||||
tileWindowRefreshRect(&a1, v5->elevation);
|
||||
@@ -1053,7 +1053,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
|
||||
if (v16 != NULL) {
|
||||
int actionMenuItemsCount = 0;
|
||||
int actionMenuItems[6];
|
||||
switch ((v16->fid & 0xF000000) >> 24) {
|
||||
switch (FID_TYPE(v16->fid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
actionMenuItems[actionMenuItemsCount++] = GAME_MOUSE_ACTION_MENU_ITEM_USE;
|
||||
actionMenuItems[actionMenuItemsCount++] = GAME_MOUSE_ACTION_MENU_ITEM_LOOK;
|
||||
@@ -1072,7 +1072,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
|
||||
actionMenuItems[actionMenuItemsCount++] = GAME_MOUSE_ACTION_MENU_ITEM_TALK;
|
||||
}
|
||||
} else {
|
||||
if (!_critter_flag_check(v16->pid, 32)) {
|
||||
if (!_critter_flag_check(v16->pid, CRITTER_FLAG_0x20)) {
|
||||
actionMenuItems[actionMenuItemsCount++] = GAME_MOUSE_ACTION_MENU_ITEM_USE;
|
||||
}
|
||||
}
|
||||
@@ -1108,7 +1108,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
|
||||
|
||||
if (gameMouseRenderActionMenuItems(mouseX, mouseY, actionMenuItems, actionMenuItemsCount, _scr_size.right - _scr_size.left + 1, _scr_size.bottom - _scr_size.top - 99) == 0) {
|
||||
Rect v43;
|
||||
int fid = buildFid(6, 283, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 283, 0, 0, 0);
|
||||
if (objectSetFid(gGameMouseHexCursor, fid, &v43) == 0 && _gmouse_3d_move_to(mouseX, mouseY, gElevation, &v43) == 0) {
|
||||
tileWindowRefreshRect(&v43, gElevation);
|
||||
isoDisable();
|
||||
@@ -1171,7 +1171,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
|
||||
actionTalk(gDude, v16);
|
||||
break;
|
||||
case GAME_MOUSE_ACTION_MENU_ITEM_USE:
|
||||
switch ((v16->fid & 0xF000000) >> 24) {
|
||||
switch (FID_TYPE(v16->fid)) {
|
||||
case OBJ_TYPE_SCENERY:
|
||||
_action_use_an_object(gDude, v16);
|
||||
break;
|
||||
@@ -1242,7 +1242,7 @@ int gameMouseSetCursor(int cursor)
|
||||
}
|
||||
|
||||
CacheEntry* mouseCursorFrmHandle;
|
||||
int fid = buildFid(6, gGameMouseCursorFrmIds[cursor], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseCursorFrmIds[cursor], 0, 0, 0);
|
||||
Art* mouseCursorFrm = artLock(fid, &mouseCursorFrmHandle);
|
||||
if (mouseCursorFrm == NULL) {
|
||||
return -1;
|
||||
@@ -1327,10 +1327,10 @@ void gameMouseSetMode(int mode)
|
||||
return;
|
||||
}
|
||||
|
||||
int fid = buildFid(6, 0, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 0, 0, 0, 0);
|
||||
gameMouseSetBouncingCursorFid(fid);
|
||||
|
||||
fid = buildFid(6, gGameMouseModeFrmIds[mode], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[mode], 0, 0, 0);
|
||||
|
||||
Rect rect;
|
||||
if (objectSetFid(gGameMouseHexCursor, fid, &rect) == -1) {
|
||||
@@ -1472,7 +1472,7 @@ int gameMouseSetBouncingCursorFid(int fid)
|
||||
// 0x44CD0C
|
||||
void gameMouseResetBouncingCursorFid()
|
||||
{
|
||||
int fid = buildFid(6, 0, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 0, 0, 0, 0);
|
||||
gameMouseSetBouncingCursorFid(fid);
|
||||
}
|
||||
|
||||
@@ -1601,7 +1601,7 @@ Object* gameMouseGetObjectUnderCursor(int objectType, bool a2, int elevation)
|
||||
v4 = ptr->object;
|
||||
if ((ptr->flags & 0x01) != 0) {
|
||||
if ((ptr->flags & 0x04) == 0) {
|
||||
if ((ptr->object->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER || (ptr->object->data.critter.combat.results & (DAM_KNOCKED_OUT | DAM_DEAD)) == 0) {
|
||||
if (FID_TYPE(ptr->object->fid) != OBJ_TYPE_CRITTER || (ptr->object->data.critter.combat.results & (DAM_KNOCKED_OUT | DAM_DEAD)) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1620,14 +1620,14 @@ Object* gameMouseGetObjectUnderCursor(int objectType, bool a2, int elevation)
|
||||
int gameMouseRenderPrimaryAction(int x, int y, int menuItem, int width, int height)
|
||||
{
|
||||
CacheEntry* menuItemFrmHandle;
|
||||
int menuItemFid = buildFid(6, gGameMouseActionMenuItemFrmIds[menuItem], 0, 0, 0);
|
||||
int menuItemFid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseActionMenuItemFrmIds[menuItem], 0, 0, 0);
|
||||
Art* menuItemFrm = artLock(menuItemFid, &menuItemFrmHandle);
|
||||
if (menuItemFrm == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
CacheEntry* arrowFrmHandle;
|
||||
int arrowFid = buildFid(6, gGameMouseModeFrmIds[GAME_MOUSE_MODE_ARROW], 0, 0, 0);
|
||||
int arrowFid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[GAME_MOUSE_MODE_ARROW], 0, 0, 0);
|
||||
Art* arrowFrm = artLock(arrowFid, &arrowFrmHandle);
|
||||
if (arrowFrm == NULL) {
|
||||
artUnlock(menuItemFrmHandle);
|
||||
@@ -1666,7 +1666,7 @@ int gameMouseRenderPrimaryAction(int x, int y, int menuItem, int width, int heig
|
||||
} else {
|
||||
artUnlock(arrowFrmHandle);
|
||||
|
||||
arrowFid = buildFid(6, 285, 0, 0, 0);
|
||||
arrowFid = buildFid(OBJ_TYPE_INTERFACE, 285, 0, 0, 0);
|
||||
arrowFrm = artLock(arrowFid, &arrowFrmHandle);
|
||||
arrowFrmData = artGetFrameData(arrowFrm, 0, 0);
|
||||
arrowFrmDest += menuItemFrmWidth;
|
||||
@@ -1725,7 +1725,7 @@ int gameMouseRenderActionMenuItems(int x, int y, const int* menuItems, int menuI
|
||||
frmId -= 1;
|
||||
}
|
||||
|
||||
int fid = buildFid(6, frmId, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
|
||||
|
||||
menuItemFrms[index] = artLock(fid, &(menuItemFrmHandles[index]));
|
||||
if (menuItemFrms[index] == NULL) {
|
||||
@@ -1736,7 +1736,7 @@ int gameMouseRenderActionMenuItems(int x, int y, const int* menuItems, int menuI
|
||||
}
|
||||
}
|
||||
|
||||
int fid = buildFid(6, gGameMouseModeFrmIds[GAME_MOUSE_MODE_ARROW], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[GAME_MOUSE_MODE_ARROW], 0, 0, 0);
|
||||
CacheEntry* arrowFrmHandle;
|
||||
Art* arrowFrm = artLock(fid, &arrowFrmHandle);
|
||||
if (arrowFrm == NULL) {
|
||||
@@ -1772,7 +1772,7 @@ int gameMouseRenderActionMenuItems(int x, int y, const int* menuItems, int menuI
|
||||
}
|
||||
} else {
|
||||
// Mirrored arrow (from left to right).
|
||||
fid = buildFid(6, 285, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 285, 0, 0, 0);
|
||||
arrowFrm = artLock(fid, &arrowFrmHandle);
|
||||
arrowData = artGetFrameData(arrowFrm, 0, 0);
|
||||
gGameMouseActionMenuFrm->xOffsets[0] = -gGameMouseActionMenuFrm->xOffsets[0];
|
||||
@@ -1820,7 +1820,7 @@ int gameMouseHighlightActionMenuItemAtIndex(int menuItemIndex)
|
||||
}
|
||||
|
||||
CacheEntry* handle;
|
||||
int fid = buildFid(6, gGameMouseActionMenuItemFrmIds[gGameMouseActionMenuItems[gGameMouseActionMenuHighlightedItemIndex]], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseActionMenuItemFrmIds[gGameMouseActionMenuItems[gGameMouseActionMenuHighlightedItemIndex]], 0, 0, 0);
|
||||
Art* art = artLock(fid, &handle);
|
||||
if (art == NULL) {
|
||||
return -1;
|
||||
@@ -1832,7 +1832,7 @@ int gameMouseHighlightActionMenuItemAtIndex(int menuItemIndex)
|
||||
blitBufferToBuffer(data, width, height, width, _gmouse_3d_menu_actions_start + gGameMouseActionMenuFrmWidth * height * gGameMouseActionMenuHighlightedItemIndex, gGameMouseActionMenuFrmWidth);
|
||||
artUnlock(handle);
|
||||
|
||||
fid = buildFid(6, gGameMouseActionMenuItemFrmIds[gGameMouseActionMenuItems[menuItemIndex]] - 1, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseActionMenuItemFrmIds[gGameMouseActionMenuItems[menuItemIndex]] - 1, 0, 0, 0);
|
||||
art = artLock(fid, &handle);
|
||||
if (art == NULL) {
|
||||
return -1;
|
||||
@@ -1851,7 +1851,7 @@ int gameMouseHighlightActionMenuItemAtIndex(int menuItemIndex)
|
||||
int gameMouseRenderAccuracy(const char* string, int color)
|
||||
{
|
||||
CacheEntry* crosshairFrmHandle;
|
||||
int fid = buildFid(6, gGameMouseModeFrmIds[GAME_MOUSE_MODE_CROSSHAIR], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[GAME_MOUSE_MODE_CROSSHAIR], 0, 0, 0);
|
||||
Art* crosshairFrm = artLock(fid, &crosshairFrmHandle);
|
||||
if (crosshairFrm == NULL) {
|
||||
return -1;
|
||||
@@ -1910,7 +1910,7 @@ int gameMouseRenderActionPoints(const char* string, int color)
|
||||
|
||||
fontSetCurrent(oldFont);
|
||||
|
||||
int fid = buildFid(6, 1, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 1, 0, 0, 0);
|
||||
gameMouseSetBouncingCursorFid(fid);
|
||||
|
||||
return 0;
|
||||
@@ -1934,12 +1934,12 @@ int gameMouseObjectsInit()
|
||||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 0, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 0, 0, 0, 0);
|
||||
if (objectCreateWithFidPid(&gGameMouseBouncingCursor, fid, -1) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 1, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 1, 0, 0, 0);
|
||||
if (objectCreateWithFidPid(&gGameMouseHexCursor, fid, -1) != 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -2031,35 +2031,35 @@ int gameMouseActionMenuInit()
|
||||
int fid;
|
||||
|
||||
// actmenu.frm - action menu
|
||||
fid = buildFid(6, 283, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 283, 0, 0, 0);
|
||||
gGameMouseActionMenuFrm = artLock(fid, &gGameMouseActionMenuFrmHandle);
|
||||
if (gGameMouseActionMenuFrm == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// actpick.frm - action pick
|
||||
fid = buildFid(6, 282, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 282, 0, 0, 0);
|
||||
gGameMouseActionPickFrm = artLock(fid, &gGameMouseActionPickFrmHandle);
|
||||
if (gGameMouseActionPickFrm == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// acttohit.frm - action to hit
|
||||
fid = buildFid(6, 284, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 284, 0, 0, 0);
|
||||
gGameMouseActionHitFrm = artLock(fid, &gGameMouseActionHitFrmHandle);
|
||||
if (gGameMouseActionHitFrm == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// blank.frm - used be mset000.frm for top of bouncing mouse cursor
|
||||
fid = buildFid(6, 0, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 0, 0, 0, 0);
|
||||
gGameMouseBouncingCursorFrm = artLock(fid, &gGameMouseBouncingCursorFrmHandle);
|
||||
if (gGameMouseBouncingCursorFrm == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// msef000.frm - hex mouse cursor
|
||||
fid = buildFid(6, 1, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 1, 0, 0, 0);
|
||||
gGameMouseHexCursorFrm = artLock(fid, &gGameMouseHexCursorFrmHandle);
|
||||
if (gGameMouseHexCursorFrm == NULL) {
|
||||
goto err;
|
||||
@@ -2145,7 +2145,7 @@ void gameMouseActionMenuFree()
|
||||
// 0x44DF40
|
||||
int gameMouseUpdateHexCursorFid(Rect* rect)
|
||||
{
|
||||
int fid = buildFid(6, gGameMouseModeFrmIds[gGameMouseMode], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[gGameMouseMode], 0, 0, 0);
|
||||
if (gGameMouseHexCursor->fid == fid) {
|
||||
return -1;
|
||||
}
|
||||
@@ -2210,7 +2210,7 @@ int _gmouse_3d_move_to(int x, int y, int elevation, Rect* a4)
|
||||
int y1 = 0;
|
||||
|
||||
int fid = gGameMouseBouncingCursor->fid;
|
||||
if ((fid & 0xF000000) >> 24 == OBJ_TYPE_TILE) {
|
||||
if (FID_TYPE(fid) == OBJ_TYPE_TILE) {
|
||||
int squareTile = squareTileFromScreenXY(x, y, elevation);
|
||||
if (squareTile == -1) {
|
||||
tile = HEX_GRID_WIDTH * (2 * (squareTile / SQUARE_GRID_WIDTH) + 1) + 2 * (squareTile % SQUARE_GRID_WIDTH) + 1;
|
||||
@@ -2398,7 +2398,7 @@ int objectIsDoor(Object* object)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_SCENERY) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_SCENERY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -176,7 +176,7 @@ int gameMoviePlay(int movie, int flags)
|
||||
int gameMovieWindowY = (screenGetHeight() - GAME_MOVIE_WINDOW_HEIGHT) / 2;
|
||||
int win = windowCreate(gameMovieWindowX,
|
||||
gameMovieWindowY,
|
||||
GAME_MOVIE_WINDOW_WIDTH,
|
||||
GAME_MOVIE_WINDOW_WIDTH,
|
||||
GAME_MOVIE_WINDOW_HEIGHT,
|
||||
0,
|
||||
WINDOW_FLAG_0x10);
|
||||
@@ -258,7 +258,7 @@ int gameMoviePlay(int movie, int flags)
|
||||
_mouse_get_raw_state(&x, &y, &buttons);
|
||||
|
||||
v11 |= buttons;
|
||||
} while ((v11 & 1) == 0 && (v11 & 2) == 0 || (buttons & 1) != 0 || (buttons & 2) != 0);
|
||||
} while (((v11 & 1) == 0 && (v11 & 2) == 0) || (buttons & 1) != 0 || (buttons & 2) != 0);
|
||||
|
||||
_movieStop();
|
||||
_moviefx_stop();
|
||||
|
||||
+7
-9
@@ -1118,7 +1118,7 @@ Sound* soundEffectLoad(const char* name, Object* object)
|
||||
}
|
||||
|
||||
if (object != NULL) {
|
||||
if ((object->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER && (name[0] == 'H' || name[0] == 'N')) {
|
||||
if (FID_TYPE(object->fid) == OBJ_TYPE_CRITTER && (name[0] == 'H' || name[0] == 'N')) {
|
||||
char v9 = name[1];
|
||||
if (v9 == 'A' || v9 == 'F' || v9 == 'M') {
|
||||
if (v9 == 'A') {
|
||||
@@ -1230,7 +1230,7 @@ void soundEffectDelete(Sound* sound)
|
||||
}
|
||||
|
||||
// 0x4514F0
|
||||
int _gsnd_anim_sound(Sound* sound)
|
||||
int _gsnd_anim_sound(Sound* sound, void* a2)
|
||||
{
|
||||
if (!gGameSoundInitialized) {
|
||||
return 0;
|
||||
@@ -1287,7 +1287,7 @@ int _gsound_compute_relative_volume(Object* obj)
|
||||
v3 = 0x7FFF;
|
||||
|
||||
if (obj) {
|
||||
type = (obj->fid & 0xF000000) >> 24;
|
||||
type = FID_TYPE(obj->fid);
|
||||
if (type == 0 || type == 1 || type == 2) {
|
||||
v7 = objectGetOwner(obj);
|
||||
if (!v7) {
|
||||
@@ -1325,7 +1325,7 @@ char* sfxBuildCharName(Object* a1, int anim, int extra)
|
||||
char v8;
|
||||
char v9;
|
||||
|
||||
if (artCopyFileName((a1->fid & 0xF000000) >> 24, a1->fid & 0xFFF, v7) == -1) {
|
||||
if (artCopyFileName(FID_TYPE(a1->fid), a1->fid & 0xFFF, v7) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1399,12 +1399,10 @@ char* sfxBuildWeaponName(int effectType, Object* weapon, int hitMode, Object* ta
|
||||
v6 = 1;
|
||||
}
|
||||
|
||||
int damageType = weaponGetDamageType(NULL, weapon);
|
||||
// TODO: Check damageType conditions.
|
||||
if (effectTypeCode != 'H' || target == NULL || damageType == DAMAGE_TYPE_EXPLOSION || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP) {
|
||||
if (effectTypeCode != 'H' || target == NULL || weaponIsGrenade(weapon)) {
|
||||
materialCode = 'X';
|
||||
} else {
|
||||
const int type = (target->fid & 0xF000000) >> 24;
|
||||
const int type = FID_TYPE(target->fid);
|
||||
int material;
|
||||
switch (type) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
@@ -1466,7 +1464,7 @@ char* sfxBuildSceneryName(int actionType, int action, const char* name)
|
||||
// 0x4518D
|
||||
char* sfxBuildOpenName(Object* object, int action)
|
||||
{
|
||||
if ((object->fid & 0xF000000) >> 24 == OBJ_TYPE_SCENERY) {
|
||||
if (FID_TYPE(object->fid) == OBJ_TYPE_SCENERY) {
|
||||
char scenerySoundId;
|
||||
Proto* proto;
|
||||
if (protoGetProto(object->pid, &proto) != -1) {
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ int _gsound_play_sfx_file_volume(const char* a1, int a2);
|
||||
Sound* soundEffectLoad(const char* name, Object* a2);
|
||||
Sound* soundEffectLoadWithVolume(const char* a1, Object* a2, int a3);
|
||||
void soundEffectDelete(Sound* a1);
|
||||
int _gsnd_anim_sound(Sound* a1);
|
||||
int _gsnd_anim_sound(Sound* sound, void* a2);
|
||||
int soundEffectPlay(Sound* a1);
|
||||
int _gsound_compute_relative_volume(Object* obj);
|
||||
char* sfxBuildCharName(Object* a1, int anim, int extra);
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ int graphCompress(unsigned char* a1, unsigned char* a2, int a3)
|
||||
int v11 = v36 + 1;
|
||||
if (_match_length > 2) {
|
||||
v29[v36 + 1] = _match_position;
|
||||
v29[v36 + 2] = ((_match_length - 3) | (_match_position >> 4) & 0xF0);
|
||||
v29[v36 + 2] = ((_match_length - 3) | ((_match_position >> 4) & 0xF0));
|
||||
v36 = v11 + 1;
|
||||
} else {
|
||||
_match_length = 1;
|
||||
|
||||
+54
-52
@@ -438,7 +438,7 @@ int interfaceInit()
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 16, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 16, 0, 0, 0);
|
||||
backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -447,13 +447,13 @@ int interfaceInit()
|
||||
blitBufferToBuffer(backgroundFrmData, INTERFACE_BAR_WIDTH, INTERFACE_BAR_HEIGHT - 1, INTERFACE_BAR_WIDTH, gInterfaceWindowBuffer, 640);
|
||||
artUnlock(backgroundFrmHandle);
|
||||
|
||||
fid = buildFid(6, 47, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 47, 0, 0, 0);
|
||||
gInventoryButtonUpFrmData = artLockFrameData(fid, 0, 0, &gInventoryButtonUpFrmHandle);
|
||||
if (gInventoryButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 46, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 46, 0, 0, 0);
|
||||
gInventoryButtonDownFrmData = artLockFrameData(fid, 0, 0, &gInventoryButtonDownFrmHandle);
|
||||
if (gInventoryButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -466,13 +466,13 @@ int interfaceInit()
|
||||
|
||||
buttonSetCallbacks(gInventoryButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
fid = buildFid(6, 18, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 18, 0, 0, 0);
|
||||
gOptionsButtonUpFrmData = artLockFrameData(fid, 0, 0, &gOptionsButtonUpFrmHandle);
|
||||
if (gOptionsButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 17, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 17, 0, 0, 0);
|
||||
gOptionsButtonDownFrmData = artLockFrameData(fid, 0, 0, &gOptionsButtonDownFrmHandle);
|
||||
if (gOptionsButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -485,19 +485,19 @@ int interfaceInit()
|
||||
|
||||
buttonSetCallbacks(gOptionsButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
fid = buildFid(6, 6, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0);
|
||||
gSkilldexButtonUpFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonUpFrmHandle);
|
||||
if (gSkilldexButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 7, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 7, 0, 0, 0);
|
||||
gSkilldexButtonDownFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonDownFrmHandle);
|
||||
if (gSkilldexButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 6, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0);
|
||||
gSkilldexButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonMaskFrmHandle);
|
||||
if (gSkilldexButtonMaskFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -511,19 +511,19 @@ int interfaceInit()
|
||||
buttonSetMask(gSkilldexButton, gSkilldexButtonMaskFrmData);
|
||||
buttonSetCallbacks(gSkilldexButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
fid = buildFid(6, 13, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 13, 0, 0, 0);
|
||||
gMapButtonUpFrmData = artLockFrameData(fid, 0, 0, &gMapButtonUpFrmHandle);
|
||||
if (gMapButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 10, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 10, 0, 0, 0);
|
||||
gMapButtonDownFrmData = artLockFrameData(fid, 0, 0, &gMapButtonDownFrmHandle);
|
||||
if (gMapButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 13, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 13, 0, 0, 0);
|
||||
gMapButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gMapButtonMaskFrmHandle);
|
||||
if (gMapButtonMaskFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -537,13 +537,13 @@ int interfaceInit()
|
||||
buttonSetMask(gMapButton, gMapButtonMaskFrmData);
|
||||
buttonSetCallbacks(gMapButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
fid = buildFid(6, 59, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 59, 0, 0, 0);
|
||||
gPipboyButtonUpFrmData = artLockFrameData(fid, 0, 0, &gPipboyButtonUpFrmHandle);
|
||||
if (gPipboyButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 58, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 58, 0, 0, 0);
|
||||
gPipboyButtonDownFrmData = artLockFrameData(fid, 0, 0, &gPipboyButtonDownFrmHandle);
|
||||
if (gPipboyButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -557,13 +557,13 @@ int interfaceInit()
|
||||
buttonSetMask(gPipboyButton, gMapButtonMaskFrmData);
|
||||
buttonSetCallbacks(gPipboyButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
fid = buildFid(6, 57, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 57, 0, 0, 0);
|
||||
gCharacterButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterButtonUpFrmHandle);
|
||||
if (gCharacterButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 56, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 56, 0, 0, 0);
|
||||
gCharacterButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterButtonDownFrmHandle);
|
||||
if (gCharacterButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -577,19 +577,19 @@ int interfaceInit()
|
||||
buttonSetMask(gCharacterButton, gMapButtonMaskFrmData);
|
||||
buttonSetCallbacks(gCharacterButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
fid = buildFid(6, 32, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 32, 0, 0, 0);
|
||||
gSingleAttackButtonUpData = artLockFrameData(fid, 0, 0, &gSingleAttackButtonUpHandle);
|
||||
if (gSingleAttackButtonUpData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 31, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 31, 0, 0, 0);
|
||||
gSingleAttackButtonDownData = artLockFrameData(fid, 0, 0, &gSingleAttackButtonDownHandle);
|
||||
if (gSingleAttackButtonDownData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 73, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 73, 0, 0, 0);
|
||||
_itemButtonDisabled = artLockFrameData(fid, 0, 0, &_itemButtonDisabledKey);
|
||||
if (_itemButtonDisabled == NULL) {
|
||||
goto err;
|
||||
@@ -606,19 +606,19 @@ int interfaceInit()
|
||||
buttonSetRightMouseCallbacks(gSingleAttackButton, -1, KEY_LOWERCASE_N, NULL, NULL);
|
||||
buttonSetCallbacks(gSingleAttackButton, _gsound_lrg_butt_press, _gsound_lrg_butt_release);
|
||||
|
||||
fid = buildFid(6, 6, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0);
|
||||
gChangeHandsButtonUpFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonUpFrmHandle);
|
||||
if (gChangeHandsButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 7, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 7, 0, 0, 0);
|
||||
gChangeHandsButtonDownFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonDownFrmHandle);
|
||||
if (gChangeHandsButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 6, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0);
|
||||
gChangeHandsButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonMaskFrmHandle);
|
||||
if (gChangeHandsButtonMaskFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -633,25 +633,25 @@ int interfaceInit()
|
||||
buttonSetMask(gChangeHandsButton, gChangeHandsButtonMaskFrmData);
|
||||
buttonSetCallbacks(gChangeHandsButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
fid = buildFid(6, 82, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 82, 0, 0, 0);
|
||||
gNumbersFrmData = artLockFrameData(fid, 0, 0, &gNumbersFrmHandle);
|
||||
if (gNumbersFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 83, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 83, 0, 0, 0);
|
||||
gGreenLightFrmData = artLockFrameData(fid, 0, 0, &gGreenLightFrmHandle);
|
||||
if (gGreenLightFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 84, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 84, 0, 0, 0);
|
||||
gYellowLightFrmData = artLockFrameData(fid, 0, 0, &gYellowLightFrmHandle);
|
||||
if (gYellowLightFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 85, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 85, 0, 0, 0);
|
||||
gRedLightFrmData = artLockFrameData(fid, 0, 0, &gRedLightFrmHandle);
|
||||
if (gRedLightFrmData == NULL) {
|
||||
goto err;
|
||||
@@ -1592,7 +1592,7 @@ void interfaceBarEndButtonsShow(bool animated)
|
||||
return;
|
||||
}
|
||||
|
||||
int fid = buildFid(6, 104, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 104, 0, 0, 0);
|
||||
CacheEntry* handle;
|
||||
Art* art = artLock(fid, &handle);
|
||||
if (art == NULL) {
|
||||
@@ -1644,7 +1644,7 @@ void interfaceBarEndButtonsHide(bool animated)
|
||||
return;
|
||||
}
|
||||
|
||||
int fid = buildFid(6, 104, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 104, 0, 0, 0);
|
||||
CacheEntry* handle;
|
||||
Art* art = artLock(fid, &handle);
|
||||
if (art == NULL) {
|
||||
@@ -1693,7 +1693,7 @@ void interfaceBarEndButtonsRenderGreenLights()
|
||||
buttonEnable(gEndCombatButton);
|
||||
|
||||
// endltgrn.frm - green lights around end turn/combat window
|
||||
int lightsFid = buildFid(6, 109, 0, 0, 0);
|
||||
int lightsFid = buildFid(OBJ_TYPE_INTERFACE, 109, 0, 0, 0);
|
||||
CacheEntry* lightsFrmHandle;
|
||||
unsigned char* lightsFrmData = artLockFrameData(lightsFid, 0, 0, &lightsFrmHandle);
|
||||
if (lightsFrmData == NULL) {
|
||||
@@ -1717,7 +1717,7 @@ void interfaceBarEndButtonsRenderRedLights()
|
||||
|
||||
CacheEntry* lightsFrmHandle;
|
||||
// endltred.frm - red lights around end turn/combat window
|
||||
int lightsFid = buildFid(6, 110, 0, 0, 0);
|
||||
int lightsFid = buildFid(OBJ_TYPE_INTERFACE, 110, 0, 0, 0);
|
||||
unsigned char* lightsFrmData = artLockFrameData(lightsFid, 0, 0, &lightsFrmHandle);
|
||||
if (lightsFrmData == NULL) {
|
||||
return;
|
||||
@@ -1751,10 +1751,10 @@ static int interfaceBarRefreshMainAction()
|
||||
int fid;
|
||||
if (_proto_action_can_use_on(itemState->item->pid)) {
|
||||
// USE ON
|
||||
fid = buildFid(6, 294, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 294, 0, 0, 0);
|
||||
} else if (_obj_action_can_use(itemState->item)) {
|
||||
// USE
|
||||
fid = buildFid(6, 292, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 292, 0, 0, 0);
|
||||
} else {
|
||||
fid = -1;
|
||||
}
|
||||
@@ -1782,20 +1782,20 @@ static int interfaceBarRefreshMainAction()
|
||||
// jump table.
|
||||
switch (itemState->action) {
|
||||
case INTERFACE_ITEM_ACTION_PRIMARY_AIMING:
|
||||
bullseyeFid = buildFid(6, 288, 0, 0, 0);
|
||||
bullseyeFid = buildFid(OBJ_TYPE_INTERFACE, 288, 0, 0, 0);
|
||||
// FALLTHROUGH
|
||||
case INTERFACE_ITEM_ACTION_PRIMARY:
|
||||
hitMode = itemState->primaryHitMode;
|
||||
break;
|
||||
case INTERFACE_ITEM_ACTION_SECONDARY_AIMING:
|
||||
bullseyeFid = buildFid(6, 288, 0, 0, 0);
|
||||
bullseyeFid = buildFid(OBJ_TYPE_INTERFACE, 288, 0, 0, 0);
|
||||
// FALLTHROUGH
|
||||
case INTERFACE_ITEM_ACTION_SECONDARY:
|
||||
hitMode = itemState->secondaryHitMode;
|
||||
break;
|
||||
case INTERFACE_ITEM_ACTION_RELOAD:
|
||||
actionPoints = _item_mp_cost(gDude, gInterfaceCurrentHand == HAND_LEFT ? HIT_MODE_LEFT_WEAPON_RELOAD : HIT_MODE_RIGHT_WEAPON_RELOAD, false);
|
||||
primaryFid = buildFid(6, 291, 0, 0, 0);
|
||||
primaryFid = buildFid(OBJ_TYPE_INTERFACE, 291, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1893,7 +1893,7 @@ static int interfaceBarRefreshMainAction()
|
||||
break;
|
||||
}
|
||||
|
||||
primaryFid = buildFid(6, id, 0, 0, 0);
|
||||
primaryFid = buildFid(OBJ_TYPE_INTERFACE, id, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (primaryFid != -1) {
|
||||
@@ -1913,7 +1913,7 @@ static int interfaceBarRefreshMainAction()
|
||||
|
||||
if (actionPoints >= 0 && actionPoints < 10) {
|
||||
// movement point text
|
||||
int fid = buildFid(6, 289, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 289, 0, 0, 0);
|
||||
|
||||
CacheEntry* handle;
|
||||
Art* art = artLock(fid, &handle);
|
||||
@@ -1936,7 +1936,7 @@ static int interfaceBarRefreshMainAction()
|
||||
int offset = width + 7;
|
||||
|
||||
// movement point numbers - ten numbers 0 to 9, each 10 pixels wide.
|
||||
fid = buildFid(6, 290, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 290, 0, 0, 0);
|
||||
art = artLock(fid, &handle);
|
||||
if (art != NULL) {
|
||||
width = artGetWidth(art, 0, 0);
|
||||
@@ -2018,30 +2018,32 @@ static void interfaceBarSwapHandsAnimatePutAwayTakeOutSequence(int previousWeapo
|
||||
gInterfaceBarSwapHandsInProgress = true;
|
||||
|
||||
reg_anim_clear(gDude);
|
||||
reg_anim_begin(2);
|
||||
reg_anim_update_light(gDude, 4, 0);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterSetLightDistance(gDude, 4, 0);
|
||||
|
||||
if (previousWeaponAnimationCode != 0) {
|
||||
const char* sfx = sfxBuildCharName(gDude, ANIM_PUT_AWAY, CHARACTER_SOUND_EFFECT_UNUSED);
|
||||
reg_anim_play_sfx(gDude, sfx, 0);
|
||||
reg_anim_animate(gDude, ANIM_PUT_AWAY, 0);
|
||||
animationRegisterPlaySoundEffect(gDude, sfx, 0);
|
||||
animationRegisterAnimate(gDude, ANIM_PUT_AWAY, 0);
|
||||
}
|
||||
|
||||
reg_anim_11_1(NULL, NULL, _intface_redraw_items_callback, -1);
|
||||
// TODO: Get rid of cast.
|
||||
animationRegisterCallbackForced(NULL, NULL, (AnimationCallback*)_intface_redraw_items_callback, -1);
|
||||
|
||||
Object* item = gInterfaceItemStates[gInterfaceCurrentHand].item;
|
||||
if (item != NULL && item->lightDistance > 4) {
|
||||
reg_anim_update_light(gDude, item->lightDistance, 0);
|
||||
animationRegisterSetLightDistance(gDude, item->lightDistance, 0);
|
||||
}
|
||||
|
||||
if (weaponAnimationCode != 0) {
|
||||
reg_anim_18(gDude, weaponAnimationCode, -1);
|
||||
animationRegisterTakeOutWeapon(gDude, weaponAnimationCode, -1);
|
||||
} else {
|
||||
int fid = buildFid(1, gDude->fid & 0xFFF, ANIM_STAND, 0, gDude->rotation + 1);
|
||||
reg_anim_17(gDude, fid, -1);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, gDude->fid & 0xFFF, ANIM_STAND, 0, gDude->rotation + 1);
|
||||
animationRegisterSetFid(gDude, fid, -1);
|
||||
}
|
||||
|
||||
reg_anim_11_1(NULL, NULL, _intface_change_fid_callback, -1);
|
||||
// TODO: Get rid of cast.
|
||||
animationRegisterCallbackForced(NULL, NULL, (AnimationCallback*)_intface_change_fid_callback, -1);
|
||||
|
||||
if (reg_anim_end() == -1) {
|
||||
return;
|
||||
@@ -2084,13 +2086,13 @@ static int endTurnButtonInit()
|
||||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 105, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 105, 0, 0, 0);
|
||||
gEndTurnButtonUpFrmData = artLockFrameData(fid, 0, 0, &gEndTurnButtonUpFrmHandle);
|
||||
if (gEndTurnButtonUpFrmData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 106, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 106, 0, 0, 0);
|
||||
gEndTurnButtonDownFrmData = artLockFrameData(fid, 0, 0, &gEndTurnButtonDownFrmHandle);
|
||||
if (gEndTurnButtonDownFrmData == NULL) {
|
||||
return -1;
|
||||
@@ -2147,13 +2149,13 @@ static int endCombatButtonInit()
|
||||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 107, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 107, 0, 0, 0);
|
||||
gEndCombatButtonUpFrmData = artLockFrameData(fid, 0, 0, &gEndCombatButtonUpFrmHandle);
|
||||
if (gEndCombatButtonUpFrmData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 108, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 108, 0, 0, 0);
|
||||
gEndCombatButtonDownFrmData = artLockFrameData(fid, 0, 0, &gEndCombatButtonDownFrmHandle);
|
||||
if (gEndCombatButtonDownFrmData == NULL) {
|
||||
return -1;
|
||||
@@ -2412,7 +2414,7 @@ static int indicatorBarInit()
|
||||
CacheEntry* indicatorBoxFrmHandle;
|
||||
int width;
|
||||
int height;
|
||||
int indicatorBoxFid = buildFid(6, 126, 0, 0, 0);
|
||||
int indicatorBoxFid = buildFid(OBJ_TYPE_INTERFACE, 126, 0, 0, 0);
|
||||
unsigned char* indicatorBoxFrmData = artLockFrameDataReturningSize(indicatorBoxFid, &indicatorBoxFrmHandle, &width, &height);
|
||||
if (indicatorBoxFrmData == NULL) {
|
||||
debugPrint("\nINTRFACE: Error initializing indicator box graphics! **\n");
|
||||
|
||||
+28
-24
@@ -398,7 +398,7 @@ static void _detachProgram(Program* program)
|
||||
static void _purgeProgram(Program* program)
|
||||
{
|
||||
if (!program->exited) {
|
||||
_removeProgramReferences_(program);
|
||||
intLibRemoveProgramReferences(program);
|
||||
program->exited = true;
|
||||
}
|
||||
}
|
||||
@@ -781,7 +781,7 @@ static void opCancelAll(Program* program)
|
||||
static void opIf(Program* program)
|
||||
{
|
||||
ProgramValue value = programStackPopValue(program);
|
||||
|
||||
|
||||
if (!value.isEmpty()) {
|
||||
programStackPopValue(program);
|
||||
} else {
|
||||
@@ -1526,7 +1526,10 @@ static void opDivide(Program* program)
|
||||
divisor = (float)value[0].integerValue;
|
||||
}
|
||||
|
||||
if ((int)divisor & 0x7FFFFFFF) {
|
||||
// NOTE: Original code is slightly different, it performs bitwise and
|
||||
// with 0x7FFFFFFF in order to determine if it's zero. Probably some
|
||||
// kind of compiler optimization.
|
||||
if (divisor == 0.0) {
|
||||
programFatalError("Division (DIV) by zero");
|
||||
}
|
||||
|
||||
@@ -1536,7 +1539,8 @@ static void opDivide(Program* program)
|
||||
if (value[0].opcode == VALUE_TYPE_FLOAT) {
|
||||
divisor = value[0].floatValue;
|
||||
|
||||
if ((int)divisor & 0x7FFFFFFF) {
|
||||
// NOTE: Same as above.
|
||||
if (divisor == 0.0) {
|
||||
programFatalError("Division (DIV) by zero");
|
||||
}
|
||||
|
||||
@@ -1963,7 +1967,7 @@ static void opCall(Program* program)
|
||||
// 0x46B590
|
||||
static void op801F(Program* program)
|
||||
{
|
||||
program->field_84 = programStackPopInteger(program);
|
||||
program->windowId = programStackPopInteger(program);
|
||||
program->field_7C = (int (*)(Program*))programStackPopPointer(program);
|
||||
program->flags = programStackPopInteger(program) & 0xFFFF;
|
||||
}
|
||||
@@ -2216,7 +2220,7 @@ static void opExportProcedure(Program* program)
|
||||
|
||||
unsigned char* proc_ptr = program->procedures + 4 + sizeof(Procedure) * procedureIndex;
|
||||
|
||||
char *procedureName = programGetIdentifier(program, stackReadInt32(proc_ptr, 0));
|
||||
char* procedureName = programGetIdentifier(program, stackReadInt32(proc_ptr, 0));
|
||||
int procedureAddress = stackReadInt32(proc_ptr, 16);
|
||||
|
||||
if (externalProcedureCreate(program, procedureName, procedureAddress, argumentCount) != 0) {
|
||||
@@ -2253,7 +2257,7 @@ static void opExit(Program* program)
|
||||
}
|
||||
|
||||
if (!program->exited) {
|
||||
_removeProgramReferences_(program);
|
||||
intLibRemoveProgramReferences(program);
|
||||
program->exited = true;
|
||||
}
|
||||
}
|
||||
@@ -2297,7 +2301,7 @@ static void opCallStart(Program* program)
|
||||
_interpret(program->child, 24);
|
||||
|
||||
program->child->parent = program;
|
||||
program->child->field_84 = program->field_84;
|
||||
program->child->windowId = program->windowId;
|
||||
}
|
||||
|
||||
// spawn
|
||||
@@ -2323,7 +2327,7 @@ static void opSpawn(Program* program)
|
||||
_interpret(program->child, 24);
|
||||
|
||||
program->child->parent = program;
|
||||
program->child->field_84 = program->field_84;
|
||||
program->child->windowId = program->windowId;
|
||||
|
||||
if ((program->flags & PROGRAM_FLAG_CRITICAL_SECTION) != 0) {
|
||||
program->child->flags |= PROGRAM_FLAG_CRITICAL_SECTION;
|
||||
@@ -2349,7 +2353,7 @@ static Program* forkProgram(Program* program)
|
||||
|
||||
_interpret(forked, 24);
|
||||
|
||||
forked->field_84 = program->field_84;
|
||||
forked->windowId = program->windowId;
|
||||
|
||||
return forked;
|
||||
}
|
||||
@@ -2516,7 +2520,7 @@ void interpreterRegisterOpcodeHandlers()
|
||||
interpreterRegisterOpcode(OPCODE_START_CRITICAL, opEnterCriticalSection);
|
||||
interpreterRegisterOpcode(OPCODE_END_CRITICAL, opLeaveCriticalSection);
|
||||
|
||||
_initIntlib();
|
||||
intLibInit();
|
||||
_initExport();
|
||||
}
|
||||
|
||||
@@ -2524,7 +2528,7 @@ void interpreterRegisterOpcodeHandlers()
|
||||
void _interpretClose()
|
||||
{
|
||||
externalVariablesClear();
|
||||
_intlibClose();
|
||||
intLibExit();
|
||||
}
|
||||
|
||||
// 0x46CCA4
|
||||
@@ -2641,7 +2645,7 @@ static void _setupCallWithReturnVal(Program* program, int address, int returnAdd
|
||||
|
||||
programStackPushPointer(program, (void*)program->field_7C);
|
||||
|
||||
programStackPushInteger(program, program->field_84);
|
||||
programStackPushInteger(program, program->windowId);
|
||||
|
||||
program->flags &= ~0xFFFF;
|
||||
program->instructionPointer = address;
|
||||
@@ -2664,11 +2668,11 @@ static void _setupExternalCallWithReturnVal(Program* program1, Program* program2
|
||||
|
||||
programStackPushPointer(program2, (void*)program2->field_7C);
|
||||
|
||||
programStackPushInteger(program2, program2->field_84);
|
||||
programStackPushInteger(program2, program2->windowId);
|
||||
|
||||
program2->flags &= ~0xFFFF;
|
||||
program2->instructionPointer = address;
|
||||
program2->field_84 = program1->field_84;
|
||||
program2->windowId = program1->windowId;
|
||||
|
||||
program1->flags |= PROGRAM_FLAG_0x20;
|
||||
}
|
||||
@@ -2683,9 +2687,9 @@ void _executeProc(Program* program, int procedure_index)
|
||||
unsigned char* procedure_ptr;
|
||||
int flags;
|
||||
char err[256];
|
||||
Program* v12;
|
||||
Program* context;
|
||||
|
||||
procedure_ptr = program->procedures + 4 + 24 * procedure_index;
|
||||
procedure_ptr = program->procedures + 4 + sizeof(Procedure) * procedure_index;
|
||||
flags = stackReadInt32(procedure_ptr, 4);
|
||||
if (!(flags & PROCEDURE_FLAG_IMPORTED)) {
|
||||
address = stackReadInt32(procedure_ptr, 16);
|
||||
@@ -2699,7 +2703,7 @@ void _executeProc(Program* program, int procedure_index)
|
||||
}
|
||||
|
||||
program->flags |= PROGRAM_FLAG_CRITICAL_SECTION;
|
||||
v12 = program;
|
||||
context = program;
|
||||
} else {
|
||||
identifier = programGetIdentifier(program, stackReadInt32(procedure_ptr, 0));
|
||||
external_program = externalProcedureGetProgram(identifier, &address, &arguments_count);
|
||||
@@ -2721,7 +2725,7 @@ void _executeProc(Program* program, int procedure_index)
|
||||
|
||||
programStackPushInteger(external_program, 0);
|
||||
|
||||
procedure_ptr = external_program->procedures + 4 + 24 * procedure_index;
|
||||
procedure_ptr = external_program->procedures + 4 + sizeof(Procedure) * procedure_index;
|
||||
flags = stackReadInt32(procedure_ptr, 4);
|
||||
|
||||
if (!(flags & PROCEDURE_FLAG_CRITICAL)) {
|
||||
@@ -2729,10 +2733,10 @@ void _executeProc(Program* program, int procedure_index)
|
||||
}
|
||||
|
||||
external_program->flags |= PROGRAM_FLAG_CRITICAL_SECTION;
|
||||
v12 = external_program;
|
||||
context = external_program;
|
||||
}
|
||||
|
||||
_interpret(v12, 0);
|
||||
_interpret(context, 0);
|
||||
}
|
||||
|
||||
// Returns index of the procedure with specified name or -1 if no such
|
||||
@@ -2769,10 +2773,10 @@ void _executeProcedure(Program* program, int procedure_index)
|
||||
jmp_buf jmp_buf;
|
||||
Program* v13;
|
||||
|
||||
procedure_ptr = program->procedures + 4 + 24 * procedure_index;
|
||||
procedure_ptr = program->procedures + 4 + sizeof(Procedure) * procedure_index;
|
||||
flags = stackReadInt32(procedure_ptr, 4);
|
||||
|
||||
if (flags & 0x04) {
|
||||
if (flags & PROCEDURE_FLAG_IMPORTED) {
|
||||
identifier = programGetIdentifier(program, stackReadInt32(procedure_ptr, 0));
|
||||
external_program = externalProcedureGetProgram(identifier, &address, &arguments_count);
|
||||
if (external_program == NULL) {
|
||||
@@ -2875,7 +2879,7 @@ void _updatePrograms()
|
||||
curr = next;
|
||||
}
|
||||
_doEvents();
|
||||
_updateIntLib();
|
||||
intLibUpdate();
|
||||
}
|
||||
|
||||
// 0x46E238
|
||||
|
||||
+1
-1
@@ -167,7 +167,7 @@ typedef struct Program {
|
||||
int field_78; // time when program begin execution (for the first time)?, -1 - program never executed
|
||||
int (*field_7C)(struct Program* s); // proc to check timer
|
||||
int flags; // flags
|
||||
int field_84;
|
||||
int windowId;
|
||||
bool exited;
|
||||
ProgramStack* stackValues;
|
||||
ProgramStack* returnStackValues;
|
||||
|
||||
+96
-85
@@ -19,7 +19,6 @@
|
||||
#include "game_sound.h"
|
||||
#include "geometry.h"
|
||||
#include "interface.h"
|
||||
#include "interpreter.h"
|
||||
#include "item.h"
|
||||
#include "light.h"
|
||||
#include "loadsave.h"
|
||||
@@ -300,8 +299,8 @@ static void opObjectClose(Program* program);
|
||||
static void opGameUiDisable(Program* program);
|
||||
static void opGameUiEnable(Program* program);
|
||||
static void opGameUiIsDisabled(Program* program);
|
||||
static void opFadeOut(Program* program);
|
||||
static void opFadeIn(Program* program);
|
||||
static void opGameFadeOut(Program* program);
|
||||
static void opGameFadeIn(Program* program);
|
||||
static void opItemCapsTotal(Program* program);
|
||||
static void opItemCapsAdjust(Program* program);
|
||||
static void _op_anim_action_frame(Program* program);
|
||||
@@ -496,11 +495,11 @@ static int _correctFidForRemovedItem(Object* a1, Object* a2, int flags)
|
||||
}
|
||||
|
||||
if (v8 == 0) {
|
||||
newFid = buildFid((fid & 0xF000000) >> 24, fid & 0xFFF, (fid & 0xFF0000) >> 16, 0, (fid & 0x70000000) >> 28);
|
||||
newFid = buildFid(FID_TYPE(fid), fid & 0xFFF, FID_ANIM_TYPE(fid), 0, (fid & 0x70000000) >> 28);
|
||||
}
|
||||
} else {
|
||||
if (a1 == gDude) {
|
||||
newFid = buildFid((fid & 0xF000000) >> 24, _art_vault_guy_num, (fid & 0xFF0000) >> 16, v8, (fid & 0x70000000) >> 28);
|
||||
newFid = buildFid(FID_TYPE(fid), _art_vault_guy_num, FID_ANIM_TYPE(fid), v8, (fid & 0x70000000) >> 28);
|
||||
}
|
||||
|
||||
_adjust_ac(a1, a2, NULL);
|
||||
@@ -557,7 +556,7 @@ static void opSetMapStart(Program* program)
|
||||
int elevation = programStackPopInteger(program);
|
||||
int y = programStackPopInteger(program);
|
||||
int x = programStackPopInteger(program);
|
||||
|
||||
|
||||
if (mapSetElevation(elevation) != 0) {
|
||||
scriptError("\nScript Error: %s: op_set_map_start: map_set_elevation failed", program->name);
|
||||
return;
|
||||
@@ -619,7 +618,7 @@ static void opHasSkill(Program* program)
|
||||
|
||||
int result = 0;
|
||||
if (object != NULL) {
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
result = skillGetValue(object, skill);
|
||||
}
|
||||
} else {
|
||||
@@ -658,7 +657,7 @@ static void opRollVsSkill(Program* program)
|
||||
|
||||
int roll = ROLL_CRITICAL_FAILURE;
|
||||
if (object != NULL) {
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
int sid = scriptGetSid(program);
|
||||
|
||||
Script* script;
|
||||
@@ -835,7 +834,7 @@ static void opRandom(Program* program)
|
||||
}
|
||||
|
||||
int result;
|
||||
if (_vcr_status() == 2) {
|
||||
if (vcrGetState() == VCR_STATE_TURNED_OFF) {
|
||||
result = randomBetween(data[1], data[0]);
|
||||
} else {
|
||||
result = (data[0] - data[1]) / 2;
|
||||
@@ -899,7 +898,7 @@ static void opMoveTo(Program* program)
|
||||
Rect before;
|
||||
objectGetRect(object, &before);
|
||||
|
||||
if (object->elevation != elevation && (object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (object->elevation != elevation && PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
_combat_delete_critter(object);
|
||||
}
|
||||
|
||||
@@ -964,7 +963,7 @@ static void opCreateObject(Program* program)
|
||||
|
||||
if (sid != -1) {
|
||||
int scriptType = 0;
|
||||
switch (object->pid >> 24) {
|
||||
switch (PID_TYPE(object->pid)) {
|
||||
case OBJ_TYPE_CRITTER:
|
||||
scriptType = SCRIPT_TYPE_CRITTER;
|
||||
break;
|
||||
@@ -991,7 +990,7 @@ static void opCreateObject(Program* program)
|
||||
script->field_14 = sid - 1;
|
||||
|
||||
if (scriptType == SCRIPT_TYPE_SPATIAL) {
|
||||
script->sp.built_tile = ((object->elevation << 29) & 0xE0000000) | object->tile;
|
||||
script->sp.built_tile = builtTileCreate(object->tile, object->elevation);
|
||||
script->sp.radius = 3;
|
||||
}
|
||||
|
||||
@@ -1020,7 +1019,7 @@ static void opDestroyObject(Program* program)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (_isLoadingGame()) {
|
||||
debugPrint("\nError: attempt to destroy critter in load/save-game: %s!", program->name);
|
||||
program->flags &= ~PROGRAM_FLAG_0x20;
|
||||
@@ -1030,7 +1029,7 @@ static void opDestroyObject(Program* program)
|
||||
|
||||
bool isSelf = object == scriptGetSelf(program);
|
||||
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
_combat_delete_critter(object);
|
||||
}
|
||||
|
||||
@@ -1311,7 +1310,7 @@ static void opGetObjectType(Program* program)
|
||||
|
||||
int objectType = -1;
|
||||
if (object != NULL) {
|
||||
objectType = (object->fid & 0xF000000) >> 24;
|
||||
objectType = FID_TYPE(object->fid);
|
||||
}
|
||||
|
||||
programStackPushInteger(program, objectType);
|
||||
@@ -1325,7 +1324,7 @@ static void opGetItemType(Program* program)
|
||||
|
||||
int itemType = -1;
|
||||
if (obj != NULL) {
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_ITEM) {
|
||||
Proto* proto;
|
||||
if (protoGetProto(obj->pid, &proto) != -1) {
|
||||
itemType = itemGetType(obj);
|
||||
@@ -1400,8 +1399,8 @@ static void opAnimateStand(Program* program)
|
||||
}
|
||||
|
||||
if (!isInCombat()) {
|
||||
reg_anim_begin(1);
|
||||
reg_anim_animate(object, ANIM_STAND, 0);
|
||||
reg_anim_begin(ANIMATION_REQUEST_UNRESERVED);
|
||||
animationRegisterAnimate(object, ANIM_STAND, 0);
|
||||
reg_anim_end();
|
||||
}
|
||||
}
|
||||
@@ -1424,8 +1423,8 @@ static void opAnimateStandReverse(Program* program)
|
||||
}
|
||||
|
||||
if (!isInCombat()) {
|
||||
reg_anim_begin(0x01);
|
||||
reg_anim_animate_reverse(object, ANIM_STAND, 0);
|
||||
reg_anim_begin(ANIMATION_REQUEST_UNRESERVED);
|
||||
animationRegisterAnimateReversed(object, ANIM_STAND, 0);
|
||||
reg_anim_end();
|
||||
}
|
||||
}
|
||||
@@ -1468,12 +1467,12 @@ static void opAnimateMoveObjectToTile(Program* program)
|
||||
flags &= ~0x10;
|
||||
}
|
||||
|
||||
reg_anim_begin(1);
|
||||
reg_anim_begin(ANIMATION_REQUEST_UNRESERVED);
|
||||
|
||||
if (flags == 0) {
|
||||
reg_anim_obj_move_to_tile(object, tile, object->elevation, -1, 0);
|
||||
animationRegisterMoveToTile(object, tile, object->elevation, -1, 0);
|
||||
} else {
|
||||
reg_anim_obj_run_to_tile(object, tile, object->elevation, -1, 0);
|
||||
animationRegisterRunToTile(object, tile, object->elevation, -1, 0);
|
||||
}
|
||||
|
||||
reg_anim_end();
|
||||
@@ -1739,7 +1738,7 @@ static void opWieldItem(Program* program)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
scriptPredefinedError(program, "wield_obj_critter", SCRIPT_ERROR_FOLLOWS);
|
||||
debugPrint(" Only works for critters! ERROR ERROR ERROR!");
|
||||
return;
|
||||
@@ -1805,7 +1804,7 @@ static void opUseObject(Program* program)
|
||||
}
|
||||
|
||||
Object* self = scriptGetSelf(program);
|
||||
if ((self->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(self->pid) == OBJ_TYPE_CRITTER) {
|
||||
_action_use_an_object(script->target, object);
|
||||
} else {
|
||||
_obj_use(self, object);
|
||||
@@ -1946,7 +1945,7 @@ static void opStartGameDialog(Program* program)
|
||||
}
|
||||
|
||||
gGameDialogHeadFid = -1;
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
Proto* proto;
|
||||
if (protoGetProto(obj->pid, &proto) == -1) {
|
||||
return;
|
||||
@@ -2009,7 +2008,7 @@ static void opMetarule3(Program* program)
|
||||
ProgramValue param2 = programStackPopValue(program);
|
||||
ProgramValue param1 = programStackPopValue(program);
|
||||
int rule = programStackPopInteger(program);
|
||||
|
||||
|
||||
ProgramValue result;
|
||||
result.opcode = VALUE_TYPE_INT;
|
||||
result.integerValue = 0;
|
||||
@@ -2048,7 +2047,7 @@ static void opMetarule3(Program* program)
|
||||
|
||||
Object* object = objectFindFirstAtLocation(elevation, tile);
|
||||
while (object != NULL) {
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (critterFound) {
|
||||
result.opcode = VALUE_TYPE_PTR;
|
||||
result.pointerValue = object;
|
||||
@@ -2069,9 +2068,9 @@ static void opMetarule3(Program* program)
|
||||
Object* obj = static_cast<Object*>(param1.pointerValue);
|
||||
int frmId = param2.integerValue;
|
||||
|
||||
int fid = buildFid((obj->fid & 0xF000000) >> 24,
|
||||
int fid = buildFid(FID_TYPE(obj->fid),
|
||||
frmId,
|
||||
(obj->fid & 0xFF0000) >> 16,
|
||||
FID_ANIM_TYPE(obj->fid),
|
||||
(obj->fid & 0xF000) >> 12,
|
||||
(obj->fid & 0x70000000) >> 28);
|
||||
|
||||
@@ -2139,7 +2138,7 @@ static void opSetObjectVisibility(Program* program)
|
||||
|
||||
Rect rect;
|
||||
if (objectHide(obj, &rect) != -1) {
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
obj->flags |= OBJECT_NO_BLOCK;
|
||||
}
|
||||
|
||||
@@ -2148,7 +2147,7 @@ static void opSetObjectVisibility(Program* program)
|
||||
}
|
||||
} else {
|
||||
if ((obj->flags & OBJECT_HIDDEN) != 0) {
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
obj->flags &= ~OBJECT_NO_BLOCK;
|
||||
}
|
||||
|
||||
@@ -2364,7 +2363,7 @@ static int _correctDeath(Object* critter, int anim, bool forceBack)
|
||||
if (violenceLevel < VIOLENCE_LEVEL_MAXIMUM_BLOOD) {
|
||||
useStandardDeath = true;
|
||||
} else {
|
||||
int fid = buildFid(1, critter->fid & 0xFFF, anim, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, anim, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
if (!artExists(fid)) {
|
||||
useStandardDeath = true;
|
||||
}
|
||||
@@ -2374,7 +2373,7 @@ static int _correctDeath(Object* critter, int anim, bool forceBack)
|
||||
if (forceBack) {
|
||||
anim = ANIM_FALL_BACK;
|
||||
} else {
|
||||
int fid = buildFid(1, critter->fid & 0xFFF, ANIM_FALL_FRONT, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, ANIM_FALL_FRONT, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
if (artExists(fid)) {
|
||||
anim = ANIM_FALL_FRONT;
|
||||
} else {
|
||||
@@ -2407,7 +2406,7 @@ static void opKillCritterType(Program* program)
|
||||
|
||||
Object* obj = objectFindFirst();
|
||||
while (obj != NULL) {
|
||||
if (((obj->fid & 0xFF0000) >> 16) >= ANIM_FALL_BACK_SF) {
|
||||
if (FID_ANIM_TYPE(obj->fid) >= ANIM_FALL_BACK_SF) {
|
||||
obj = objectFindNext();
|
||||
continue;
|
||||
}
|
||||
@@ -2447,7 +2446,7 @@ static void opKillCritterType(Program* program)
|
||||
|
||||
objectFindFirst();
|
||||
|
||||
gMapHeader.field_38 = gameTimeGetTime();
|
||||
gMapHeader.lastVisitTime = gameTimeGetTime();
|
||||
}
|
||||
|
||||
obj = objectFindNext();
|
||||
@@ -2471,7 +2470,7 @@ static void opCritterDamage(Program* program)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
scriptPredefinedError(program, "critter_damage", SCRIPT_ERROR_FOLLOWS);
|
||||
debugPrint(" Can't call on non-critters!");
|
||||
return;
|
||||
@@ -2485,7 +2484,7 @@ static void opCritterDamage(Program* program)
|
||||
bool animate = (damageTypeWithFlags & 0x200) == 0;
|
||||
bool bypassArmor = (damageTypeWithFlags & 0x100) != 0;
|
||||
int damageType = damageTypeWithFlags & ~(0x100 | 0x200);
|
||||
_action_dmg(object->tile, object->elevation, amount, amount, damageType, animate, bypassArmor);
|
||||
actionDamage(object->tile, object->elevation, amount, amount, damageType, animate, bypassArmor);
|
||||
|
||||
program->flags &= ~PROGRAM_FLAG_0x20;
|
||||
|
||||
@@ -2567,12 +2566,12 @@ static void opHasTrait(Program* program)
|
||||
case CRITTER_TRAIT_OBJECT:
|
||||
switch (param) {
|
||||
case CRITTER_TRAIT_OBJECT_AI_PACKET:
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
result = object->data.critter.combat.aiPacket;
|
||||
}
|
||||
break;
|
||||
case CRITTER_TRAIT_OBJECT_TEAM:
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
result = object->data.critter.combat.team;
|
||||
}
|
||||
break;
|
||||
@@ -2681,7 +2680,7 @@ static void opGameDialogSystemEnter(Program* program)
|
||||
}
|
||||
|
||||
Object* self = scriptGetSelf(program);
|
||||
if ((self->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(self->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (!critterIsActive(self)) {
|
||||
return;
|
||||
}
|
||||
@@ -2723,11 +2722,11 @@ static void opGetCritterState(Program* program)
|
||||
Object* critter = static_cast<Object*>(programStackPopPointer(program));
|
||||
|
||||
int state = CRITTER_STATE_DEAD;
|
||||
if (critter != NULL && (critter->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (critter != NULL && PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (critterIsActive(critter)) {
|
||||
state = CRITTER_STATE_NORMAL;
|
||||
|
||||
int anim = (critter->fid & 0xFF0000) >> 16;
|
||||
int anim = FID_ANIM_TYPE(critter->fid);
|
||||
if (anim >= ANIM_FALL_BACK_SF && anim <= ANIM_FALL_FRONT_SF) {
|
||||
state = CRITTER_STATE_PRONE;
|
||||
}
|
||||
@@ -2809,7 +2808,7 @@ static void opCritterAttemptPlacement(Program* program)
|
||||
return;
|
||||
}
|
||||
|
||||
if (elevation != critter->elevation && critter->pid >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (elevation != critter->elevation && PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER) {
|
||||
_combat_delete_critter(critter);
|
||||
}
|
||||
|
||||
@@ -2853,7 +2852,7 @@ static void opCritterAddTrait(Program* program)
|
||||
Object* object = static_cast<Object*>(programStackPopPointer(program));
|
||||
|
||||
if (object != NULL) {
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
switch (kind) {
|
||||
case CRITTER_TRAIT_PERK:
|
||||
if (1) {
|
||||
@@ -2928,7 +2927,7 @@ static void opCritterRemoveTrait(Program* program)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
switch (kind) {
|
||||
case CRITTER_TRAIT_PERK:
|
||||
while (perkGetRank(object, param) > 0) {
|
||||
@@ -2997,7 +2996,7 @@ static void opCritterGetInventoryObject(Program* program)
|
||||
int type = programStackPopInteger(program);
|
||||
Object* critter = static_cast<Object*>(programStackPopPointer(program));
|
||||
|
||||
if ((critter->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER) {
|
||||
switch (type) {
|
||||
case INVEN_TYPE_WORN:
|
||||
programStackPushPointer(program, critterGetArmor(critter));
|
||||
@@ -3006,6 +3005,8 @@ static void opCritterGetInventoryObject(Program* program)
|
||||
if (critter == gDude) {
|
||||
if (interfaceGetCurrentHand() != HAND_LEFT) {
|
||||
programStackPushPointer(program, critterGetItem2(critter));
|
||||
} else {
|
||||
programStackPushPointer(program, NULL);
|
||||
}
|
||||
} else {
|
||||
programStackPushPointer(program, critterGetItem2(critter));
|
||||
@@ -3015,6 +3016,8 @@ static void opCritterGetInventoryObject(Program* program)
|
||||
if (critter == gDude) {
|
||||
if (interfaceGetCurrentHand() == HAND_LEFT) {
|
||||
programStackPushPointer(program, critterGetItem1(critter));
|
||||
} else {
|
||||
programStackPushPointer(program, NULL);
|
||||
}
|
||||
} else {
|
||||
programStackPushPointer(program, critterGetItem1(critter));
|
||||
@@ -3276,13 +3279,13 @@ static void opMetarule(Program* program)
|
||||
case METARULE_WEAPON_DAMAGE_TYPE:
|
||||
if (1) {
|
||||
Object* object = static_cast<Object*>(param.pointerValue);
|
||||
if ((object->pid >> 24) == OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_ITEM) {
|
||||
if (itemGetType(object) == ITEM_TYPE_WEAPON) {
|
||||
result = weaponGetDamageType(NULL, object);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (buildFid(5, 10, 0, 0, 0) == object->fid) {
|
||||
if (buildFid(OBJ_TYPE_MISC, 10, 0, 0, 0) == object->fid) {
|
||||
result = DAMAGE_TYPE_EXPLOSION;
|
||||
break;
|
||||
}
|
||||
@@ -3295,10 +3298,10 @@ static void opMetarule(Program* program)
|
||||
case METARULE_CRITTER_BARTERS:
|
||||
if (1) {
|
||||
Object* object = static_cast<Object*>(param.pointerValue);
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
Proto* proto;
|
||||
protoGetProto(object->pid, &proto);
|
||||
if ((proto->critter.data.flags & 0x02) != 0) {
|
||||
if ((proto->critter.data.flags & CRITTER_FLAG_0x2) != 0) {
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
@@ -3344,40 +3347,40 @@ static void opAnim(Program* program)
|
||||
|
||||
if (anim < ANIM_COUNT) {
|
||||
CritterCombatData* combatData = NULL;
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
combatData = &(obj->data.critter.combat);
|
||||
}
|
||||
|
||||
anim = _correctDeath(obj, anim, true);
|
||||
|
||||
reg_anim_begin(1);
|
||||
reg_anim_begin(ANIMATION_REQUEST_UNRESERVED);
|
||||
|
||||
// TODO: Not sure about the purpose, why it handles knock down flag?
|
||||
if (frame == 0) {
|
||||
reg_anim_animate(obj, anim, 0);
|
||||
animationRegisterAnimate(obj, anim, 0);
|
||||
if (anim >= ANIM_FALL_BACK && anim <= ANIM_FALL_FRONT_BLOOD) {
|
||||
int fid = buildFid(1, obj->fid & 0xFFF, anim + 28, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 28);
|
||||
reg_anim_17(obj, fid, -1);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, obj->fid & 0xFFF, anim + 28, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 28);
|
||||
animationRegisterSetFid(obj, fid, -1);
|
||||
}
|
||||
|
||||
if (combatData != NULL) {
|
||||
combatData->results &= DAM_KNOCKED_DOWN;
|
||||
}
|
||||
} else {
|
||||
int fid = buildFid((obj->fid & 0xF000000) >> 24, obj->fid & 0xFFF, anim, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 24);
|
||||
reg_anim_animate_reverse(obj, anim, 0);
|
||||
int fid = buildFid(FID_TYPE(obj->fid), obj->fid & 0xFFF, anim, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 24);
|
||||
animationRegisterAnimateReversed(obj, anim, 0);
|
||||
|
||||
if (anim == ANIM_PRONE_TO_STANDING) {
|
||||
fid = buildFid((obj->fid & 0xF000000) >> 24, obj->fid & 0xFFF, ANIM_FALL_FRONT_SF, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 24);
|
||||
fid = buildFid(FID_TYPE(obj->fid), obj->fid & 0xFFF, ANIM_FALL_FRONT_SF, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 24);
|
||||
} else if (anim == ANIM_BACK_TO_STANDING) {
|
||||
fid = buildFid((obj->fid & 0xF000000) >> 24, obj->fid & 0xFFF, ANIM_FALL_BACK_SF, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 24);
|
||||
fid = buildFid(FID_TYPE(obj->fid), obj->fid & 0xFFF, ANIM_FALL_BACK_SF, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 24);
|
||||
}
|
||||
|
||||
if (combatData != NULL) {
|
||||
combatData->results |= DAM_KNOCKED_DOWN;
|
||||
}
|
||||
|
||||
reg_anim_17(obj, fid, -1);
|
||||
animationRegisterSetFid(obj, fid, -1);
|
||||
}
|
||||
|
||||
reg_anim_end();
|
||||
@@ -3447,7 +3450,7 @@ static void opRegAnimAnimate(Program* program)
|
||||
int violenceLevel = VIOLENCE_LEVEL_NONE;
|
||||
if (anim != 20 || object == NULL || object->pid != 0x100002F || (configGetInt(&gGameConfig, GAME_CONFIG_PREFERENCES_KEY, GAME_CONFIG_VIOLENCE_LEVEL_KEY, &violenceLevel) && violenceLevel >= 2)) {
|
||||
if (object != NULL) {
|
||||
reg_anim_animate(object, anim, delay);
|
||||
animationRegisterAnimate(object, anim, delay);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_animate", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
@@ -3465,7 +3468,7 @@ static void opRegAnimAnimateReverse(Program* program)
|
||||
|
||||
if (!isInCombat()) {
|
||||
if (object != NULL) {
|
||||
reg_anim_animate_reverse(object, anim, delay);
|
||||
animationRegisterAnimateReversed(object, anim, delay);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_animate_reverse", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
@@ -3482,7 +3485,7 @@ static void opRegAnimObjectMoveToObject(Program* program)
|
||||
|
||||
if (!isInCombat()) {
|
||||
if (object != NULL) {
|
||||
reg_anim_obj_move_to_obj(object, dest, -1, delay);
|
||||
animationRegisterMoveToObject(object, dest, -1, delay);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_obj_move_to_obj", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
@@ -3499,7 +3502,7 @@ static void opRegAnimObjectRunToObject(Program* program)
|
||||
|
||||
if (!isInCombat()) {
|
||||
if (object != NULL) {
|
||||
reg_anim_obj_run_to_obj(object, dest, -1, delay);
|
||||
animationRegisterRunToObject(object, dest, -1, delay);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_obj_run_to_obj", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
@@ -3516,7 +3519,7 @@ static void opRegAnimObjectMoveToTile(Program* program)
|
||||
|
||||
if (!isInCombat()) {
|
||||
if (object != NULL) {
|
||||
reg_anim_obj_move_to_tile(object, tile, object->elevation, -1, delay);
|
||||
animationRegisterMoveToTile(object, tile, object->elevation, -1, delay);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_obj_move_to_tile", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
@@ -3533,7 +3536,7 @@ static void opRegAnimObjectRunToTile(Program* program)
|
||||
|
||||
if (!isInCombat()) {
|
||||
if (object != NULL) {
|
||||
reg_anim_obj_run_to_tile(object, tile, object->elevation, -1, delay);
|
||||
animationRegisterRunToTile(object, tile, object->elevation, -1, delay);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_obj_run_to_tile", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
@@ -3670,8 +3673,8 @@ static void opGetDaysSinceLastVisit(Program* program)
|
||||
{
|
||||
int days;
|
||||
|
||||
if (gMapHeader.field_38 != 0) {
|
||||
days = (gameTimeGetTime() - gMapHeader.field_38) / GAME_TIME_TICKS_PER_DAY;
|
||||
if (gMapHeader.lastVisitTime != 0) {
|
||||
days = (gameTimeGetTime() - gMapHeader.lastVisitTime) / GAME_TIME_TICKS_PER_DAY;
|
||||
} else {
|
||||
days = -1;
|
||||
}
|
||||
@@ -3755,7 +3758,6 @@ static void _op_gsay_option(Program* program)
|
||||
}
|
||||
} else {
|
||||
programFatalError("Invalid arg 3 to sayOption");
|
||||
|
||||
}
|
||||
|
||||
program->flags &= ~PROGRAM_FLAG_0x20;
|
||||
@@ -3864,7 +3866,7 @@ static void opGetPoison(Program* program)
|
||||
|
||||
int poison = 0;
|
||||
if (obj != NULL) {
|
||||
if (obj->pid >> 24 == 1) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
poison = critterGetPoison(obj);
|
||||
} else {
|
||||
debugPrint("\nScript Error: get_poison: who is not a critter!");
|
||||
@@ -3911,7 +3913,7 @@ static void opRegAnimAnimateForever(Program* program)
|
||||
|
||||
if (!isInCombat()) {
|
||||
if (obj != NULL) {
|
||||
reg_anim_animate_forever(obj, anim, -1);
|
||||
animationRegisterAnimateForever(obj, anim, -1);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_animate_forever", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
@@ -4115,7 +4117,7 @@ static void opGameUiIsDisabled(Program* program)
|
||||
|
||||
// gfade_out
|
||||
// 0x45B404
|
||||
static void opFadeOut(Program* program)
|
||||
static void opGameFadeOut(Program* program)
|
||||
{
|
||||
int data = programStackPopInteger(program);
|
||||
|
||||
@@ -4128,7 +4130,7 @@ static void opFadeOut(Program* program)
|
||||
|
||||
// gfade_in
|
||||
// 0x45B47C
|
||||
static void opFadeIn(Program* program)
|
||||
static void opGameFadeIn(Program* program)
|
||||
{
|
||||
int data = programStackPopInteger(program);
|
||||
|
||||
@@ -4182,7 +4184,7 @@ static void _op_anim_action_frame(Program* program)
|
||||
int actionFrame = 0;
|
||||
|
||||
if (object != NULL) {
|
||||
int fid = buildFid((object->fid & 0xF000000) >> 24, object->fid & 0xFFF, anim, 0, object->rotation);
|
||||
int fid = buildFid(FID_TYPE(object->fid), object->fid & 0xFFF, anim, 0, object->rotation);
|
||||
CacheEntry* frmHandle;
|
||||
Art* frm = artLock(fid, &frmHandle);
|
||||
if (frm != NULL) {
|
||||
@@ -4210,7 +4212,7 @@ static void opRegAnimPlaySfx(Program* program)
|
||||
}
|
||||
|
||||
if (obj != NULL) {
|
||||
reg_anim_play_sfx(obj, soundEffectName, delay);
|
||||
animationRegisterPlaySoundEffect(obj, soundEffectName, delay);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_play_sfx", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
@@ -4225,7 +4227,7 @@ static void opCritterModifySkill(Program* program)
|
||||
Object* critter = static_cast<Object*>(programStackPopPointer(program));
|
||||
|
||||
if (critter != NULL && points != 0) {
|
||||
if (critter->pid >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (critter == gDude) {
|
||||
int normalizedPoints = abs(points);
|
||||
if (skillIsTagged(skill)) {
|
||||
@@ -4426,7 +4428,7 @@ static void opDestroyMultipleObjects(Program* program)
|
||||
|
||||
int result = 0;
|
||||
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
_combat_delete_critter(object);
|
||||
}
|
||||
|
||||
@@ -4498,7 +4500,7 @@ static void opUseObjectOnObject(Program* program)
|
||||
}
|
||||
|
||||
Object* self = scriptGetSelf(program);
|
||||
if ((self->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(self->pid) == OBJ_TYPE_CRITTER) {
|
||||
_action_use_an_item_on_object(self, target, item);
|
||||
} else {
|
||||
_obj_use_item_on(self, target, item);
|
||||
@@ -4719,10 +4721,10 @@ static void opTerminateCombat(Program* program)
|
||||
_game_user_wants_to_quit = 1;
|
||||
Object* self = scriptGetSelf(program);
|
||||
if (self != NULL) {
|
||||
if ((self->pid >> 24) == 1) {
|
||||
if (PID_TYPE(self->pid) == OBJ_TYPE_CRITTER) {
|
||||
self->data.critter.combat.maneuver |= CRITTER_MANEUVER_STOP_ATTACKING;
|
||||
self->data.critter.combat.whoHitMe = NULL;
|
||||
_combatAIInfoSetLastTarget(self, NULL);
|
||||
aiInfoSetLastTarget(self, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4753,7 +4755,7 @@ static void opCritterStopAttacking(Program* program)
|
||||
if (obj != NULL) {
|
||||
obj->data.critter.combat.maneuver |= CRITTER_MANEUVER_STOP_ATTACKING;
|
||||
obj->data.critter.combat.whoHitMe = NULL;
|
||||
_combatAIInfoSetLastTarget(obj, NULL);
|
||||
aiInfoSetLastTarget(obj, NULL);
|
||||
} else {
|
||||
scriptPredefinedError(program, "critter_stop_attacking", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
@@ -4963,8 +4965,8 @@ void _initIntExtra()
|
||||
interpreterRegisterOpcode(0x8133, opGameUiDisable); // op_game_ui_disable
|
||||
interpreterRegisterOpcode(0x8134, opGameUiEnable); // op_game_ui_enable
|
||||
interpreterRegisterOpcode(0x8135, opGameUiIsDisabled); // op_game_ui_is_disabled
|
||||
interpreterRegisterOpcode(0x8136, opFadeOut); // op_gfade_out
|
||||
interpreterRegisterOpcode(0x8137, opFadeIn); // op_gfade_in
|
||||
interpreterRegisterOpcode(0x8136, opGameFadeOut); // op_gfade_out
|
||||
interpreterRegisterOpcode(0x8137, opGameFadeIn); // op_gfade_in
|
||||
interpreterRegisterOpcode(0x8138, opItemCapsTotal); // op_item_caps_total
|
||||
interpreterRegisterOpcode(0x8139, opItemCapsAdjust); // op_item_caps_adjust
|
||||
interpreterRegisterOpcode(0x813A, _op_anim_action_frame); // op_anim_action_frame
|
||||
@@ -4997,7 +4999,16 @@ void _initIntExtra()
|
||||
interpreterRegisterOpcode(0x8155, opCritterStopAttacking); // op_critter_stop_attacking
|
||||
}
|
||||
|
||||
// NOTE: Uncollapsed 0x45D878.
|
||||
//
|
||||
// 0x45D878
|
||||
void _intExtraRemoveProgramReferences_()
|
||||
void intExtraUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
// NOTE: Uncollapsed 0x45D878.
|
||||
//
|
||||
// 0x45D878
|
||||
void intExtraRemoveProgramReferences(Program* program)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#ifndef INTERPRETER_EXTRA_H
|
||||
#define INTERPRETER_EXTRA_H
|
||||
|
||||
#include "interpreter.h"
|
||||
|
||||
void _intExtraClose_();
|
||||
void _initIntExtra();
|
||||
void _intExtraRemoveProgramReferences_();
|
||||
void intExtraUpdate();
|
||||
void intExtraRemoveProgramReferences(Program* program);
|
||||
|
||||
#endif /* INTERPRETER_EXTRA_H */
|
||||
|
||||
+1157
-112
File diff suppressed because it is too large
Load Diff
@@ -3,12 +3,12 @@
|
||||
|
||||
#include "interpreter.h"
|
||||
|
||||
typedef void (*OFF_59E160)(Program*);
|
||||
typedef void(IntLibProgramDeleteCallback)(Program*);
|
||||
|
||||
void _updateIntLib();
|
||||
void _intlibClose();
|
||||
void _initIntlib();
|
||||
void _interpretRegisterProgramDeleteCallback(OFF_59E160 fn);
|
||||
void _removeProgramReferences_(Program* program);
|
||||
void intLibUpdate();
|
||||
void intLibExit();
|
||||
void intLibInit();
|
||||
void intLibRegisterProgramDeleteCallback(IntLibProgramDeleteCallback* callback);
|
||||
void intLibRemoveProgramReferences(Program* program);
|
||||
|
||||
#endif /* INTERPRETER_LIB_H */
|
||||
|
||||
+78
-78
@@ -675,7 +675,7 @@ static bool _setup_inventory(int inventoryWindowType)
|
||||
gInventoryWindowMaxY = windowDescription->height + inventoryWindowY;
|
||||
|
||||
unsigned char* dest = windowGetBuffer(gInventoryWindow);
|
||||
int backgroundFid = buildFid(6, windowDescription->field_0, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, windowDescription->field_0, 0, 0, 0);
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
@@ -821,10 +821,10 @@ static bool _setup_inventory(int inventoryWindowType)
|
||||
unsigned char* buttonDownData;
|
||||
unsigned char* buttonDisabledData;
|
||||
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[0]));
|
||||
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[1]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
@@ -853,13 +853,13 @@ static bool _setup_inventory(int inventoryWindowType)
|
||||
// TODO: Figure out why it building fid in chain.
|
||||
|
||||
// Large arrow up (normal).
|
||||
fid = buildFid(6, 100, 0, 0, 0);
|
||||
fid = buildFid(6, fid, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 100, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, fid, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[2]));
|
||||
|
||||
// Large arrow up (pressed).
|
||||
fid = buildFid(6, 101, 0, 0, 0);
|
||||
fid = buildFid(6, fid, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 101, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, fid, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[3]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
@@ -877,15 +877,15 @@ static bool _setup_inventory(int inventoryWindowType)
|
||||
}
|
||||
} else {
|
||||
// Large up arrow (normal).
|
||||
fid = buildFid(6, 49, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 49, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[2]));
|
||||
|
||||
// Large up arrow (pressed).
|
||||
fid = buildFid(6, 50, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 50, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[3]));
|
||||
|
||||
// Large up arrow (disabled).
|
||||
fid = buildFid(6, 53, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 53, 0, 0, 0);
|
||||
buttonDisabledData = artLockFrameData(fid, 0, 0, &(_ikey[4]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL && buttonDisabledData != NULL) {
|
||||
@@ -913,13 +913,13 @@ static bool _setup_inventory(int inventoryWindowType)
|
||||
|
||||
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_TRADE) {
|
||||
// Large dialog down button (normal)
|
||||
fid = buildFid(6, 93, 0, 0, 0);
|
||||
fid = buildFid(6, fid, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 93, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, fid, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[5]));
|
||||
|
||||
// Dialog down button (pressed)
|
||||
fid = buildFid(6, 94, 0, 0, 0);
|
||||
fid = buildFid(6, fid, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 94, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, fid, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[6]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
@@ -943,15 +943,15 @@ static bool _setup_inventory(int inventoryWindowType)
|
||||
}
|
||||
} else {
|
||||
// Large arrow down (normal).
|
||||
fid = buildFid(6, 51, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 51, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[5]));
|
||||
|
||||
// Large arrow down (pressed).
|
||||
fid = buildFid(6, 52, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 52, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[6]));
|
||||
|
||||
// Large arrow down (disabled).
|
||||
fid = buildFid(6, 54, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 54, 0, 0, 0);
|
||||
buttonDisabledData = artLockFrameData(fid, 0, 0, &(_ikey[7]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL && buttonDisabledData != NULL) {
|
||||
@@ -986,11 +986,11 @@ static bool _setup_inventory(int inventoryWindowType)
|
||||
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_LOOT) {
|
||||
if (!_gIsSteal) {
|
||||
// Take all button (normal)
|
||||
fid = buildFid(6, 436, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 436, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[8]));
|
||||
|
||||
// Take all button (pressed)
|
||||
fid = buildFid(6, 437, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 437, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[9]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
@@ -1004,11 +1004,11 @@ static bool _setup_inventory(int inventoryWindowType)
|
||||
}
|
||||
} else {
|
||||
// Inventory button up (normal)
|
||||
fid = buildFid(6, 49, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 49, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[8]));
|
||||
|
||||
// Inventory button up (pressed)
|
||||
fid = buildFid(6, 50, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 50, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[9]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
@@ -1026,11 +1026,11 @@ static bool _setup_inventory(int inventoryWindowType)
|
||||
}
|
||||
|
||||
// Inventory button down (normal)
|
||||
fid = buildFid(6, 51, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 51, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[8]));
|
||||
|
||||
// Inventory button down (pressed).
|
||||
fid = buildFid(6, 52, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 52, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[9]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
@@ -1178,7 +1178,7 @@ static void _display_inventory(int a1, int a2, int inventoryWindowType)
|
||||
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_NORMAL) {
|
||||
pitch = 499;
|
||||
|
||||
int backgroundFid = buildFid(6, 48, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 48, 0, 0, 0);
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
@@ -1191,7 +1191,7 @@ static void _display_inventory(int a1, int a2, int inventoryWindowType)
|
||||
|
||||
if (gInventoryLeftHandItem != NULL && gInventoryLeftHandItem == gInventoryRightHandItem) {
|
||||
// Clear item1.
|
||||
int itemBackgroundFid = buildFid(6, 32, 0, 0, 0);
|
||||
int itemBackgroundFid = buildFid(OBJ_TYPE_INTERFACE, 32, 0, 0, 0);
|
||||
|
||||
CacheEntry* itemBackgroundFrmHandle;
|
||||
Art* itemBackgroundFrm = artLock(itemBackgroundFid, &itemBackgroundFrmHandle);
|
||||
@@ -1212,7 +1212,7 @@ static void _display_inventory(int a1, int a2, int inventoryWindowType)
|
||||
} else if (inventoryWindowType == INVENTORY_WINDOW_TYPE_USE_ITEM_ON) {
|
||||
pitch = 292;
|
||||
|
||||
int backgroundFid = buildFid(6, 113, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 113, 0, 0, 0);
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
@@ -1224,7 +1224,7 @@ static void _display_inventory(int a1, int a2, int inventoryWindowType)
|
||||
} else if (inventoryWindowType == INVENTORY_WINDOW_TYPE_LOOT) {
|
||||
pitch = 537;
|
||||
|
||||
int backgroundFid = buildFid(6, 114, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 114, 0, 0, 0);
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
@@ -1333,7 +1333,7 @@ static void _display_target_inventory(int a1, int a2, Inventory* inventory, int
|
||||
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_LOOT) {
|
||||
pitch = 537;
|
||||
|
||||
int fid = buildFid(6, 114, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 114, 0, 0, 0);
|
||||
|
||||
CacheEntry* handle;
|
||||
unsigned char* data = artLockFrameData(fid, 0, 0, &handle);
|
||||
@@ -1521,7 +1521,7 @@ static void _display_body(int fid, int inventoryWindowType)
|
||||
rect.bottom = rect.top + INVENTORY_BODY_VIEW_HEIGHT - 1;
|
||||
|
||||
int frmId = gGameDialogSpeakerIsPartyMember ? 420 : 111;
|
||||
int backgroundFid = buildFid(6, frmId, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
|
||||
|
||||
unsigned char* src = artLockFrameData(backgroundFid, 0, 0, &backrgroundFrmHandle);
|
||||
if (src != NULL) {
|
||||
@@ -1563,7 +1563,7 @@ static void _display_body(int fid, int inventoryWindowType)
|
||||
rect.right = rect.left + INVENTORY_BODY_VIEW_WIDTH - 1;
|
||||
rect.bottom = rect.top + INVENTORY_BODY_VIEW_HEIGHT - 1;
|
||||
|
||||
int backgroundFid = buildFid(6, 114, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 114, 0, 0, 0);
|
||||
unsigned char* src = artLockFrameData(backgroundFid, 0, 0, &backrgroundFrmHandle);
|
||||
if (src != NULL) {
|
||||
blitBufferToBuffer(src + 537 * rect.top + rect.left,
|
||||
@@ -1610,7 +1610,7 @@ static int inventoryCommonInit()
|
||||
for (index = 0; index < INVENTORY_WINDOW_CURSOR_COUNT; index++) {
|
||||
InventoryCursorData* cursorData = &(gInventoryCursorData[index]);
|
||||
|
||||
int fid = buildFid(6, gInventoryWindowCursorFrmIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gInventoryWindowCursorFrmIds[index], 0, 0, 0);
|
||||
Art* frm = artLock(fid, &(cursorData->frmHandle));
|
||||
if (frm == NULL) {
|
||||
break;
|
||||
@@ -1792,7 +1792,7 @@ static void _inven_pickup(int keyCode, int a2)
|
||||
}
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundFid = buildFid(6, 48, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 48, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData != NULL) {
|
||||
blitBufferToBuffer(backgroundFrmData + 499 * rect.top + rect.left, width, height, 499, windowBuffer + 499 * rect.top + rect.left, 499);
|
||||
@@ -1803,7 +1803,7 @@ static void _inven_pickup(int keyCode, int a2)
|
||||
rect.bottom = rect.top + height - 1;
|
||||
} else {
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundFid = buildFid(6, 48, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 48, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData != NULL) {
|
||||
blitBufferToBuffer(backgroundFrmData + 499 * 286 + 154, 180, 61, 499, windowBuffer + 499 * 286 + 154, 499);
|
||||
@@ -2043,7 +2043,7 @@ void _adjust_ac(Object* critter, Object* oldArmor, Object* newArmor)
|
||||
static void _adjust_fid()
|
||||
{
|
||||
int fid;
|
||||
if ((_inven_dude->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(_inven_dude->fid) == OBJ_TYPE_CRITTER) {
|
||||
Proto* proto;
|
||||
|
||||
int v0 = _art_vault_guy_num;
|
||||
@@ -2082,7 +2082,7 @@ static void _adjust_fid()
|
||||
}
|
||||
}
|
||||
|
||||
fid = buildFid(1, v0, 0, animationCode, 0);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, v0, 0, animationCode, 0);
|
||||
} else {
|
||||
fid = _inven_dude->fid;
|
||||
}
|
||||
@@ -2325,7 +2325,7 @@ static void inventoryRenderSummary()
|
||||
|
||||
unsigned char* windowBuffer = windowGetBuffer(gInventoryWindow);
|
||||
|
||||
int fid = buildFid(6, 48, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 48, 0, 0, 0);
|
||||
|
||||
CacheEntry* backgroundHandle;
|
||||
unsigned char* backgroundData = artLockFrameData(fid, 0, 0, &backgroundHandle);
|
||||
@@ -2515,7 +2515,7 @@ static void inventoryRenderSummary()
|
||||
// Total wt:
|
||||
messageListItem.num = 20;
|
||||
if (messageListGetItem(&gInventoryMessageList, &messageListItem)) {
|
||||
if (_stack[0]->pid >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(_stack[0]->pid) == OBJ_TYPE_CRITTER) {
|
||||
int carryWeight = critterGetStat(_stack[0], STAT_CARRY_WEIGHT);
|
||||
int inventoryWeight = objectGetInventoryWeight(_stack[0]);
|
||||
sprintf(formattedText, "%s %d/%d", messageListItem.text, inventoryWeight, carryWeight);
|
||||
@@ -2623,7 +2623,7 @@ int _invenWieldFunc(Object* critter, Object* item, int a3, bool a4)
|
||||
{
|
||||
if (a4) {
|
||||
if (!isoIsDisabled()) {
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2631,7 +2631,7 @@ int _invenWieldFunc(Object* critter, Object* item, int a3, bool a4)
|
||||
if (itemType == ITEM_TYPE_ARMOR) {
|
||||
Object* armor = critterGetArmor(critter);
|
||||
if (armor != NULL) {
|
||||
armor->flags = ~OBJECT_WORN;
|
||||
armor->flags &= ~OBJECT_WORN;
|
||||
}
|
||||
|
||||
item->flags |= OBJECT_WORN;
|
||||
@@ -2649,8 +2649,8 @@ int _invenWieldFunc(Object* critter, Object* item, int a3, bool a4)
|
||||
|
||||
if (critter == gDude) {
|
||||
if (!isoIsDisabled()) {
|
||||
int fid = buildFid(1, baseFrmId, 0, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
reg_anim_17(critter, fid, 0);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, baseFrmId, 0, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
animationRegisterSetFid(critter, fid, 0);
|
||||
}
|
||||
} else {
|
||||
_adjust_ac(critter, armor, item);
|
||||
@@ -2665,7 +2665,7 @@ int _invenWieldFunc(Object* critter, Object* item, int a3, bool a4)
|
||||
|
||||
int weaponAnimationCode = weaponGetAnimationCode(item);
|
||||
int hitModeAnimationCode = weaponGetAnimationForHitMode(item, HIT_MODE_RIGHT_WEAPON_PRIMARY);
|
||||
int fid = buildFid(1, critter->fid & 0xFFF, hitModeAnimationCode, weaponAnimationCode, critter->rotation + 1);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, hitModeAnimationCode, weaponAnimationCode, critter->rotation + 1);
|
||||
if (!artExists(fid)) {
|
||||
debugPrint("\ninven_wield failed! ERROR ERROR ERROR!");
|
||||
return -1;
|
||||
@@ -2730,21 +2730,21 @@ int _invenWieldFunc(Object* critter, Object* item, int a3, bool a4)
|
||||
if (a4) {
|
||||
if (!isoIsDisabled()) {
|
||||
const char* soundEffectName = sfxBuildCharName(critter, ANIM_PUT_AWAY, CHARACTER_SOUND_EFFECT_UNUSED);
|
||||
reg_anim_play_sfx(critter, soundEffectName, 0);
|
||||
reg_anim_animate(critter, ANIM_PUT_AWAY, 0);
|
||||
animationRegisterPlaySoundEffect(critter, soundEffectName, 0);
|
||||
animationRegisterAnimate(critter, ANIM_PUT_AWAY, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (a4 && !isoIsDisabled()) {
|
||||
if (weaponAnimationCode != 0) {
|
||||
reg_anim_18(critter, weaponAnimationCode, -1);
|
||||
animationRegisterTakeOutWeapon(critter, weaponAnimationCode, -1);
|
||||
} else {
|
||||
int fid = buildFid(1, critter->fid & 0xFFF, 0, 0, critter->rotation + 1);
|
||||
reg_anim_17(critter, fid, -1);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, 0, 0, critter->rotation + 1);
|
||||
animationRegisterSetFid(critter, fid, -1);
|
||||
}
|
||||
} else {
|
||||
int fid = buildFid(1, critter->fid & 0xFFF, 0, weaponAnimationCode, critter->rotation + 1);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, 0, weaponAnimationCode, critter->rotation + 1);
|
||||
_dude_stand(critter, critter->rotation, fid);
|
||||
}
|
||||
}
|
||||
@@ -2791,20 +2791,20 @@ int _invenUnwieldFunc(Object* obj, int a2, int a3)
|
||||
|
||||
if (v6 == a2 && ((obj->fid & 0xF000) >> 12) != 0) {
|
||||
if (a3 && !isoIsDisabled()) {
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
|
||||
const char* sfx = sfxBuildCharName(obj, ANIM_PUT_AWAY, CHARACTER_SOUND_EFFECT_UNUSED);
|
||||
reg_anim_play_sfx(obj, sfx, 0);
|
||||
animationRegisterPlaySoundEffect(obj, sfx, 0);
|
||||
|
||||
reg_anim_animate(obj, 39, 0);
|
||||
animationRegisterAnimate(obj, ANIM_PUT_AWAY, 0);
|
||||
|
||||
fid = buildFid(1, obj->fid & 0xFFF, 0, 0, obj->rotation + 1);
|
||||
reg_anim_17(obj, fid, -1);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, obj->fid & 0xFFF, 0, 0, obj->rotation + 1);
|
||||
animationRegisterSetFid(obj, fid, -1);
|
||||
|
||||
return reg_anim_end();
|
||||
}
|
||||
|
||||
fid = buildFid(1, obj->fid & 0xFFF, 0, 0, obj->rotation + 1);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, obj->fid & 0xFFF, 0, 0, obj->rotation + 1);
|
||||
_dude_stand(obj, obj->rotation, fid);
|
||||
}
|
||||
|
||||
@@ -3003,7 +3003,7 @@ static void inventoryExamineItem(Object* critter, Object* item)
|
||||
unsigned char* windowBuffer = windowGetBuffer(gInventoryWindow);
|
||||
|
||||
// Clear item description area.
|
||||
int backgroundFid = buildFid(6, 48, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 48, 0, 0, 0);
|
||||
|
||||
CacheEntry* handle;
|
||||
unsigned char* backgroundData = artLockFrameData(backgroundFid, 0, 0, &handle);
|
||||
@@ -3226,7 +3226,7 @@ static void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType)
|
||||
windowBuffer + windowDescription->width * rect.top + rect.left,
|
||||
windowDescription->width);
|
||||
} else {
|
||||
int backgroundFid = buildFid(6, windowDescription->field_0, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, windowDescription->field_0, 0, 0, 0);
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
blitBufferToBuffer(backgroundFrmData + windowDescription->width * rect.top + rect.left,
|
||||
@@ -3403,8 +3403,8 @@ int inventoryOpenLooting(Object* a1, Object* a2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((a2->fid & 0xF000000) >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (_critter_flag_check(a2->pid, 0x20)) {
|
||||
if (FID_TYPE(a2->fid) == OBJ_TYPE_CRITTER) {
|
||||
if (_critter_flag_check(a2->pid, CRITTER_FLAG_0x20)) {
|
||||
// You can't find anything to take from that.
|
||||
messageListItem.num = 50;
|
||||
if (messageListGetItem(&gInventoryMessageList, &messageListItem)) {
|
||||
@@ -3414,7 +3414,7 @@ int inventoryOpenLooting(Object* a1, Object* a2)
|
||||
}
|
||||
}
|
||||
|
||||
if (((a2->fid & 0xF000000) >> 24) == OBJ_TYPE_ITEM) {
|
||||
if (FID_TYPE(a2->fid) == OBJ_TYPE_ITEM) {
|
||||
if (itemGetType(a2) == ITEM_TYPE_CONTAINER) {
|
||||
if (a2->frame == 0) {
|
||||
CacheEntry* handle;
|
||||
@@ -3488,7 +3488,7 @@ int inventoryOpenLooting(Object* a1, Object* a2)
|
||||
int critterCount = 0;
|
||||
int critterIndex = 0;
|
||||
if (!_gIsSteal) {
|
||||
if ((a2->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(a2->fid) == OBJ_TYPE_CRITTER) {
|
||||
critterCount = objectListCreate(a2->tile, a2->elevation, OBJ_TYPE_CRITTER, &critters);
|
||||
int endIndex = critterCount - 1;
|
||||
for (int index = 0; index < critterCount; index++) {
|
||||
@@ -3520,10 +3520,10 @@ int inventoryOpenLooting(Object* a1, Object* a2)
|
||||
}
|
||||
|
||||
// Setup left arrow button.
|
||||
fid = buildFid(6, arrowFrmIds[INVENTORY_ARROW_FRM_LEFT_ARROW_UP], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, arrowFrmIds[INVENTORY_ARROW_FRM_LEFT_ARROW_UP], 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(arrowFrmHandles[INVENTORY_ARROW_FRM_LEFT_ARROW_UP]));
|
||||
|
||||
fid = buildFid(6, arrowFrmIds[INVENTORY_ARROW_FRM_LEFT_ARROW_DOWN], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, arrowFrmIds[INVENTORY_ARROW_FRM_LEFT_ARROW_DOWN], 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(arrowFrmHandles[INVENTORY_ARROW_FRM_LEFT_ARROW_DOWN]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
@@ -3534,10 +3534,10 @@ int inventoryOpenLooting(Object* a1, Object* a2)
|
||||
}
|
||||
|
||||
// Setup right arrow button.
|
||||
fid = buildFid(6, arrowFrmIds[INVENTORY_ARROW_FRM_RIGHT_ARROW_UP], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, arrowFrmIds[INVENTORY_ARROW_FRM_RIGHT_ARROW_UP], 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(arrowFrmHandles[INVENTORY_ARROW_FRM_RIGHT_ARROW_UP]));
|
||||
|
||||
fid = buildFid(6, arrowFrmIds[INVENTORY_ARROW_FRM_RIGHT_ARROW_DOWN], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, arrowFrmIds[INVENTORY_ARROW_FRM_RIGHT_ARROW_DOWN], 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(arrowFrmHandles[INVENTORY_ARROW_FRM_RIGHT_ARROW_DOWN]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
@@ -3800,7 +3800,7 @@ int inventoryOpenStealing(Object* a1, Object* a2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
_gIsSteal = (a1->pid >> 24) == OBJ_TYPE_CRITTER && critterIsActive(a2);
|
||||
_gIsSteal = PID_TYPE(a1->pid) == OBJ_TYPE_CRITTER && critterIsActive(a2);
|
||||
_gStealCount = 0;
|
||||
_gStealSize = 0;
|
||||
|
||||
@@ -3848,7 +3848,7 @@ static int _move_inventory(Object* a1, int a2, Object* a3, bool a4)
|
||||
unsigned char* windowBuffer = windowGetBuffer(gInventoryWindow);
|
||||
|
||||
CacheEntry* handle;
|
||||
int fid = buildFid(6, 114, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 114, 0, 0, 0);
|
||||
unsigned char* data = artLockFrameData(fid, 0, 0, &handle);
|
||||
if (data != NULL) {
|
||||
blitBufferToBuffer(data + 537 * rect.top + rect.left, INVENTORY_SLOT_WIDTH, INVENTORY_SLOT_HEIGHT, 537, windowBuffer + 537 * rect.top + rect.left, 537);
|
||||
@@ -3931,7 +3931,7 @@ static int _move_inventory(Object* a1, int a2, Object* a3, bool a4)
|
||||
if (rc != 1) {
|
||||
if (_item_move(a3, _inven_dude, a1, quantityToMove) == 0) {
|
||||
if ((a1->flags & OBJECT_IN_RIGHT_HAND) != 0) {
|
||||
a3->fid = buildFid((a3->fid & 0xF000000) >> 24, a3->fid & 0xFFF, (a3->fid & 0xFF0000) >> 16, 0, a3->rotation + 1);
|
||||
a3->fid = buildFid(FID_TYPE(a3->fid), a3->fid & 0xFFF, FID_ANIM_TYPE(a3->fid), 0, a3->rotation + 1);
|
||||
}
|
||||
|
||||
a3->flags &= ~OBJECT_EQUIPPED;
|
||||
@@ -4735,7 +4735,7 @@ static void _draw_amount(int value, int inventoryWindowType)
|
||||
{
|
||||
// BIGNUM.frm
|
||||
CacheEntry* handle;
|
||||
int fid = buildFid(6, 170, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 170, 0, 0, 0);
|
||||
unsigned char* data = artLockFrameData(fid, 0, 0, &handle);
|
||||
if (data == NULL) {
|
||||
return;
|
||||
@@ -4947,7 +4947,7 @@ static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item)
|
||||
unsigned char* windowBuffer = windowGetBuffer(_mt_wid);
|
||||
|
||||
CacheEntry* backgroundHandle;
|
||||
int backgroundFid = buildFid(6, windowDescription->field_0, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, windowDescription->field_0, 0, 0, 0);
|
||||
unsigned char* backgroundData = artLockFrameData(backgroundFid, 0, 0, &backgroundHandle);
|
||||
if (backgroundData != NULL) {
|
||||
blitBufferToBuffer(backgroundData, windowDescription->width, windowDescription->height, windowDescription->width, windowBuffer, windowDescription->width);
|
||||
@@ -4972,7 +4972,7 @@ static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item)
|
||||
|
||||
// Timer overlay
|
||||
CacheEntry* overlayFrmHandle;
|
||||
int overlayFid = buildFid(6, 306, 0, 0, 0);
|
||||
int overlayFid = buildFid(OBJ_TYPE_INTERFACE, 306, 0, 0, 0);
|
||||
unsigned char* overlayFrmData = artLockFrameData(overlayFid, 0, 0, &overlayFrmHandle);
|
||||
if (overlayFrmData != NULL) {
|
||||
blitBufferToBuffer(overlayFrmData, 105, 81, 105, windowBuffer + 34 * windowDescription->width + 113, windowDescription->width);
|
||||
@@ -4999,10 +4999,10 @@ static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item)
|
||||
int btn;
|
||||
|
||||
// Plus button
|
||||
fid = buildFid(6, 193, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 193, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_mt_key[0]));
|
||||
|
||||
fid = buildFid(6, 194, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 194, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_mt_key[1]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
@@ -5013,10 +5013,10 @@ static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item)
|
||||
}
|
||||
|
||||
// Minus button
|
||||
fid = buildFid(6, 191, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 191, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_mt_key[2]));
|
||||
|
||||
fid = buildFid(6, 192, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 192, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_mt_key[3]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
@@ -5026,10 +5026,10 @@ static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item)
|
||||
}
|
||||
}
|
||||
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_mt_key[4]));
|
||||
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_mt_key[5]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
@@ -5047,10 +5047,10 @@ static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item)
|
||||
}
|
||||
|
||||
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_MOVE_ITEMS) {
|
||||
fid = buildFid(6, 307, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 307, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_mt_key[6]));
|
||||
|
||||
fid = buildFid(6, 308, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 308, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_mt_key[7]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
|
||||
+16
-20
@@ -189,7 +189,7 @@ int itemAttemptAdd(Object* owner, Object* itemToAdd, int quantity)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int parentType = (owner->fid & 0xF000000) >> 24;
|
||||
int parentType = FID_TYPE(owner->fid);
|
||||
if (parentType == OBJ_TYPE_ITEM) {
|
||||
int itemType = itemGetType(owner);
|
||||
if (itemType == ITEM_TYPE_CONTAINER) {
|
||||
@@ -205,7 +205,7 @@ int itemAttemptAdd(Object* owner, Object* itemToAdd, int quantity)
|
||||
|
||||
Object* containerOwner = objectGetOwner(owner);
|
||||
if (containerOwner != NULL) {
|
||||
if (((containerOwner->fid & 0xF000000) >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(containerOwner->fid) == OBJ_TYPE_CRITTER) {
|
||||
int weightToAdd = itemGetWeight(itemToAdd);
|
||||
weightToAdd *= quantity;
|
||||
|
||||
@@ -473,7 +473,7 @@ int _item_move_all_hidden(Object* a1, Object* a2)
|
||||
for (int j = i; j < inventory->length;) {
|
||||
bool v5;
|
||||
InventoryItem* inventoryItem = &(inventory->items[j]);
|
||||
if (inventoryItem->item->pid >> 24 == OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(inventoryItem->item->pid) == OBJ_TYPE_ITEM) {
|
||||
Proto* proto;
|
||||
if (protoGetProto(inventoryItem->item->pid, &proto) != -1) {
|
||||
v5 = (proto->item.extendedFlags & ItemProtoExtendedFlags_NaturalWeapon) == 0;
|
||||
@@ -505,7 +505,7 @@ int _item_destroy_all_hidden(Object* a1)
|
||||
for (int j = i; j < inventory->length;) {
|
||||
bool v5;
|
||||
InventoryItem* inventoryItem = &(inventory->items[j]);
|
||||
if (inventoryItem->item->pid >> 24 == OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(inventoryItem->item->pid) == OBJ_TYPE_ITEM) {
|
||||
Proto* proto;
|
||||
if (protoGetProto(inventoryItem->item->pid, &proto) != -1) {
|
||||
v5 = (proto->item.extendedFlags & ItemProtoExtendedFlags_NaturalWeapon) == 0;
|
||||
@@ -584,9 +584,9 @@ int _item_drop_all(Object* critter, int tile)
|
||||
|
||||
if (hasEquippedItems) {
|
||||
Rect updatedRect;
|
||||
int fid = buildFid(1, frmId, (critter->fid & 0xFF0000) >> 16, 0, (critter->fid & 0x70000000) >> 28);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, frmId, FID_ANIM_TYPE(critter->fid), 0, (critter->fid & 0x70000000) >> 28);
|
||||
objectSetFid(critter, fid, &updatedRect);
|
||||
if (((critter->fid & 0xFF0000) >> 16) == 0) {
|
||||
if (FID_ANIM_TYPE(critter->fid) == ANIM_STAND) {
|
||||
tileWindowRefreshRect(&updatedRect, gElevation);
|
||||
}
|
||||
}
|
||||
@@ -667,7 +667,7 @@ int itemGetType(Object* item)
|
||||
return ITEM_TYPE_MISC;
|
||||
}
|
||||
|
||||
if ((item->pid >> 24) != OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(item->pid) != OBJ_TYPE_ITEM) {
|
||||
return ITEM_TYPE_MISC;
|
||||
}
|
||||
|
||||
@@ -845,7 +845,7 @@ int objectGetCost(Object* obj)
|
||||
}
|
||||
}
|
||||
|
||||
if ((obj->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(obj->fid) == OBJ_TYPE_CRITTER) {
|
||||
Object* item2 = critterGetItem2(obj);
|
||||
if (item2 != NULL && (item2->flags & OBJECT_IN_RIGHT_HAND) == 0) {
|
||||
cost += itemGetCost(item2);
|
||||
@@ -883,7 +883,7 @@ int objectGetInventoryWeight(Object* obj)
|
||||
weight += itemGetWeight(item) * inventoryItem->quantity;
|
||||
}
|
||||
|
||||
if (((obj->fid & 0xF000000) >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(obj->fid) == OBJ_TYPE_CRITTER) {
|
||||
Object* item2 = critterGetItem2(obj);
|
||||
if (item2 != NULL) {
|
||||
if ((item2->flags & OBJECT_IN_RIGHT_HAND) == 0) {
|
||||
@@ -1088,7 +1088,7 @@ int weaponIsNatural(Object* obj)
|
||||
{
|
||||
Proto* proto;
|
||||
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_ITEM) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1590,7 +1590,7 @@ int _item_w_range(Object* critter, int hitMode)
|
||||
return range;
|
||||
}
|
||||
|
||||
if (_critter_flag_check(critter->pid, 0x2000)) {
|
||||
if (_critter_flag_check(critter->pid, CRITTER_FLAG_0x2000)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -1942,14 +1942,10 @@ int _item_w_compute_ammo_cost(Object* obj, int* inout_a2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns true if weapon's damage is explosion, plasma, or emp.
|
||||
// Probably checks if weapon is granade.
|
||||
//
|
||||
// 0x4790E8
|
||||
bool _item_w_is_grenade(Object* weapon)
|
||||
bool weaponIsGrenade(Object* weapon)
|
||||
{
|
||||
int damageType = weaponGetDamageType(NULL, weapon);
|
||||
|
||||
return damageType == DAMAGE_TYPE_EXPLOSION || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP;
|
||||
}
|
||||
|
||||
@@ -1968,7 +1964,7 @@ int _item_w_area_damage_radius(Object* weapon, int hitMode)
|
||||
}
|
||||
} else if (attackType == ATTACK_TYPE_THROW) {
|
||||
// NOTE: Uninline.
|
||||
if (_item_w_is_grenade(weapon)) {
|
||||
if (weaponIsGrenade(weapon)) {
|
||||
// NOTE: Uninline.
|
||||
v1 = _item_w_grenade_dmg_radius(weapon);
|
||||
}
|
||||
@@ -2840,7 +2836,7 @@ int drugEffectEventProcess(Object* obj, void* data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3009,7 +3005,7 @@ int withdrawalEventWrite(File* stream, void* data)
|
||||
// 0x47A4C4
|
||||
static void performWithdrawalStart(Object* obj, int perk, int pid)
|
||||
{
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
debugPrint("\nERROR: perform_withdrawal_start: Was called on non-critter!");
|
||||
return;
|
||||
}
|
||||
@@ -3039,7 +3035,7 @@ static void performWithdrawalStart(Object* obj, int perk, int pid)
|
||||
// 0x47A558
|
||||
static void performWithdrawalEnd(Object* obj, int perk)
|
||||
{
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
debugPrint("\nERROR: perform_withdrawal_end: Was called on non-critter!");
|
||||
return;
|
||||
}
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@ Object* _item_w_unload(Object* weapon);
|
||||
int weaponGetActionPointCost1(Object* weapon);
|
||||
int weaponGetActionPointCost2(Object* weapon);
|
||||
int _item_w_compute_ammo_cost(Object* obj, int* inout_a2);
|
||||
bool _item_w_is_grenade(Object* weapon);
|
||||
bool weaponIsGrenade(Object* weapon);
|
||||
int _item_w_area_damage_radius(Object* weapon, int hitMode);
|
||||
int _item_w_grenade_dmg_radius(Object* weapon);
|
||||
int _item_w_rocket_dmg_radius(Object* weapon);
|
||||
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
#include "light.h"
|
||||
|
||||
#include "map_defs.h"
|
||||
#include "object.h"
|
||||
#include "perk.h"
|
||||
#include "tile.h"
|
||||
#include "object.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@@ -111,7 +111,7 @@ void lightIncreaseIntensity(int elevation, int tile, int lightIntensity)
|
||||
if (!hexGridTileIsValid(tile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
gLightIntensity[elevation][tile] += lightIntensity;
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ void lightDecreaseIntensity(int elevation, int tile, int lightIntensity)
|
||||
if (!hexGridTileIsValid(tile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
gLightIntensity[elevation][tile] -= lightIntensity;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -987,7 +987,7 @@ int lsgLoadGame(int mode)
|
||||
int v45 = _get_time();
|
||||
int v44 = v109 + 1;
|
||||
|
||||
if (v106 == 0 && v44 == 1 || v106 == 1 && v109 > 14.4) {
|
||||
if ((v106 == 0 && v44 == 1) || (v106 == 1 && v109 > 14.4)) {
|
||||
v106 = 1;
|
||||
|
||||
if (v109 > 14.4) {
|
||||
@@ -1227,7 +1227,7 @@ static int lsgWindowInit(int windowType)
|
||||
}
|
||||
|
||||
for (int index = 0; index < LOAD_SAVE_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, gLoadSaveFrmIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gLoadSaveFrmIds[index], 0, 0, 0);
|
||||
gLoadSaveFrmData[index] = artLockFrameDataReturningSize(fid,
|
||||
&(gLoadSaveFrmHandles[index]),
|
||||
&(gLoadSaveFrmSizes[index].width),
|
||||
|
||||
+118
-35
@@ -23,13 +23,16 @@
|
||||
#include "options.h"
|
||||
#include "palette.h"
|
||||
#include "platform_compat.h"
|
||||
#include "proto.h"
|
||||
#include "random.h"
|
||||
#include "scripts.h"
|
||||
#include "sfall_config.h"
|
||||
#include "selfrun.h"
|
||||
#include "sfall_config.h"
|
||||
#include "text_font.h"
|
||||
#include "version.h"
|
||||
#include "window.h"
|
||||
#include "window_manager.h"
|
||||
#include "window_manager_private.h"
|
||||
#include "word_wrap.h"
|
||||
#include "world_map.h"
|
||||
|
||||
@@ -57,7 +60,7 @@ typedef enum MainMenuOption {
|
||||
MAIN_MENU_INTRO,
|
||||
MAIN_MENU_NEW_GAME,
|
||||
MAIN_MENU_LOAD_GAME,
|
||||
MAIN_MENU_3,
|
||||
MAIN_MENU_SCREENSAVER,
|
||||
MAIN_MENU_TIMEOUT,
|
||||
MAIN_MENU_CREDITS,
|
||||
MAIN_MENU_QUOTES,
|
||||
@@ -70,6 +73,8 @@ static bool falloutInit(int argc, char** argv);
|
||||
static int _main_load_new(char* fname);
|
||||
static void mainLoop(FpsLimiter& fpsLimiter);
|
||||
static void _main_selfrun_exit();
|
||||
static void _main_selfrun_record();
|
||||
static void _main_selfrun_play();
|
||||
static void showDeath();
|
||||
static void _main_death_voiceover_callback();
|
||||
static int _mainDeathGrabTextFile(const char* fileName, char* dest);
|
||||
@@ -99,6 +104,16 @@ static int _main_selfrun_index = 0;
|
||||
// 0x5194E8
|
||||
static bool _main_show_death_scene = false;
|
||||
|
||||
// A switch to pick selfrun vs. intro video for screensaver:
|
||||
// - `false` - will play next selfrun recording
|
||||
// - `true` - will play intro video
|
||||
//
|
||||
// This value will alternate on every attempt, even if there are no selfrun
|
||||
// recordings.
|
||||
//
|
||||
// 0x5194EC
|
||||
static bool gMainMenuScreensaverCycle = false;
|
||||
|
||||
// 0x5194F0
|
||||
static int gMainMenuWindow = -1;
|
||||
|
||||
@@ -175,7 +190,7 @@ int falloutMain(int argc, char** argv)
|
||||
// SFALL: Allow to skip intro movies
|
||||
int skipOpeningMovies;
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_SKIP_OPENING_MOVIES_KEY, &skipOpeningMovies);
|
||||
if(skipOpeningMovies < 1) {
|
||||
if (skipOpeningMovies < 1) {
|
||||
gameMoviePlay(MOVIE_IPLOGO, GAME_MOVIE_FADE_IN);
|
||||
gameMoviePlay(MOVIE_INTRO, 0);
|
||||
gameMoviePlay(MOVIE_CREDITS, 0);
|
||||
@@ -207,7 +222,7 @@ int falloutMain(int argc, char** argv)
|
||||
gameMoviePlay(MOVIE_ELDER, GAME_MOVIE_STOP_MUSIC);
|
||||
randomSeedPrerandom(-1);
|
||||
|
||||
// SFALL: Override starting map.
|
||||
// SFALL: Override starting map.
|
||||
char* mapName = NULL;
|
||||
if (configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_STARTING_MAP_KEY, &mapName)) {
|
||||
if (*mapName == '\0') {
|
||||
@@ -273,8 +288,8 @@ int falloutMain(int argc, char** argv)
|
||||
case MAIN_MENU_TIMEOUT:
|
||||
debugPrint("Main menu timed-out\n");
|
||||
// FALLTHROUGH
|
||||
case MAIN_MENU_3:
|
||||
// _main_selfrun_play();
|
||||
case MAIN_MENU_SCREENSAVER:
|
||||
_main_selfrun_play();
|
||||
break;
|
||||
case MAIN_MENU_OPTIONS:
|
||||
mainMenuWindowHide(false);
|
||||
@@ -303,7 +318,7 @@ int falloutMain(int argc, char** argv)
|
||||
backgroundSoundDelete();
|
||||
break;
|
||||
case MAIN_MENU_SELFRUN:
|
||||
// _main_selfrun_record();
|
||||
_main_selfrun_record();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -329,7 +344,7 @@ static bool falloutInit(int argc, char** argv)
|
||||
_main_selfrun_exit();
|
||||
}
|
||||
|
||||
if (_selfrun_get_list(&_main_selfrun_list, &_main_selfrun_count) == 0) {
|
||||
if (selfrunInitFileList(&_main_selfrun_list, &_main_selfrun_count) == 0) {
|
||||
_main_selfrun_index = 0;
|
||||
}
|
||||
|
||||
@@ -408,7 +423,7 @@ static void mainLoop(FpsLimiter& fpsLimiter)
|
||||
static void _main_selfrun_exit()
|
||||
{
|
||||
if (_main_selfrun_list != NULL) {
|
||||
_selfrun_free_list(&_main_selfrun_list);
|
||||
selfrunFreeFileList(&_main_selfrun_list);
|
||||
}
|
||||
|
||||
_main_selfrun_count = 0;
|
||||
@@ -416,6 +431,89 @@ static void _main_selfrun_exit()
|
||||
_main_selfrun_list = NULL;
|
||||
}
|
||||
|
||||
// 0x480F64
|
||||
static void _main_selfrun_record()
|
||||
{
|
||||
SelfrunData selfrunData;
|
||||
bool ready = false;
|
||||
|
||||
char** fileList;
|
||||
int fileListLength = fileNameListInit("maps\\*.map", &fileList, 0, 0);
|
||||
if (fileListLength != 0) {
|
||||
int selectedFileIndex = _win_list_select("Select Map", fileList, fileListLength, 0, 80, 80, 0x10000 | 0x100 | 4);
|
||||
if (selectedFileIndex != -1) {
|
||||
// NOTE: It's size is likely 13 chars (on par with SelfrunData
|
||||
// fields), but due to the padding it takes 16 chars on stack.
|
||||
char recordingName[SELFRUN_RECORDING_FILE_NAME_LENGTH];
|
||||
recordingName[0] = '\0';
|
||||
if (_win_get_str(recordingName, sizeof(recordingName) - 2, "Enter name for recording (8 characters max, no extension):", 100, 100) == 0) {
|
||||
memset(&selfrunData, 0, sizeof(selfrunData));
|
||||
if (selfrunPrepareRecording(recordingName, fileList[selectedFileIndex], &selfrunData) == 0) {
|
||||
ready = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
fileNameListFree(&fileList, 0);
|
||||
}
|
||||
|
||||
if (ready) {
|
||||
mainMenuWindowHide(true);
|
||||
mainMenuWindowFree();
|
||||
backgroundSoundDelete();
|
||||
randomSeedPrerandom(0xBEEFFEED);
|
||||
gameReset();
|
||||
_proto_dude_init("premade\\combat.gcd");
|
||||
_main_load_new(selfrunData.mapFileName);
|
||||
selfrunRecordingLoop(&selfrunData);
|
||||
paletteFadeTo(gPaletteWhite);
|
||||
objectHide(gDude, NULL);
|
||||
_map_exit();
|
||||
gameReset();
|
||||
mainMenuWindowInit();
|
||||
|
||||
if (_main_selfrun_list != NULL) {
|
||||
_main_selfrun_exit();
|
||||
}
|
||||
|
||||
if (selfrunInitFileList(&_main_selfrun_list, &_main_selfrun_count) == 0) {
|
||||
_main_selfrun_index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0x48109C
|
||||
static void _main_selfrun_play()
|
||||
{
|
||||
if (!gMainMenuScreensaverCycle && _main_selfrun_count > 0) {
|
||||
SelfrunData selfrunData;
|
||||
if (selfrunPreparePlayback(_main_selfrun_list[_main_selfrun_index], &selfrunData) == 0) {
|
||||
mainMenuWindowHide(true);
|
||||
mainMenuWindowFree();
|
||||
backgroundSoundDelete();
|
||||
randomSeedPrerandom(0xBEEFFEED);
|
||||
gameReset();
|
||||
_proto_dude_init("premade\\combat.gcd");
|
||||
_main_load_new(selfrunData.mapFileName);
|
||||
selfrunPlaybackLoop(&selfrunData);
|
||||
paletteFadeTo(gPaletteWhite);
|
||||
objectHide(gDude, NULL);
|
||||
_map_exit();
|
||||
gameReset();
|
||||
mainMenuWindowInit();
|
||||
}
|
||||
|
||||
_main_selfrun_index++;
|
||||
if (_main_selfrun_index >= _main_selfrun_count) {
|
||||
_main_selfrun_index = 0;
|
||||
}
|
||||
} else {
|
||||
mainMenuWindowHide(true);
|
||||
gameMoviePlay(MOVIE_INTRO, GAME_MOVIE_PAUSE_MUSIC);
|
||||
}
|
||||
|
||||
gMainMenuScreensaverCycle = !gMainMenuScreensaverCycle;
|
||||
}
|
||||
|
||||
// 0x48118C
|
||||
static void showDeath()
|
||||
{
|
||||
@@ -445,7 +543,7 @@ static void showDeath()
|
||||
|
||||
// DEATH.FRM
|
||||
CacheEntry* backgroundHandle;
|
||||
int fid = buildFid(6, 309, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 309, 0, 0, 0);
|
||||
unsigned char* background = artLockFrameData(fid, 0, 0, &backgroundHandle);
|
||||
if (background == NULL) {
|
||||
break;
|
||||
@@ -591,32 +689,17 @@ static int _mainDeathGrabTextFile(const char* fileName, char* dest)
|
||||
// 0x481598
|
||||
static int _mainDeathWordWrap(char* text, int width, short* beginnings, short* count)
|
||||
{
|
||||
// TODO: Probably wrong.
|
||||
while (true) {
|
||||
char* p = text;
|
||||
while (*p != ':') {
|
||||
if (*p != '\0') {
|
||||
p++;
|
||||
if (*p == ':') {
|
||||
break;
|
||||
}
|
||||
if (*p != '\0') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
p = NULL;
|
||||
char* sep = strchr(text, ':');
|
||||
if (sep == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (p == NULL) {
|
||||
if (sep - 1 < text) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (p - 1 < text) {
|
||||
break;
|
||||
}
|
||||
p[0] = ' ';
|
||||
p[-1] = ' ';
|
||||
sep[0] = ' ';
|
||||
sep[-1] = ' ';
|
||||
}
|
||||
|
||||
if (wordWrap(text, width, beginnings, count) == -1) {
|
||||
@@ -671,7 +754,7 @@ static int mainMenuWindowInit()
|
||||
gMainMenuWindowBuffer = windowGetBuffer(gMainMenuWindow);
|
||||
|
||||
// mainmenu.frm
|
||||
int backgroundFid = buildFid(6, 140, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 140, 0, 0, 0);
|
||||
gMainMenuBackgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &gMainMenuBackgroundFrmHandle);
|
||||
if (gMainMenuBackgroundFrmData == NULL) {
|
||||
mainMenuWindowFree();
|
||||
@@ -692,7 +775,7 @@ static int mainMenuWindowInit()
|
||||
int fontSettings = _colorTable[21091], fontSettingsSFall = 0;
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_FONT_COLOR_KEY, &fontSettingsSFall);
|
||||
if (fontSettingsSFall && !(fontSettingsSFall & 0x010000))
|
||||
fontSettings = fontSettingsSFall & 0xFF;
|
||||
fontSettings = fontSettingsSFall & 0xFF;
|
||||
|
||||
// SFALL: Allow to move copyright text
|
||||
int offsetX = 0, offsetY = 0;
|
||||
@@ -717,7 +800,7 @@ static int mainMenuWindowInit()
|
||||
windowDrawText(gMainMenuWindow, version, 0, 615 - len, 460, fontSettings | 0x06000000);
|
||||
|
||||
// menuup.frm
|
||||
fid = buildFid(6, 299, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 299, 0, 0, 0);
|
||||
gMainMenuButtonUpFrmData = artLockFrameData(fid, 0, 0, &gMainMenuButtonUpFrmHandle);
|
||||
if (gMainMenuButtonUpFrmData == NULL) {
|
||||
mainMenuWindowFree();
|
||||
@@ -725,7 +808,7 @@ static int mainMenuWindowInit()
|
||||
}
|
||||
|
||||
// menudown.frm
|
||||
fid = buildFid(6, 300, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 300, 0, 0, 0);
|
||||
gMainMenuButtonDownFrmData = artLockFrameData(fid, 0, 0, &gMainMenuButtonDownFrmHandle);
|
||||
if (gMainMenuButtonDownFrmData == NULL) {
|
||||
mainMenuWindowFree();
|
||||
@@ -900,7 +983,7 @@ static int mainMenuWindowHandleEvents(FpsLimiter& fpsLimiter)
|
||||
} else if (keyCode == KEY_MINUS || keyCode == KEY_UNDERSCORE) {
|
||||
brightnessDecrease();
|
||||
} else if (keyCode == KEY_UPPERCASE_D || keyCode == KEY_LOWERCASE_D) {
|
||||
rc = MAIN_MENU_3;
|
||||
rc = MAIN_MENU_SCREENSAVER;
|
||||
continue;
|
||||
} else if (keyCode == 1111) {
|
||||
if (!(mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_REPEAT)) {
|
||||
|
||||
+38
-45
@@ -33,6 +33,7 @@
|
||||
#include "text_object.h"
|
||||
#include "tile.h"
|
||||
#include "window_manager.h"
|
||||
#include "window_manager_private.h"
|
||||
#include "world_map.h"
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -922,7 +923,7 @@ static int mapLoad(File* stream)
|
||||
}
|
||||
|
||||
Object* object;
|
||||
int fid = buildFid(5, 12, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_MISC, 12, 0, 0, 0);
|
||||
objectCreateWithFidPid(&object, fid, -1);
|
||||
object->flags |= (OBJECT_LIGHT_THRU | OBJECT_TEMPORARY | OBJECT_HIDDEN);
|
||||
objectSetLocation(object, 1, 0, NULL);
|
||||
@@ -1027,8 +1028,8 @@ int mapLoadSaved(char* fileName)
|
||||
|
||||
int rc = mapLoadByName(mapName);
|
||||
|
||||
if (gameTimeGetTime() >= gMapHeader.field_38) {
|
||||
if (((gameTimeGetTime() - gMapHeader.field_38) / 36000) >= 24) {
|
||||
if (gameTimeGetTime() >= gMapHeader.lastVisitTime) {
|
||||
if (((gameTimeGetTime() - gMapHeader.lastVisitTime) / GAME_TIME_TICKS_PER_HOUR) >= 24) {
|
||||
objectUnjamAll();
|
||||
}
|
||||
|
||||
@@ -1061,37 +1062,31 @@ static int _map_age_dead_critters()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v4 = (gameTimeGetTime() - gMapHeader.field_38) / 36000;
|
||||
if (v4 == 0) {
|
||||
int hoursSinceLastVisit = (gameTimeGetTime() - gMapHeader.lastVisitTime) / GAME_TIME_TICKS_PER_HOUR;
|
||||
if (hoursSinceLastVisit == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Object* obj = objectFindFirst();
|
||||
while (obj != NULL) {
|
||||
if (obj->pid >> 24 == OBJ_TYPE_CRITTER
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER
|
||||
&& obj != gDude
|
||||
&& !objectIsPartyMember(obj)
|
||||
&& !critterIsDead(obj)) {
|
||||
obj->data.critter.combat.maneuver &= 0x04;
|
||||
if (critterGetKillType(obj) != KILL_TYPE_ROBOT && _critter_flag_check(obj->pid, 512) == 0) {
|
||||
_critter_heal_hours(obj, v4);
|
||||
obj->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING;
|
||||
if (critterGetKillType(obj) != KILL_TYPE_ROBOT && _critter_flag_check(obj->pid, CRITTER_FLAG_0x200) == 0) {
|
||||
_critter_heal_hours(obj, hoursSinceLastVisit);
|
||||
}
|
||||
}
|
||||
obj = objectFindNext();
|
||||
}
|
||||
|
||||
int v20;
|
||||
if (v4 <= 336) {
|
||||
if (v4 > 144) {
|
||||
v20 = 1;
|
||||
} else {
|
||||
v20 = 0;
|
||||
}
|
||||
int agingType;
|
||||
if (hoursSinceLastVisit > 6 * 24) {
|
||||
agingType = 1;
|
||||
} else if (hoursSinceLastVisit > 14 * 24) {
|
||||
agingType = 2;
|
||||
} else {
|
||||
v20 = 2;
|
||||
}
|
||||
|
||||
if (v20 == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1101,10 +1096,10 @@ static int _map_age_dead_critters()
|
||||
|
||||
obj = objectFindFirst();
|
||||
while (obj != NULL) {
|
||||
int type = obj->pid >> 24;
|
||||
int type = PID_TYPE(obj->pid);
|
||||
if (type == OBJ_TYPE_CRITTER) {
|
||||
if (obj != gDude && critterIsDead(obj)) {
|
||||
if (critterGetKillType(obj) != KILL_TYPE_ROBOT && _critter_flag_check(obj->pid, 512) == 0) {
|
||||
if (critterGetKillType(obj) != KILL_TYPE_ROBOT && _critter_flag_check(obj->pid, CRITTER_FLAG_0x200) == 0) {
|
||||
objects[count++] = obj;
|
||||
|
||||
if (count >= capacity) {
|
||||
@@ -1117,7 +1112,7 @@ static int _map_age_dead_critters()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (v20 == 2 && type == OBJ_TYPE_MISC && obj->pid == 0x500000B) {
|
||||
} else if (agingType == 2 && type == OBJ_TYPE_MISC && obj->pid == 0x500000B) {
|
||||
objects[count++] = obj;
|
||||
if (count >= capacity) {
|
||||
capacity *= 2;
|
||||
@@ -1134,18 +1129,18 @@ static int _map_age_dead_critters()
|
||||
int rc = 0;
|
||||
for (int index = 0; index < count; index++) {
|
||||
Object* obj = objects[index];
|
||||
if (obj->pid >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (_critter_flag_check(obj->pid, 64) == 0) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (_critter_flag_check(obj->pid, CRITTER_FLAG_0x40) == 0) {
|
||||
_item_drop_all(obj, obj->tile);
|
||||
}
|
||||
|
||||
Object* a1;
|
||||
if (objectCreateWithPid(&a1, 0x5000004) == -1) {
|
||||
Object* blood;
|
||||
if (objectCreateWithPid(&blood, 0x5000004) == -1) {
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
objectSetLocation(a1, obj->tile, obj->elevation, NULL);
|
||||
objectSetLocation(blood, obj->tile, obj->elevation, NULL);
|
||||
|
||||
Proto* proto;
|
||||
protoGetProto(obj->pid, &proto);
|
||||
@@ -1160,7 +1155,7 @@ static int _map_age_dead_critters()
|
||||
}
|
||||
}
|
||||
|
||||
objectSetFrame(a1, frame, NULL);
|
||||
objectSetFrame(blood, frame, NULL);
|
||||
}
|
||||
|
||||
reg_anim_clear(obj);
|
||||
@@ -1264,7 +1259,7 @@ static void _map_fix_critter_combat_data()
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1327,13 +1322,13 @@ static int _map_save_file(File* stream)
|
||||
for (tile = 0; tile < SQUARE_GRID_SIZE; tile++) {
|
||||
int fid;
|
||||
|
||||
fid = buildFid(4, _square[elevation]->field_0[tile] & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(4, 1, 0, 0, 0)) {
|
||||
fid = buildFid(OBJ_TYPE_TILE, _square[elevation]->field_0[tile] & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
fid = buildFid(4, (_square[elevation]->field_0[tile] >> 16) & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(4, 1, 0, 0, 0)) {
|
||||
fid = buildFid(OBJ_TYPE_TILE, (_square[elevation]->field_0[tile] >> 16) & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1383,14 +1378,12 @@ static int _map_save_file(File* stream)
|
||||
|
||||
if (scriptSaveAll(stream) == -1) {
|
||||
sprintf(err, "Error saving scripts in %s", gMapHeader.name);
|
||||
// TODO: Incomplete.
|
||||
// _win_msg(err, 80, 80, _colorTable[31744]);
|
||||
_win_msg(err, 80, 80, _colorTable[31744]);
|
||||
}
|
||||
|
||||
if (objectSaveAll(stream) == -1) {
|
||||
sprintf(err, "Error saving objects in %s", gMapHeader.name);
|
||||
// TODO: Incomplete.
|
||||
// _win_msg(err, 80, 80, _colorTable[31744]);
|
||||
_win_msg(err, 80, 80, _colorTable[31744]);
|
||||
}
|
||||
|
||||
scriptsEnable();
|
||||
@@ -1424,7 +1417,7 @@ int _map_save_in_game(bool a1)
|
||||
}
|
||||
|
||||
gMapHeader.flags |= 0x01;
|
||||
gMapHeader.field_38 = gameTimeGetTime();
|
||||
gMapHeader.lastVisitTime = gameTimeGetTime();
|
||||
|
||||
char name[16];
|
||||
|
||||
@@ -1545,9 +1538,9 @@ static void _map_place_dude_and_mouse()
|
||||
_obj_clear_seen();
|
||||
|
||||
if (gDude != NULL) {
|
||||
if (((gDude->fid & 0xFF0000) >> 16) != 0) {
|
||||
if (FID_ANIM_TYPE(gDude->fid) != ANIM_STAND) {
|
||||
objectSetFrame(gDude, 0, 0);
|
||||
gDude->fid = buildFid(1, gDude->fid & 0xFFF, ANIM_STAND, (gDude->fid & 0xF000) >> 12, gDude->rotation + 1);
|
||||
gDude->fid = buildFid(OBJ_TYPE_CRITTER, gDude->fid & 0xFFF, ANIM_STAND, (gDude->fid & 0xF000) >> 12, gDude->rotation + 1);
|
||||
}
|
||||
|
||||
if (gDude->tile == -1) {
|
||||
@@ -1577,11 +1570,11 @@ static void _square_reset()
|
||||
// check subsequent calls.
|
||||
int fid = *p;
|
||||
fid &= ~0xFFFF;
|
||||
*p = ((buildFid(4, 1, 0, 0, 0) & 0xFFF | (((fid >> 16) & 0xF000) >> 12)) << 16) | (fid & 0xFFFF);
|
||||
*p = (((buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0) & 0xFFF) | (((fid >> 16) & 0xF000) >> 12)) << 16) | (fid & 0xFFFF);
|
||||
|
||||
fid = *p;
|
||||
int v3 = (fid & 0xF000) >> 12;
|
||||
int v4 = (buildFid(4, 1, 0, 0, 0) & 0xFFF) | v3;
|
||||
int v4 = (buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0) & 0xFFF) | v3;
|
||||
|
||||
fid &= ~0xFFFF;
|
||||
|
||||
@@ -1642,7 +1635,7 @@ static int mapHeaderWrite(MapHeader* ptr, File* stream)
|
||||
if (fileWriteInt32(stream, ptr->darkness) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->globalVariablesCount) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->field_34) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->field_38) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->lastVisitTime) == -1) return -1;
|
||||
if (fileWriteInt32List(stream, ptr->field_3C, 44) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
@@ -1662,7 +1655,7 @@ static int mapHeaderRead(MapHeader* ptr, File* stream)
|
||||
if (fileReadInt32(stream, &(ptr->darkness)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(ptr->globalVariablesCount)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(ptr->field_34)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(ptr->field_38)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(ptr->lastVisitTime)) == -1) return -1;
|
||||
if (fileReadInt32List(stream, ptr->field_3C, 44) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -49,7 +49,9 @@ typedef struct MapHeader {
|
||||
|
||||
// map_number
|
||||
int field_34;
|
||||
int field_38;
|
||||
|
||||
// Time in game ticks when PC last visited this map.
|
||||
int lastVisitTime;
|
||||
int field_3C[44];
|
||||
} MapHeader;
|
||||
|
||||
|
||||
+596
-12
@@ -1,57 +1,641 @@
|
||||
#include "mouse_manager.h"
|
||||
|
||||
#include "core.h"
|
||||
#include "datafile.h"
|
||||
#include "db.h"
|
||||
#include "debug.h"
|
||||
#include "memory_manager.h"
|
||||
#include "platform_compat.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// 0x5195A8
|
||||
char* (*_mouseNameMangler)(char*) = _defaultNameMangler;
|
||||
MouseManagerNameMangler* gMouseManagerNameMangler = mouseManagerNameManglerDefaultImpl;
|
||||
|
||||
// 0x5195AC
|
||||
int (*_rateCallback)() = _defaultRateCallback;
|
||||
MouseManagerRateProvider* gMouseManagerRateProvider = mouseManagerRateProviderDefaultImpl;
|
||||
|
||||
// 0x5195B0
|
||||
int (*_currentTimeCallback)() = _defaultTimeCallback;
|
||||
MouseManagerTimeProvider* gMouseManagerTimeProvider = mouseManagerTimeProviderDefaultImpl;
|
||||
|
||||
// 0x5195B4
|
||||
int _curref = 1;
|
||||
int gMouseManagerCurrentRef = 1;
|
||||
|
||||
// 0x63247C
|
||||
MouseManagerCacheEntry gMouseManagerCache[MOUSE_MGR_CACHE_CAPACITY];
|
||||
|
||||
// 0x638DFC
|
||||
bool gMouseManagerIsAnimating;
|
||||
|
||||
// 0x638E00
|
||||
unsigned char* gMouseManagerCurrentPalette;
|
||||
|
||||
// 0x638E04
|
||||
MouseManagerAnimatedData* gMouseManagerCurrentAnimatedData;
|
||||
|
||||
// 0x638E08
|
||||
unsigned char* gMouseManagerCurrentStaticData;
|
||||
|
||||
// 0x638E0C
|
||||
int gMouseManagerCurrentCacheEntryIndex;
|
||||
|
||||
// 0x485250
|
||||
char* _defaultNameMangler(char* a1)
|
||||
char* mouseManagerNameManglerDefaultImpl(char* a1)
|
||||
{
|
||||
return a1;
|
||||
}
|
||||
|
||||
// 0x485254
|
||||
int _defaultRateCallback()
|
||||
int mouseManagerRateProviderDefaultImpl()
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
|
||||
// 0x48525C
|
||||
int _defaultTimeCallback()
|
||||
int mouseManagerTimeProviderDefaultImpl()
|
||||
{
|
||||
return _get_time();
|
||||
}
|
||||
|
||||
// 0x485288
|
||||
void _mousemgrSetNameMangler(char* (*func)(char*))
|
||||
void mouseManagerSetNameMangler(MouseManagerNameMangler* func)
|
||||
{
|
||||
_mouseNameMangler = func;
|
||||
gMouseManagerNameMangler = func;
|
||||
}
|
||||
|
||||
// 0x4852B8
|
||||
void mouseManagerFreeCacheEntry(MouseManagerCacheEntry* entry)
|
||||
{
|
||||
switch (entry->type) {
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_STATIC:
|
||||
if (entry->staticData != NULL) {
|
||||
if (entry->staticData->data != NULL) {
|
||||
internal_free_safe(entry->staticData->data, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 120
|
||||
entry->staticData->data = NULL;
|
||||
}
|
||||
internal_free_safe(entry->staticData, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 123
|
||||
entry->staticData = NULL;
|
||||
}
|
||||
break;
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_ANIMATED:
|
||||
if (entry->animatedData != NULL) {
|
||||
if (entry->animatedData->field_0 != NULL) {
|
||||
for (int index = 0; index < entry->animatedData->frameCount; index++) {
|
||||
internal_free_safe(entry->animatedData->field_0[index], __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 134
|
||||
internal_free_safe(entry->animatedData->field_4[index], __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 135
|
||||
}
|
||||
internal_free_safe(entry->animatedData->field_0, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 137
|
||||
internal_free_safe(entry->animatedData->field_4, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 138
|
||||
internal_free_safe(entry->animatedData->field_8, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 139
|
||||
internal_free_safe(entry->animatedData->field_C, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 140
|
||||
}
|
||||
internal_free_safe(entry->animatedData, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 143
|
||||
entry->animatedData = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
entry->type = 0;
|
||||
entry->fileName[0] = '\0';
|
||||
}
|
||||
|
||||
// 0x4853F8
|
||||
int mouseManagerInsertCacheEntry(void** data, int type, unsigned char* palette, const char* fileName)
|
||||
{
|
||||
int foundIndex = -1;
|
||||
int index;
|
||||
for (index = 0; index < MOUSE_MGR_CACHE_CAPACITY; index++) {
|
||||
MouseManagerCacheEntry* cacheEntry = &(gMouseManagerCache[index]);
|
||||
if (cacheEntry->type == MOUSE_MANAGER_MOUSE_TYPE_NONE && foundIndex == -1) {
|
||||
foundIndex = index;
|
||||
}
|
||||
|
||||
if (compat_stricmp(fileName, cacheEntry->fileName) == 0) {
|
||||
mouseManagerFreeCacheEntry(cacheEntry);
|
||||
foundIndex = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundIndex != -1) {
|
||||
index = foundIndex;
|
||||
}
|
||||
|
||||
if (index == MOUSE_MGR_CACHE_CAPACITY) {
|
||||
int v2 = -1;
|
||||
int v1 = gMouseManagerCurrentRef;
|
||||
for (int index = 0; index < MOUSE_MGR_CACHE_CAPACITY; index++) {
|
||||
MouseManagerCacheEntry* cacheEntry = &(gMouseManagerCache[index]);
|
||||
if (v1 > cacheEntry->ref) {
|
||||
v1 = cacheEntry->ref;
|
||||
v2 = index;
|
||||
}
|
||||
}
|
||||
|
||||
if (v2 == -1) {
|
||||
debugPrint("Mouse cache overflow!!!!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
index = v2;
|
||||
mouseManagerFreeCacheEntry(&(gMouseManagerCache[index]));
|
||||
}
|
||||
|
||||
MouseManagerCacheEntry* cacheEntry = &(gMouseManagerCache[index]);
|
||||
cacheEntry->type = type;
|
||||
memcpy(cacheEntry->palette, palette, sizeof(cacheEntry->palette));
|
||||
cacheEntry->ref = gMouseManagerCurrentRef++;
|
||||
strncpy(cacheEntry->fileName, fileName, sizeof(cacheEntry->fileName) - 1);
|
||||
cacheEntry->field_32C[0] = '\0';
|
||||
cacheEntry->data = *data;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
// NOTE: Inlined.
|
||||
//
|
||||
// 0x4853D4
|
||||
void mouseManagerFlushCache()
|
||||
{
|
||||
for (int index = 0; index < MOUSE_MGR_CACHE_CAPACITY; index++) {
|
||||
mouseManagerFreeCacheEntry(&(gMouseManagerCache[index]));
|
||||
}
|
||||
}
|
||||
|
||||
// 0x48554C
|
||||
MouseManagerCacheEntry* mouseManagerFindCacheEntry(const char* fileName, unsigned char** palettePtr, int* a3, int* a4, int* widthPtr, int* heightPtr, int* typePtr)
|
||||
{
|
||||
for (int index = 0; index < MOUSE_MGR_CACHE_CAPACITY; index++) {
|
||||
MouseManagerCacheEntry* cacheEntry = &(gMouseManagerCache[index]);
|
||||
if (compat_strnicmp(cacheEntry->fileName, fileName, 31) == 0 || compat_strnicmp(cacheEntry->field_32C, fileName, 31) == 0) {
|
||||
*palettePtr = cacheEntry->palette;
|
||||
*typePtr = cacheEntry->type;
|
||||
|
||||
gMouseManagerCurrentCacheEntryIndex = index;
|
||||
|
||||
switch (cacheEntry->type) {
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_STATIC:
|
||||
*a3 = cacheEntry->staticData->field_4;
|
||||
*a4 = cacheEntry->staticData->field_8;
|
||||
*widthPtr = cacheEntry->staticData->width;
|
||||
*heightPtr = cacheEntry->staticData->height;
|
||||
break;
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_ANIMATED:
|
||||
*widthPtr = cacheEntry->animatedData->width;
|
||||
*heightPtr = cacheEntry->animatedData->height;
|
||||
*a3 = cacheEntry->animatedData->field_8[cacheEntry->animatedData->field_26];
|
||||
*a4 = cacheEntry->animatedData->field_C[cacheEntry->animatedData->field_26];
|
||||
break;
|
||||
}
|
||||
|
||||
return cacheEntry;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 0x48568C
|
||||
void _initMousemgr()
|
||||
void mouseManagerInit()
|
||||
{
|
||||
mouseSetSensitivity(1.0);
|
||||
}
|
||||
|
||||
// 0x48569C
|
||||
void mouseManagerExit()
|
||||
{
|
||||
mouseSetFrame(NULL, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
if (gMouseManagerCurrentStaticData != NULL) {
|
||||
internal_free_safe(gMouseManagerCurrentStaticData, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 243
|
||||
gMouseManagerCurrentStaticData = NULL;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
mouseManagerFlushCache();
|
||||
|
||||
gMouseManagerCurrentPalette = NULL;
|
||||
gMouseManagerCurrentAnimatedData = 0;
|
||||
}
|
||||
|
||||
// 0x485704
|
||||
void mouseManagerUpdate()
|
||||
{
|
||||
if (!gMouseManagerIsAnimating) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gMouseManagerCurrentAnimatedData == NULL) {
|
||||
debugPrint("Animating == 1 but curAnim == 0\n");
|
||||
}
|
||||
|
||||
if (gMouseManagerTimeProvider() >= gMouseManagerCurrentAnimatedData->field_1C) {
|
||||
gMouseManagerCurrentAnimatedData->field_1C = (int)(gMouseManagerCurrentAnimatedData->field_18 / gMouseManagerCurrentAnimatedData->frameCount * gMouseManagerRateProvider() + gMouseManagerTimeProvider());
|
||||
if (gMouseManagerCurrentAnimatedData->field_24 != gMouseManagerCurrentAnimatedData->field_26) {
|
||||
int v1 = gMouseManagerCurrentAnimatedData->field_26 + gMouseManagerCurrentAnimatedData->field_20;
|
||||
if (v1 < 0) {
|
||||
v1 = gMouseManagerCurrentAnimatedData->frameCount - 1;
|
||||
} else if (v1 >= gMouseManagerCurrentAnimatedData->frameCount) {
|
||||
v1 = 0;
|
||||
}
|
||||
|
||||
gMouseManagerCurrentAnimatedData->field_26 = v1;
|
||||
memcpy(gMouseManagerCurrentAnimatedData->field_0[gMouseManagerCurrentAnimatedData->field_26],
|
||||
gMouseManagerCurrentAnimatedData->field_4[gMouseManagerCurrentAnimatedData->field_26],
|
||||
gMouseManagerCurrentAnimatedData->width * gMouseManagerCurrentAnimatedData->height);
|
||||
|
||||
sub_42EE84(gMouseManagerCurrentAnimatedData->field_0[gMouseManagerCurrentAnimatedData->field_26],
|
||||
gMouseManagerCurrentPalette,
|
||||
gMouseManagerCurrentAnimatedData->width,
|
||||
gMouseManagerCurrentAnimatedData->height);
|
||||
|
||||
mouseSetFrame(gMouseManagerCurrentAnimatedData->field_0[v1],
|
||||
gMouseManagerCurrentAnimatedData->width,
|
||||
gMouseManagerCurrentAnimatedData->height,
|
||||
gMouseManagerCurrentAnimatedData->width,
|
||||
gMouseManagerCurrentAnimatedData->field_8[v1],
|
||||
gMouseManagerCurrentAnimatedData->field_C[v1],
|
||||
0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0x485868
|
||||
int mouseManagerSetFrame(char* fileName, int a2)
|
||||
{
|
||||
char* mangledFileName = gMouseManagerNameMangler(fileName);
|
||||
|
||||
unsigned char* palette;
|
||||
int temp;
|
||||
int type;
|
||||
MouseManagerCacheEntry* cacheEntry = mouseManagerFindCacheEntry(fileName, &palette, &temp, &temp, &temp, &temp, &type);
|
||||
if (cacheEntry != NULL) {
|
||||
if (type == MOUSE_MANAGER_MOUSE_TYPE_ANIMATED) {
|
||||
cacheEntry->animatedData->field_24 = a2;
|
||||
if (cacheEntry->animatedData->field_24 >= cacheEntry->animatedData->field_26) {
|
||||
int v1 = cacheEntry->animatedData->field_24 - cacheEntry->animatedData->field_26;
|
||||
int v2 = cacheEntry->animatedData->frameCount + cacheEntry->animatedData->field_26 - cacheEntry->animatedData->field_24;
|
||||
if (v1 >= v2) {
|
||||
cacheEntry->animatedData->field_20 = -1;
|
||||
} else {
|
||||
cacheEntry->animatedData->field_20 = 1;
|
||||
}
|
||||
} else {
|
||||
int v1 = cacheEntry->animatedData->field_26 - cacheEntry->animatedData->field_24;
|
||||
int v2 = cacheEntry->animatedData->frameCount + cacheEntry->animatedData->field_24 - cacheEntry->animatedData->field_26;
|
||||
if (v1 < v2) {
|
||||
cacheEntry->animatedData->field_20 = -1;
|
||||
} else {
|
||||
cacheEntry->animatedData->field_20 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gMouseManagerIsAnimating || gMouseManagerCurrentAnimatedData != cacheEntry->animatedData) {
|
||||
memcpy(cacheEntry->animatedData->field_0[cacheEntry->animatedData->field_26],
|
||||
cacheEntry->animatedData->field_4[cacheEntry->animatedData->field_26],
|
||||
cacheEntry->animatedData->width * cacheEntry->animatedData->height);
|
||||
|
||||
mouseSetFrame(cacheEntry->animatedData->field_0[cacheEntry->animatedData->field_26],
|
||||
cacheEntry->animatedData->width,
|
||||
cacheEntry->animatedData->height,
|
||||
cacheEntry->animatedData->width,
|
||||
cacheEntry->animatedData->field_8[cacheEntry->animatedData->field_26],
|
||||
cacheEntry->animatedData->field_C[cacheEntry->animatedData->field_26],
|
||||
0);
|
||||
|
||||
gMouseManagerIsAnimating = true;
|
||||
}
|
||||
|
||||
gMouseManagerCurrentAnimatedData = cacheEntry->animatedData;
|
||||
gMouseManagerCurrentPalette = palette;
|
||||
gMouseManagerCurrentAnimatedData->field_1C = gMouseManagerTimeProvider();
|
||||
return true;
|
||||
}
|
||||
|
||||
mouseManagerSetMousePointer(fileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (gMouseManagerIsAnimating) {
|
||||
gMouseManagerCurrentPalette = 0;
|
||||
gMouseManagerIsAnimating = 0;
|
||||
gMouseManagerCurrentAnimatedData = 0;
|
||||
} else {
|
||||
if (gMouseManagerCurrentStaticData != NULL) {
|
||||
internal_free_safe(gMouseManagerCurrentStaticData, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 337
|
||||
gMouseManagerCurrentStaticData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
File* stream = fileOpen(mangledFileName, "r");
|
||||
if (stream == NULL) {
|
||||
debugPrint("mouseSetFrame: couldn't find %s\n", mangledFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
char string[80];
|
||||
fileReadString(string, sizeof(string), stream);
|
||||
if (compat_strnicmp(string, "anim", 4) != 0) {
|
||||
fileClose(stream);
|
||||
mouseManagerSetMousePointer(fileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
char* sep = strchr(string, ' ');
|
||||
if (sep == NULL) {
|
||||
// FIXME: Leaks stream.
|
||||
return false;
|
||||
}
|
||||
|
||||
int v3;
|
||||
float v4;
|
||||
sscanf(sep + 1, "%d %f", &v3, &v4);
|
||||
|
||||
MouseManagerAnimatedData* animatedData = (MouseManagerAnimatedData*)internal_malloc_safe(sizeof(*animatedData), __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 359
|
||||
animatedData->field_0 = (unsigned char**)internal_malloc_safe(sizeof(*animatedData->field_0) * v3, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 360
|
||||
animatedData->field_4 = (unsigned char**)internal_malloc_safe(sizeof(*animatedData->field_4) * v3, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 361
|
||||
animatedData->field_8 = (int*)internal_malloc_safe(sizeof(*animatedData->field_8) * v3, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 362
|
||||
animatedData->field_C = (int*)internal_malloc_safe(sizeof(*animatedData->field_8) * v3, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 363
|
||||
animatedData->field_18 = v4;
|
||||
animatedData->field_1C = gMouseManagerTimeProvider();
|
||||
animatedData->field_26 = 0;
|
||||
animatedData->field_24 = a2;
|
||||
animatedData->frameCount = v3;
|
||||
if (animatedData->frameCount / 2 <= a2) {
|
||||
animatedData->field_20 = -1;
|
||||
} else {
|
||||
animatedData->field_20 = 1;
|
||||
}
|
||||
|
||||
int width;
|
||||
int height;
|
||||
for (int index = 0; index < v3; index++) {
|
||||
string[0] = '\0';
|
||||
fileReadString(string, sizeof(string), stream);
|
||||
if (string[0] == '\0') {
|
||||
debugPrint("Not enough frames in %s, got %d, needed %d", mangledFileName, index, v3);
|
||||
break;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
char* sep = strchr(string, ' ');
|
||||
if (sep == NULL) {
|
||||
debugPrint("Bad line %s in %s\n", string, fileName);
|
||||
// FIXME: Leaking stream.
|
||||
return false;
|
||||
}
|
||||
|
||||
*sep = '\0';
|
||||
|
||||
int v5;
|
||||
int v6;
|
||||
sscanf(sep + 1, "%d %d", &v5, &v6);
|
||||
|
||||
animatedData->field_4[index] = datafileReadRaw(gMouseManagerNameMangler(string), &width, &height);
|
||||
animatedData->field_0[index] = (unsigned char*)internal_malloc_safe(width * height, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 390
|
||||
memcpy(animatedData->field_0[index], animatedData->field_4[index], width * height);
|
||||
sub_42EE84(animatedData->field_0[index], datafileGetPalette(), width, height);
|
||||
animatedData->field_8[index] = v5;
|
||||
animatedData->field_C[index] = v6;
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
animatedData->width = width;
|
||||
animatedData->height = height;
|
||||
|
||||
gMouseManagerCurrentCacheEntryIndex = mouseManagerInsertCacheEntry(reinterpret_cast<void**>(&animatedData), MOUSE_MANAGER_MOUSE_TYPE_ANIMATED, datafileGetPalette(), fileName);
|
||||
strncpy(gMouseManagerCache[gMouseManagerCurrentCacheEntryIndex].field_32C, fileName, 31);
|
||||
|
||||
gMouseManagerCurrentAnimatedData = animatedData;
|
||||
gMouseManagerCurrentPalette = gMouseManagerCache[gMouseManagerCurrentCacheEntryIndex].palette;
|
||||
gMouseManagerIsAnimating = true;
|
||||
|
||||
mouseSetFrame(animatedData->field_0[0],
|
||||
animatedData->width,
|
||||
animatedData->height,
|
||||
animatedData->width,
|
||||
animatedData->field_8[0],
|
||||
animatedData->field_C[0],
|
||||
0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x485E58
|
||||
bool mouseManagerSetMouseShape(char* fileName, int a2, int a3)
|
||||
{
|
||||
unsigned char* palette;
|
||||
int temp;
|
||||
int width;
|
||||
int height;
|
||||
int type;
|
||||
MouseManagerCacheEntry* cacheEntry = mouseManagerFindCacheEntry(fileName, &palette, &temp, &temp, &width, &height, &type);
|
||||
char* mangledFileName = gMouseManagerNameMangler(fileName);
|
||||
|
||||
if (cacheEntry == NULL) {
|
||||
MouseManagerStaticData* staticData;
|
||||
staticData = (MouseManagerStaticData*)internal_malloc_safe(sizeof(*staticData), __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 430
|
||||
staticData->data = datafileReadRaw(mangledFileName, &height, &width);
|
||||
staticData->field_4 = a2;
|
||||
staticData->field_8 = a3;
|
||||
staticData->width = width;
|
||||
staticData->height = height;
|
||||
gMouseManagerCurrentCacheEntryIndex = mouseManagerInsertCacheEntry(reinterpret_cast<void**>(&staticData), MOUSE_MANAGER_MOUSE_TYPE_STATIC, datafileGetPalette(), fileName);
|
||||
|
||||
// NOTE: Original code is slightly different. It obtains address of
|
||||
// `staticData` and sets it's it into `cacheEntry`, which is a bit
|
||||
// awkward. Maybe there is more level on indirection was used. Any way
|
||||
// in order to make code path below unaltered take entire cache entry.
|
||||
cacheEntry = &(gMouseManagerCache[gMouseManagerCurrentCacheEntryIndex]);
|
||||
|
||||
type = MOUSE_MANAGER_MOUSE_TYPE_STATIC;
|
||||
palette = gMouseManagerCache[gMouseManagerCurrentCacheEntryIndex].palette;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_STATIC:
|
||||
if (gMouseManagerCurrentStaticData != NULL) {
|
||||
internal_free_safe(gMouseManagerCurrentStaticData, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 446
|
||||
}
|
||||
|
||||
gMouseManagerCurrentStaticData = (unsigned char*)internal_malloc_safe(width * height, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 448
|
||||
memcpy(gMouseManagerCurrentStaticData, cacheEntry->staticData->data, width * height);
|
||||
sub_42EE84(gMouseManagerCurrentStaticData, palette, width, height);
|
||||
mouseSetFrame(gMouseManagerCurrentStaticData, width, height, width, a2, a3, 0);
|
||||
gMouseManagerIsAnimating = false;
|
||||
break;
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_ANIMATED:
|
||||
gMouseManagerCurrentAnimatedData = cacheEntry->animatedData;
|
||||
gMouseManagerIsAnimating = true;
|
||||
gMouseManagerCurrentPalette = palette;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x486010
|
||||
bool mouseManagerSetMousePointer(char* fileName)
|
||||
{
|
||||
unsigned char* palette;
|
||||
int v1;
|
||||
int v2;
|
||||
int width;
|
||||
int height;
|
||||
int type;
|
||||
MouseManagerCacheEntry* cacheEntry = mouseManagerFindCacheEntry(fileName, &palette, &v1, &v2, &width, &height, &type);
|
||||
if (cacheEntry != NULL) {
|
||||
if (gMouseManagerCurrentStaticData != NULL) {
|
||||
internal_free_safe(gMouseManagerCurrentStaticData, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 482
|
||||
gMouseManagerCurrentStaticData = NULL;
|
||||
}
|
||||
|
||||
gMouseManagerCurrentPalette = NULL;
|
||||
gMouseManagerIsAnimating = false;
|
||||
gMouseManagerCurrentAnimatedData = 0;
|
||||
|
||||
switch (type) {
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_STATIC:
|
||||
gMouseManagerCurrentStaticData = (unsigned char*)internal_malloc_safe(width * height, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 492
|
||||
memcpy(gMouseManagerCurrentStaticData, cacheEntry->staticData->data, width * height);
|
||||
sub_42EE84(gMouseManagerCurrentStaticData, palette, width, height);
|
||||
mouseSetFrame(gMouseManagerCurrentStaticData, width, height, width, v1, v2, 0);
|
||||
gMouseManagerIsAnimating = false;
|
||||
break;
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_ANIMATED:
|
||||
gMouseManagerCurrentAnimatedData = cacheEntry->animatedData;
|
||||
gMouseManagerCurrentPalette = palette;
|
||||
gMouseManagerCurrentAnimatedData->field_26 = 0;
|
||||
gMouseManagerCurrentAnimatedData->field_24 = 0;
|
||||
mouseSetFrame(gMouseManagerCurrentAnimatedData->field_0[0],
|
||||
gMouseManagerCurrentAnimatedData->width,
|
||||
gMouseManagerCurrentAnimatedData->height,
|
||||
gMouseManagerCurrentAnimatedData->width,
|
||||
gMouseManagerCurrentAnimatedData->field_8[0],
|
||||
gMouseManagerCurrentAnimatedData->field_C[0],
|
||||
0);
|
||||
gMouseManagerIsAnimating = true;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
char* dot = strrchr(fileName, '.');
|
||||
if (dot != NULL && compat_stricmp(dot + 1, "mou") == 0) {
|
||||
return mouseManagerSetMouseShape(fileName, 0, 0);
|
||||
}
|
||||
|
||||
char* mangledFileName = gMouseManagerNameMangler(fileName);
|
||||
File* stream = fileOpen(mangledFileName, "r");
|
||||
if (stream == NULL) {
|
||||
debugPrint("Can't find %s\n", mangledFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
char string[80];
|
||||
string[0] = '\0';
|
||||
fileReadString(string, sizeof(string) - 1, stream);
|
||||
if (string[0] == '\0') {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rc;
|
||||
if (compat_strnicmp(string, "anim", 4) == 0) {
|
||||
fileClose(stream);
|
||||
rc = mouseManagerSetFrame(fileName, 0);
|
||||
} else {
|
||||
// NOTE: Uninline.
|
||||
char* sep = strchr(string, ' ');
|
||||
if (sep != NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*sep = '\0';
|
||||
|
||||
int v3;
|
||||
int v4;
|
||||
sscanf(sep + 1, "%d %d", &v3, &v4);
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
rc = mouseManagerSetMouseShape(string, v3, v4);
|
||||
}
|
||||
|
||||
strncpy(gMouseManagerCache[gMouseManagerCurrentCacheEntryIndex].field_32C, fileName, 31);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// 0x4862AC
|
||||
void mouseManagerResetMouse()
|
||||
{
|
||||
MouseManagerCacheEntry* entry = &(gMouseManagerCache[gMouseManagerCurrentCacheEntryIndex]);
|
||||
|
||||
int imageWidth;
|
||||
int imageHeight;
|
||||
switch (entry->type) {
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_STATIC:
|
||||
imageWidth = entry->staticData->width;
|
||||
imageHeight = entry->staticData->height;
|
||||
break;
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_ANIMATED:
|
||||
imageWidth = entry->animatedData->width;
|
||||
imageHeight = entry->animatedData->height;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (entry->type) {
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_STATIC:
|
||||
if (gMouseManagerCurrentStaticData != NULL) {
|
||||
if (gMouseManagerCurrentStaticData != NULL) {
|
||||
internal_free_safe(gMouseManagerCurrentStaticData, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 572
|
||||
}
|
||||
|
||||
gMouseManagerCurrentStaticData = (unsigned char*)internal_malloc_safe(imageWidth * imageHeight, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 574
|
||||
memcpy(gMouseManagerCurrentStaticData, entry->staticData->data, imageWidth * imageHeight);
|
||||
sub_42EE84(gMouseManagerCurrentStaticData, entry->palette, imageWidth, imageHeight);
|
||||
|
||||
mouseSetFrame(gMouseManagerCurrentStaticData,
|
||||
imageWidth,
|
||||
imageHeight,
|
||||
imageWidth,
|
||||
entry->staticData->field_4,
|
||||
entry->staticData->field_8,
|
||||
0);
|
||||
} else {
|
||||
debugPrint("Hm, current mouse type is M_STATIC, but no current mouse pointer\n");
|
||||
}
|
||||
break;
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_ANIMATED:
|
||||
if (gMouseManagerCurrentAnimatedData != NULL) {
|
||||
for (int index = 0; index < gMouseManagerCurrentAnimatedData->frameCount; index++) {
|
||||
memcpy(gMouseManagerCurrentAnimatedData->field_0[index], gMouseManagerCurrentAnimatedData->field_4[index], imageWidth * imageHeight);
|
||||
sub_42EE84(gMouseManagerCurrentAnimatedData->field_0[index], entry->palette, imageWidth, imageHeight);
|
||||
}
|
||||
|
||||
mouseSetFrame(gMouseManagerCurrentAnimatedData->field_0[gMouseManagerCurrentAnimatedData->field_26],
|
||||
imageWidth,
|
||||
imageHeight,
|
||||
imageWidth,
|
||||
gMouseManagerCurrentAnimatedData->field_8[gMouseManagerCurrentAnimatedData->field_26],
|
||||
gMouseManagerCurrentAnimatedData->field_C[gMouseManagerCurrentAnimatedData->field_26],
|
||||
0);
|
||||
} else {
|
||||
debugPrint("Hm, current mouse type is M_ANIMATED, but no current mouse pointer\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0x4865C4
|
||||
void _mouseHide()
|
||||
void mouseManagerHideMouse()
|
||||
{
|
||||
mouseHideCursor();
|
||||
}
|
||||
|
||||
// 0x4865CC
|
||||
void _mouseShow()
|
||||
void mouseManagerShowMouse()
|
||||
{
|
||||
mouseShowCursor();
|
||||
}
|
||||
|
||||
+75
-10
@@ -1,16 +1,81 @@
|
||||
#ifndef MOUSE_MANAGER_H
|
||||
#define MOUSE_MANAGER_H
|
||||
|
||||
extern char* (*_mouseNameMangler)(char*);
|
||||
extern int (*_rateCallback)();
|
||||
extern int (*_currentTimeCallback)();
|
||||
#define MOUSE_MGR_CACHE_CAPACITY 32
|
||||
|
||||
char* _defaultNameMangler(char* a1);
|
||||
int _defaultRateCallback();
|
||||
int _defaultTimeCallback();
|
||||
void _mousemgrSetNameMangler(char* (*func)(char*));
|
||||
void _initMousemgr();
|
||||
void _mouseHide();
|
||||
void _mouseShow();
|
||||
typedef char*(MouseManagerNameMangler)(char* fileName);
|
||||
typedef int(MouseManagerRateProvider)();
|
||||
typedef int(MouseManagerTimeProvider)();
|
||||
|
||||
typedef enum MouseManagerMouseType {
|
||||
MOUSE_MANAGER_MOUSE_TYPE_NONE,
|
||||
MOUSE_MANAGER_MOUSE_TYPE_STATIC,
|
||||
MOUSE_MANAGER_MOUSE_TYPE_ANIMATED,
|
||||
} MouseManagerMouseType;
|
||||
|
||||
typedef struct MouseManagerStaticData {
|
||||
unsigned char* data;
|
||||
int field_4;
|
||||
int field_8;
|
||||
int width;
|
||||
int height;
|
||||
} MouseManagerStaticData;
|
||||
|
||||
typedef struct MouseManagerAnimatedData {
|
||||
unsigned char** field_0;
|
||||
unsigned char** field_4;
|
||||
int* field_8;
|
||||
int* field_C;
|
||||
int width;
|
||||
int height;
|
||||
float field_18;
|
||||
int field_1C;
|
||||
int field_20;
|
||||
signed char field_24;
|
||||
signed char frameCount;
|
||||
signed char field_26;
|
||||
} MouseManagerAnimatedData;
|
||||
|
||||
typedef struct MouseManagerCacheEntry {
|
||||
union {
|
||||
void* data;
|
||||
MouseManagerStaticData* staticData;
|
||||
MouseManagerAnimatedData* animatedData;
|
||||
};
|
||||
int type;
|
||||
unsigned char palette[256 * 3];
|
||||
int ref;
|
||||
char fileName[32];
|
||||
char field_32C[32];
|
||||
} MouseManagerCacheEntry;
|
||||
|
||||
extern MouseManagerNameMangler* gMouseManagerNameMangler;
|
||||
extern MouseManagerRateProvider* gMouseManagerRateProvider;
|
||||
extern MouseManagerTimeProvider* gMouseManagerTimeProvider;
|
||||
|
||||
extern MouseManagerCacheEntry gMouseManagerCache[MOUSE_MGR_CACHE_CAPACITY];
|
||||
extern bool gMouseManagerIsAnimating;
|
||||
extern unsigned char* gMouseManagerCurrentPalette;
|
||||
extern MouseManagerAnimatedData* gMouseManagerCurrentAnimatedData;
|
||||
extern unsigned char* gMouseManagerCurrentStaticData;
|
||||
extern int gMouseManagerCurrentCacheEntryIndex;
|
||||
|
||||
char* mouseManagerNameManglerDefaultImpl(char* a1);
|
||||
int mouseManagerRateProviderDefaultImpl();
|
||||
int mouseManagerTimeProviderDefaultImpl();
|
||||
void mouseManagerSetNameMangler(MouseManagerNameMangler* func);
|
||||
void mouseManagerFreeCacheEntry(MouseManagerCacheEntry* entry);
|
||||
int mouseManagerInsertCacheEntry(void** data, int type, unsigned char* palette, const char* fileName);
|
||||
void mouseManagerFlushCache();
|
||||
MouseManagerCacheEntry* mouseManagerFindCacheEntry(const char* fileName, unsigned char** palettePtr, int* a3, int* a4, int* widthPtr, int* heightPtr, int* typePtr);
|
||||
void mouseManagerInit();
|
||||
void mouseManagerExit();
|
||||
void mouseManagerUpdate();
|
||||
int mouseManagerSetFrame(char* fileName, int a2);
|
||||
bool mouseManagerSetMouseShape(char* fileName, int a2, int a3);
|
||||
bool mouseManagerSetMousePointer(char* fileName);
|
||||
void mouseManagerResetMouse();
|
||||
void mouseManagerHideMouse();
|
||||
void mouseManagerShowMouse();
|
||||
|
||||
#endif /* MOUSE_MANAGER_H */
|
||||
|
||||
+211
-67
@@ -14,6 +14,7 @@
|
||||
#include "pointer_registry.h"
|
||||
#include "sound.h"
|
||||
#include "text_font.h"
|
||||
#include "window.h"
|
||||
#include "window_manager.h"
|
||||
|
||||
#include <string.h>
|
||||
@@ -29,11 +30,14 @@ typedef struct MovieSubtitleListNode {
|
||||
static void* movieMallocImpl(size_t size);
|
||||
static void movieFreeImpl(void* ptr);
|
||||
static bool movieReadImpl(int fileHandle, void* buf, int count);
|
||||
static void movieDirectImpl(SDL_Surface* a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9);
|
||||
static void movieBufferedImpl(SDL_Surface* a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9);
|
||||
static int _movieScaleSubRectAlpha(int a1);
|
||||
static int _blitAlpha(int win, unsigned char* a2, int a3, int a4, int a5);
|
||||
static int _blitNormal(int win, int a2, int a3, int a4, int a5);
|
||||
static void movieDirectImpl(SDL_Surface* surface, int srcWidth, int srcHeight, int srcX, int srcY, int destWidth, int destHeight, int a8, int a9);
|
||||
static void movieBufferedImpl(SDL_Surface* surface, int srcWidth, int srcHeight, int srcX, int srcY, int destWidth, int destHeight, int a8, int a9);
|
||||
static int _movieScaleSubRect(int win, unsigned char* data, int width, int height, int pitch);
|
||||
static int _movieScaleSubRectAlpha(int win, unsigned char* data, int width, int height, int pitch);
|
||||
static int _movieScaleWindowAlpha(int win, unsigned char* data, int width, int height, int pitch);
|
||||
static int _blitAlpha(int win, unsigned char* data, int width, int height, int pitch);
|
||||
static int _movieScaleWindow(int win, unsigned char* data, int width, int height, int pitch);
|
||||
static int _blitNormal(int win, unsigned char* data, int width, int height, int pitch);
|
||||
static void movieSetPaletteEntriesImpl(unsigned char* palette, int start, int end);
|
||||
static int _noop();
|
||||
static void _cleanupMovie(int a1);
|
||||
@@ -51,6 +55,30 @@ static int gMovieWindow = -1;
|
||||
// 0x5195BC
|
||||
static int gMovieSubtitlesFont = -1;
|
||||
|
||||
// 0x5195C0
|
||||
static MovieBlitFunc* gMovieBlitFuncs[2][2][2] = {
|
||||
{
|
||||
{
|
||||
_blitNormal,
|
||||
_blitNormal,
|
||||
},
|
||||
{
|
||||
_movieScaleWindow,
|
||||
_movieScaleSubRect,
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
_blitAlpha,
|
||||
_blitAlpha,
|
||||
},
|
||||
{
|
||||
_movieScaleWindowAlpha,
|
||||
_movieScaleSubRectAlpha,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// 0x5195E0
|
||||
static MovieSetPaletteEntriesProc* gMovieSetPaletteEntriesProc = _setSystemPaletteEntries;
|
||||
|
||||
@@ -72,19 +100,21 @@ static Rect _movieRect;
|
||||
// 0x638E30
|
||||
static void (*_movieCallback)();
|
||||
|
||||
// 0x638E34
|
||||
MovieEndFunc* _endMovieFunc;
|
||||
|
||||
// 0x638E38
|
||||
static MovieSetPaletteProc* gMoviePaletteProc;
|
||||
|
||||
// NOTE: Some kind of callback which was intended to change movie file path
|
||||
// in place during opening movie file to find subsitutions. This callback is
|
||||
// never set.
|
||||
//
|
||||
// 0x638E3C
|
||||
static int (*_failedOpenFunc)(char* filePath);
|
||||
static MovieFailedOpenFunc* _failedOpenFunc;
|
||||
|
||||
// 0x638E40
|
||||
static MovieBuildSubtitleFilePathProc* gMovieBuildSubtitleFilePathProc;
|
||||
|
||||
// 0x638E44
|
||||
static MovieStartFunc* _startMovieFunc;
|
||||
|
||||
// 0x638E48
|
||||
static int _subtitleW;
|
||||
|
||||
@@ -103,6 +133,9 @@ static int _lastMovieSY;
|
||||
// 0x638E5C
|
||||
static int _movieScaleFlag;
|
||||
|
||||
// 0x638E60
|
||||
static MoviePreDrawFunc* _moviePreDrawFunc;
|
||||
|
||||
// 0x638E64
|
||||
static int _lastMovieH;
|
||||
|
||||
@@ -134,7 +167,7 @@ static int _movieH;
|
||||
static int _movieOffset;
|
||||
|
||||
// 0x638E8C
|
||||
static void (*_movieCaptureFrameFunc)(void*, int, int, int, int, int);
|
||||
static MovieCaptureFrameProc* _movieCaptureFrameFunc;
|
||||
|
||||
// 0x638E90
|
||||
static unsigned char* _lastMovieBuffer;
|
||||
@@ -143,7 +176,7 @@ static unsigned char* _lastMovieBuffer;
|
||||
static int _movieW;
|
||||
|
||||
// 0x638E98
|
||||
static void (*_movieFrameGrabFunc)();
|
||||
static MovieFrameGrabProc* _movieFrameGrabFunc;
|
||||
|
||||
// 0x638EA0
|
||||
static int _subtitleH;
|
||||
@@ -172,6 +205,31 @@ static unsigned char* _alphaBuf;
|
||||
static SDL_Surface* gMovieSdlSurface = NULL;
|
||||
static int gMovieFileStreamPointerKey = 0;
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4865E0
|
||||
void _movieSetPreDrawFunc(MoviePreDrawFunc* preDrawFunc)
|
||||
{
|
||||
_moviePreDrawFunc = preDrawFunc;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4865E8
|
||||
void _movieSetFailedOpenFunc(MovieFailedOpenFunc* failedOpenFunc)
|
||||
{
|
||||
_failedOpenFunc = failedOpenFunc;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4865F0
|
||||
void _movieSetFunc(MovieStartFunc* startFunc, MovieEndFunc* endFunc)
|
||||
{
|
||||
_startMovieFunc = startFunc;
|
||||
_endMovieFunc = endFunc;
|
||||
}
|
||||
|
||||
// 0x4865FC
|
||||
static void* movieMallocImpl(size_t size)
|
||||
{
|
||||
@@ -249,7 +307,14 @@ static void movieDirectImpl(SDL_Surface* surface, int srcWidth, int srcHeight, i
|
||||
|
||||
if (_movieCaptureFrameFunc != NULL) {
|
||||
if (SDL_LockSurface(surface) == 0) {
|
||||
_movieCaptureFrameFunc(surface->pixels, srcWidth, destRect.x, destRect.y, destRect.w, destRect.h);
|
||||
_movieCaptureFrameFunc(static_cast<unsigned char*>(surface->pixels),
|
||||
srcWidth,
|
||||
srcHeight,
|
||||
surface->pitch,
|
||||
destRect.x,
|
||||
destRect.y,
|
||||
destRect.w,
|
||||
destRect.h);
|
||||
SDL_UnlockSurface(surface);
|
||||
}
|
||||
}
|
||||
@@ -269,8 +334,6 @@ static void movieDirectImpl(SDL_Surface* surface, int srcWidth, int srcHeight, i
|
||||
// 0x486900
|
||||
static void movieBufferedImpl(SDL_Surface* a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9)
|
||||
{
|
||||
int v13;
|
||||
|
||||
if (gMovieWindow == -1) {
|
||||
return;
|
||||
}
|
||||
@@ -290,55 +353,135 @@ static void movieBufferedImpl(SDL_Surface* a1, int a2, int a3, int a4, int a5, i
|
||||
}
|
||||
|
||||
if (_movieCaptureFrameFunc != NULL) {
|
||||
// TODO: Ignore, _movieCaptureFrameFunc is never set.
|
||||
// _movieCaptureFrameFunc()
|
||||
_movieCaptureFrameFunc(static_cast<unsigned char*>(a1->pixels), a2, a3, a1->pitch, _movieRect.left, _movieRect.top, a6, a7);
|
||||
}
|
||||
|
||||
if (_movieFrameGrabFunc != NULL) {
|
||||
// TODO: Ignore, _movieFrameGrabFunc is never set.
|
||||
// _movieFrameGrabFunc();
|
||||
_movieFrameGrabFunc(static_cast<unsigned char*>(a1->pixels), a2, a3, a1->pitch);
|
||||
} else {
|
||||
v13 = 4 * _movieSubRectFlag + 8 * _movieScaleFlag + 16 * _movieAlphaFlag;
|
||||
// TODO: Incomplete.
|
||||
MovieBlitFunc* func = gMovieBlitFuncs[_movieAlphaFlag][_movieScaleFlag][_movieSubRectFlag];
|
||||
if (func(gMovieWindow, static_cast<unsigned char*>(a1->pixels), a2, a3, a1->pitch) != 0) {
|
||||
if (_moviePreDrawFunc != NULL) {
|
||||
_moviePreDrawFunc(gMovieWindow, &_movieRect);
|
||||
}
|
||||
|
||||
windowRefreshRect(gMovieWindow, &_movieRect);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(a1);
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x486A98
|
||||
void _movieSetFrameGrabFunc(MovieFrameGrabProc* proc)
|
||||
{
|
||||
_movieFrameGrabFunc = proc;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x486AA0
|
||||
void _movieSetCaptureFrameFunc(MovieCaptureFrameProc* func)
|
||||
{
|
||||
_movieCaptureFrameFunc = func;
|
||||
}
|
||||
|
||||
// 0x486B68
|
||||
int _movieScaleSubRect(int win, unsigned char* data, int width, int height, int pitch)
|
||||
{
|
||||
int windowWidth = windowGetWidth(win);
|
||||
unsigned char* windowBuffer = windowGetBuffer(win) + windowWidth * _movieY + _movieX;
|
||||
if (width * 4 / 3 > _movieW) {
|
||||
gMovieFlags |= 0x01;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v1 = width / 3;
|
||||
for (int y = 0; y < height; y++) {
|
||||
int x;
|
||||
for (x = 0; x < v1; x++) {
|
||||
unsigned int value = data[0];
|
||||
value |= data[1] << 8;
|
||||
value |= data[2] << 16;
|
||||
value |= data[2] << 24;
|
||||
|
||||
*(unsigned int*)windowBuffer = value;
|
||||
|
||||
windowBuffer += 4;
|
||||
data += 3;
|
||||
}
|
||||
|
||||
for (x = x * 3; x < width; x++) {
|
||||
*windowBuffer++ = *data++;
|
||||
}
|
||||
|
||||
data += pitch - width;
|
||||
windowBuffer += windowWidth - _movieW;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 0x486C74
|
||||
static int _movieScaleSubRectAlpha(int a1)
|
||||
int _movieScaleSubRectAlpha(int win, unsigned char* data, int width, int height, int pitch)
|
||||
{
|
||||
gMovieFlags |= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Uncollapsed 0x486C74.
|
||||
int _movieScaleWindowAlpha(int win, unsigned char* data, int width, int height, int pitch)
|
||||
{
|
||||
gMovieFlags |= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x486C80
|
||||
static int _blitAlpha(int win, unsigned char* a2, int a3, int a4, int a5)
|
||||
int _blitAlpha(int win, unsigned char* data, int width, int height, int pitch)
|
||||
{
|
||||
unsigned char* buf;
|
||||
int offset;
|
||||
int windowWidth = windowGetWidth(win);
|
||||
unsigned char* windowBuffer = windowGetBuffer(win);
|
||||
_alphaBltBuf(data, width, height, pitch, _alphaWindowBuf, _alphaBuf, windowBuffer + windowWidth * _movieY + _movieX, windowWidth);
|
||||
return 1;
|
||||
}
|
||||
|
||||
offset = windowGetWidth(win) * _movieY + _movieX;
|
||||
buf = windowGetBuffer(win);
|
||||
// 0x486CD4
|
||||
int _movieScaleWindow(int win, unsigned char* data, int width, int height, int pitch)
|
||||
{
|
||||
int windowWidth = windowGetWidth(win);
|
||||
if (width != 3 * windowWidth / 4) {
|
||||
gMovieFlags |= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: Incomplete.
|
||||
// _alphaBltBuf(a2, a3, a4, a5, _alphaWindowBuf, _alphaBuf, buf + offset, windowGetWidth(win));
|
||||
unsigned char* windowBuffer = windowGetBuffer(win);
|
||||
for (int y = 0; y < height; y++) {
|
||||
int scaledWidth = width / 3;
|
||||
for (int x = 0; x < scaledWidth; x++) {
|
||||
unsigned int value = data[0];
|
||||
value |= data[1] << 8;
|
||||
value |= data[2] << 16;
|
||||
value |= data[3] << 24;
|
||||
|
||||
*(unsigned int*)windowBuffer = value;
|
||||
|
||||
windowBuffer += 4;
|
||||
data += 3;
|
||||
}
|
||||
data += pitch - width;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 0x486D84
|
||||
static int _blitNormal(int win, int a2, int a3, int a4, int a5)
|
||||
int _blitNormal(int win, unsigned char* data, int width, int height, int pitch)
|
||||
{
|
||||
unsigned char* buf;
|
||||
int offset;
|
||||
|
||||
offset = windowGetWidth(win) * _movieY + _movieX;
|
||||
buf = windowGetBuffer(win);
|
||||
|
||||
// TODO: Incomplete.
|
||||
// _drawScaled(buf + offset, _movieW, _movieH, windowGetWidth(win), a2, a3, a4, a5);
|
||||
|
||||
int windowWidth = windowGetWidth(win);
|
||||
unsigned char* windowBuffer = windowGetBuffer(win);
|
||||
_drawScaled(windowBuffer + windowWidth * _movieY + _movieX, _movieW, _movieH, windowWidth, data, width, height, pitch);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -373,10 +516,9 @@ static void _cleanupMovie(int a1)
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Probably can be ignored.
|
||||
// if (_endMovieFunc) {
|
||||
// _endMovieFunc(_movieW, _movieX, _movieH);
|
||||
// }
|
||||
if (_endMovieFunc != NULL) {
|
||||
_endMovieFunc(gMovieWindow, _movieX, _movieY, _movieW, _movieH);
|
||||
}
|
||||
|
||||
int frame;
|
||||
int dropped;
|
||||
@@ -579,30 +721,18 @@ static void movieLoadSubtitles(char* filePath)
|
||||
|
||||
char* pch;
|
||||
|
||||
pch = string;
|
||||
while (*pch != '\0' && *pch != '\n') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch != '\0') {
|
||||
pch = strchr(string, '\n');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
}
|
||||
|
||||
pch = string;
|
||||
while (*pch != '\0' && *pch != '\r') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch != '\0') {
|
||||
pch = strchr(string, '\r');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
}
|
||||
|
||||
pch = string;
|
||||
while (*pch != '\0' && *pch != ':') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch != '\0') {
|
||||
pch = strchr(string, ':');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
subtitle->num = atoi(string);
|
||||
subtitle->text = strdup_safe(pch + 1, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 1058
|
||||
@@ -737,14 +867,28 @@ static int _movieStart(int win, char* filePath, int (*a3)())
|
||||
debugPrint("not scaled\n");
|
||||
}
|
||||
|
||||
// TODO: Probably can be ignored, never set.
|
||||
// if (_startMovieFunc) {
|
||||
// _startMovieFunc();
|
||||
// }
|
||||
if (_startMovieFunc != NULL) {
|
||||
_startMovieFunc(gMovieWindow);
|
||||
}
|
||||
|
||||
if (_alphaHandle != NULL) {
|
||||
// TODO: Probably can be ignored, never set.
|
||||
abort();
|
||||
int size;
|
||||
fileReadInt32(_alphaHandle, &size);
|
||||
|
||||
short tmp;
|
||||
fileReadInt16(_alphaHandle, &tmp);
|
||||
fileReadInt16(_alphaHandle, &tmp);
|
||||
|
||||
_alphaBuf = (unsigned char*)internal_malloc_safe(size, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 1178
|
||||
_alphaWindowBuf = (unsigned char*)internal_malloc_safe(_movieH * _movieW, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 1179
|
||||
|
||||
unsigned char* windowBuffer = windowGetBuffer(gMovieWindow);
|
||||
blitBufferToBuffer(windowBuffer + windowGetWidth(gMovieWindow) * _movieY + _movieX,
|
||||
_movieW,
|
||||
_movieH,
|
||||
windowGetWidth(gMovieWindow),
|
||||
_alphaWindowBuf,
|
||||
_movieW);
|
||||
}
|
||||
|
||||
_movieRect.left = _movieX;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef MOVIE_H
|
||||
#define MOVIE_H
|
||||
|
||||
#include "geometry.h"
|
||||
|
||||
typedef enum MovieFlags {
|
||||
MOVIE_FLAG_0x01 = 0x01,
|
||||
MOVIE_FLAG_0x02 = 0x02,
|
||||
@@ -19,6 +21,13 @@ typedef enum MovieExtendedFlags {
|
||||
typedef char* MovieBuildSubtitleFilePathProc(char* movieFilePath);
|
||||
typedef void MovieSetPaletteEntriesProc(unsigned char* palette, int start, int end);
|
||||
typedef void MovieSetPaletteProc(int frame);
|
||||
typedef void(MovieFrameGrabProc)(unsigned char* data, int width, int height, int pitch);
|
||||
typedef void(MovieCaptureFrameProc)(unsigned char* data, int width, int height, int pitch, int movieX, int movieY, int movieWidth, int movieHeight);
|
||||
typedef int(MovieBlitFunc)(int win, unsigned char* data, int width, int height, int pitch);
|
||||
typedef void(MoviePreDrawFunc)(int win, Rect* rect);
|
||||
typedef void(MovieStartFunc)(int win);
|
||||
typedef void(MovieEndFunc)(int win, int x, int y, int width, int height);
|
||||
typedef int(MovieFailedOpenFunc)(char* path);
|
||||
|
||||
void movieInit();
|
||||
void movieExit();
|
||||
|
||||
+2
-6
@@ -715,11 +715,7 @@ static void* _ioRead(int size)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!gMovieLibReadProc(_io_handle, buf, size)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buf;
|
||||
return gMovieLibReadProc(_io_handle, buf, size) < 1 ? NULL : buf;
|
||||
}
|
||||
|
||||
// 0x4F4D40
|
||||
@@ -1869,7 +1865,7 @@ static void _nfPkDecomp(unsigned char* a1, unsigned char* a2, int a3, int a4, in
|
||||
int v7;
|
||||
int i;
|
||||
int j;
|
||||
int v10;
|
||||
ptrdiff_t v10;
|
||||
int v11;
|
||||
int v13;
|
||||
int byte;
|
||||
|
||||
+1
-1
@@ -89,7 +89,7 @@ static void _nevs_removeprogramreferences(Program* program)
|
||||
// 0x488418
|
||||
void _nevs_initonce()
|
||||
{
|
||||
_interpretRegisterProgramDeleteCallback(_nevs_removeprogramreferences);
|
||||
intLibRegisterProgramDeleteCallback(_nevs_removeprogramreferences);
|
||||
|
||||
if (gNevs == NULL) {
|
||||
gNevs = (Nevs*)internal_calloc_safe(sizeof(Nevs), NEVS_COUNT, __FILE__, __LINE__); // "..\\int\\NEVS.C", 131
|
||||
|
||||
+56
-9
@@ -27,6 +27,10 @@ enum {
|
||||
OBJ_TYPE_COUNT,
|
||||
};
|
||||
|
||||
#define FID_TYPE(value) ((value) & 0xF000000) >> 24
|
||||
#define PID_TYPE(value) (value) >> 24
|
||||
#define SID_TYPE(value) (value) >> 24
|
||||
|
||||
typedef enum OutlineType {
|
||||
OUTLINE_TYPE_HOSTILE = 1,
|
||||
OUTLINE_TYPE_2 = 2,
|
||||
@@ -66,6 +70,20 @@ typedef enum ObjectFlags {
|
||||
OBJECT_OPEN_DOOR = OBJECT_SHOOT_THRU | OBJECT_LIGHT_THRU | OBJECT_NO_BLOCK,
|
||||
} ObjectFlags;
|
||||
|
||||
typedef enum CritterFlags {
|
||||
CRITTER_FLAG_0x2 = 0x2,
|
||||
CRITTER_FLAG_0x20 = 0x20,
|
||||
CRITTER_FLAG_0x40 = 0x40,
|
||||
CRITTER_FLAG_0x80 = 0x80,
|
||||
CRITTER_FLAG_0x100 = 0x100,
|
||||
CRITTER_FLAG_0x200 = 0x200,
|
||||
CRITTER_FLAG_0x400 = 0x400,
|
||||
CRITTER_FLAG_0x800 = 0x800,
|
||||
CRITTER_FLAG_0x1000 = 0x1000,
|
||||
CRITTER_FLAG_0x2000 = 0x2000,
|
||||
CRITTER_FLAG_0x4000 = 0x4000,
|
||||
} CritterFlags;
|
||||
|
||||
#define OUTLINE_TYPE_MASK 0xFFFFFF
|
||||
#define OUTLINE_PALETTED 0x40000000
|
||||
#define OUTLINE_DISABLED 0x80000000
|
||||
@@ -77,9 +95,12 @@ typedef enum ObjectFlags {
|
||||
#define CONTAINER_FLAG_LOCKED 0x02000000
|
||||
#define DOOR_FLAG_LOCKED 0x02000000
|
||||
|
||||
#define CRITTER_MANEUVER_0x01 0x01
|
||||
#define CRITTER_MANEUVER_STOP_ATTACKING 0x02
|
||||
#define CRITTER_MANUEVER_FLEEING 0x04
|
||||
typedef enum CritterManeuver {
|
||||
CRITTER_MANEUVER_NONE = 0,
|
||||
CRITTER_MANEUVER_0x01 = 0x01,
|
||||
CRITTER_MANEUVER_STOP_ATTACKING = 0x02,
|
||||
CRITTER_MANUEVER_FLEEING = 0x04,
|
||||
} CritterManeuver;
|
||||
|
||||
typedef enum Dam {
|
||||
DAM_KNOCKED_OUT = 0x01,
|
||||
@@ -178,18 +199,18 @@ typedef struct DoorSceneryData {
|
||||
} DoorSceneryData;
|
||||
|
||||
typedef struct StairsSceneryData {
|
||||
int field_0; // obj_pudg.pudstairs.destMap
|
||||
int field_4; // obj_pudg.pudstairs.destBuiltTile
|
||||
int destinationMap; // obj_pudg.pudstairs.destMap
|
||||
int destinationBuiltTile; // obj_pudg.pudstairs.destBuiltTile
|
||||
} StairsSceneryData;
|
||||
|
||||
typedef struct ElevatorSceneryData {
|
||||
int field_0; // obj_pudg.pudelevator.elevType
|
||||
int field_4; // obj_pudg.pudelevator.elevLevel
|
||||
int type;
|
||||
int level;
|
||||
} ElevatorSceneryData;
|
||||
|
||||
typedef struct LadderSceneryData {
|
||||
int field_0;
|
||||
int field_4;
|
||||
int destinationMap;
|
||||
int destinationBuiltTile;
|
||||
} LadderSceneryData;
|
||||
|
||||
typedef union SceneryObjectData {
|
||||
@@ -252,4 +273,30 @@ typedef struct ObjectListNode {
|
||||
struct ObjectListNode* next;
|
||||
} ObjectListNode;
|
||||
|
||||
#define BUILT_TILE_TILE_MASK 0x3FFFFFF
|
||||
#define BUILT_TILE_ELEVATION_MASK 0xE0000000
|
||||
#define BUILT_TILE_ELEVATION_SHIFT 29
|
||||
#define BUILT_TILE_ROTATION_MASK 0x1C000000
|
||||
#define BUILT_TILE_ROTATION_SHIFT 26
|
||||
|
||||
static inline int builtTileGetTile(int builtTile)
|
||||
{
|
||||
return builtTile & BUILT_TILE_TILE_MASK;
|
||||
}
|
||||
|
||||
static inline int builtTileGetElevation(int builtTile)
|
||||
{
|
||||
return (builtTile & BUILT_TILE_ELEVATION_MASK) >> BUILT_TILE_ELEVATION_SHIFT;
|
||||
}
|
||||
|
||||
static inline int builtTileGetRotation(int builtTile)
|
||||
{
|
||||
return (builtTile & BUILT_TILE_ROTATION_MASK) >> BUILT_TILE_ROTATION_SHIFT;
|
||||
}
|
||||
|
||||
static inline int builtTileCreate(int tile, int elevation)
|
||||
{
|
||||
return tile | ((elevation << BUILT_TILE_ELEVATION_SHIFT) & BUILT_TILE_ELEVATION_MASK);
|
||||
}
|
||||
|
||||
#endif /* OBJ_TYPES_H */
|
||||
|
||||
+54
-54
@@ -332,7 +332,7 @@ int objectsInit(unsigned char* buf, int width, int height, int pitch)
|
||||
gObjectsWindowBufferSize = height * width;
|
||||
gObjectsWindowPitch = pitch;
|
||||
|
||||
dudeFid = buildFid(1, _art_vault_guy_num, 0, 0, 0);
|
||||
dudeFid = buildFid(OBJ_TYPE_CRITTER, _art_vault_guy_num, 0, 0, 0);
|
||||
objectCreateWithFidPid(&gDude, dudeFid, 0x1000000);
|
||||
|
||||
gDude->flags |= OBJECT_FLAG_0x400;
|
||||
@@ -346,7 +346,7 @@ int objectsInit(unsigned char* buf, int width, int height, int pitch)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
eggFid = buildFid(6, 2, 0, 0, 0);
|
||||
eggFid = buildFid(OBJ_TYPE_INTERFACE, 2, 0, 0, 0);
|
||||
objectCreateWithFidPid(&gEgg, eggFid, -1);
|
||||
gEgg->flags |= OBJECT_FLAG_0x400;
|
||||
gEgg->flags |= OBJECT_TEMPORARY;
|
||||
@@ -437,13 +437,13 @@ int objectRead(Object* obj, File* stream)
|
||||
}
|
||||
|
||||
if (obj->pid < 0x5000010 || obj->pid > 0x5000017) {
|
||||
if ((obj->pid >> 24) == 0 && !(gMapHeader.flags & 0x01)) {
|
||||
if (PID_TYPE(obj->pid) == 0 && !(gMapHeader.flags & 0x01)) {
|
||||
_object_fix_weapon_ammo(obj);
|
||||
}
|
||||
} else {
|
||||
if (obj->data.misc.map <= 0) {
|
||||
if ((obj->fid & 0xFFF) < 33) {
|
||||
obj->fid = buildFid(5, (obj->fid & 0xFFF) + 16, (obj->fid & 0xFF0000) >> 16, 0, 0);
|
||||
obj->fid = buildFid(OBJ_TYPE_MISC, (obj->fid & 0xFFF) + 16, FID_ANIM_TYPE(obj->fid), 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -544,7 +544,7 @@ static int objectLoadAllInternal(File* stream)
|
||||
|
||||
_obj_insert(objectListNode);
|
||||
|
||||
if ((objectListNode->obj->flags & OBJECT_FLAG_0x400) && (objectListNode->obj->flags >> 24) == OBJ_TYPE_CRITTER && objectListNode->obj->pid != 18000) {
|
||||
if ((objectListNode->obj->flags & OBJECT_FLAG_0x400) && PID_TYPE(objectListNode->obj->pid) == OBJ_TYPE_CRITTER && objectListNode->obj->pid != 18000) {
|
||||
objectListNode->obj->flags &= ~OBJECT_FLAG_0x400;
|
||||
}
|
||||
|
||||
@@ -619,7 +619,7 @@ static void _obj_fix_combat_cid_for_dude()
|
||||
// 0x48911C
|
||||
static void _object_fix_weapon_ammo(Object* obj)
|
||||
{
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_ITEM) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -641,7 +641,7 @@ static void _object_fix_weapon_ammo(Object* obj)
|
||||
obj->data.item.weapon.ammoQuantity = proto->item.data.weapon.ammoCapacity;
|
||||
}
|
||||
} else {
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_MISC) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_MISC) {
|
||||
// FIXME: looks like this code in unreachable
|
||||
charges = obj->data.item.misc.charges;
|
||||
if (charges == 0xCCCCCCCC) {
|
||||
@@ -723,7 +723,7 @@ int objectSaveAll(File* stream)
|
||||
|
||||
CritterCombatData* combatData = NULL;
|
||||
Object* whoHitMe = NULL;
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
combatData = &(object->data.critter.combat);
|
||||
whoHitMe = combatData->whoHitMe;
|
||||
if (whoHitMe != 0) {
|
||||
@@ -739,7 +739,7 @@ int objectSaveAll(File* stream)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
combatData->whoHitMe = whoHitMe;
|
||||
}
|
||||
|
||||
@@ -965,7 +965,7 @@ int objectCreateWithFidPid(Object** objectPtr, int fid, int pid)
|
||||
objectListNode->obj->pid = pid;
|
||||
objectListNode->obj->id = scriptsNewObjectId();
|
||||
|
||||
if (pid == -1 || (pid >> 24) == OBJ_TYPE_TILE) {
|
||||
if (pid == -1 || PID_TYPE(pid) == OBJ_TYPE_TILE) {
|
||||
Inventory* inventory = &(objectListNode->obj->data.inventory);
|
||||
inventory->length = 0;
|
||||
inventory->items = NULL;
|
||||
@@ -1451,7 +1451,7 @@ int objectSetLocation(Object* obj, int tile, int elevation, Rect* rect)
|
||||
}
|
||||
|
||||
if (isInCombat()) {
|
||||
if ((obj->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(obj->fid) == OBJ_TYPE_CRITTER) {
|
||||
bool v8 = obj->outline != 0 && (obj->outline & OUTLINE_DISABLED) == 0;
|
||||
_combat_update_critter_outline_for_los(obj, v8);
|
||||
}
|
||||
@@ -1471,7 +1471,7 @@ int objectSetLocation(Object* obj, int tile, int elevation, Rect* rect)
|
||||
}
|
||||
|
||||
if (elevation == elev) {
|
||||
if ((obj->fid & 0xF000000) >> 24 == OBJ_TYPE_MISC) {
|
||||
if (FID_TYPE(obj->fid) == OBJ_TYPE_MISC) {
|
||||
if (obj->pid >= 0x5000010 && obj->pid <= 0x5000017) {
|
||||
ObjectData* data = &(obj->data);
|
||||
|
||||
@@ -1498,9 +1498,9 @@ int objectSetLocation(Object* obj, int tile, int elevation, Rect* rect)
|
||||
int v15 = tile / 200 / 2;
|
||||
if (v14 != _obj_last_roof_x || v15 != _obj_last_roof_y || elevation != _obj_last_elev) {
|
||||
int v16 = _square[elevation]->field_0[v14 + 100 * v15];
|
||||
int v31 = buildFid(4, (v16 >> 16) & 0xFFF, 0, 0, 0);
|
||||
int v31 = buildFid(OBJ_TYPE_TILE, (v16 >> 16) & 0xFFF, 0, 0, 0);
|
||||
int v32 = _square[elevation]->field_0[_obj_last_roof_x + 100 * _obj_last_roof_y];
|
||||
int v34 = buildFid(4, 1, 0, 0, 0) == v31;
|
||||
int v34 = buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0) == v31;
|
||||
|
||||
if (v34 != _obj_last_is_empty || (((v16 >> 16) & 0xF000) >> 12) != (((v32 >> 16) & 0xF000) >> 12)) {
|
||||
if (_obj_last_is_empty == 0) {
|
||||
@@ -1538,7 +1538,7 @@ int objectSetLocation(Object* obj, int tile, int elevation, Rect* rect)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (elevation != _obj_last_elev && (obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (elevation != _obj_last_elev && PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
_combat_delete_critter(obj);
|
||||
}
|
||||
}
|
||||
@@ -1549,8 +1549,8 @@ int objectSetLocation(Object* obj, int tile, int elevation, Rect* rect)
|
||||
// 0x48A9A0
|
||||
int _obj_reset_roof()
|
||||
{
|
||||
int fid = buildFid(4, (_square[gDude->elevation]->field_0[_obj_last_roof_x + 100 * _obj_last_roof_y] >> 16) & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(4, 1, 0, 0, 0)) {
|
||||
int fid = buildFid(OBJ_TYPE_TILE, (_square[gDude->elevation]->field_0[_obj_last_roof_x + 100 * _obj_last_roof_y] >> 16) & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0)) {
|
||||
_tile_fill_roof(_obj_last_roof_x, _obj_last_roof_y, gDude->elevation, 1);
|
||||
}
|
||||
return 0;
|
||||
@@ -2100,13 +2100,13 @@ bool _obj_action_can_use(Object* obj)
|
||||
// 0x48B278
|
||||
bool _obj_action_can_talk_to(Object* obj)
|
||||
{
|
||||
return _proto_action_can_talk_to(obj->pid) && ((obj->pid >> 24) == OBJ_TYPE_CRITTER) && critterIsActive(obj);
|
||||
return _proto_action_can_talk_to(obj->pid) && (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) && critterIsActive(obj);
|
||||
}
|
||||
|
||||
// 0x48B2A8
|
||||
bool _obj_portal_is_walk_thru(Object* obj)
|
||||
{
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_SCENERY) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_SCENERY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2207,7 +2207,7 @@ Object* objectFindFirst()
|
||||
}
|
||||
|
||||
while (objectListNode != NULL) {
|
||||
if (artIsObjectTypeHidden((objectListNode->obj->fid & 0xF000000) >> 24) == 0) {
|
||||
if (artIsObjectTypeHidden(FID_TYPE(objectListNode->obj->fid)) == 0) {
|
||||
gObjectFindLastObjectListNode = objectListNode;
|
||||
return objectListNode->obj;
|
||||
}
|
||||
@@ -2234,7 +2234,7 @@ Object* objectFindNext()
|
||||
|
||||
while (objectListNode != NULL) {
|
||||
Object* object = objectListNode->obj;
|
||||
if (!artIsObjectTypeHidden((object->fid & 0xF000000) >> 24)) {
|
||||
if (!artIsObjectTypeHidden(FID_TYPE(object->fid))) {
|
||||
gObjectFindLastObjectListNode = objectListNode;
|
||||
return object;
|
||||
}
|
||||
@@ -2257,7 +2257,7 @@ Object* objectFindFirstAtElevation(int elevation)
|
||||
while (objectListNode != NULL) {
|
||||
Object* object = objectListNode->obj;
|
||||
if (object->elevation == elevation) {
|
||||
if (!artIsObjectTypeHidden((object->fid & 0xF000000) >> 24)) {
|
||||
if (!artIsObjectTypeHidden(FID_TYPE(object->fid))) {
|
||||
gObjectFindLastObjectListNode = objectListNode;
|
||||
return object;
|
||||
}
|
||||
@@ -2287,7 +2287,7 @@ Object* objectFindNextAtElevation()
|
||||
while (objectListNode != NULL) {
|
||||
Object* object = objectListNode->obj;
|
||||
if (object->elevation == gObjectFindElevation) {
|
||||
if (!artIsObjectTypeHidden((object->fid & 0xF000000) >> 24)) {
|
||||
if (!artIsObjectTypeHidden(FID_TYPE(object->fid))) {
|
||||
gObjectFindLastObjectListNode = objectListNode;
|
||||
return object;
|
||||
}
|
||||
@@ -2310,7 +2310,7 @@ Object* objectFindFirstAtLocation(int elevation, int tile)
|
||||
while (objectListNode != NULL) {
|
||||
Object* object = objectListNode->obj;
|
||||
if (object->elevation == elevation) {
|
||||
if (!artIsObjectTypeHidden((object->fid & 0xF000000) >> 24)) {
|
||||
if (!artIsObjectTypeHidden(FID_TYPE(object->fid))) {
|
||||
gObjectFindLastObjectListNode = objectListNode;
|
||||
return object;
|
||||
}
|
||||
@@ -2334,7 +2334,7 @@ Object* objectFindNextAtLocation()
|
||||
while (objectListNode != NULL) {
|
||||
Object* object = objectListNode->obj;
|
||||
if (object->elevation == gObjectFindElevation) {
|
||||
if (!artIsObjectTypeHidden((object->fid & 0xF000000) >> 24)) {
|
||||
if (!artIsObjectTypeHidden(FID_TYPE(object->fid))) {
|
||||
gObjectFindLastObjectListNode = objectListNode;
|
||||
return object;
|
||||
}
|
||||
@@ -2449,7 +2449,7 @@ Object* _obj_blocking_at(Object* a1, int tile, int elev)
|
||||
v7 = objectListNode->obj;
|
||||
if (v7->elevation == elev) {
|
||||
if ((v7->flags & OBJECT_HIDDEN) == 0 && (v7->flags & OBJECT_NO_BLOCK) == 0 && v7 != a1) {
|
||||
type = (v7->fid & 0xF000000) >> 24;
|
||||
type = FID_TYPE(v7->fid);
|
||||
if (type == OBJ_TYPE_CRITTER
|
||||
|| type == OBJ_TYPE_SCENERY
|
||||
|| type == OBJ_TYPE_WALL) {
|
||||
@@ -2469,7 +2469,7 @@ Object* _obj_blocking_at(Object* a1, int tile, int elev)
|
||||
if ((v7->flags & OBJECT_MULTIHEX) != 0) {
|
||||
if (v7->elevation == elev) {
|
||||
if ((v7->flags & OBJECT_HIDDEN) == 0 && (v7->flags & OBJECT_NO_BLOCK) == 0 && v7 != a1) {
|
||||
type = (v7->fid & 0xF000000) >> 24;
|
||||
type = FID_TYPE(v7->fid);
|
||||
if (type == OBJ_TYPE_CRITTER
|
||||
|| type == OBJ_TYPE_SCENERY
|
||||
|| type == OBJ_TYPE_WALL) {
|
||||
@@ -2499,7 +2499,7 @@ Object* _obj_shoot_blocking_at(Object* obj, int tile, int elev)
|
||||
if (candidate->elevation == elev) {
|
||||
unsigned int flags = candidate->flags;
|
||||
if ((flags & OBJECT_HIDDEN) == 0 && ((flags & OBJECT_NO_BLOCK) == 0 || (flags & OBJECT_SHOOT_THRU) == 0) && candidate != obj) {
|
||||
int type = (candidate->fid & 0xF000000) >> 24;
|
||||
int type = FID_TYPE(candidate->fid);
|
||||
// SFALL: Fix to prevent corpses from blocking line of fire.
|
||||
if ((type == OBJ_TYPE_CRITTER && !critterIsDead(candidate))
|
||||
|| type == OBJ_TYPE_SCENERY
|
||||
@@ -2524,7 +2524,7 @@ Object* _obj_shoot_blocking_at(Object* obj, int tile, int elev)
|
||||
if ((flags & OBJECT_MULTIHEX) != 0) {
|
||||
if (candidate->elevation == elev) {
|
||||
if ((flags & OBJECT_HIDDEN) == 0 && (flags & OBJECT_NO_BLOCK) == 0 && candidate != obj) {
|
||||
int type = (candidate->fid & 0xF000000) >> 24;
|
||||
int type = FID_TYPE(candidate->fid);
|
||||
// SFALL: Fix to prevent corpses from blocking line of
|
||||
// fire.
|
||||
if ((type == OBJ_TYPE_CRITTER && !critterIsDead(candidate))
|
||||
@@ -2556,7 +2556,7 @@ Object* _obj_ai_blocking_at(Object* a1, int tile, int elevation)
|
||||
if ((object->flags & OBJECT_HIDDEN) == 0
|
||||
&& (object->flags & OBJECT_NO_BLOCK) == 0
|
||||
&& object != a1) {
|
||||
int objectType = (object->fid & 0xF000000) >> 24;
|
||||
int objectType = FID_TYPE(object->fid);
|
||||
if (objectType == OBJ_TYPE_CRITTER
|
||||
|| objectType == OBJ_TYPE_SCENERY
|
||||
|| objectType == OBJ_TYPE_WALL) {
|
||||
@@ -2585,7 +2585,7 @@ Object* _obj_ai_blocking_at(Object* a1, int tile, int elevation)
|
||||
if ((object->flags & OBJECT_HIDDEN) == 0
|
||||
&& (object->flags & OBJECT_NO_BLOCK) == 0
|
||||
&& object != a1) {
|
||||
int objectType = (object->fid & 0xF000000) >> 24;
|
||||
int objectType = FID_TYPE(object->fid);
|
||||
if (objectType == OBJ_TYPE_CRITTER
|
||||
|| objectType == OBJ_TYPE_SCENERY
|
||||
|| objectType == OBJ_TYPE_WALL) {
|
||||
@@ -2639,7 +2639,7 @@ Object* _obj_sight_blocking_at(Object* a1, int tile, int elevation)
|
||||
&& (object->flags & OBJECT_HIDDEN) == 0
|
||||
&& (object->flags & OBJECT_LIGHT_THRU) == 0
|
||||
&& object != a1) {
|
||||
int objectType = (object->fid & 0xF000000) >> 24;
|
||||
int objectType = FID_TYPE(object->fid);
|
||||
if (objectType == OBJ_TYPE_SCENERY || objectType == OBJ_TYPE_WALL) {
|
||||
return object;
|
||||
}
|
||||
@@ -2713,7 +2713,7 @@ int objectListCreate(int tile, int elevation, int objectType, Object*** objectLi
|
||||
Object* obj = objectListNode->obj;
|
||||
if ((obj->flags & OBJECT_HIDDEN) == 0
|
||||
&& obj->elevation == elevation
|
||||
&& ((obj->fid & 0xF000000) >> 24) == objectType) {
|
||||
&& FID_TYPE(obj->fid) == objectType) {
|
||||
count++;
|
||||
}
|
||||
objectListNode = objectListNode->next;
|
||||
@@ -2725,7 +2725,7 @@ int objectListCreate(int tile, int elevation, int objectType, Object*** objectLi
|
||||
Object* obj = objectListNode->obj;
|
||||
if ((obj->flags & OBJECT_HIDDEN) == 0
|
||||
&& obj->elevation == elevation
|
||||
&& ((objectListNode->obj->fid & 0xF000000) >> 24) == objectType) {
|
||||
&& FID_TYPE(objectListNode->obj->fid) == objectType) {
|
||||
count++;
|
||||
}
|
||||
objectListNode = objectListNode->next;
|
||||
@@ -2748,7 +2748,7 @@ int objectListCreate(int tile, int elevation, int objectType, Object*** objectLi
|
||||
Object* obj = objectListNode->obj;
|
||||
if ((obj->flags & OBJECT_HIDDEN) == 0
|
||||
&& obj->elevation == elevation
|
||||
&& ((obj->fid & 0xF000000) >> 24) == objectType) {
|
||||
&& FID_TYPE(obj->fid) == objectType) {
|
||||
*objects++ = obj;
|
||||
}
|
||||
objectListNode = objectListNode->next;
|
||||
@@ -2760,7 +2760,7 @@ int objectListCreate(int tile, int elevation, int objectType, Object*** objectLi
|
||||
Object* obj = objectListNode->obj;
|
||||
if ((obj->flags & OBJECT_HIDDEN) == 0
|
||||
&& obj->elevation == elevation
|
||||
&& ((obj->fid & 0xF000000) >> 24) == objectType) {
|
||||
&& FID_TYPE(obj->fid) == objectType) {
|
||||
*objects++ = obj;
|
||||
}
|
||||
objectListNode = objectListNode->next;
|
||||
@@ -3003,7 +3003,7 @@ int _obj_intersects_with(Object* object, int x, int y)
|
||||
flags |= 0x02;
|
||||
}
|
||||
} else {
|
||||
int type = (object->fid & 0xF000000) >> 24;
|
||||
int type = FID_TYPE(object->fid);
|
||||
if (type == OBJ_TYPE_SCENERY || type == OBJ_TYPE_WALL) {
|
||||
Proto* proto;
|
||||
protoGetProto(object->pid, &proto);
|
||||
@@ -3064,7 +3064,7 @@ int _obj_create_intersect_list(int x, int y, int elevation, int objectType, Obje
|
||||
}
|
||||
|
||||
if (object->elevation == elevation
|
||||
&& (objectType == -1 || (object->fid & 0xF000000) >> 24 == objectType)
|
||||
&& (objectType == -1 || FID_TYPE(object->fid) == objectType)
|
||||
&& object != gEgg) {
|
||||
int flags = _obj_intersects_with(object, x, y);
|
||||
if (flags != 0) {
|
||||
@@ -3164,7 +3164,7 @@ void _obj_process_seen()
|
||||
// 0x48C8E4
|
||||
char* objectGetName(Object* obj)
|
||||
{
|
||||
int objectType = (obj->fid & 0xF000000) >> 24;
|
||||
int objectType = FID_TYPE(obj->fid);
|
||||
switch (objectType) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
return itemGetName(obj);
|
||||
@@ -3178,7 +3178,7 @@ char* objectGetName(Object* obj)
|
||||
// 0x48C914
|
||||
char* objectGetDescription(Object* obj)
|
||||
{
|
||||
if (((obj->fid & 0xF000000) >> 24) == OBJ_TYPE_ITEM) {
|
||||
if (FID_TYPE(obj->fid) == OBJ_TYPE_ITEM) {
|
||||
return itemGetDescription(obj);
|
||||
}
|
||||
|
||||
@@ -3226,13 +3226,13 @@ void _obj_preload_art_cache(int flags)
|
||||
int v11 = gObjectFidsLength;
|
||||
int v12 = gObjectFidsLength;
|
||||
|
||||
if ((gObjectFids[v12 - 1] & 0xF000000) >> 24 == 3) {
|
||||
int v13 = 0;
|
||||
if (FID_TYPE(gObjectFids[v12 - 1]) == OBJ_TYPE_WALL) {
|
||||
int objectType = OBJ_TYPE_ITEM;
|
||||
do {
|
||||
v11--;
|
||||
v13 = (gObjectFids[v12 - 1] & 0xF000000) >> 24;
|
||||
objectType = FID_TYPE(gObjectFids[v12 - 1]);
|
||||
v12--;
|
||||
} while (v13 == 3);
|
||||
} while (objectType == OBJ_TYPE_WALL);
|
||||
v11++;
|
||||
}
|
||||
|
||||
@@ -3251,7 +3251,7 @@ void _obj_preload_art_cache(int flags)
|
||||
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
if (arr[i] != 0) {
|
||||
int fid = buildFid(4, i, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_TILE, i, 0, 0, 0);
|
||||
if (artLock(fid, &cache_handle) != NULL) {
|
||||
artUnlock(cache_handle);
|
||||
}
|
||||
@@ -3543,7 +3543,7 @@ static int _obj_save_obj(File* stream, Object* object)
|
||||
|
||||
CritterCombatData* combatData = NULL;
|
||||
Object* whoHitMe = NULL;
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
combatData = &(object->data.critter.combat);
|
||||
whoHitMe = combatData->whoHitMe;
|
||||
if (whoHitMe != 0) {
|
||||
@@ -3559,7 +3559,7 @@ static int _obj_save_obj(File* stream, Object* object)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
combatData->whoHitMe = whoHitMe;
|
||||
}
|
||||
|
||||
@@ -4602,7 +4602,7 @@ static int _obj_adjust_light(Object* obj, int a2, Rect* rect)
|
||||
|
||||
v14 = (objectListNode->obj->flags & OBJECT_LIGHT_THRU) == 0;
|
||||
|
||||
if ((objectListNode->obj->fid & 0xF000000) >> 24 == OBJ_TYPE_WALL) {
|
||||
if (FID_TYPE(objectListNode->obj->fid) == OBJ_TYPE_WALL) {
|
||||
if ((objectListNode->obj->flags & OBJECT_FLAT) == 0) {
|
||||
Proto* proto;
|
||||
protoGetProto(objectListNode->obj->pid, &proto);
|
||||
@@ -4933,7 +4933,7 @@ static void objectDrawOutline(Object* object, Rect* rect)
|
||||
// 0x48F1B0
|
||||
static void _obj_render_object(Object* object, Rect* rect, int light)
|
||||
{
|
||||
int type = (object->fid & 0xF000000) >> 24;
|
||||
int type = FID_TYPE(object->fid);
|
||||
if (artIsObjectTypeHidden(type)) {
|
||||
return;
|
||||
}
|
||||
@@ -5146,7 +5146,7 @@ static void _obj_render_object(Object* object, Rect* rect, int light)
|
||||
// 0x48FA14
|
||||
void _obj_fix_violence_settings(int* fid)
|
||||
{
|
||||
if ((*fid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(*fid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5181,12 +5181,12 @@ void _obj_fix_violence_settings(int* fid)
|
||||
break;
|
||||
}
|
||||
|
||||
int anim = (*fid & 0xFF0000) >> 16;
|
||||
int anim = FID_ANIM_TYPE(*fid);
|
||||
if (anim >= start && anim <= end) {
|
||||
anim = (anim == ANIM_FALL_BACK_BLOOD_SF)
|
||||
? ANIM_FALL_BACK_SF
|
||||
: ANIM_FALL_FRONT_SF;
|
||||
*fid = buildFid(1, *fid & 0xFFF, anim, (*fid & 0xF000) >> 12, (*fid & 0x70000000) >> 28);
|
||||
*fid = buildFid(OBJ_TYPE_CRITTER, *fid & 0xFFF, anim, (*fid & 0xF000) >> 12, (*fid & 0x70000000) >> 28);
|
||||
}
|
||||
|
||||
if (shouldResetViolenceLevel) {
|
||||
@@ -5200,8 +5200,8 @@ static int _obj_preload_sort(const void* a1, const void* a2)
|
||||
int v1 = *(int*)a1;
|
||||
int v2 = *(int*)a2;
|
||||
|
||||
int v3 = _cd_order[(v1 & 0xF000000) >> 24];
|
||||
int v4 = _cd_order[(v2 & 0xF000000) >> 24];
|
||||
int v3 = _cd_order[FID_TYPE(v1)];
|
||||
int v4 = _cd_order[FID_TYPE(v2)];
|
||||
|
||||
int cmp = v3 - v4;
|
||||
if (cmp != 0) {
|
||||
|
||||
+9
-3
@@ -574,7 +574,7 @@ static int optionsWindowInit()
|
||||
}
|
||||
|
||||
for (int index = 0; index < OPTIONS_WINDOW_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, gOptionsWindowFrmIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gOptionsWindowFrmIds[index], 0, 0, 0);
|
||||
gOptionsWindowFrmData[index] = artLockFrameDataReturningSize(fid, &(gOptionsWindowFrmHandles[index]), &(gOptionsWindowFrmSizes[index].width), &(gOptionsWindowFrmSizes[index].height));
|
||||
|
||||
if (gOptionsWindowFrmData[index] == NULL) {
|
||||
@@ -730,7 +730,7 @@ int showPause(bool a1)
|
||||
_ShadeScreen(a1);
|
||||
|
||||
for (int index = 0; index < PAUSE_WINDOW_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, graphicIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, graphicIds[index], 0, 0, 0);
|
||||
frmData[index] = artLockFrameDataReturningSize(fid, &(frmHandles[index]), &(frmSizes[index].width), &(frmSizes[index].height));
|
||||
if (frmData[index] == NULL) {
|
||||
while (--index >= 0) {
|
||||
@@ -1498,7 +1498,7 @@ static int preferencesWindowInit()
|
||||
_SaveSettings();
|
||||
|
||||
for (i = 0; i < PREFERENCES_WINDOW_FRM_COUNT; i++) {
|
||||
fid = buildFid(6, gPreferencesWindowFrmIds[i], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, gPreferencesWindowFrmIds[i], 0, 0, 0);
|
||||
gPreferencesWindowFrmData[i] = artLockFrameDataReturningSize(fid, &(gPreferencesWindowFrmHandles[i]), &(gPreferencesWindowFrmSizes[i].width), &(gPreferencesWindowFrmSizes[i].height));
|
||||
if (gPreferencesWindowFrmData[i] == NULL) {
|
||||
for (; i != 0; i--) {
|
||||
@@ -2064,3 +2064,9 @@ static void _DoThing(int eventCode)
|
||||
|
||||
_changed = true;
|
||||
}
|
||||
|
||||
// 0x48FC48
|
||||
int _do_options()
|
||||
{
|
||||
return showOptionsWithInitialKeyCode(-1);
|
||||
}
|
||||
|
||||
@@ -29,5 +29,6 @@ int preferencesSave(File* stream);
|
||||
int preferencesLoad(File* stream);
|
||||
void brightnessIncrease();
|
||||
void brightnessDecrease();
|
||||
int _do_options();
|
||||
|
||||
#endif /* OPTIONS_H */
|
||||
|
||||
+24
-24
@@ -1,9 +1,9 @@
|
||||
#include "party_member.h"
|
||||
|
||||
#include "combat_ai.h"
|
||||
#include "combat_ai_defs.h"
|
||||
#include "animation.h"
|
||||
#include "color.h"
|
||||
#include "combat_ai.h"
|
||||
#include "combat_ai_defs.h"
|
||||
#include "config.h"
|
||||
#include "critter.h"
|
||||
#include "debug.h"
|
||||
@@ -558,7 +558,7 @@ static int _partyMemberPrepLoadInstance(STRUCT_519DA8* a1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
obj->data.critter.combat.whoHitMe = NULL;
|
||||
}
|
||||
|
||||
@@ -605,7 +605,7 @@ static int _partyMemberPrepLoadInstance(STRUCT_519DA8* a1)
|
||||
|
||||
scriptRemove(script->sid);
|
||||
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
_dude_stand(obj, obj->rotation, -1);
|
||||
}
|
||||
|
||||
@@ -660,7 +660,7 @@ static int _partyMemberRecoverLoadInstance(STRUCT_519DA8* a1)
|
||||
}
|
||||
|
||||
int scriptType = SCRIPT_TYPE_CRITTER;
|
||||
if ((a1->object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(a1->object->pid) != OBJ_TYPE_CRITTER) {
|
||||
scriptType = SCRIPT_TYPE_ITEM;
|
||||
}
|
||||
|
||||
@@ -791,7 +791,7 @@ int _partyMemberSyncPosition()
|
||||
for (int index = 1; index < gPartyMembersLength; index++) {
|
||||
STRUCT_519DA8* partyMember = &(gPartyMembers[index]);
|
||||
Object* partyMemberObj = partyMember->object;
|
||||
if ((partyMemberObj->flags & OBJECT_HIDDEN) == 0 && (partyMemberObj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if ((partyMemberObj->flags & OBJECT_HIDDEN) == 0 && PID_TYPE(partyMemberObj->pid) == OBJ_TYPE_CRITTER) {
|
||||
int rotation;
|
||||
if ((n % 2) != 0) {
|
||||
rotation = clockwiseRotation;
|
||||
@@ -822,7 +822,7 @@ int _partyMemberRestingHeal(int a1)
|
||||
|
||||
for (int index = 0; index < gPartyMembersLength; index++) {
|
||||
STRUCT_519DA8* partyMember = &(gPartyMembers[index]);
|
||||
if ((partyMember->object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(partyMember->object->pid) == OBJ_TYPE_CRITTER) {
|
||||
int healingRate = critterGetStat(partyMember->object, STAT_HEALING_RATE);
|
||||
critterAdjustHitPoints(partyMember->object, v1 * healingRate);
|
||||
}
|
||||
@@ -892,7 +892,7 @@ int _getPartyMemberCount()
|
||||
for (int index = 1; index < gPartyMembersLength; index++) {
|
||||
Object* object = gPartyMembers[index].object;
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER || critterIsDead(object) || (object->flags & OBJECT_HIDDEN) != 0) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER || critterIsDead(object) || (object->flags & OBJECT_HIDDEN) != 0) {
|
||||
count--;
|
||||
}
|
||||
}
|
||||
@@ -1126,7 +1126,7 @@ int partyMemberGetBestSkill(Object* object)
|
||||
return bestSkill;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return bestSkill;
|
||||
}
|
||||
|
||||
@@ -1152,7 +1152,7 @@ Object* partyMemberGetBestInSkill(int skill)
|
||||
|
||||
for (int index = 0; index < gPartyMembersLength; index++) {
|
||||
Object* object = gPartyMembers[index].object;
|
||||
if ((object->flags & OBJECT_HIDDEN) == 0 && (object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if ((object->flags & OBJECT_HIDDEN) == 0 && PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
int value = skillGetValue(object, skill);
|
||||
if (value > bestValue) {
|
||||
bestValue = value;
|
||||
@@ -1173,7 +1173,7 @@ int partyGetBestSkillValue(int skill)
|
||||
|
||||
for (int index = 0; index < gPartyMembersLength; index++) {
|
||||
Object* object = gPartyMembers[index].object;
|
||||
if ((object->flags & OBJECT_HIDDEN) == 0 && (object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if ((object->flags & OBJECT_HIDDEN) == 0 && PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
int value = skillGetValue(object, skill);
|
||||
if (value > bestValue) {
|
||||
bestValue = value;
|
||||
@@ -1191,7 +1191,7 @@ static int _partyFixMultipleMembers()
|
||||
|
||||
int critterCount = 0;
|
||||
for (Object* obj = objectFindFirst(); obj != NULL; obj = objectFindNext()) {
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
critterCount++;
|
||||
}
|
||||
|
||||
@@ -1294,7 +1294,7 @@ bool partyMemberSupportsDisposition(Object* critter, int disposition)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1317,7 +1317,7 @@ bool partyMemberSupportsAreaAttackMode(Object* object, int areaAttackMode)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1340,7 +1340,7 @@ bool partyMemberSupportsRunAwayMode(Object* object, int runAwayMode)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1363,7 +1363,7 @@ bool partyMemberSupportsBestWeapon(Object* object, int bestWeapon)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1386,7 +1386,7 @@ bool partyMemberSupportsDistance(Object* object, int distanceMode)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1409,7 +1409,7 @@ bool partyMemberSupportsAttackWho(Object* object, int attackWho)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1432,7 +1432,7 @@ bool partyMemberSupportsChemUse(Object* object, int chemUse)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1475,7 +1475,7 @@ int _partyMemberIncLevels()
|
||||
break;
|
||||
}
|
||||
|
||||
if ((obj->pid >> 24) != 1) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1527,9 +1527,9 @@ int _partyMemberIncLevels()
|
||||
// %s has gained in some abilities.
|
||||
text = getmsg(&gMiscMessageList, &msg, 9000);
|
||||
sprintf(str, text, name);
|
||||
displayMonitorAddMessage(text);
|
||||
displayMonitorAddMessage(str);
|
||||
|
||||
debugPrint(text);
|
||||
debugPrint(str);
|
||||
|
||||
// Individual message
|
||||
msg.num = 9000 + 10 * v0 + ptr_519DBC->field_0 - 1;
|
||||
@@ -1623,7 +1623,7 @@ bool partyIsAnyoneCanBeHealedByRest()
|
||||
STRUCT_519DA8* ptr = &(gPartyMembers[index]);
|
||||
Object* object = ptr->object;
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) continue;
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) continue;
|
||||
if (critterIsDead(object)) continue;
|
||||
if ((object->flags & OBJECT_HIDDEN) != 0) continue;
|
||||
if (critterGetKillType(object) == KILL_TYPE_ROBOT) continue;
|
||||
@@ -1650,7 +1650,7 @@ int partyGetMaxWoundToHealByRest()
|
||||
STRUCT_519DA8* ptr = &(gPartyMembers[index]);
|
||||
Object* object = ptr->object;
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) continue;
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) continue;
|
||||
if (critterIsDead(object)) continue;
|
||||
if ((object->flags & OBJECT_HIDDEN) != 0) continue;
|
||||
if (critterGetKillType(object) == KILL_TYPE_ROBOT) continue;
|
||||
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
#include "pcx.h"
|
||||
|
||||
#include "memory_manager.h"
|
||||
|
||||
// 0x519DC8
|
||||
unsigned char gPcxLastRunLength = 0;
|
||||
|
||||
// 0x519DC9
|
||||
unsigned char gPcxLastValue = 0;
|
||||
|
||||
// NOTE: The reading method in this function is a little bit odd. It does not
|
||||
// use high level reading functions, which can read right into struct. Instead
|
||||
// they read everything into temporary variables. There are no error checks.
|
||||
//
|
||||
// 0x4961D4
|
||||
void pcxReadHeader(PcxHeader* pcxHeader, File* stream)
|
||||
{
|
||||
pcxHeader->identifier = fileReadChar(stream);
|
||||
pcxHeader->version = fileReadChar(stream);
|
||||
pcxHeader->encoding = fileReadChar(stream);
|
||||
pcxHeader->bitsPerPixel = fileReadChar(stream);
|
||||
|
||||
short minX;
|
||||
fileRead(&minX, 2, 1, stream);
|
||||
pcxHeader->minX = minX;
|
||||
|
||||
short minY;
|
||||
fileRead(&minY, 2, 1, stream);
|
||||
pcxHeader->minY = minY;
|
||||
|
||||
short maxX;
|
||||
fileRead(&maxX, 2, 1, stream);
|
||||
pcxHeader->maxX = maxX;
|
||||
|
||||
short maxY;
|
||||
fileRead(&maxY, 2, 1, stream);
|
||||
pcxHeader->maxY = maxY;
|
||||
|
||||
short horizontalResolution;
|
||||
fileRead(&horizontalResolution, 2, 1, stream);
|
||||
pcxHeader->horizontalResolution = horizontalResolution;
|
||||
|
||||
short verticalResolution;
|
||||
fileRead(&verticalResolution, 2, 1, stream);
|
||||
pcxHeader->verticalResolution = verticalResolution;
|
||||
|
||||
for (int index = 0; index < 48; index++) {
|
||||
pcxHeader->palette[index] = fileReadChar(stream);
|
||||
}
|
||||
|
||||
pcxHeader->reserved1 = fileReadChar(stream);
|
||||
pcxHeader->planeCount = fileReadChar(stream);
|
||||
|
||||
short bytesPerLine;
|
||||
fileRead(&bytesPerLine, 2, 1, stream);
|
||||
pcxHeader->bytesPerLine = bytesPerLine;
|
||||
|
||||
short paletteType;
|
||||
fileRead(&paletteType, 2, 1, stream);
|
||||
pcxHeader->paletteType = paletteType;
|
||||
|
||||
short horizontalScreenSize;
|
||||
fileRead(&horizontalScreenSize, 2, 1, stream);
|
||||
pcxHeader->horizontalScreenSize = horizontalScreenSize;
|
||||
|
||||
short verticalScreenSize;
|
||||
fileRead(&verticalScreenSize, 2, 1, stream);
|
||||
pcxHeader->verticalScreenSize = verticalScreenSize;
|
||||
|
||||
for (int index = 0; index < 54; index++) {
|
||||
pcxHeader->reserved2[index] = fileReadChar(stream);
|
||||
}
|
||||
}
|
||||
|
||||
// 0x49636C
|
||||
int pcxReadLine(unsigned char* data, int size, File* stream)
|
||||
{
|
||||
unsigned char runLength = gPcxLastRunLength;
|
||||
unsigned char value = gPcxLastValue;
|
||||
|
||||
int uncompressedSize = 0;
|
||||
int index = 0;
|
||||
do {
|
||||
uncompressedSize += runLength;
|
||||
while (runLength > 0 && index < size) {
|
||||
data[index] = value;
|
||||
runLength--;
|
||||
index++;
|
||||
}
|
||||
|
||||
gPcxLastRunLength = runLength;
|
||||
gPcxLastValue = value;
|
||||
|
||||
if (runLength != 0) {
|
||||
uncompressedSize -= runLength;
|
||||
break;
|
||||
}
|
||||
|
||||
value = fileReadChar(stream);
|
||||
if ((value & 0xC0) == 0xC0) {
|
||||
gPcxLastRunLength = value & 0x3F;
|
||||
value = fileReadChar(stream);
|
||||
runLength = gPcxLastRunLength;
|
||||
} else {
|
||||
runLength = 1;
|
||||
}
|
||||
} while (index < size);
|
||||
|
||||
gPcxLastRunLength = runLength;
|
||||
gPcxLastValue = value;
|
||||
|
||||
return uncompressedSize;
|
||||
}
|
||||
|
||||
// 0x49641C
|
||||
int pcxReadPalette(PcxHeader* pcxHeader, unsigned char* palette, File* stream)
|
||||
{
|
||||
if (pcxHeader->version != 5) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long pos = fileTell(stream);
|
||||
long size = fileGetSize(stream);
|
||||
fileSeek(stream, size - 769, SEEK_SET);
|
||||
if (fileReadChar(stream) != 12) {
|
||||
fileSeek(stream, pos, SEEK_SET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int index = 0; index < 768; index++) {
|
||||
palette[index] = fileReadChar(stream);
|
||||
}
|
||||
|
||||
fileSeek(stream, pos, SEEK_SET);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 0x496494
|
||||
unsigned char* pcxRead(const char* path, int* widthPtr, int* heightPtr, unsigned char* palette)
|
||||
{
|
||||
File* stream = fileOpen(path, "rb");
|
||||
if (stream == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PcxHeader pcxHeader;
|
||||
pcxReadHeader(&pcxHeader, stream);
|
||||
|
||||
int width = pcxHeader.maxX - pcxHeader.minX + 1;
|
||||
int height = pcxHeader.maxY - pcxHeader.minY + 1;
|
||||
|
||||
*widthPtr = width;
|
||||
*heightPtr = height;
|
||||
|
||||
int bytesPerLine = pcxHeader.planeCount * pcxHeader.bytesPerLine;
|
||||
unsigned char* data = (unsigned char*)internal_malloc_safe(bytesPerLine * height, __FILE__, __LINE__); // "..\\int\\PCX.C", 195
|
||||
if (data == NULL) {
|
||||
// NOTE: This code is unreachable, internal_malloc_safe never fails.
|
||||
fileClose(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gPcxLastRunLength = 0;
|
||||
gPcxLastValue = 0;
|
||||
|
||||
unsigned char* ptr = data;
|
||||
for (int y = 0; y < height; y++) {
|
||||
pcxReadLine(ptr, bytesPerLine, stream);
|
||||
ptr += width;
|
||||
}
|
||||
|
||||
pcxReadPalette(&pcxHeader, palette, stream);
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef PCX_H
|
||||
#define PCX_H
|
||||
|
||||
#include "db.h"
|
||||
|
||||
typedef struct PcxHeader {
|
||||
unsigned char identifier;
|
||||
unsigned char version;
|
||||
unsigned char encoding;
|
||||
unsigned char bitsPerPixel;
|
||||
short minX;
|
||||
short minY;
|
||||
short maxX;
|
||||
short maxY;
|
||||
short horizontalResolution;
|
||||
short verticalResolution;
|
||||
unsigned char palette[48];
|
||||
unsigned char reserved1;
|
||||
unsigned char planeCount;
|
||||
short bytesPerLine;
|
||||
short paletteType;
|
||||
short horizontalScreenSize;
|
||||
short verticalScreenSize;
|
||||
unsigned char reserved2[54];
|
||||
} PcxHeader;
|
||||
|
||||
extern unsigned char gPcxLastRunLength;
|
||||
extern unsigned char gPcxLastValue;
|
||||
|
||||
void pcxReadHeader(PcxHeader* pcxHeader, File* stream);
|
||||
int pcxReadLine(unsigned char* data, int size, File* stream);
|
||||
int pcxReadPalette(PcxHeader* pcxHeader, unsigned char* palette, File* stream);
|
||||
unsigned char* pcxRead(const char* path, int* widthPtr, int* heightPtr, unsigned char* palette);
|
||||
|
||||
#endif /* PCX_H */
|
||||
+2
-2
@@ -535,7 +535,7 @@ int perkGetFrmId(int perk)
|
||||
// 0x496BFC
|
||||
void perkAddEffect(Object* critter, int perk)
|
||||
{
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
debugPrint("\nERROR: perk_add_effect: Was called on non-critter!");
|
||||
return;
|
||||
}
|
||||
@@ -575,7 +575,7 @@ void perkAddEffect(Object* critter, int perk)
|
||||
// 0x496CE0
|
||||
void perkRemoveEffect(Object* critter, int perk)
|
||||
{
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
debugPrint("\nERROR: perk_remove_effect: Was called on non-critter!");
|
||||
return;
|
||||
}
|
||||
|
||||
+5
-5
@@ -512,7 +512,7 @@ static int pipboyWindowInit(bool forceRest)
|
||||
|
||||
int index;
|
||||
for (index = 0; index < PIPBOY_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, gPipboyFrmIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gPipboyFrmIds[index], 0, 0, 0);
|
||||
gPipboyFrmData[index] = artLockFrameDataReturningSize(fid, &(gPipboyFrmHandles[index]), &(gPipboyFrmSizes[index].width), &(gPipboyFrmSizes[index].height));
|
||||
if (gPipboyFrmData[index] == NULL) {
|
||||
break;
|
||||
@@ -939,7 +939,7 @@ static void pipboyWindowHandleStatus(int a1)
|
||||
return;
|
||||
}
|
||||
|
||||
if (gPipboyMouseX > 459 && a1 != 1027 || a1 == 1026) {
|
||||
if ((gPipboyMouseX > 459 && a1 != 1027) || a1 == 1026) {
|
||||
if (gPipboyHolodiskLastPage <= _view_page) {
|
||||
if (a1 != 1026) {
|
||||
soundPlayFile("ib1p1xx1");
|
||||
@@ -1087,7 +1087,7 @@ static void pipboyWindowHandleStatus(int a1)
|
||||
|
||||
// Skip quests in the same location.
|
||||
//
|
||||
// FIXME: This code should be identical to the one in the
|
||||
// FIXME: This code should be identical to the one in the
|
||||
// `pipboyWindowRenderQuestLocationList`. See buffer overread
|
||||
// bug involved.
|
||||
for (; index < gQuestsCount; index++) {
|
||||
@@ -2013,7 +2013,7 @@ static bool pipboyRest(int hours, int minutes, int duration)
|
||||
rc = true;
|
||||
}
|
||||
|
||||
unsigned int v8 = (unsigned int)((double)hour / v7 * (hours * 36000.0) + gameTime);
|
||||
unsigned int v8 = (unsigned int)((double)hour / v7 * (hours * GAME_TIME_TICKS_PER_HOUR) + gameTime);
|
||||
unsigned int nextEventTime = queueGetNextEventTime();
|
||||
if (!rc && v8 >= nextEventTime) {
|
||||
gameTimeSetTime(nextEventTime + 1);
|
||||
@@ -2050,7 +2050,7 @@ static bool pipboyRest(int hours, int minutes, int duration)
|
||||
}
|
||||
|
||||
if (!rc) {
|
||||
gameTimeSetTime(gameTime + 36000 * hours);
|
||||
gameTimeSetTime(gameTime + GAME_TIME_TICKS_PER_HOUR * hours);
|
||||
}
|
||||
|
||||
pipboyDrawNumber(gameTimeGetHour(), 4, PIPBOY_WINDOW_TIME_X, PIPBOY_WINDOW_TIME_Y);
|
||||
|
||||
@@ -55,7 +55,7 @@ void compat_splitpath(const char* path, char* drive, char* dir, char* fname, cha
|
||||
#ifdef _WIN32
|
||||
_splitpath(path, drive, dir, fname, ext);
|
||||
#else
|
||||
const char *driveStart = path;
|
||||
const char* driveStart = path;
|
||||
if (path[0] == '/' && path[1] == '/') {
|
||||
path += 2;
|
||||
while (*path != '\0' && *path != '/' && *path != '.') {
|
||||
@@ -130,7 +130,7 @@ void compat_makepath(char* path, const char* drive, const char* dir, const char*
|
||||
if (*drive != '\0') {
|
||||
strcpy(path, drive);
|
||||
path = strchr(path, '\0');
|
||||
|
||||
|
||||
if (path[-1] == '/') {
|
||||
path--;
|
||||
} else {
|
||||
|
||||
+80
-88
@@ -185,17 +185,21 @@ static char** _perk_code_strs;
|
||||
// 0x6648BC
|
||||
static char** _critter_stats_list;
|
||||
|
||||
// NOTE: Inlined.
|
||||
void _proto_make_path(char* path, int pid)
|
||||
{
|
||||
strcpy(path, _cd_path_base);
|
||||
strcat(path, _proto_path_base);
|
||||
if (pid != -1) {
|
||||
strcat(path, artGetObjectTypeName(PID_TYPE(pid)));
|
||||
}
|
||||
}
|
||||
|
||||
// Append proto file name to proto_path from proto.lst.
|
||||
//
|
||||
// 0x49E758
|
||||
int _proto_list_str(int pid, char* proto_path)
|
||||
{
|
||||
char path[COMPAT_MAX_PATH];
|
||||
char str[COMPAT_MAX_PATH];
|
||||
char* pch;
|
||||
File* stream;
|
||||
int i;
|
||||
|
||||
if (pid == -1) {
|
||||
return -1;
|
||||
}
|
||||
@@ -204,17 +208,17 @@ int _proto_list_str(int pid, char* proto_path)
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(path, _cd_path_base);
|
||||
strcat(path, "proto\\");
|
||||
strcat(path, artGetObjectTypeName(pid >> 24));
|
||||
char path[COMPAT_MAX_PATH];
|
||||
_proto_make_path(path, pid);
|
||||
strcat(path, "\\");
|
||||
strcat(path, artGetObjectTypeName(pid >> 24));
|
||||
strcat(path, artGetObjectTypeName(PID_TYPE(pid)));
|
||||
strcat(path, ".lst");
|
||||
|
||||
stream = fileOpen(path, "rt");
|
||||
File* stream = fileOpen(path, "rt");
|
||||
|
||||
i = 1;
|
||||
while (fileReadString(str, sizeof(str), stream)) {
|
||||
int i = 1;
|
||||
char string[256];
|
||||
while (fileReadString(string, sizeof(string), stream)) {
|
||||
if (i == (pid & 0xFFFFFF)) {
|
||||
break;
|
||||
}
|
||||
@@ -228,14 +232,17 @@ int _proto_list_str(int pid, char* proto_path)
|
||||
return -1;
|
||||
}
|
||||
|
||||
pch = str;
|
||||
while (*pch != '\0' && *pch != '\n') {
|
||||
*proto_path = *pch;
|
||||
proto_path++;
|
||||
pch++;
|
||||
char* pch = strchr(string, ' ');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
}
|
||||
|
||||
*proto_path = '\0';
|
||||
pch = strchr(string, '\n');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
}
|
||||
|
||||
strcpy(proto_path, string);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -252,7 +259,7 @@ bool _proto_action_can_use(int pid)
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((pid >> 24) == OBJ_TYPE_ITEM && proto->item.type == ITEM_TYPE_CONTAINER) {
|
||||
if (PID_TYPE(pid) == OBJ_TYPE_ITEM && proto->item.type == ITEM_TYPE_CONTAINER) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -271,7 +278,7 @@ bool _proto_action_can_use_on(int pid)
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((pid >> 24) == OBJ_TYPE_ITEM && proto->item.type == ITEM_TYPE_DRUG) {
|
||||
if (PID_TYPE(pid) == OBJ_TYPE_ITEM && proto->item.type == ITEM_TYPE_DRUG) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -286,7 +293,7 @@ bool _proto_action_can_talk_to(int pid)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(pid) == OBJ_TYPE_CRITTER) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -302,7 +309,7 @@ bool _proto_action_can_talk_to(int pid)
|
||||
// 0x49EA5C
|
||||
int _proto_action_can_pickup(int pid)
|
||||
{
|
||||
if ((pid >> 24) != OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(pid) != OBJ_TYPE_ITEM) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -326,7 +333,7 @@ char* protoGetMessage(int pid, int message)
|
||||
Proto* proto;
|
||||
if (protoGetProto(pid, &proto) != -1) {
|
||||
if (proto->messageId != -1) {
|
||||
MessageList* messageList = &(_proto_msg_files[pid >> 24]);
|
||||
MessageList* messageList = &(_proto_msg_files[PID_TYPE(pid)]);
|
||||
|
||||
MessageListItem messageListItem;
|
||||
messageListItem.num = proto->messageId + message;
|
||||
@@ -366,7 +373,7 @@ static int _proto_critter_init(Proto* a1, int a2)
|
||||
|
||||
a1->pid = -1;
|
||||
a1->messageId = 100 * v1;
|
||||
a1->fid = buildFid(1, v1 - 1, 0, 0, 0);
|
||||
a1->fid = buildFid(OBJ_TYPE_CRITTER, v1 - 1, 0, 0, 0);
|
||||
a1->critter.lightDistance = 0;
|
||||
a1->critter.lightIntensity = 0;
|
||||
a1->critter.flags = 0x20000000;
|
||||
@@ -377,7 +384,7 @@ static int _proto_critter_init(Proto* a1, int a2)
|
||||
a1->critter.headFid = -1;
|
||||
a1->critter.aiPacket = 1;
|
||||
if (!artExists(a1->fid)) {
|
||||
a1->fid = buildFid(1, 0, 0, 0, 0);
|
||||
a1->fid = buildFid(OBJ_TYPE_CRITTER, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
CritterProtoData* data = &(a1->critter.data);
|
||||
@@ -437,7 +444,7 @@ int objectDataRead(Object* obj, File* stream)
|
||||
// TODO: See below.
|
||||
if (fileReadInt32(stream, (int*)&(inventory->items)) == -1) return -1;
|
||||
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (fileReadInt32(stream, &(obj->data.critter.field_0)) == -1) return -1;
|
||||
if (objectCritterCombatDataRead(&(obj->data.critter.combat), stream) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.critter.hp)) == -1) return -1;
|
||||
@@ -451,7 +458,7 @@ int objectDataRead(Object* obj, File* stream)
|
||||
obj->data.flags = 0;
|
||||
}
|
||||
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
if (protoGetProto(obj->pid, &proto) == -1) return -1;
|
||||
|
||||
@@ -482,27 +489,27 @@ int objectDataRead(Object* obj, File* stream)
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.door.openFlags)) == -1) return -1;
|
||||
break;
|
||||
case SCENERY_TYPE_STAIRS:
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.stairs.field_4)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.stairs.field_0)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.stairs.destinationBuiltTile)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.stairs.destinationMap)) == -1) return -1;
|
||||
break;
|
||||
case SCENERY_TYPE_ELEVATOR:
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.elevator.field_0)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.elevator.field_4)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.elevator.type)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.elevator.level)) == -1) return -1;
|
||||
break;
|
||||
case SCENERY_TYPE_LADDER_UP:
|
||||
if (gMapHeader.version == 19) {
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.field_4)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.destinationBuiltTile)) == -1) return -1;
|
||||
} else {
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.field_0)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.field_4)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.destinationMap)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.destinationBuiltTile)) == -1) return -1;
|
||||
}
|
||||
break;
|
||||
case SCENERY_TYPE_LADDER_DOWN:
|
||||
if (gMapHeader.version == 19) {
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.field_4)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.destinationBuiltTile)) == -1) return -1;
|
||||
} else {
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.field_0)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.field_4)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.destinationMap)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.destinationBuiltTile)) == -1) return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -534,7 +541,7 @@ int objectDataWrite(Object* obj, File* stream)
|
||||
// this field is shared with something else.
|
||||
if (fileWriteInt32(stream, (intptr_t)data->inventory.items) == -1) return -1;
|
||||
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (fileWriteInt32(stream, data->flags) == -1) return -1;
|
||||
if (objectCritterCombatDataWrite(&(obj->data.critter.combat), stream) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->critter.hp) == -1) return -1;
|
||||
@@ -543,7 +550,7 @@ int objectDataWrite(Object* obj, File* stream)
|
||||
} else {
|
||||
if (fileWriteInt32(stream, data->flags) == -1) return -1;
|
||||
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
if (protoGetProto(obj->pid, &proto) == -1) return -1;
|
||||
|
||||
@@ -571,20 +578,20 @@ int objectDataWrite(Object* obj, File* stream)
|
||||
if (fileWriteInt32(stream, data->scenery.door.openFlags) == -1) return -1;
|
||||
break;
|
||||
case SCENERY_TYPE_STAIRS:
|
||||
if (fileWriteInt32(stream, data->scenery.stairs.field_4) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.stairs.field_0) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.stairs.destinationBuiltTile) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.stairs.destinationMap) == -1) return -1;
|
||||
break;
|
||||
case SCENERY_TYPE_ELEVATOR:
|
||||
if (fileWriteInt32(stream, data->scenery.elevator.field_0) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.elevator.field_4) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.elevator.type) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.elevator.level) == -1) return -1;
|
||||
break;
|
||||
case SCENERY_TYPE_LADDER_UP:
|
||||
if (fileWriteInt32(stream, data->scenery.ladder.field_0) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.elevator.field_4) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.ladder.destinationMap) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.ladder.destinationBuiltTile) == -1) return -1;
|
||||
break;
|
||||
case SCENERY_TYPE_LADDER_DOWN:
|
||||
if (fileWriteInt32(stream, data->scenery.ladder.field_0) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.elevator.field_4) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.ladder.destinationMap) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.ladder.destinationBuiltTile) == -1) return -1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -624,7 +631,7 @@ static int _proto_update_gen(Object* obj)
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
switch (proto->item.type) {
|
||||
case ITEM_TYPE_CONTAINER:
|
||||
@@ -651,16 +658,16 @@ static int _proto_update_gen(Object* obj)
|
||||
data->scenery.door.openFlags = proto->scenery.data.door.openFlags;
|
||||
break;
|
||||
case SCENERY_TYPE_STAIRS:
|
||||
data->scenery.stairs.field_4 = proto->scenery.data.stairs.field_0;
|
||||
data->scenery.stairs.field_0 = proto->scenery.data.stairs.field_4;
|
||||
data->scenery.stairs.destinationBuiltTile = proto->scenery.data.stairs.field_0;
|
||||
data->scenery.stairs.destinationMap = proto->scenery.data.stairs.field_4;
|
||||
break;
|
||||
case SCENERY_TYPE_ELEVATOR:
|
||||
data->scenery.elevator.field_0 = proto->scenery.data.elevator.field_0;
|
||||
data->scenery.elevator.field_4 = proto->scenery.data.elevator.field_4;
|
||||
data->scenery.elevator.type = proto->scenery.data.elevator.type;
|
||||
data->scenery.elevator.level = proto->scenery.data.elevator.level;
|
||||
break;
|
||||
case SCENERY_TYPE_LADDER_UP:
|
||||
case SCENERY_TYPE_LADDER_DOWN:
|
||||
data->scenery.ladder.field_0 = proto->scenery.data.ladder.field_0;
|
||||
data->scenery.ladder.destinationMap = proto->scenery.data.ladder.field_0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -698,7 +705,7 @@ int _proto_update_init(Object* obj)
|
||||
obj->field_2C_array[i] = 0;
|
||||
}
|
||||
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
return _proto_update_gen(obj);
|
||||
}
|
||||
|
||||
@@ -749,11 +756,11 @@ int _proto_dude_update_gender()
|
||||
v1 = (gDude->fid & 0xF000) >> 12;
|
||||
}
|
||||
|
||||
int fid = buildFid(1, _art_vault_guy_num, 0, v1, 0);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, _art_vault_guy_num, 0, v1, 0);
|
||||
objectSetFid(gDude, fid, NULL);
|
||||
}
|
||||
|
||||
proto->fid = buildFid(1, _art_vault_guy_num, 0, 0, 0);
|
||||
proto->fid = buildFid(OBJ_TYPE_CRITTER, _art_vault_guy_num, 0, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -762,7 +769,7 @@ int _proto_dude_update_gender()
|
||||
// 0x49FA64
|
||||
int _proto_dude_init(const char* path)
|
||||
{
|
||||
gDudeProto.fid = buildFid(1, _art_vault_guy_num, 0, 0, 0);
|
||||
gDudeProto.fid = buildFid(OBJ_TYPE_CRITTER, _art_vault_guy_num, 0, 0, 0);
|
||||
|
||||
if (_init_true) {
|
||||
_obj_inven_free(&(gDude->data.inventory));
|
||||
@@ -822,7 +829,7 @@ int protoGetDataMember(int pid, int member, ProtoDataMemberValue* value)
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (pid >> 24) {
|
||||
switch (PID_TYPE(pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
switch (member) {
|
||||
case ITEM_DATA_MEMBER_PID:
|
||||
@@ -1076,7 +1083,7 @@ int protoInit()
|
||||
_proto_critter_init((Proto*)&gDudeProto, 0x1000000);
|
||||
|
||||
gDudeProto.pid = 0x1000000;
|
||||
gDudeProto.fid = buildFid(1, 1, 0, 0, 0);
|
||||
gDudeProto.fid = buildFid(OBJ_TYPE_CRITTER, 1, 0, 0, 0);
|
||||
|
||||
gDude->pid = 0x1000000;
|
||||
gDude->sid = 1;
|
||||
@@ -1188,7 +1195,7 @@ void protoReset()
|
||||
// TODO: Get rid of cast.
|
||||
_proto_critter_init((Proto*)&gDudeProto, 0x1000000);
|
||||
gDudeProto.pid = 0x1000000;
|
||||
gDudeProto.fid = buildFid(1, 1, 0, 0, 0);
|
||||
gDudeProto.fid = buildFid(OBJ_TYPE_CRITTER, 1, 0, 0, 0);
|
||||
|
||||
gDude->pid = 0x1000000;
|
||||
gDude->sid = -1;
|
||||
@@ -1233,9 +1240,7 @@ static int _proto_header_load()
|
||||
ptr->max_entries_num = 1;
|
||||
|
||||
char path[COMPAT_MAX_PATH];
|
||||
strcpy(path, _cd_path_base);
|
||||
strcat(path, _proto_path_base);
|
||||
strcat(path, artGetObjectTypeName(index));
|
||||
_proto_make_path(path, index << 24);
|
||||
strcat(path, "\\");
|
||||
strcat(path, artGetObjectTypeName(index));
|
||||
strcat(path, ".lst");
|
||||
@@ -1358,8 +1363,8 @@ static int protoSceneryDataRead(SceneryProtoData* scenery_data, int type, File*
|
||||
|
||||
return 0;
|
||||
case SCENERY_TYPE_ELEVATOR:
|
||||
if (fileReadInt32(stream, &(scenery_data->elevator.field_0)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(scenery_data->elevator.field_4)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(scenery_data->elevator.type)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(scenery_data->elevator.level)) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
case SCENERY_TYPE_LADDER_UP:
|
||||
@@ -1384,7 +1389,7 @@ static int protoRead(Proto* proto, File* stream)
|
||||
if (fileReadInt32(stream, &(proto->messageId)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(proto->fid)) == -1) return -1;
|
||||
|
||||
switch (proto->pid >> 24) {
|
||||
switch (PID_TYPE(proto->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
if (fileReadInt32(stream, &(proto->item.lightDistance)) == -1) return -1;
|
||||
if (_db_freadInt(stream, &(proto->item.lightIntensity)) == -1) return -1;
|
||||
@@ -1544,8 +1549,8 @@ static int protoSceneryDataWrite(SceneryProtoData* scenery_data, int type, File*
|
||||
|
||||
return 0;
|
||||
case SCENERY_TYPE_ELEVATOR:
|
||||
if (fileWriteInt32(stream, scenery_data->elevator.field_0) == -1) return -1;
|
||||
if (fileWriteInt32(stream, scenery_data->elevator.field_4) == -1) return -1;
|
||||
if (fileWriteInt32(stream, scenery_data->elevator.type) == -1) return -1;
|
||||
if (fileWriteInt32(stream, scenery_data->elevator.level) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
case SCENERY_TYPE_LADDER_UP:
|
||||
@@ -1569,7 +1574,7 @@ static int protoWrite(Proto* proto, File* stream)
|
||||
if (fileWriteInt32(stream, proto->messageId) == -1) return -1;
|
||||
if (fileWriteInt32(stream, proto->fid) == -1) return -1;
|
||||
|
||||
switch (proto->pid >> 24) {
|
||||
switch (PID_TYPE(proto->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
if (fileWriteInt32(stream, proto->item.lightDistance) == -1) return -1;
|
||||
if (_db_fwriteLong(stream, proto->item.lightIntensity) == -1) return -1;
|
||||
@@ -1645,13 +1650,7 @@ int _proto_save_pid(int pid)
|
||||
}
|
||||
|
||||
char path[260];
|
||||
strcpy(path, _cd_path_base);
|
||||
strcat(path, _proto_path_base);
|
||||
|
||||
if (pid != -1) {
|
||||
strcat(path, artGetObjectTypeName(pid >> 24));
|
||||
}
|
||||
|
||||
_proto_make_path(path, pid);
|
||||
strcat(path, "\\");
|
||||
|
||||
_proto_list_str(pid, path + strlen(path));
|
||||
@@ -1672,14 +1671,7 @@ int _proto_save_pid(int pid)
|
||||
static int _proto_load_pid(int pid, Proto** protoPtr)
|
||||
{
|
||||
char path[COMPAT_MAX_PATH];
|
||||
strcpy(path, _cd_path_base);
|
||||
|
||||
strcat(path, "proto\\");
|
||||
|
||||
if (pid != -1) {
|
||||
strcat(path, artGetObjectTypeName(pid >> 24));
|
||||
}
|
||||
|
||||
_proto_make_path(path, pid);
|
||||
strcat(path, "\\");
|
||||
|
||||
if (_proto_list_str(pid, path + strlen(path)) == -1) {
|
||||
@@ -1693,7 +1685,7 @@ static int _proto_load_pid(int pid, Proto** protoPtr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_proto_find_free_subnode(pid >> 24, protoPtr) == -1) {
|
||||
if (_proto_find_free_subnode(PID_TYPE(pid), protoPtr) == -1) {
|
||||
fileClose(stream);
|
||||
return -1;
|
||||
}
|
||||
@@ -1826,7 +1818,7 @@ int protoGetProto(int pid, Proto** protoPtr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ProtoList* protoList = &(_protoLists[pid >> 24]);
|
||||
ProtoList* protoList = &(_protoLists[PID_TYPE(pid)]);
|
||||
ProtoListExtent* protoListExtent = protoList->head;
|
||||
while (protoListExtent != NULL) {
|
||||
for (int index = 0; index < protoListExtent->length; index++) {
|
||||
@@ -1841,7 +1833,7 @@ int protoGetProto(int pid, Proto** protoPtr)
|
||||
|
||||
if (protoList->head != NULL && protoList->tail != NULL) {
|
||||
if (PROTO_LIST_EXTENT_SIZE * protoList->length - (PROTO_LIST_EXTENT_SIZE - protoList->tail->length) > PROTO_LIST_MAX_ENTRIES) {
|
||||
_proto_remove_some_list(pid >> 24);
|
||||
_proto_remove_some_list(PID_TYPE(pid));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@ extern char _cd_path_base[COMPAT_MAX_PATH];
|
||||
extern MessageList gProtoMessageList;
|
||||
extern char* _proto_none_str;
|
||||
|
||||
void _proto_make_path(char* path, int pid);
|
||||
int _proto_list_str(int pid, char* proto_path);
|
||||
bool _proto_action_can_use(int pid);
|
||||
bool _proto_action_can_use_on(int pid);
|
||||
|
||||
+65
-65
@@ -76,7 +76,7 @@ int _obj_new_sid(Object* object, int* sidPtr)
|
||||
}
|
||||
|
||||
int sid;
|
||||
int objectType = object->pid >> 24;
|
||||
int objectType = PID_TYPE(object->pid);
|
||||
if (objectType < OBJ_TYPE_TILE) {
|
||||
sid = proto->sid;
|
||||
} else if (objectType == OBJ_TYPE_TILE) {
|
||||
@@ -91,7 +91,7 @@ int _obj_new_sid(Object* object, int* sidPtr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int scriptType = sid >> 24;
|
||||
int scriptType = SID_TYPE(sid);
|
||||
if (scriptAdd(sidPtr, scriptType) == -1) {
|
||||
return -1;
|
||||
}
|
||||
@@ -108,7 +108,7 @@ int _obj_new_sid(Object* object, int* sidPtr)
|
||||
}
|
||||
|
||||
if (scriptType == SCRIPT_TYPE_SPATIAL) {
|
||||
script->sp.built_tile = object->tile | ((object->elevation << 29) & 0xE0000000);
|
||||
script->sp.built_tile = builtTileCreate(object->tile, object->elevation);
|
||||
script->sp.radius = 3;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ int _obj_new_sid_inst(Object* obj, int scriptType, int a3)
|
||||
|
||||
script->field_14 = a3;
|
||||
if (scriptType == SCRIPT_TYPE_SPATIAL) {
|
||||
script->sp.built_tile = ((obj->elevation << 29) & 0xE0000000) | obj->tile;
|
||||
script->sp.built_tile = builtTileCreate(obj->tile, obj->elevation);
|
||||
script->sp.radius = 3;
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ int _obj_new_sid_inst(Object* obj, int scriptType, int a3)
|
||||
|
||||
_scr_find_str_run_info(a3 & 0xFFFFFF, &(script->field_50), sid);
|
||||
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
obj->field_80 = script->field_14;
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ int _obj_look_at_func(Object* a1, Object* a2, void (*a3)(char* string))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (((a2->fid & 0xF000000) >> 24) == OBJ_TYPE_TILE) {
|
||||
if (FID_TYPE(a2->fid) == OBJ_TYPE_TILE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ int _obj_look_at_func(Object* a1, Object* a2, void (*a3)(char* string))
|
||||
if (!scriptOverrides) {
|
||||
MessageListItem messageListItem;
|
||||
|
||||
if ((a2->pid >> 24) == OBJ_TYPE_CRITTER && critterIsDead(a2)) {
|
||||
if (PID_TYPE(a2->pid) == OBJ_TYPE_CRITTER && critterIsDead(a2)) {
|
||||
messageListItem.num = 491 + randomBetween(0, 1);
|
||||
} else {
|
||||
messageListItem.num = 490;
|
||||
@@ -240,7 +240,7 @@ int _obj_examine_func(Object* critter, Object* target, void (*fn)(char* string))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((target->fid & 0xF000000) >> 24 == OBJ_TYPE_TILE) {
|
||||
if (FID_TYPE(target->fid) == OBJ_TYPE_TILE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -271,7 +271,7 @@ int _obj_examine_func(Object* critter, Object* target, void (*fn)(char* string))
|
||||
}
|
||||
fn(messageListItem.text);
|
||||
} else {
|
||||
if ((target->pid >> 24) != OBJ_TYPE_CRITTER || !critterIsDead(target)) {
|
||||
if (PID_TYPE(target->pid) != OBJ_TYPE_CRITTER || !critterIsDead(target)) {
|
||||
fn(description);
|
||||
}
|
||||
}
|
||||
@@ -283,7 +283,7 @@ int _obj_examine_func(Object* critter, Object* target, void (*fn)(char* string))
|
||||
|
||||
char formattedText[260];
|
||||
|
||||
int type = target->pid >> 24;
|
||||
int type = PID_TYPE(target->pid);
|
||||
if (type == OBJ_TYPE_CRITTER) {
|
||||
if (target != gDude && perkGetRank(gDude, PERK_AWARENESS) && !critterIsDead(target)) {
|
||||
MessageListItem hpMessageListItem;
|
||||
@@ -597,7 +597,7 @@ static int _obj_remove_from_inven(Object* critter, Object* item)
|
||||
int v11 = 0;
|
||||
if (critterGetItem2(critter) == item) {
|
||||
if (critter != gDude || interfaceGetCurrentHand()) {
|
||||
fid = buildFid(1, critter->fid & 0xFFF, (critter->fid & 0xFF0000) >> 16, 0, critter->rotation);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, FID_ANIM_TYPE(critter->fid), 0, critter->rotation);
|
||||
objectSetFid(critter, fid, &updatedRect);
|
||||
v11 = 2;
|
||||
} else {
|
||||
@@ -605,7 +605,7 @@ static int _obj_remove_from_inven(Object* critter, Object* item)
|
||||
}
|
||||
} else if (critterGetItem1(critter) == item) {
|
||||
if (critter == gDude && !interfaceGetCurrentHand()) {
|
||||
fid = buildFid(1, critter->fid & 0xFFF, (critter->fid & 0xFF0000) >> 16, 0, critter->rotation);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, FID_ANIM_TYPE(critter->fid), 0, critter->rotation);
|
||||
objectSetFid(critter, fid, &updatedRect);
|
||||
v11 = 2;
|
||||
} else {
|
||||
@@ -620,7 +620,7 @@ static int _obj_remove_from_inven(Object* critter, Object* item)
|
||||
v5 = proto->fid;
|
||||
}
|
||||
|
||||
fid = buildFid(1, v5, (critter->fid & 0xFF0000) >> 16, (critter->fid & 0xF000) >> 12, critter->rotation);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, v5, FID_ANIM_TYPE(critter->fid), (critter->fid & 0xF000) >> 12, critter->rotation);
|
||||
objectSetFid(critter, fid, &updatedRect);
|
||||
v11 = 3;
|
||||
}
|
||||
@@ -1165,7 +1165,7 @@ static int _protinst_default_use_item(Object* a1, Object* a2, Object* item)
|
||||
int rc;
|
||||
switch (itemGetType(item)) {
|
||||
case ITEM_TYPE_DRUG:
|
||||
if ((a2->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(a2->pid) != OBJ_TYPE_CRITTER) {
|
||||
if (a1 == gDude) {
|
||||
// That does nothing
|
||||
messageListItem.num = 582;
|
||||
@@ -1422,7 +1422,7 @@ int _check_scenery_ap_cost(Object* obj, Object* a2)
|
||||
// 0x49C740
|
||||
int _obj_use(Object* a1, Object* a2)
|
||||
{
|
||||
int type = (a2->fid & 0xF000000) >> 24;
|
||||
int type = FID_TYPE(a2->fid);
|
||||
if (a1 == gDude) {
|
||||
if (type != OBJ_TYPE_SCENERY) {
|
||||
return -1;
|
||||
@@ -1438,7 +1438,7 @@ int _obj_use(Object* a1, Object* a2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((a2->pid >> 24) == OBJ_TYPE_SCENERY && sceneryProto->scenery.type == SCENERY_TYPE_DOOR) {
|
||||
if (PID_TYPE(a2->pid) == OBJ_TYPE_SCENERY && sceneryProto->scenery.type == SCENERY_TYPE_DOOR) {
|
||||
return _obj_use_door(a1, a2, 0);
|
||||
}
|
||||
|
||||
@@ -1457,7 +1457,7 @@ int _obj_use(Object* a1, Object* a2)
|
||||
}
|
||||
|
||||
if (!scriptOverrides) {
|
||||
if ((a2->pid >> 24) == OBJ_TYPE_SCENERY) {
|
||||
if (PID_TYPE(a2->pid) == OBJ_TYPE_SCENERY) {
|
||||
if (sceneryProto->scenery.type == SCENERY_TYPE_LADDER_DOWN) {
|
||||
if (useLadderDown(a1, a2, 0) == 0) {
|
||||
scriptOverrides = true;
|
||||
@@ -1498,21 +1498,21 @@ int _obj_use(Object* a1, Object* a2)
|
||||
// 0x49C900
|
||||
static int useLadderDown(Object* a1, Object* ladder, int a3)
|
||||
{
|
||||
int builtTile = ladder->data.scenery.ladder.field_4;
|
||||
int builtTile = ladder->data.scenery.ladder.destinationBuiltTile;
|
||||
if (builtTile == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tile = builtTile & 0x3FFFFFF;
|
||||
int elevation = (builtTile & 0xE0000000) >> 29;
|
||||
if (ladder->data.scenery.ladder.field_0 != 0) {
|
||||
int tile = builtTileGetTile(builtTile);
|
||||
int elevation = builtTileGetElevation(builtTile);
|
||||
if (ladder->data.scenery.ladder.destinationMap != 0) {
|
||||
MapTransition transition;
|
||||
memset(&transition, 0, sizeof(transition));
|
||||
|
||||
transition.map = ladder->data.scenery.ladder.field_0;
|
||||
transition.map = ladder->data.scenery.ladder.destinationMap;
|
||||
transition.elevation = elevation;
|
||||
transition.tile = tile;
|
||||
transition.rotation = (builtTile & 0x1C000000) >> 26;
|
||||
transition.rotation = builtTileGetRotation(builtTile);
|
||||
|
||||
mapSetTransition(&transition);
|
||||
|
||||
@@ -1532,21 +1532,21 @@ static int useLadderDown(Object* a1, Object* ladder, int a3)
|
||||
// 0x49C9A4
|
||||
static int useLadderUp(Object* a1, Object* ladder, int a3)
|
||||
{
|
||||
int builtTile = ladder->data.scenery.ladder.field_4;
|
||||
int builtTile = ladder->data.scenery.ladder.destinationBuiltTile;
|
||||
if (builtTile == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tile = builtTile & 0x3FFFFFF;
|
||||
int elevation = (builtTile & 0xE0000000) >> 29;
|
||||
if (ladder->data.scenery.ladder.field_0 != 0) {
|
||||
int tile = builtTileGetTile(builtTile);
|
||||
int elevation = builtTileGetElevation(builtTile);
|
||||
if (ladder->data.scenery.ladder.destinationMap != 0) {
|
||||
MapTransition transition;
|
||||
memset(&transition, 0, sizeof(transition));
|
||||
|
||||
transition.map = ladder->data.scenery.ladder.field_0;
|
||||
transition.map = ladder->data.scenery.ladder.destinationMap;
|
||||
transition.elevation = elevation;
|
||||
transition.tile = tile;
|
||||
transition.rotation = (builtTile & 0x1C000000) >> 26;
|
||||
transition.rotation = builtTileGetRotation(builtTile);
|
||||
|
||||
mapSetTransition(&transition);
|
||||
|
||||
@@ -1566,21 +1566,21 @@ static int useLadderUp(Object* a1, Object* ladder, int a3)
|
||||
// 0x49CA48
|
||||
static int useStairs(Object* a1, Object* stairs, int a3)
|
||||
{
|
||||
int builtTile = stairs->data.scenery.stairs.field_4;
|
||||
int builtTile = stairs->data.scenery.stairs.destinationBuiltTile;
|
||||
if (builtTile == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tile = builtTile & 0x3FFFFFF;
|
||||
int elevation = (builtTile & 0xE0000000) >> 29;
|
||||
if (stairs->data.scenery.stairs.field_0 > 0) {
|
||||
int tile = builtTileGetTile(builtTile);
|
||||
int elevation = builtTileGetElevation(builtTile);
|
||||
if (stairs->data.scenery.stairs.destinationMap > 0) {
|
||||
MapTransition transition;
|
||||
memset(&transition, 0, sizeof(transition));
|
||||
|
||||
transition.map = stairs->data.scenery.stairs.field_0;
|
||||
transition.map = stairs->data.scenery.stairs.destinationMap;
|
||||
transition.elevation = elevation;
|
||||
transition.tile = tile;
|
||||
transition.rotation = (builtTile & 0x1C000000) >> 26;
|
||||
transition.rotation = builtTileGetRotation(builtTile);
|
||||
|
||||
mapSetTransition(&transition);
|
||||
|
||||
@@ -1734,31 +1734,31 @@ int _obj_use_door(Object* a1, Object* a2, int a3)
|
||||
step = 1;
|
||||
}
|
||||
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
|
||||
for (int i = start; i != end; i += step) {
|
||||
if (i != 0) {
|
||||
if (a3 == 0) {
|
||||
reg_anim_11_0(a2, a2, _set_door_state_closed, -1);
|
||||
animationRegisterCallback(a2, a2, (AnimationCallback*)_set_door_state_closed, -1);
|
||||
}
|
||||
|
||||
const char* sfx = sfxBuildOpenName(a2, SCENERY_SOUND_EFFECT_CLOSED);
|
||||
reg_anim_play_sfx(a2, sfx, -1);
|
||||
animationRegisterPlaySoundEffect(a2, sfx, -1);
|
||||
|
||||
reg_anim_animate_reverse(a2, 0, 0);
|
||||
animationRegisterAnimateReversed(a2, ANIM_STAND, 0);
|
||||
} else {
|
||||
if (a3 == 0) {
|
||||
reg_anim_11_0(a2, a2, _set_door_state_open, -1);
|
||||
animationRegisterCallback(a2, a2, (AnimationCallback*)_set_door_state_open, -1);
|
||||
}
|
||||
|
||||
const char* sfx = sfxBuildOpenName(a2, SCENERY_SOUND_EFFECT_CLOSED);
|
||||
reg_anim_play_sfx(a2, sfx, -1);
|
||||
animationRegisterPlaySoundEffect(a2, sfx, -1);
|
||||
|
||||
reg_anim_animate(a2, 0, 0);
|
||||
animationRegisterAnimate(a2, ANIM_STAND, 0);
|
||||
}
|
||||
}
|
||||
|
||||
reg_anim_11_1(a2, a2, _check_door_state, -1);
|
||||
animationRegisterCallbackForced(a2, a2, (AnimationCallback*)_check_door_state, -1);
|
||||
|
||||
reg_anim_end();
|
||||
}
|
||||
@@ -1769,7 +1769,7 @@ int _obj_use_door(Object* a1, Object* a2, int a3)
|
||||
// 0x49CE7C
|
||||
int _obj_use_container(Object* critter, Object* item)
|
||||
{
|
||||
if (((item->fid & 0xF000000) >> 24) != OBJ_TYPE_ITEM) {
|
||||
if (FID_TYPE(item->fid) != OBJ_TYPE_ITEM) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1817,16 +1817,16 @@ int _obj_use_container(Object* critter, Object* item)
|
||||
return -1;
|
||||
}
|
||||
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
|
||||
if (item->frame == 0) {
|
||||
const char* sfx = sfxBuildOpenName(item, SCENERY_SOUND_EFFECT_OPEN);
|
||||
reg_anim_play_sfx(item, sfx, 0);
|
||||
reg_anim_animate(item, 0, 0);
|
||||
animationRegisterPlaySoundEffect(item, sfx, 0);
|
||||
animationRegisterAnimate(item, ANIM_STAND, 0);
|
||||
} else {
|
||||
const char* sfx = sfxBuildOpenName(item, SCENERY_SOUND_EFFECT_CLOSED);
|
||||
reg_anim_play_sfx(item, sfx, 0);
|
||||
reg_anim_animate_reverse(item, 0, 0);
|
||||
animationRegisterPlaySoundEffect(item, sfx, 0);
|
||||
animationRegisterAnimateReversed(item, ANIM_STAND, 0);
|
||||
}
|
||||
|
||||
reg_anim_end();
|
||||
@@ -1902,7 +1902,7 @@ static bool _obj_is_lockable(Object* obj)
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
if (proto->item.type == ITEM_TYPE_CONTAINER) {
|
||||
return true;
|
||||
@@ -1926,7 +1926,7 @@ bool objectIsLocked(Object* obj)
|
||||
}
|
||||
|
||||
ObjectData* data = &(obj->data);
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
return data->flags & CONTAINER_FLAG_LOCKED;
|
||||
case OBJ_TYPE_SCENERY:
|
||||
@@ -1943,7 +1943,7 @@ int objectLock(Object* object)
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (object->pid >> 24) {
|
||||
switch (PID_TYPE(object->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
object->data.flags |= OBJ_LOCKED;
|
||||
break;
|
||||
@@ -1964,7 +1964,7 @@ int objectUnlock(Object* object)
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (object->pid >> 24) {
|
||||
switch (PID_TYPE(object->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
object->data.flags &= ~OBJ_LOCKED;
|
||||
return 0;
|
||||
@@ -1989,7 +1989,7 @@ static bool _obj_is_openable(Object* obj)
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
if (proto->item.type == ITEM_TYPE_CONTAINER) {
|
||||
return true;
|
||||
@@ -2028,24 +2028,24 @@ static int objectOpenClose(Object* obj)
|
||||
|
||||
objectUnjamLock(obj);
|
||||
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
|
||||
if (obj->frame != 0) {
|
||||
reg_anim_11_1(obj, obj, _set_door_state_closed, -1);
|
||||
animationRegisterCallbackForced(obj, obj, (AnimationCallback*)_set_door_state_closed, -1);
|
||||
|
||||
const char* sfx = sfxBuildOpenName(obj, SCENERY_SOUND_EFFECT_CLOSED);
|
||||
reg_anim_play_sfx(obj, sfx, -1);
|
||||
animationRegisterPlaySoundEffect(obj, sfx, -1);
|
||||
|
||||
reg_anim_animate_reverse(obj, 0, 0);
|
||||
animationRegisterAnimateReversed(obj, ANIM_STAND, 0);
|
||||
} else {
|
||||
reg_anim_11_1(obj, obj, _set_door_state_open, -1);
|
||||
animationRegisterCallbackForced(obj, obj, (AnimationCallback*)_set_door_state_open, -1);
|
||||
|
||||
const char* sfx = sfxBuildOpenName(obj, SCENERY_SOUND_EFFECT_OPEN);
|
||||
reg_anim_play_sfx(obj, sfx, -1);
|
||||
reg_anim_animate(obj, 0, 0);
|
||||
animationRegisterPlaySoundEffect(obj, sfx, -1);
|
||||
animationRegisterAnimate(obj, ANIM_STAND, 0);
|
||||
}
|
||||
|
||||
reg_anim_11_1(obj, obj, _check_door_state, -1);
|
||||
animationRegisterCallbackForced(obj, obj, (AnimationCallback*)_check_door_state, -1);
|
||||
|
||||
reg_anim_end();
|
||||
|
||||
@@ -2079,7 +2079,7 @@ static bool objectIsJammed(Object* obj)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_SCENERY) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_SCENERY) {
|
||||
if ((obj->data.scenery.door.openFlags & OBJ_JAMMED) != 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -2101,7 +2101,7 @@ int objectJamLock(Object* obj)
|
||||
}
|
||||
|
||||
ObjectData* data = &(obj->data);
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
data->flags |= CONTAINER_FLAG_JAMMED;
|
||||
break;
|
||||
@@ -2121,7 +2121,7 @@ int objectUnjamLock(Object* obj)
|
||||
}
|
||||
|
||||
ObjectData* data = &(obj->data);
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
data->flags &= ~CONTAINER_FLAG_JAMMED;
|
||||
break;
|
||||
|
||||
+2
-2
@@ -362,8 +362,8 @@ typedef struct {
|
||||
} SceneryProtoStairsData;
|
||||
|
||||
typedef struct {
|
||||
int field_0; // d.lower_tile
|
||||
int field_4; // d.upper_tile
|
||||
int type;
|
||||
int level;
|
||||
} SceneryProtoElevatorData;
|
||||
|
||||
typedef struct {
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ typedef struct WithdrawalEvent {
|
||||
|
||||
typedef struct ScriptEvent {
|
||||
int sid;
|
||||
int field_4;
|
||||
int fixedParam;
|
||||
} ScriptEvent;
|
||||
|
||||
typedef struct RadiationEvent {
|
||||
|
||||
+91
-15
@@ -44,6 +44,82 @@ void _regionSetBound(Region* region)
|
||||
}
|
||||
}
|
||||
|
||||
// 0x4A2C14
|
||||
bool regionContainsPoint(Region* region, int x, int y)
|
||||
{
|
||||
if (region == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (x < region->field_24 || x > region->field_2C || y < region->field_28 || y > region->field_30) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int v1;
|
||||
|
||||
Point* prev = &(region->points[0]);
|
||||
if (x >= prev->x) {
|
||||
if (y >= prev->y) {
|
||||
v1 = 2;
|
||||
} else {
|
||||
v1 = 1;
|
||||
}
|
||||
} else {
|
||||
if (y >= prev->y) {
|
||||
v1 = 3;
|
||||
} else {
|
||||
v1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int v4 = 0;
|
||||
for (int index = 0; index < region->pointsLength; index++) {
|
||||
int v2;
|
||||
|
||||
Point* point = &(region->points[index + 1]);
|
||||
if (x >= point->x) {
|
||||
if (y >= point->y) {
|
||||
v2 = 2;
|
||||
} else {
|
||||
v2 = 1;
|
||||
}
|
||||
} else {
|
||||
if (y >= point->y) {
|
||||
v2 = 3;
|
||||
} else {
|
||||
v2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int v3 = v2 - v1;
|
||||
switch (v3) {
|
||||
case -3:
|
||||
v3 = 1;
|
||||
break;
|
||||
case -2:
|
||||
case 2:
|
||||
if ((double)x < ((double)point->x - (double)(prev->x - point->x) / (double)(prev->y - point->y) * (double)(point->y - y))) {
|
||||
v3 = -v3;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
v3 = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
prev = point;
|
||||
v1 = v2;
|
||||
|
||||
v4 += v3;
|
||||
}
|
||||
|
||||
if (v4 == 4 || v4 == -4) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 0x4A2D78
|
||||
Region* regionCreate(int initialCapacity)
|
||||
{
|
||||
@@ -62,24 +138,24 @@ Region* regionCreate(int initialCapacity)
|
||||
region->field_74 = 0;
|
||||
region->field_28 = INT_MIN;
|
||||
region->field_30 = INT_MAX;
|
||||
region->field_54 = 0;
|
||||
region->field_5C = 0;
|
||||
region->field_64 = 0;
|
||||
region->procs[3] = 0;
|
||||
region->rightProcs[1] = 0;
|
||||
region->rightProcs[3] = 0;
|
||||
region->field_68 = 0;
|
||||
region->field_6C = 0;
|
||||
region->rightProcs[0] = 0;
|
||||
region->field_70 = 0;
|
||||
region->field_60 = 0;
|
||||
region->field_78 = 0;
|
||||
region->field_7C = 0;
|
||||
region->field_80 = 0;
|
||||
region->field_84 = 0;
|
||||
region->rightProcs[2] = 0;
|
||||
region->mouseEventCallback = NULL;
|
||||
region->rightMouseEventCallback = NULL;
|
||||
region->mouseEventCallbackUserData = 0;
|
||||
region->rightMouseEventCallbackUserData = 0;
|
||||
region->pointsLength = 0;
|
||||
region->field_24 = 0;
|
||||
region->field_2C = 0;
|
||||
region->field_50 = 0;
|
||||
region->field_4C = 0;
|
||||
region->field_48 = 0;
|
||||
region->field_58 = 0;
|
||||
region->field_24 = region->field_28;
|
||||
region->field_2C = region->field_30;
|
||||
region->procs[2] = 0;
|
||||
region->procs[1] = 0;
|
||||
region->procs[0] = 0;
|
||||
region->rightProcs[0] = 0;
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
+10
-12
@@ -6,6 +6,10 @@
|
||||
|
||||
#define REGION_NAME_LENGTH (32)
|
||||
|
||||
typedef struct Region Region;
|
||||
|
||||
typedef void RegionMouseEventCallback(Region* region, void* userData, int event);
|
||||
|
||||
typedef struct Region {
|
||||
char name[REGION_NAME_LENGTH];
|
||||
Point* points;
|
||||
@@ -18,22 +22,16 @@ typedef struct Region {
|
||||
int pointsLength;
|
||||
int pointsCapacity;
|
||||
Program* program;
|
||||
int field_48;
|
||||
int field_4C;
|
||||
int field_50;
|
||||
int field_54;
|
||||
int field_58;
|
||||
int field_5C;
|
||||
int field_60;
|
||||
int field_64;
|
||||
int procs[4];
|
||||
int rightProcs[4];
|
||||
int field_68;
|
||||
int field_6C;
|
||||
int field_70;
|
||||
int field_74;
|
||||
int field_78;
|
||||
int field_7C;
|
||||
int field_80;
|
||||
int field_84;
|
||||
RegionMouseEventCallback* mouseEventCallback;
|
||||
RegionMouseEventCallback* rightMouseEventCallback;
|
||||
void* mouseEventCallbackUserData;
|
||||
void* rightMouseEventCallbackUserData;
|
||||
void* userData;
|
||||
} Region;
|
||||
|
||||
|
||||
+39
-32
@@ -29,8 +29,8 @@
|
||||
#include "window_manager_private.h"
|
||||
#include "world_map.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
@@ -567,12 +567,12 @@ Object* scriptGetSelf(Program* program)
|
||||
return script->owner;
|
||||
}
|
||||
|
||||
if ((sid >> 24) != SCRIPT_TYPE_SPATIAL) {
|
||||
if (SID_TYPE(sid) != SCRIPT_TYPE_SPATIAL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Object* object;
|
||||
int fid = buildFid(6, 3, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 3, 0, 0, 0);
|
||||
objectCreateWithFidPid(&object, fid, -1);
|
||||
objectHide(object, NULL);
|
||||
_obj_toggle_flat(object, NULL);
|
||||
@@ -595,7 +595,7 @@ Object* scriptGetSelf(Program* program)
|
||||
Script* spatialScript = scriptGetFirstSpatialScript(elevation);
|
||||
while (spatialScript != NULL) {
|
||||
if (spatialScript == script) {
|
||||
objectSetLocation(object, script->sp.built_tile & 0x3FFFFFF, elevation, NULL);
|
||||
objectSetLocation(object, builtTileGetTile(script->sp.built_tile), elevation, NULL);
|
||||
return object;
|
||||
}
|
||||
spatialScript = scriptGetNextSpatialScript();
|
||||
@@ -780,7 +780,7 @@ void _scrSetQueueTestVals(Object* a1, int a2)
|
||||
int _scrQueueRemoveFixed(Object* obj, void* data)
|
||||
{
|
||||
ScriptEvent* scriptEvent = (ScriptEvent*)data;
|
||||
return obj == _scrQueueTestObj && scriptEvent->field_4 == _scrQueueTestValue;
|
||||
return obj == _scrQueueTestObj && scriptEvent->fixedParam == _scrQueueTestValue;
|
||||
}
|
||||
|
||||
// 0x4A3E60
|
||||
@@ -792,7 +792,7 @@ int scriptAddTimerEvent(int sid, int delay, int param)
|
||||
}
|
||||
|
||||
scriptEvent->sid = sid;
|
||||
scriptEvent->field_4 = param;
|
||||
scriptEvent->fixedParam = param;
|
||||
|
||||
Script* script;
|
||||
if (scriptGetScript(sid, &script) == -1) {
|
||||
@@ -814,7 +814,7 @@ int scriptEventWrite(File* stream, void* data)
|
||||
ScriptEvent* scriptEvent = (ScriptEvent*)data;
|
||||
|
||||
if (fileWriteInt32(stream, scriptEvent->sid) == -1) return -1;
|
||||
if (fileWriteInt32(stream, scriptEvent->field_4) == -1) return -1;
|
||||
if (fileWriteInt32(stream, scriptEvent->fixedParam) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -828,7 +828,7 @@ int scriptEventRead(File* stream, void** dataPtr)
|
||||
}
|
||||
|
||||
if (fileReadInt32(stream, &(scriptEvent->sid)) == -1) goto err;
|
||||
if (fileReadInt32(stream, &(scriptEvent->field_4)) == -1) goto err;
|
||||
if (fileReadInt32(stream, &(scriptEvent->fixedParam)) == -1) goto err;
|
||||
|
||||
*dataPtr = scriptEvent;
|
||||
|
||||
@@ -852,7 +852,7 @@ int scriptEventProcess(Object* obj, void* data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
script->fixedParam = scriptEvent->field_4;
|
||||
script->fixedParam = scriptEvent->fixedParam;
|
||||
|
||||
scriptExecProc(scriptEvent->sid, SCRIPT_PROC_TIMED);
|
||||
|
||||
@@ -929,7 +929,7 @@ int scriptsHandleRequests()
|
||||
Object* elevatorDoors = objectFindFirstAtElevation(gDude->elevation);
|
||||
while (elevatorDoors != NULL) {
|
||||
int pid = elevatorDoors->pid;
|
||||
if ((pid >> 24) == OBJ_TYPE_SCENERY
|
||||
if (PID_TYPE(pid) == OBJ_TYPE_SCENERY
|
||||
&& (pid == PROTO_ID_0x2000099 || pid == PROTO_ID_0x20001A5 || pid == PROTO_ID_0x20001D6)
|
||||
&& tileDistanceBetween(elevatorDoors->tile, gDude->tile) <= 4) {
|
||||
break;
|
||||
@@ -955,7 +955,7 @@ int scriptsHandleRequests()
|
||||
Object* elevatorDoors = objectFindFirstAtElevation(gDude->elevation);
|
||||
while (elevatorDoors != NULL) {
|
||||
int pid = elevatorDoors->pid;
|
||||
if ((pid >> 24) == OBJ_TYPE_SCENERY
|
||||
if (PID_TYPE(pid) == OBJ_TYPE_SCENERY
|
||||
&& (pid == PROTO_ID_0x2000099 || pid == PROTO_ID_0x20001A5 || pid == PROTO_ID_0x20001D6)
|
||||
&& tileDistanceBetween(elevatorDoors->tile, gDude->tile) <= 4) {
|
||||
break;
|
||||
@@ -1035,7 +1035,7 @@ int _scripts_check_state_in_combat()
|
||||
Object* elevatorDoors = objectFindFirstAtElevation(gDude->elevation);
|
||||
while (elevatorDoors != NULL) {
|
||||
int pid = elevatorDoors->pid;
|
||||
if ((pid >> 24) == OBJ_TYPE_SCENERY
|
||||
if (PID_TYPE(pid) == OBJ_TYPE_SCENERY
|
||||
&& (pid == PROTO_ID_0x2000099 || pid == PROTO_ID_0x20001A5 || pid == PROTO_ID_0x20001D6)
|
||||
&& tileDistanceBetween(elevatorDoors->tile, gDude->tile) <= 4) {
|
||||
break;
|
||||
@@ -1137,8 +1137,8 @@ int scriptsRequestElevator(Object* a1, int a2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: What the hell is this?
|
||||
tile -= 1005;
|
||||
// In the following code we are looking for an elevator. 5 tiles in each direction
|
||||
tile = tile - (HEX_GRID_WIDTH * 5) - 5; // left upper corner
|
||||
|
||||
Object* obj;
|
||||
for (int y = -5; y < 5; y++) {
|
||||
@@ -1163,12 +1163,12 @@ int scriptsRequestElevator(Object* a1, int a2)
|
||||
break;
|
||||
}
|
||||
|
||||
tile += 190;
|
||||
tile += HEX_GRID_WIDTH - 10;
|
||||
}
|
||||
|
||||
if (obj != NULL) {
|
||||
elevatorType = obj->data.scenery.elevator.field_0;
|
||||
elevatorLevel = obj->data.scenery.elevator.field_4;
|
||||
elevatorType = obj->data.scenery.elevator.type;
|
||||
elevatorLevel = obj->data.scenery.elevator.level;
|
||||
}
|
||||
|
||||
if (elevatorType == -1) {
|
||||
@@ -1224,6 +1224,13 @@ int scriptsRequestStealing(Object* a1, Object* a2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Inlined.
|
||||
void _script_make_path(char* path)
|
||||
{
|
||||
strcpy(path, _cd_path_base);
|
||||
strcat(path, gScriptsBasePath);
|
||||
}
|
||||
|
||||
// exec_script_proc
|
||||
// 0x4A4810
|
||||
int scriptExecProc(int sid, int proc)
|
||||
@@ -1341,7 +1348,8 @@ bool scriptHasProc(int sid, int proc)
|
||||
static int scriptsLoadScriptsList()
|
||||
{
|
||||
char path[COMPAT_MAX_PATH];
|
||||
sprintf(path, "%s%s", "scripts\\", "scripts.lst");
|
||||
_script_make_path(path);
|
||||
strcat(path, "scripts.lst");
|
||||
|
||||
File* stream = fileOpen(path, "rt");
|
||||
if (stream == NULL) {
|
||||
@@ -1716,8 +1724,7 @@ static int _scr_header_load()
|
||||
_num_script_indexes = 0;
|
||||
|
||||
char path[COMPAT_MAX_PATH];
|
||||
strcpy(path, _cd_path_base);
|
||||
strcat(path, gScriptsBasePath);
|
||||
_script_make_path(path);
|
||||
strcat(path, "scripts.lst");
|
||||
|
||||
File* stream = fileOpen(path, "rt");
|
||||
@@ -1757,7 +1764,7 @@ static int scriptWrite(Script* scr, File* stream)
|
||||
if (fileWriteInt32(stream, scr->sid) == -1) return -1;
|
||||
if (fileWriteInt32(stream, scr->field_4) == -1) return -1;
|
||||
|
||||
switch (scr->sid >> 24) {
|
||||
switch (SID_TYPE(scr->sid)) {
|
||||
case SCRIPT_TYPE_SPATIAL:
|
||||
if (fileWriteInt32(stream, scr->sp.built_tile) == -1) return -1;
|
||||
if (fileWriteInt32(stream, scr->sp.radius) == -1) return -1;
|
||||
@@ -1911,7 +1918,7 @@ static int scriptRead(Script* scr, File* stream)
|
||||
if (fileReadInt32(stream, &(scr->sid)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(scr->field_4)) == -1) return -1;
|
||||
|
||||
switch (scr->sid >> 24) {
|
||||
switch (SID_TYPE(scr->sid)) {
|
||||
case SCRIPT_TYPE_SPATIAL:
|
||||
if (fileReadInt32(stream, &(scr->sp.built_tile)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(scr->sp.radius)) == -1) return -1;
|
||||
@@ -2066,7 +2073,7 @@ int scriptGetScript(int sid, Script** scriptPtr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ScriptList* scriptList = &(gScriptLists[sid >> 24]);
|
||||
ScriptList* scriptList = &(gScriptLists[SID_TYPE(sid)]);
|
||||
ScriptListExtent* scriptListExtent = scriptList->head;
|
||||
|
||||
while (scriptListExtent != NULL) {
|
||||
@@ -2221,7 +2228,7 @@ int scriptRemove(int sid)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ScriptList* scriptList = &(gScriptLists[sid >> 24]);
|
||||
ScriptList* scriptList = &(gScriptLists[SID_TYPE(sid)]);
|
||||
|
||||
ScriptListExtent* scriptListExtent = scriptList->head;
|
||||
int index;
|
||||
@@ -2399,7 +2406,7 @@ static Script* scriptGetFirstSpatialScript(int elevation)
|
||||
}
|
||||
|
||||
Script* script = &(gScriptsEnumerationScriptListExtent->scripts[0]);
|
||||
if ((script->flags & SCRIPT_FLAG_0x02) != 0 || ((script->sp.built_tile & 0xE0000000) >> 29) != elevation) {
|
||||
if ((script->flags & SCRIPT_FLAG_0x02) != 0 || builtTileGetElevation(script->sp.built_tile) != elevation) {
|
||||
script = scriptGetNextSpatialScript();
|
||||
}
|
||||
|
||||
@@ -2431,7 +2438,7 @@ static Script* scriptGetNextSpatialScript()
|
||||
}
|
||||
|
||||
Script* script = &(scriptListExtent->scripts[scriptIndex]);
|
||||
if ((script->flags & SCRIPT_FLAG_0x02) == 0 && ((script->sp.built_tile & 0xE0000000) >> 29) == gScriptsEnumerationElevation) {
|
||||
if ((script->flags & SCRIPT_FLAG_0x02) == 0 && builtTileGetElevation(script->sp.built_tile) == gScriptsEnumerationElevation) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2486,7 +2493,7 @@ bool scriptsExecSpatialProc(Object* object, int tile, int elevation)
|
||||
|
||||
_scr_SpatialsEnabled = false;
|
||||
|
||||
int builtTile = ((elevation << 29) & 0xE0000000) | tile;
|
||||
int builtTile = builtTileCreate(tile, elevation);
|
||||
|
||||
for (Script* script = scriptGetFirstSpatialScript(elevation); script != NULL; script = scriptGetNextSpatialScript()) {
|
||||
if (builtTile == script->sp.built_tile) {
|
||||
@@ -2497,7 +2504,7 @@ bool scriptsExecSpatialProc(Object* object, int tile, int elevation)
|
||||
continue;
|
||||
}
|
||||
|
||||
int distance = tileDistanceBetween(script->sp.built_tile & 0x3FFFFFF, tile);
|
||||
int distance = tileDistanceBetween(builtTileGetTile(script->sp.built_tile), tile);
|
||||
if (distance > script->sp.radius) {
|
||||
continue;
|
||||
}
|
||||
@@ -2686,7 +2693,7 @@ char* _scr_get_msg_str_speech(int messageListId, int messageId, int a3)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (((gGameDialogHeadFid & 0xF000000) >> 24) != 8) {
|
||||
if (FID_TYPE(gGameDialogHeadFid) != OBJ_TYPE_HEAD) {
|
||||
a3 = 0;
|
||||
}
|
||||
|
||||
@@ -2717,7 +2724,7 @@ char* _scr_get_msg_str_speech(int messageListId, int messageId, int a3)
|
||||
// 0x4A6D64
|
||||
int scriptGetLocalVar(int sid, int variable, int* value)
|
||||
{
|
||||
if (sid >> 24 == SCRIPT_TYPE_SYSTEM) {
|
||||
if (SID_TYPE(sid) == SCRIPT_TYPE_SYSTEM) {
|
||||
debugPrint("\nError! System scripts/Map scripts not allowed local_vars! ");
|
||||
|
||||
_tempStr1[0] = '\0';
|
||||
@@ -2859,8 +2866,8 @@ int _scr_explode_scenery(Object* a1, int tile, int radius, int elevation)
|
||||
}
|
||||
|
||||
if (script->procs[SCRIPT_PROC_DAMAGE] > 0
|
||||
&& (script->sp.built_tile & 0xE0000000) >> 29 == elevation
|
||||
&& tileDistanceBetween(script->sp.built_tile & 0x3FFFFFF, tile) <= radius) {
|
||||
&& builtTileGetElevation(script->sp.built_tile) == elevation
|
||||
&& tileDistanceBetween(builtTileGetTile(script->sp.built_tile), tile) <= radius) {
|
||||
scriptIds[scriptsCount] = script->sid;
|
||||
scriptsCount += 1;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
#define SCRIPT_FLAG_0x08 (0x08)
|
||||
#define SCRIPT_FLAG_0x10 (0x10)
|
||||
|
||||
// 60 * 60 * 10
|
||||
#define GAME_TIME_TICKS_PER_HOUR 36000
|
||||
|
||||
// 24 * 60 * 60 * 10
|
||||
#define GAME_TIME_TICKS_PER_DAY (864000)
|
||||
|
||||
@@ -175,6 +178,7 @@ void scriptsRequestDialog(Object* a1);
|
||||
void scriptsRequestEndgame();
|
||||
int scriptsRequestLooting(Object* a1, Object* a2);
|
||||
int scriptsRequestStealing(Object* a1, Object* a2);
|
||||
void _script_make_path(char* path);
|
||||
int scriptExecProc(int sid, int proc);
|
||||
bool scriptHasProc(int sid, int proc);
|
||||
int _scr_find_str_run_info(int a1, int* a2, int sid);
|
||||
|
||||
+197
-5
@@ -1,15 +1,18 @@
|
||||
#include "selfrun.h"
|
||||
|
||||
#include "core.h"
|
||||
#include "db.h"
|
||||
#include "game.h"
|
||||
#include "game_config.h"
|
||||
#include "platform_compat.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// 0x51C8D8
|
||||
int _selfrun_state = 0;
|
||||
int gSelfrunState = SELFRUN_STATE_TURNED_OFF;
|
||||
|
||||
// 0x4A8BE0
|
||||
int _selfrun_get_list(char*** fileListPtr, int* fileListLengthPtr)
|
||||
int selfrunInitFileList(char*** fileListPtr, int* fileListLengthPtr)
|
||||
{
|
||||
if (fileListPtr == NULL) {
|
||||
return -1;
|
||||
@@ -25,7 +28,7 @@ int _selfrun_get_list(char*** fileListPtr, int* fileListLengthPtr)
|
||||
}
|
||||
|
||||
// 0x4A8C10
|
||||
int _selfrun_free_list(char*** fileListPtr)
|
||||
int selfrunFreeFileList(char*** fileListPtr)
|
||||
{
|
||||
if (fileListPtr == NULL) {
|
||||
return -1;
|
||||
@@ -36,9 +39,198 @@ int _selfrun_free_list(char*** fileListPtr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x4A8C28
|
||||
int selfrunPreparePlayback(const char* fileName, SelfrunData* selfrunData)
|
||||
{
|
||||
if (fileName == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (selfrunData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (vcrGetState() != VCR_STATE_TURNED_OFF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (gSelfrunState != SELFRUN_STATE_TURNED_OFF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char path[COMPAT_MAX_PATH];
|
||||
sprintf(path, "%s%s", "selfrun\\", fileName);
|
||||
|
||||
if (selfrunReadData(path, selfrunData) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
gSelfrunState = SELFRUN_STATE_PLAYING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x4A8C88
|
||||
void selfrunPlaybackLoop(SelfrunData* selfrunData)
|
||||
{
|
||||
if (gSelfrunState == SELFRUN_STATE_PLAYING) {
|
||||
char path[COMPAT_MAX_PATH];
|
||||
sprintf(path, "%s%s", "selfrun\\", selfrunData->recordingFileName);
|
||||
|
||||
if (vcrPlay(path, VCR_TERMINATE_ON_KEY_PRESS | VCR_TERMINATE_ON_MOUSE_PRESS, selfrunPlaybackCompleted)) {
|
||||
bool cursorWasHidden = cursorIsHidden();
|
||||
if (cursorWasHidden) {
|
||||
mouseShowCursor();
|
||||
}
|
||||
|
||||
while (gSelfrunState == SELFRUN_STATE_PLAYING) {
|
||||
int keyCode = _get_input();
|
||||
if (keyCode != selfrunData->stopKeyCode) {
|
||||
gameHandleKey(keyCode, false);
|
||||
}
|
||||
}
|
||||
|
||||
while (mouseGetEvent() != 0) {
|
||||
_get_input();
|
||||
}
|
||||
|
||||
if (cursorWasHidden) {
|
||||
mouseHideCursor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0x4A8D28
|
||||
int selfrunPrepareRecording(const char* recordingName, const char* mapFileName, SelfrunData* selfrunData)
|
||||
{
|
||||
if (recordingName == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mapFileName == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (vcrGetState() != VCR_STATE_TURNED_OFF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (gSelfrunState != SELFRUN_STATE_TURNED_OFF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(selfrunData->recordingFileName, "%s%s", recordingName, ".vcr");
|
||||
strcpy(selfrunData->mapFileName, mapFileName);
|
||||
|
||||
selfrunData->stopKeyCode = KEY_CTRL_R;
|
||||
|
||||
char path[COMPAT_MAX_PATH];
|
||||
sprintf(path, "%s%s%s", "selfrun\\", recordingName, ".sdf");
|
||||
|
||||
if (selfrunWriteData(path, selfrunData) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
gSelfrunState = SELFRUN_STATE_RECORDING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x4A8DDC
|
||||
void selfrunRecordingLoop(SelfrunData* selfrunData)
|
||||
{
|
||||
if (gSelfrunState == SELFRUN_STATE_RECORDING) {
|
||||
char path[COMPAT_MAX_PATH];
|
||||
sprintf(path, "%s%s", "selfrun\\", selfrunData->recordingFileName);
|
||||
if (vcrRecord(path)) {
|
||||
if (!cursorIsHidden()) {
|
||||
mouseShowCursor();
|
||||
}
|
||||
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
int keyCode = _get_input();
|
||||
if (keyCode == selfrunData->stopKeyCode) {
|
||||
vcrStop();
|
||||
_game_user_wants_to_quit = 2;
|
||||
done = true;
|
||||
} else {
|
||||
gameHandleKey(keyCode, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
gSelfrunState = SELFRUN_STATE_TURNED_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
// 0x4A8E74
|
||||
void _selfrun_playback_callback()
|
||||
void selfrunPlaybackCompleted(int reason)
|
||||
{
|
||||
_game_user_wants_to_quit = 2;
|
||||
_selfrun_state = 0;
|
||||
gSelfrunState = SELFRUN_STATE_TURNED_OFF;
|
||||
}
|
||||
|
||||
// 0x4A8E8C
|
||||
int selfrunReadData(const char* path, SelfrunData* selfrunData)
|
||||
{
|
||||
if (path == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (selfrunData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
File* stream = fileOpen(path, "rb");
|
||||
if (stream == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rc = -1;
|
||||
if (fileReadFixedLengthString(stream, selfrunData->recordingFileName, SELFRUN_RECORDING_FILE_NAME_LENGTH) == 0
|
||||
&& fileReadFixedLengthString(stream, selfrunData->mapFileName, SELFRUN_MAP_FILE_NAME_LENGTH) == 0
|
||||
&& fileReadInt32(stream, &(selfrunData->stopKeyCode)) == 0) {
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// 0x4A8EF4
|
||||
int selfrunWriteData(const char* path, SelfrunData* selfrunData)
|
||||
{
|
||||
if (path == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (selfrunData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* masterPatches;
|
||||
configGetString(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_MASTER_PATCHES_KEY, &masterPatches);
|
||||
|
||||
char selfrunDirectoryPath[COMPAT_MAX_PATH];
|
||||
sprintf(selfrunDirectoryPath, "%s\\%s", masterPatches, "selfrun\\");
|
||||
|
||||
compat_mkdir(selfrunDirectoryPath);
|
||||
|
||||
File* stream = fileOpen(path, "wb");
|
||||
if (stream == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rc = -1;
|
||||
if (fileWriteFixedLengthString(stream, selfrunData->recordingFileName, SELFRUN_RECORDING_FILE_NAME_LENGTH) == 0
|
||||
&& fileWriteFixedLengthString(stream, selfrunData->mapFileName, SELFRUN_MAP_FILE_NAME_LENGTH) == 0
|
||||
&& fileWriteInt32(stream, selfrunData->stopKeyCode) == 0) {
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
+27
-4
@@ -1,10 +1,33 @@
|
||||
#ifndef SELFRUN_H
|
||||
#define SELFRUN_H
|
||||
|
||||
extern int _selfrun_state;
|
||||
#define SELFRUN_RECORDING_FILE_NAME_LENGTH 13
|
||||
#define SELFRUN_MAP_FILE_NAME_LENGTH 13
|
||||
|
||||
int _selfrun_get_list(char*** fileListPtr, int* fileListLengthPtr);
|
||||
int _selfrun_free_list(char*** fileListPtr);
|
||||
void _selfrun_playback_callback();
|
||||
typedef enum SelfrunState {
|
||||
SELFRUN_STATE_TURNED_OFF,
|
||||
SELFRUN_STATE_PLAYING,
|
||||
SELFRUN_STATE_RECORDING,
|
||||
} SelfrunState;
|
||||
|
||||
typedef struct SelfrunData {
|
||||
char recordingFileName[SELFRUN_RECORDING_FILE_NAME_LENGTH];
|
||||
char mapFileName[SELFRUN_MAP_FILE_NAME_LENGTH];
|
||||
int stopKeyCode;
|
||||
} SelfrunData;
|
||||
|
||||
static_assert(sizeof(SelfrunData) == 32, "wrong size");
|
||||
|
||||
extern int gSelfrunState;
|
||||
|
||||
int selfrunInitFileList(char*** fileListPtr, int* fileListLengthPtr);
|
||||
int selfrunFreeFileList(char*** fileListPtr);
|
||||
int selfrunPreparePlayback(const char* fileName, SelfrunData* selfrunData);
|
||||
void selfrunPlaybackLoop(SelfrunData* selfrunData);
|
||||
int selfrunPrepareRecording(const char* recordingName, const char* mapFileName, SelfrunData* selfrunData);
|
||||
void selfrunRecordingLoop(SelfrunData* selfrunData);
|
||||
void selfrunPlaybackCompleted(int reason);
|
||||
int selfrunReadData(const char* path, SelfrunData* selfrunData);
|
||||
int selfrunWriteData(const char* path, SelfrunData* selfrunData);
|
||||
|
||||
#endif /* SELFRUN_H */
|
||||
|
||||
+4
-4
@@ -1032,7 +1032,7 @@ int skillsPerformStealing(Object* a1, Object* a2, Object* item, bool isPlanting)
|
||||
// -4% per item size
|
||||
stealModifier -= 4 * itemGetSize(item);
|
||||
|
||||
if (((a2->fid & 0xF000000) >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(a2->fid) == OBJ_TYPE_CRITTER) {
|
||||
// check facing: -25% if face to face
|
||||
if (_is_hit_from_front(a1, a2)) {
|
||||
stealModifier -= 25;
|
||||
@@ -1064,7 +1064,7 @@ int skillsPerformStealing(Object* a1, Object* a2, Object* item, bool isPlanting)
|
||||
catchRoll = ROLL_SUCCESS;
|
||||
} else {
|
||||
int catchChance;
|
||||
if ((a2->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(a2->pid) == OBJ_TYPE_CRITTER) {
|
||||
catchChance = skillGetValue(a2, SKILL_STEAL) - stealModifier;
|
||||
} else {
|
||||
catchChance = 30 - stealModifier;
|
||||
@@ -1145,7 +1145,7 @@ static int skillGetFreeUsageSlot(int skill)
|
||||
}
|
||||
|
||||
int time = gameTimeGetTime();
|
||||
int hoursSinceLastUsage = (time - _timesSkillUsed[skill][SKILLS_MAX_USES_PER_DAY - 1]) / 36000;
|
||||
int hoursSinceLastUsage = (time - _timesSkillUsed[skill][0]) / GAME_TIME_TICKS_PER_HOUR;
|
||||
if (hoursSinceLastUsage <= 24) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1162,7 +1162,7 @@ int skillUpdateLastUse(int skill)
|
||||
}
|
||||
|
||||
if (_timesSkillUsed[skill][slot] != 0) {
|
||||
for (int i = 0; i < slot - 1; i++) {
|
||||
for (int i = 0; i < slot; i++) {
|
||||
_timesSkillUsed[skill][i] = _timesSkillUsed[skill][i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user