summaryrefslogtreecommitdiffstats
path: root/tools/statepropbuilder
diff options
context:
space:
mode:
authorSvxy <aidan61605@gmail.com>2023-05-31 23:31:32 +0200
committerSvxy <aidan61605@gmail.com>2023-05-31 23:31:32 +0200
commiteb4b3404aa00220d659e532151dab13d642c17a3 (patch)
tree7e1107c4995489a26c4007e41b53ea8d00ab2134 /tools/statepropbuilder
downloadThe-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.gz
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.bz2
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.lz
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.xz
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.zst
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.zip
Diffstat (limited to 'tools/statepropbuilder')
-rw-r--r--tools/statepropbuilder/apps/spbuilder/art/new.bmpbin0 -> 822 bytes
-rw-r--r--tools/statepropbuilder/apps/spbuilder/art/open.bmpbin0 -> 822 bytes
-rw-r--r--tools/statepropbuilder/apps/spbuilder/art/save.bmpbin0 -> 822 bytes
-rw-r--r--tools/statepropbuilder/apps/spbuilder/art/saveas.bmpbin0 -> 822 bytes
-rw-r--r--tools/statepropbuilder/apps/spbuilder/bin/data/Copy of events.txt16
-rw-r--r--tools/statepropbuilder/apps/spbuilder/bin/data/callbacks.txt18
-rw-r--r--tools/statepropbuilder/apps/spbuilder/bin/data/events.txt12
-rw-r--r--tools/statepropbuilder/apps/spbuilder/bin/data/init.txt0
-rw-r--r--tools/statepropbuilder/apps/spbuilder/bin/empty.txt0
-rw-r--r--tools/statepropbuilder/apps/spbuilder/bin/pddidx8d.dllbin0 -> 512083 bytes
-rw-r--r--tools/statepropbuilder/apps/spbuilder/bin/spbuilder.exebin0 -> 515584 bytes
-rw-r--r--tools/statepropbuilder/apps/spbuilder/bin/spengine.dllbin0 -> 8462428 bytes
-rw-r--r--tools/statepropbuilder/apps/spbuilder/build/spbuilder/spbuilder.bpr128
-rw-r--r--tools/statepropbuilder/apps/spbuilder/build/spengine/spengine.dsp179
-rw-r--r--tools/statepropbuilder/apps/spbuilder/build/spengine/spengine.dsw245
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/callbacksframe.cpp73
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/callbacksframe.dfm58
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/callbacksframe.h34
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/eventsframe.cpp75
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/eventsframe.dfm58
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/eventsframe.h34
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/fcframe.cpp136
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/fcframe.dfm120
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/fcframe.h44
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/main.cpp704
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/main.dfm783
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/main.h163
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/visframe.cpp24
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/visframe.dfm42
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/builder/visframe.h28
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/engine/aicollisionsolveragent.cpp59
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/engine/aicollisionsolveragent.hpp43
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/engine/context.cpp792
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/engine/context.hpp119
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/engine/dllmain.cpp43
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/engine/platform.cpp94
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/engine/stateprop.cpp445
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/engine/stateprop.hpp120
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/engine/statepropdata.cpp509
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/engine/statepropdata.hpp139
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/engine/statepropdatatypes.hpp45
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/engine/workspace.cpp879
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/engine/workspace.hpp67
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/interface/base.hpp25
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/interface/context.hpp50
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/interface/platform.hpp24
-rw-r--r--tools/statepropbuilder/apps/spbuilder/code/sp/interface/workspace.hpp89
-rw-r--r--tools/statepropbuilder/art/BombBlloon.p3dbin0 -> 36094 bytes
-rw-r--r--tools/statepropbuilder/art/BombBlloon_spdata.p3dbin0 -> 801 bytes
-rw-r--r--tools/statepropbuilder/art/Bouncy_Ape.p3dbin0 -> 137872 bytes
-rw-r--r--tools/statepropbuilder/art/Bouncy_Ape_spdata.p3dbin0 -> 3625 bytes
-rw-r--r--tools/statepropbuilder/art/air_pump_1.p3dbin0 -> 134645 bytes
-rw-r--r--tools/statepropbuilder/art/air_pump_1_collision.p3dbin0 -> 1599 bytes
-rw-r--r--tools/statepropbuilder/art/air_pump_1_spdata.p3dbin0 -> 979 bytes
-rw-r--r--tools/statepropbuilder/art/ball_rebounder.p3dbin0 -> 24272 bytes
-rw-r--r--tools/statepropbuilder/art/ball_rebounder_collision.p3dbin0 -> 4479 bytes
-rw-r--r--tools/statepropbuilder/art/ball_rebounder_spdata.p3dbin0 -> 426 bytes
-rw-r--r--tools/statepropbuilder/art/ball_target.p3dbin0 -> 46505 bytes
-rw-r--r--tools/statepropbuilder/art/ball_target_spdata.p3dbin0 -> 193 bytes
-rw-r--r--tools/statepropbuilder/art/barrel.p3dbin0 -> 35657 bytes
-rw-r--r--tools/statepropbuilder/art/barrel_collision.p3dbin0 -> 2423 bytes
-rw-r--r--tools/statepropbuilder/art/barrel_spdata.p3dbin0 -> 602 bytes
-rw-r--r--tools/statepropbuilder/art/big_gulp_of_pop.p3dbin0 -> 23801 bytes
-rw-r--r--tools/statepropbuilder/art/big_gulp_of_pop_spdata.p3dbin0 -> 626 bytes
-rw-r--r--tools/statepropbuilder/art/biker_chick_temp.p3dbin0 -> 205324 bytes
-rw-r--r--tools/statepropbuilder/art/biker_chick_temp_spdata.p3dbin0 -> 413 bytes
-rw-r--r--tools/statepropbuilder/art/box_of_chips.p3dbin0 -> 23128 bytes
-rw-r--r--tools/statepropbuilder/art/box_of_chips_spdata.p3dbin0 -> 610 bytes
-rw-r--r--tools/statepropbuilder/art/box_wooden.p3dbin0 -> 18592 bytes
-rw-r--r--tools/statepropbuilder/art/box_wooden_spdata.p3dbin0 -> 980 bytes
-rw-r--r--tools/statepropbuilder/art/cage_collision.p3dbin0 -> 10243 bytes
-rw-r--r--tools/statepropbuilder/art/cameraTrigger.p3dbin0 -> 974 bytes
-rw-r--r--tools/statepropbuilder/art/camera_test.p3dbin0 -> 7101 bytes
-rw-r--r--tools/statepropbuilder/art/camera_test_collision.p3dbin0 -> 1391 bytes
-rw-r--r--tools/statepropbuilder/art/camera_test_spdata.p3dbin0 -> 193 bytes
-rw-r--r--tools/statepropbuilder/art/carney_A.p3dbin0 -> 218252 bytes
-rw-r--r--tools/statepropbuilder/art/carney_A_collisions.p3dbin0 -> 1118 bytes
-rw-r--r--tools/statepropbuilder/art/carney_A_spdata.p3dbin0 -> 1786 bytes
-rw-r--r--tools/statepropbuilder/art/carney_stall_1.p3dbin0 -> 145207 bytes
-rw-r--r--tools/statepropbuilder/art/carney_stall_1_collision.p3dbin0 -> 3859 bytes
-rw-r--r--tools/statepropbuilder/art/carney_stall_1_spdata.p3dbin0 -> 989 bytes
-rw-r--r--tools/statepropbuilder/art/carney_stall_2.p3dbin0 -> 117739 bytes
-rw-r--r--tools/statepropbuilder/art/carney_stall_2_collision.p3dbin0 -> 3859 bytes
-rw-r--r--tools/statepropbuilder/art/carney_stall_2_spdata.p3dbin0 -> 1013 bytes
-rw-r--r--tools/statepropbuilder/art/carney_stall_2_spdata_spdata.p3dbin0 -> 1013 bytes
-rw-r--r--tools/statepropbuilder/art/stateprop.p3dbin0 -> 141791 bytes
-rw-r--r--tools/statepropbuilder/art/weapon.p3dbin0 -> 135773 bytes
-rw-r--r--tools/statepropbuilder/build/win32/stateprop.dsp108
-rw-r--r--tools/statepropbuilder/inc/stateprop/stateprop.hpp86
-rw-r--r--tools/statepropbuilder/inc/stateprop/statepropdata.hpp99
-rw-r--r--tools/statepropbuilder/inc/stateprop/statepropdatatypes.hpp45
-rw-r--r--tools/statepropbuilder/lib/dummy.txt0
-rw-r--r--tools/statepropbuilder/lib/stateproppd.abin0 -> 440394 bytes
-rw-r--r--tools/statepropbuilder/lib/stateproppt.abin0 -> 295484 bytes
-rw-r--r--tools/statepropbuilder/src/stateprop.cpp299
-rw-r--r--tools/statepropbuilder/src/statepropdata.cpp249
96 files changed, 7402 insertions, 0 deletions
diff --git a/tools/statepropbuilder/apps/spbuilder/art/new.bmp b/tools/statepropbuilder/apps/spbuilder/art/new.bmp
new file mode 100644
index 0000000..df77654
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/art/new.bmp
Binary files differ
diff --git a/tools/statepropbuilder/apps/spbuilder/art/open.bmp b/tools/statepropbuilder/apps/spbuilder/art/open.bmp
new file mode 100644
index 0000000..7a468c4
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/art/open.bmp
Binary files differ
diff --git a/tools/statepropbuilder/apps/spbuilder/art/save.bmp b/tools/statepropbuilder/apps/spbuilder/art/save.bmp
new file mode 100644
index 0000000..8bfd2cc
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/art/save.bmp
Binary files differ
diff --git a/tools/statepropbuilder/apps/spbuilder/art/saveas.bmp b/tools/statepropbuilder/apps/spbuilder/art/saveas.bmp
new file mode 100644
index 0000000..8845043
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/art/saveas.bmp
Binary files differ
diff --git a/tools/statepropbuilder/apps/spbuilder/bin/data/Copy of events.txt b/tools/statepropbuilder/apps/spbuilder/bin/data/Copy of events.txt
new file mode 100644
index 0000000..a2302b6
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/bin/data/Copy of events.txt
@@ -0,0 +1,16 @@
+START
+STOP
+TOGGLE
+OPEN
+CLOSE
+ENABLE
+DISABLE
+TALK
+DESTROY
+BREAK
+IDLE
+ATTACK
+FLEE
+COLLECT
+GETHIT
+TRAMPOLINE_BOUNCE
diff --git a/tools/statepropbuilder/apps/spbuilder/bin/data/callbacks.txt b/tools/statepropbuilder/apps/spbuilder/bin/data/callbacks.txt
new file mode 100644
index 0000000..79aad12
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/bin/data/callbacks.txt
@@ -0,0 +1,18 @@
+REMOVE_FROM_WORLD
+SPAWN_5_COINS
+REMOVE_COLLISION_VOLUME
+FIRE_ENERGY_BOLT
+KILL SPEED
+SPAWN_10_COINS
+SPAWN_15_COINS
+SPAWN_20_COINS
+RADIATE_FORCE
+EMIT_LEAVES
+OBJECT_DESTROYED
+SPAWN_5_COINS_Z
+SPAWN_1_COIN
+COLA_DESTROYED
+CAMSHAKE
+REMOVE_1ST_VOL
+REMOVE_2ND_VOL
+REMOVE_3RD_VOL
diff --git a/tools/statepropbuilder/apps/spbuilder/bin/data/events.txt b/tools/statepropbuilder/apps/spbuilder/bin/data/events.txt
new file mode 100644
index 0000000..16f124d
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/bin/data/events.txt
@@ -0,0 +1,12 @@
+IDLE
+FADE_IN
+FADE_OUT
+MOVING
+ATTACK_CHARGING
+ATTACK_CHARGED
+ATTACKING
+DESTROYED
+HIT
+FEATHER_TOUCH
+STOMP
+VEHICLE_HIT \ No newline at end of file
diff --git a/tools/statepropbuilder/apps/spbuilder/bin/data/init.txt b/tools/statepropbuilder/apps/spbuilder/bin/data/init.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/bin/data/init.txt
diff --git a/tools/statepropbuilder/apps/spbuilder/bin/empty.txt b/tools/statepropbuilder/apps/spbuilder/bin/empty.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/bin/empty.txt
diff --git a/tools/statepropbuilder/apps/spbuilder/bin/pddidx8d.dll b/tools/statepropbuilder/apps/spbuilder/bin/pddidx8d.dll
new file mode 100644
index 0000000..a31fd8c
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/bin/pddidx8d.dll
Binary files differ
diff --git a/tools/statepropbuilder/apps/spbuilder/bin/spbuilder.exe b/tools/statepropbuilder/apps/spbuilder/bin/spbuilder.exe
new file mode 100644
index 0000000..074eaa8
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/bin/spbuilder.exe
Binary files differ
diff --git a/tools/statepropbuilder/apps/spbuilder/bin/spengine.dll b/tools/statepropbuilder/apps/spbuilder/bin/spengine.dll
new file mode 100644
index 0000000..9efa51b
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/bin/spengine.dll
Binary files differ
diff --git a/tools/statepropbuilder/apps/spbuilder/build/spbuilder/spbuilder.bpr b/tools/statepropbuilder/apps/spbuilder/build/spbuilder/spbuilder.bpr
new file mode 100644
index 0000000..c51533b
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/build/spbuilder/spbuilder.bpr
@@ -0,0 +1,128 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!-- C++Builder XML Project -->
+<PROJECT>
+ <MACROS>
+ <VERSION value="BCB.05.03"/>
+ <PROJECT value="../../bin\spbuilder.exe"/>
+ <OBJFILES value="spbuilder.obj ..\..\code\sp\builder\main.obj
+ ..\..\code\sp\builder\fcframe.obj ..\..\code\sp\builder\visframe.obj
+ ..\..\code\sp\builder\eventsframe.obj
+ ..\..\code\sp\builder\callbacksframe.obj"/>
+ <RESFILES value="spbuilder.res"/>
+ <DEFFILE value=""/>
+ <RESDEPEN value="$(RESFILES) ..\..\code\sp\builder\main.dfm
+ ..\..\code\sp\builder\fcframe.dfm ..\..\code\sp\builder\visframe.dfm
+ ..\..\code\sp\builder\eventsframe.dfm
+ ..\..\code\sp\builder\callbacksframe.dfm"/>
+ <LIBFILES value=""/>
+ <LIBRARIES value="Vclx50.lib Vcl50.lib"/>
+ <SPARELIBS value="Vcl50.lib Vclx50.lib"/>
+ <PACKAGES value="Vcl50.bpi Vclx50.bpi bcbsmp50.bpi Qrpt50.bpi Vcldb50.bpi Vclbde50.bpi
+ ibsmp50.bpi vcldbx50.bpi TeeUI50.bpi TeeDB50.bpi Tee50.bpi TeeQR50.bpi
+ VCLIB50.bpi bcbie50.bpi vclie50.bpi Inetdb50.bpi Inet50.bpi NMFast50.bpi
+ dclocx50.bpi bcb2kaxserver50.bpi"/>
+ <PATHCPP value=".;..\..\code\sp\builder"/>
+ <PATHPAS value=".;"/>
+ <PATHRC value=".;"/>
+ <PATHASM value=".;"/>
+ <DEBUGLIBPATH value="$(BCB)\lib\debug"/>
+ <RELEASELIBPATH value="$(BCB)\lib\release"/>
+ <LINKER value="tlink32"/>
+ <USERDEFINES value="_DEBUG"/>
+ <SYSDEFINES value="NO_STRICT"/>
+ <MAINSOURCE value="spbuilder.cpp"/>
+ <INCLUDEPATH value="&quot;D:\Program Files\Borland\CBuilder5\Projects\&quot;;..\..\code\sp\builder;$(BCB)\include;$(BCB)\include\vcl;..\..\code"/>
+ <LIBPATH value="&quot;D:\Program Files\Borland\CBuilder5\Projects\&quot;;..\..\code\sp\builder;$(BCB)\lib\obj;$(BCB)\lib;..\..\bin"/>
+ <WARNINGS value="-w-par"/>
+ </MACROS>
+ <OPTIONS>
+ <CFLAG1 value="-Od -H=$(BCB)\lib\vcl50.csm -Hc -Vx -Ve -X- -r- -a8 -b- -k -y -v -vi- -c
+ -tW -tWM"/>
+ <PFLAGS value="-$YD -$W -$O- -v -JPHNE -M"/>
+ <RFLAGS value=""/>
+ <AFLAGS value="/mx /w2 /zi"/>
+ <LFLAGS value="-D&quot;&quot; -aa -Tpe -x -Gn -v"/>
+ </OPTIONS>
+ <LINKER>
+ <ALLOBJ value="c0w32.obj sysinit.obj $(OBJFILES)"/>
+ <ALLRES value="$(RESFILES)"/>
+ <ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cp32mt.lib spengineb.lib"/>
+ </LINKER>
+ <IDEOPTIONS>
+[Version Info]
+IncludeVerInfo=0
+AutoIncBuild=0
+MajorVer=1
+MinorVer=0
+Release=0
+Build=0
+Debug=0
+PreRelease=0
+Special=0
+Private=0
+DLL=0
+Locale=1033
+CodePage=1252
+
+[Version Info Keys]
+CompanyName=
+FileDescription=
+FileVersion=1.0.0.0
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=1.0.0.0
+Comments=
+
+[HistoryLists\hlIncludePath]
+Count=6
+Item0=D:\Program Files\Borland\CBuilder5\Projects\;..\..\code\sp\builder;$(BCB)\include;$(BCB)\include\vcl;..\..\code
+Item1=D:\Program Files\Borland\CBuilder5\Projects;..\..\code\sp\builder;$(BCB)\include;$(BCB)\include\vcl;..\..\code
+Item2=..\..\code\sp\builder;$(BCB)\include;$(BCB)\include\vcl;..\..\code
+Item3=..\..\code\sp\builder;$(BCB)\include;$(BCB)\include\vcl;..\..\code\sp
+Item4=..\..\code\sp\builder;$(BCB)\include;$(BCB)\include\vcl;..\..\code\sp\
+Item5=..\..\code\sp\builder;$(BCB)\include;$(BCB)\include\vcl
+
+[HistoryLists\hlLibraryPath]
+Count=4
+Item0=D:\Program Files\Borland\CBuilder5\Projects\;..\..\code\sp\builder;$(BCB)\lib\obj;$(BCB)\lib;..\..\bin
+Item1=D:\Program Files\Borland\CBuilder5\Projects;..\..\code\sp\builder;$(BCB)\lib\obj;$(BCB)\lib;..\..\bin
+Item2=..\..\code\sp\builder;$(BCB)\lib\obj;$(BCB)\lib;..\..\bin
+Item3=..\..\code\sp\builder;$(BCB)\lib\obj;$(BCB)\lib
+
+[HistoryLists\hlDebugSourcePath]
+Count=1
+Item0=$(BCB)\source\vcl
+
+[HistoryLists\hlConditionals]
+Count=1
+Item0=_DEBUG
+
+[HistoryLists\hlFinalOutputDir]
+Count=2
+Item0=../../bin\
+Item1=../../bin
+
+[Debugging]
+DebugSourceDirs=$(BCB)\source\vcl
+
+[Parameters]
+RunParams=
+HostApplication=
+RemoteHost=
+RemotePath=
+RemoteDebug=0
+
+[Compiler]
+ShowInfoMsgs=0
+LinkDebugVcl=0
+LinkCGLIB=0
+
+[Language]
+ActiveLang=
+ProjectLang=
+RootDir=
+ </IDEOPTIONS>
+</PROJECT> \ No newline at end of file
diff --git a/tools/statepropbuilder/apps/spbuilder/build/spengine/spengine.dsp b/tools/statepropbuilder/apps/spbuilder/build/spengine/spengine.dsp
new file mode 100644
index 0000000..0e4b5e2
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/build/spengine/spengine.dsp
@@ -0,0 +1,179 @@
+# Microsoft Developer Studio Project File - Name="spengine" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 60000
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=spengine - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "spengine.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "spengine.mak" CFG="spengine - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "spengine - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "spengine - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "spengine"
+# PROP Scc_LocalPath "."
+CPP=snCl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "spengine - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPENGINE_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../code" /I "../../../../../ftech/radcore/inc/" /I "../../../../../radmath/" /I "../../../../../pure3d/" /I "../../../../../poser/inc/" /I "../../../../../pure3d/toollib/inc" /I "../../../../../pure3d/constants/" /I "../../../../../sim/" /D "NDEBUG" /D "RAD_TUNE" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAD_WIN32" /D "RAD_PC" /D "SMARTPROP_ENGINE" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=snLink.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /dll /machine:I386 /out:"../../bin/spengine.dll"
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy ..\..\..\..\..\pure3d\build\lib\pddidx8t.dll ..\..\bin coff2omf release\spengine.lib ..\..\bin\spengineb.lib
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "spengine - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPENGINE_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GR /ZI /Od /I "../../code/" /I "../../../../../radcore/inc/" /I "../../../../../radmath" /I "../../../../../pure3d/" /I "../../../../../sim/" /I "../../../../../poser/inc/" /I "../../../../../pure3d/toollib/inc" /I "../../../../../pure3d/constants/" /I "../../../../../radcontent/inc" /D "_DEBUG" /D "RAD_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAD_WIN32" /D "RAD_PC" /D "SMARTPROP_ENGINE" /FR /YX /FD /I /I /I /I /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=snLink.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"libc.lib" /out:"../../bin/spengine.dll" /pdbtype:sept
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy ..\..\..\..\..\pure3d\build\lib\pddidx8d.dll ..\..\bin coff2omf debug\spengine.lib ..\..\bin\spengineb.lib
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "spengine - Win32 Release"
+# Name "spengine - Win32 Debug"
+# Begin Group "interface"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\code\sp\interface\base.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\interface\context.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\interface.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\interface\platform.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\interface\workspace.hpp
+# End Source File
+# End Group
+# Begin Group "engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\code\sp\engine\aicollisionsolveragent.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\engine\aicollisionsolveragent.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\engine\context.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\engine\context.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\engine\dllmain.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\engine\platform.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\engine\stateprop.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\engine\stateprop.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\engine\statepropdata.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\engine\statepropdata.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\engine\statepropdatatypes.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\engine\workspace.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\code\sp\engine\workspace.hpp
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/tools/statepropbuilder/apps/spbuilder/build/spengine/spengine.dsw b/tools/statepropbuilder/apps/spbuilder/build/spengine/spengine.dsw
new file mode 100644
index 0000000..520d8ab
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/build/spengine/spengine.dsw
@@ -0,0 +1,245 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Pure3D"=..\..\..\..\..\pure3d\build\win32\Pure3D.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+ begin source code control
+ Pure3D
+ ..\..\..\..\..\pure3d\build\win32
+ end source code control
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "freetype"=..\..\..\..\..\pure3d\lib\freetype\builds\win32\visualc\freetype.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+ begin source code control
+ "$/DEV/freetype", KAOAAAAA
+ ..\..\..\..\..\pure3d\lib\freetype\builds\win32\visualc
+ end source code control
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "libpng"=..\..\..\..\..\pure3d\build\win32\libpng.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+ begin source code control
+ libpng
+ ..\..\..\..\..\pure3d\build\win32
+ end source code control
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "pddidx8"=..\..\..\..\..\pure3d\build\win32\pddidx8.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+ begin source code control
+ nbrooke-dual
+ ..\..\..\..\..\pure3d\build\win32
+ end source code control
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name radmath
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "poser"=..\..\..\..\..\poser\build\win32\poser.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+ begin source code control
+ poser
+ ..\..\..\..\..\poser
+ end source code control
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "radcontent"=..\..\..\..\..\radcontent\build\win32\radcontent.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+ begin source code control
+ radcontent
+ ..\..\..\..\..\radcontent
+ end source code control
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "radcore"=..\..\..\..\..\radcore\build\win32\radcore.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+ begin source code control
+ radcore
+ ..\..\..\..\..\radcore\build\win32
+ end source code control
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "radmath"=..\..\..\..\..\radmath\build\win32\radmath.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+ begin source code control
+ nbrooke-dual
+ ..\..\..\..\..\radmath\build\win32
+ end source code control
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "sim"=..\..\..\..\..\sim\build\win32\sim.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+ begin source code control
+ sim
+ ..\..\..\..\..\sim
+ end source code control
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "spengine"=.\spengine.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+ begin source code control
+ spengine
+ .
+ end source code control
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name libpng
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name pddidx8
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name Pure3D
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name radcore
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name radmath
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name zlib
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name toollib
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name freetype
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name sim
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name poser
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name radcontent
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "toollib"=..\..\..\..\..\pure3d\toollib\toollib.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+ begin source code control
+ toollib
+ ..\..\..\..\..\pure3d\toollib
+ end source code control
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "zlib"=..\..\..\..\..\pure3d\build\win32\zlib.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+ begin source code control
+ zlib
+ ..\..\..\..\..\pure3d\build\win32
+ end source code control
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/callbacksframe.cpp b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/callbacksframe.cpp
new file mode 100644
index 0000000..adc81aa
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/callbacksframe.cpp
@@ -0,0 +1,73 @@
+//---------------------------------------------------------------------------
+
+#include <vcl.h>
+#pragma hdrstop
+
+#include <sp/interface.hpp>
+#include "callbacksframe.h"
+//---------------------------------------------------------------------------
+#pragma package(smart_init)
+#pragma resource "*.dfm"
+
+extern bool g_ForceDataUpdate;
+extern bool g_IsDataSaved;
+
+TFrame4 *Frame4;
+//---------------------------------------------------------------------------
+__fastcall TFrame4::TFrame4(TComponent* Owner,int cbindex) :
+ TFrame(Owner),
+ m_CBIndex( cbindex )
+{
+}
+//---------------------------------------------------------------------------
+void __fastcall TFrame4::CallbackComboBoxChange(TObject *Sender)
+{
+ CallbackData cbData;
+ SPGetCallbackData( SPGetCurrentState() , m_CBIndex , &cbData );
+
+ int index = CallbackComboBox->ItemIndex;
+ AnsiString eventname = CallbackComboBox->Items->Strings[index];
+ SPEditCallback( SPGetCurrentState() , m_CBIndex , eventname.c_str() , index , cbData.onFrame );
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TFrame4::OnFrameEditBoxChange(TObject *Sender)
+{
+ CallbackData cbData;
+ SPGetCallbackData( SPGetCurrentState() , m_CBIndex , &cbData );
+
+ AnsiString onFrame = OnFrameEditBox->Text;
+ float frame = 0.f;
+ try
+ {
+ frame = onFrame.ToDouble();
+ }
+ catch (Exception&)
+ {
+ frame = cbData.onFrame;
+ AnsiString oldFrame;
+ oldFrame.sprintf("%0.3f" , frame);
+ OnFrameEditBox->Text = oldFrame;
+ }
+
+ SPEditCallback( SPGetCurrentState() , m_CBIndex , cbData.callbackName , cbData.callbackID , frame );
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TFrame4::Button1Click(TObject *Sender)
+{
+ SPDeleteCallback( SPGetCurrentState() , m_CBIndex );
+ g_ForceDataUpdate = true;
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+
+void __fastcall TFrame4::OnFrameEditBoxExit(TObject *Sender)
+{
+ g_ForceDataUpdate = true;
+}
+//---------------------------------------------------------------------------
+
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/callbacksframe.dfm b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/callbacksframe.dfm
new file mode 100644
index 0000000..bddefe4
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/callbacksframe.dfm
@@ -0,0 +1,58 @@
+object Frame4: TFrame4
+ Left = 0
+ Top = 0
+ Width = 286
+ Height = 71
+ TabOrder = 0
+ object Panel1: TPanel
+ Left = 0
+ Top = 0
+ Width = 286
+ Height = 71
+ Align = alClient
+ BevelInner = bvLowered
+ TabOrder = 0
+ object Label2: TLabel
+ Left = 8
+ Top = 10
+ Width = 41
+ Height = 13
+ Caption = 'Callback'
+ end
+ object Label1: TLabel
+ Left = 8
+ Top = 35
+ Width = 43
+ Height = 13
+ Caption = 'On frame'
+ end
+ object CallbackComboBox: TComboBox
+ Left = 56
+ Top = 5
+ Width = 121
+ Height = 21
+ Style = csDropDownList
+ ItemHeight = 13
+ TabOrder = 0
+ OnChange = CallbackComboBoxChange
+ end
+ object OnFrameEditBox: TEdit
+ Left = 56
+ Top = 30
+ Width = 49
+ Height = 21
+ TabOrder = 1
+ OnChange = OnFrameEditBoxChange
+ OnExit = OnFrameEditBoxExit
+ end
+ object Button1: TButton
+ Left = 110
+ Top = 30
+ Width = 67
+ Height = 23
+ Caption = 'delete'
+ TabOrder = 2
+ OnClick = Button1Click
+ end
+ end
+end
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/callbacksframe.h b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/callbacksframe.h
new file mode 100644
index 0000000..b2b0519
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/callbacksframe.h
@@ -0,0 +1,34 @@
+//---------------------------------------------------------------------------
+
+
+#ifndef callbacksframeH
+#define callbacksframeH
+//---------------------------------------------------------------------------
+#include <Classes.hpp>
+#include <Controls.hpp>
+#include <StdCtrls.hpp>
+#include <Forms.hpp>
+#include <ExtCtrls.hpp>
+//---------------------------------------------------------------------------
+class TFrame4 : public TFrame
+{
+__published: // IDE-managed Components
+ TPanel *Panel1;
+ TLabel *Label2;
+ TComboBox *CallbackComboBox;
+ TLabel *Label1;
+ TEdit *OnFrameEditBox;
+ TButton *Button1;
+ void __fastcall CallbackComboBoxChange(TObject *Sender);
+ void __fastcall OnFrameEditBoxChange(TObject *Sender);
+ void __fastcall Button1Click(TObject *Sender);
+ void __fastcall OnFrameEditBoxExit(TObject *Sender);
+private: // User declarations
+ int m_CBIndex;
+public: // User declarations
+ __fastcall TFrame4(TComponent* Owner,int cbindex);
+};
+//---------------------------------------------------------------------------
+extern PACKAGE TFrame4 *Frame4;
+//---------------------------------------------------------------------------
+#endif
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/eventsframe.cpp b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/eventsframe.cpp
new file mode 100644
index 0000000..09ded82
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/eventsframe.cpp
@@ -0,0 +1,75 @@
+//---------------------------------------------------------------------------
+
+#include <vcl.h>
+#pragma hdrstop
+#include <sp/interface.hpp>
+#include "eventsframe.h"
+#include "main.h"
+
+extern float g_ForceDataUpdate;
+extern bool g_IsDataSaved;
+
+//---------------------------------------------------------------------------
+#pragma package(smart_init)
+#pragma resource "*.dfm"
+TFrame3 *Frame3;
+//---------------------------------------------------------------------------
+__fastcall TFrame3::TFrame3(TComponent* Owner , int EventIndex ) :
+ TFrame(Owner),
+ m_EventIndex( EventIndex )
+{
+}
+//---------------------------------------------------------------------------
+void __fastcall TFrame3::EventComboBoxChange(TObject *Sender)
+{
+ EventData eventData;
+ SPGetEventData( SPGetCurrentState() , m_EventIndex , &eventData );
+ int index = EventComboBox->ItemIndex;
+ AnsiString eventname = EventComboBox->Items->Strings[index];
+ SPEditEvent( SPGetCurrentState() , m_EventIndex , eventname.c_str() , index , eventData.toState );
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TFrame3::ToFrameEditBoxChange(TObject *Sender)
+{
+ EventData eventData;
+ SPGetEventData( SPGetCurrentState() , m_EventIndex , &eventData );
+
+ int index = EventComboBox->ItemIndex;
+ AnsiString eventname = EventComboBox->Items->Strings[index];
+ AnsiString toState = ToFrameEditBox->Text;
+ int state = 0;
+ try
+ {
+ state = toState.ToInt();
+ }
+ catch (Exception&)
+ {
+ state = eventData.toState + 1;
+ }
+ if ( state > SPGetNumberOfStates() || state == 0 )
+ {
+ state = eventData.toState + 1;
+ g_ForceDataUpdate = true;
+ }
+
+ SPEditEvent( SPGetCurrentState() , m_EventIndex , eventname.c_str() , index , state - 1 );
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TFrame3::Button1Click(TObject *Sender)
+{
+ SPDeleteEvent( SPGetCurrentState() , m_EventIndex );
+ g_ForceDataUpdate = true;
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TFrame3::ToFrameEditBoxExit(TObject *Sender)
+{
+ g_ForceDataUpdate = true;
+}
+//---------------------------------------------------------------------------
+
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/eventsframe.dfm b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/eventsframe.dfm
new file mode 100644
index 0000000..cf1d0e6
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/eventsframe.dfm
@@ -0,0 +1,58 @@
+object Frame3: TFrame3
+ Left = 0
+ Top = 0
+ Width = 212
+ Height = 62
+ TabOrder = 0
+ object Panel1: TPanel
+ Left = 0
+ Top = 0
+ Width = 212
+ Height = 62
+ Align = alClient
+ BevelInner = bvLowered
+ TabOrder = 0
+ object Label1: TLabel
+ Left = 8
+ Top = 10
+ Width = 44
+ Height = 13
+ Caption = 'On event'
+ end
+ object Label2: TLabel
+ Left = 8
+ Top = 35
+ Width = 50
+ Height = 13
+ Caption = 'go to state'
+ end
+ object EventComboBox: TComboBox
+ Left = 64
+ Top = 5
+ Width = 113
+ Height = 21
+ Style = csDropDownList
+ ItemHeight = 13
+ TabOrder = 0
+ OnChange = EventComboBoxChange
+ end
+ object ToFrameEditBox: TEdit
+ Left = 64
+ Top = 30
+ Width = 41
+ Height = 21
+ TabOrder = 1
+ OnChange = ToFrameEditBoxChange
+ OnExit = ToFrameEditBoxExit
+ end
+ object Button1: TButton
+ Left = 110
+ Top = 30
+ Width = 67
+ Height = 23
+ Caption = 'delete'
+ TabOrder = 2
+ OnClick = Button1Click
+ end
+ end
+end
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/eventsframe.h b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/eventsframe.h
new file mode 100644
index 0000000..9154617
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/eventsframe.h
@@ -0,0 +1,34 @@
+//---------------------------------------------------------------------------
+
+
+#ifndef eventsframeH
+#define eventsframeH
+//---------------------------------------------------------------------------
+#include <Classes.hpp>
+#include <Controls.hpp>
+#include <StdCtrls.hpp>
+#include <Forms.hpp>
+#include <ExtCtrls.hpp>
+//---------------------------------------------------------------------------
+class TFrame3 : public TFrame
+{
+__published: // IDE-managed Components
+ TPanel *Panel1;
+ TLabel *Label1;
+ TComboBox *EventComboBox;
+ TLabel *Label2;
+ TEdit *ToFrameEditBox;
+ TButton *Button1;
+ void __fastcall EventComboBoxChange(TObject *Sender);
+ void __fastcall ToFrameEditBoxChange(TObject *Sender);
+ void __fastcall Button1Click(TObject *Sender);
+ void __fastcall ToFrameEditBoxExit(TObject *Sender);
+private: // User declarations
+ int m_EventIndex;
+public: // User declarations
+ __fastcall TFrame3(TComponent* Owner , int EventIndex );
+};
+//---------------------------------------------------------------------------
+extern PACKAGE TFrame3 *Frame3;
+//---------------------------------------------------------------------------
+#endif
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/fcframe.cpp b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/fcframe.cpp
new file mode 100644
index 0000000..0a508b4
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/fcframe.cpp
@@ -0,0 +1,136 @@
+//---------------------------------------------------------------------------
+
+#include <vcl.h>
+#include <sp/interface.hpp>
+#pragma hdrstop
+
+#include "fcframe.h"
+//---------------------------------------------------------------------------
+#pragma package(smart_init)
+#pragma resource "*.dfm"
+
+extern bool g_IsDataSaved;
+extern bool g_ForceDataUpdate;
+
+TFrame1 *Frame1;
+//---------------------------------------------------------------------------
+__fastcall TFrame1::TFrame1(TComponent* Owner , int fcindex)
+ : TFrame(Owner) , m_FCIndex( fcindex )
+{
+}
+
+//---------------------------------------------------------------------------
+
+
+void __fastcall TFrame1::CyclicCheckBoxClick(TObject *Sender)
+{
+ SPSetCyclic( SPGetCurrentState() , m_FCIndex , this->CyclicCheckBox->State != cbUnchecked );
+ this->cycleForEditBox->Enabled = CyclicCheckBox->State != cbUnchecked;
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TFrame1::MaxFrameEditBoxChange(TObject *Sender)
+{
+ FrameControllerData fcData;
+ SPGetFrameControllerData( SPGetCurrentState() , m_FCIndex , &fcData );
+
+ AnsiString frame;
+ frame = this->MaxFrameEditBox->Text;
+ float f = 0.0f;
+ try
+ {
+ f = frame.ToDouble();
+ }
+ catch (Exception&)
+ {
+ f = fcData.maxFrame;
+ }
+
+ SPSetFrameRange( SPGetCurrentState() , m_FCIndex , fcData.minFrame , f );
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TFrame1::MinFrameEditBoxChange(TObject *Sender)
+{
+ FrameControllerData fcData;
+ SPGetFrameControllerData( SPGetCurrentState() , m_FCIndex , &fcData );
+
+ AnsiString frame;
+ frame = this->MinFrameEditBox->Text;
+ float f = 0.0f;
+
+ try
+ {
+ f = frame.ToDouble();
+
+ }
+ catch (Exception&)
+ {
+ f = fcData.minFrame;
+ }
+
+ SPSetFrameRange( SPGetCurrentState() , m_FCIndex , f , fcData.maxFrame );
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TFrame1::holdFrameCheckboxClick(TObject *Sender)
+{
+ SPSetHoldFrame( SPGetCurrentState() , m_FCIndex , holdFrameCheckbox->Checked );
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TFrame1::speedEditBoxChange(TObject *Sender)
+{
+ FrameControllerData fcData;
+ SPGetFrameControllerData( SPGetCurrentState() , m_FCIndex , &fcData );
+
+ AnsiString speed;
+ speed = this->speedEditBox->Text;
+ float fSpeed = 0.0f;
+
+ try
+ {
+ fSpeed = speed.ToDouble();
+ }
+ catch (Exception&)
+ {
+ fSpeed = fcData.relativeSpeed;
+ }
+
+ SPSetRelativeSpeed( SPGetCurrentState() , m_FCIndex , fSpeed );
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TFrame1::cycleForEditBoxChange(TObject *Sender)
+{
+ FrameControllerData fcData;
+ SPGetFrameControllerData( SPGetCurrentState() , m_FCIndex , &fcData );
+
+ AnsiString cycles;
+ cycles = cycleForEditBox->Text;
+ int iCycles = 0;
+ try
+ {
+ iCycles = cycles.ToInt();
+ }
+ catch (Exception&)
+ {
+ iCycles = fcData.numberOfCycles;
+ }
+
+ SPSetNumberOfCycles( SPGetCurrentState() , m_FCIndex , iCycles );
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TFrame1::EditBoxExit(TObject *Sender)
+{
+ //do something here
+ g_ForceDataUpdate = true;
+}
+//---------------------------------------------------------------------------
+
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/fcframe.dfm b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/fcframe.dfm
new file mode 100644
index 0000000..fb63774
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/fcframe.dfm
@@ -0,0 +1,120 @@
+object Frame1: TFrame1
+ Left = 0
+ Top = 0
+ Width = 1066
+ Height = 30
+ TabOrder = 0
+ object Panel1: TPanel
+ Left = 0
+ Top = 0
+ Width = 1066
+ Height = 30
+ Align = alClient
+ BevelInner = bvLowered
+ TabOrder = 0
+ object FrameControllerNameLabel: TLabel
+ Left = 10
+ Top = 7
+ Width = 24
+ Height = 13
+ Caption = 'none'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clNavy
+ Font.Height = -8
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ end
+ object Label1: TLabel
+ Left = 130
+ Top = 7
+ Width = 52
+ Height = 13
+ Caption = 'Frame: Min'
+ end
+ object Label3: TLabel
+ Left = 256
+ Top = 7
+ Width = 20
+ Height = 13
+ Caption = 'Max'
+ end
+ object Label4: TLabel
+ Left = 720
+ Top = 7
+ Width = 29
+ Height = 13
+ Caption = 'Frame'
+ end
+ object Label5: TLabel
+ Left = 352
+ Top = 8
+ Width = 31
+ Height = 13
+ Caption = 'Speed'
+ end
+ object MinFrameEditBox: TEdit
+ Left = 186
+ Top = 4
+ Width = 60
+ Height = 21
+ TabOrder = 0
+ OnChange = MinFrameEditBoxChange
+ OnExit = EditBoxExit
+ end
+ object MaxFrameEditBox: TEdit
+ Left = 280
+ Top = 4
+ Width = 60
+ Height = 21
+ TabOrder = 1
+ OnChange = MaxFrameEditBoxChange
+ OnExit = EditBoxExit
+ end
+ object CyclicCheckBox: TCheckBox
+ Left = 456
+ Top = 7
+ Width = 49
+ Height = 17
+ Caption = 'Cycle'
+ TabOrder = 2
+ OnClick = CyclicCheckBoxClick
+ end
+ object CurrentFrameLabel: TEdit
+ Left = 760
+ Top = 4
+ Width = 60
+ Height = 21
+ TabOrder = 3
+ end
+ object holdFrameCheckbox: TCheckBox
+ Left = 560
+ Top = 7
+ Width = 57
+ Height = 17
+ Caption = 'Hold'
+ TabOrder = 4
+ OnClick = holdFrameCheckboxClick
+ end
+ object cycleForEditBox: TEdit
+ Left = 503
+ Top = 4
+ Width = 39
+ Height = 21
+ Enabled = False
+ TabOrder = 5
+ Text = '0'
+ OnChange = cycleForEditBoxChange
+ OnExit = EditBoxExit
+ end
+ object speedEditBox: TEdit
+ Left = 387
+ Top = 4
+ Width = 57
+ Height = 21
+ TabOrder = 6
+ OnChange = speedEditBoxChange
+ OnExit = EditBoxExit
+ end
+ end
+end
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/fcframe.h b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/fcframe.h
new file mode 100644
index 0000000..fcc0f0a
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/fcframe.h
@@ -0,0 +1,44 @@
+//---------------------------------------------------------------------------
+
+
+#ifndef fcframeH
+#define fcframeH
+//---------------------------------------------------------------------------
+#include <Classes.hpp>
+#include <Controls.hpp>
+#include <StdCtrls.hpp>
+#include <Forms.hpp>
+#include <ExtCtrls.hpp>
+//---------------------------------------------------------------------------
+class TFrame1 : public TFrame
+{
+__published: // IDE-managed Components
+ TPanel *Panel1;
+ TLabel *FrameControllerNameLabel;
+ TLabel *Label1;
+ TEdit *MinFrameEditBox;
+ TLabel *Label3;
+ TEdit *MaxFrameEditBox;
+ TCheckBox *CyclicCheckBox;
+ TLabel *Label4;
+ TEdit *CurrentFrameLabel;
+ TCheckBox *holdFrameCheckbox;
+ TEdit *cycleForEditBox;
+ TEdit *speedEditBox;
+ TLabel *Label5;
+ void __fastcall CyclicCheckBoxClick(TObject *Sender);
+ void __fastcall MaxFrameEditBoxChange(TObject *Sender);
+ void __fastcall MinFrameEditBoxChange(TObject *Sender);
+ void __fastcall holdFrameCheckboxClick(TObject *Sender);
+ void __fastcall speedEditBoxChange(TObject *Sender);
+ void __fastcall cycleForEditBoxChange(TObject *Sender);
+ void __fastcall EditBoxExit(TObject *Sender);
+private: // User declarations
+ int m_FCIndex;
+public: // User declarations
+ __fastcall TFrame1(TComponent* Owner , int fcindex);
+};
+//---------------------------------------------------------------------------
+extern PACKAGE TFrame1 *Frame1;
+//---------------------------------------------------------------------------
+#endif
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/main.cpp b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/main.cpp
new file mode 100644
index 0000000..1192623
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/main.cpp
@@ -0,0 +1,704 @@
+//---------------------------------------------------------------------------
+
+#include <vcl.h>
+#include <sp/interface.hpp>
+#include <direct.h>
+
+#include <errno.h>
+#include <dos.h>
+#include <io.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#pragma hdrstop
+
+#include "main.h"
+#include "sp/builder/fcframe.h"
+#include "sp/builder/eventsframe.h"
+
+float g_ForceDataUpdate = false;
+bool g_IsDataSaved = true;
+
+/* returns the attributes of a DOS file */
+int get_file_attrib(char *filename)
+{
+ return(_rtl_chmod(filename, 0));
+}
+//---------------------------------------------------------------------------
+
+void FVUShiftStateToMouse(TShiftState shiftState, int& buttons, int& shift)
+{
+ buttons = 0;
+ if (shiftState.Contains(ssLeft))
+ buttons |= MK_LBUTTON;
+ if (shiftState.Contains(ssRight))
+ buttons |= MK_RBUTTON;
+ if (shiftState.Contains(ssMiddle))
+ buttons |= MK_MBUTTON;
+
+ shift = 0;
+ if (shiftState.Contains(ssShift))
+ shift |= MK_SHIFT;
+ if (shiftState.Contains(ssCtrl))
+ shift |= MK_CONTROL;
+}
+//---------------------------------------------------------------------------
+#pragma package(smart_init)
+#pragma resource "*.dfm"
+TMainForm *MainForm;
+//---------------------------------------------------------------------------
+__fastcall TMainForm::TMainForm(TComponent* Owner) :
+ TForm(Owner),
+ m_numFCPanels(0),
+ m_numDrawablePanels(0),
+ m_numEvents(0),
+ m_numCallbacks(0),
+ m_CurrentPropState(-1)
+{
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::ApplicationEvents1Idle(TObject *Sender,
+ bool &Done)
+{
+ int i;
+ SPContextAdvance();
+ SPContextDisplay();
+
+ //update frames
+ float currentFrame = SPGetBaseFrameControllerFrame();
+ AnsiString frame;
+ frame.sprintf("%0.3f",currentFrame);
+ CurrentFrameWindow->Text = frame;
+
+ for ( i = 0; i < m_numFCPanels; i++ )
+ {
+ frame.sprintf("%0.3f",SPGetFrameControllerFrame( i ));
+ m_FCPanels[i]->CurrentFrameLabel->Text = frame;
+ }
+
+ Save1->Enabled = ! g_IsDataSaved;
+
+ //check for a new state
+ int newState = SPGetCurrentState();
+ if ( m_CurrentPropState != newState || g_ForceDataUpdate )
+ {
+ UpdateStateInfo();
+ UpdateFrameControllers();
+ UpdateDrawables();
+ UpdateEvents();
+ UpdateCallbacks();
+ m_CurrentPropState = newState;
+ g_ForceDataUpdate = false;
+ }
+
+ static bool bgloaded = false;
+ if ( ! bgloaded )
+ {
+ //load the events list
+ AnsiString fname = Application->ExeName;
+ fname.SetLength( fname.Length() - 13 );
+ fname.cat_sprintf("data\\init.txt");
+ TComboBox* cbox = new TComboBox( this );
+ cbox->Parent = Panel4;
+ cbox->Items->LoadFromFile(fname);
+ if ( cbox->Items->Count >= 1 )
+ {
+ AnsiString bgfilename = cbox->Items->Strings[0];
+ SPLoadBackground( bgfilename.c_str() );
+ }
+
+ delete cbox;
+ bgloaded = true;
+ }
+
+ Done = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::FormShow(TObject *Sender)
+{
+ SPPlatformOpen( Handle );
+
+ HWND desktopHwnd = GetDesktopWindow();
+ RECT rect;
+ GetWindowRect(desktopHwnd, &rect);
+
+ P3DPanel->Width = rect.right - rect.left;
+ P3DPanel->Height = rect.bottom - rect.top;
+ SPContextOpen(P3DPanel->Handle);
+ SPContextViewResize(P3DClientPanel->ClientWidth, P3DClientPanel->ClientHeight);
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
+{
+ SPContextClose();
+ SPPlatformClose();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::P3DClientPanelResize(TObject *Sender)
+{
+ SPContextViewResize(P3DClientPanel->ClientWidth, P3DClientPanel->ClientHeight);
+ SPContextDisplay();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::FileOpenExecute(TObject *Sender)
+{
+ if (OpenDialog1->Execute())
+ {
+ int i;
+ SPLoad( OpenDialog1->FileName.c_str() );
+ FileName = OpenDialog1->FileName;
+ m_CurrentPropState = -1;
+
+ //Remove old panels
+ for (i = 0; i < m_numFCPanels; i++)
+ {
+ delete m_FCPanels[i];
+ m_FCPanels[i] = NULL;
+ }
+ m_numFCPanels = 0;
+
+ for (i = 0; i < m_numDrawablePanels; i++)
+ {
+ delete m_DrawablePanels[i];
+ m_DrawablePanels[i] = NULL;
+ }
+ m_numDrawablePanels = 0;
+
+ //Set up new panels
+ int numfc = SPGetNumFrameControllers();
+ m_numFCPanels = numfc;
+ for (i = 0; i < numfc; i++ )
+ {
+ AnsiString framename;
+ framename.sprintf("fcframe%i", i );
+ TFrame1* f = new TFrame1( this , i );
+ f->Parent = Panel4;
+ f->Name = framename;
+ m_FCPanels[i] = f;
+ }
+ Panel2->Height = numfc * 33 + 35 + 32;
+ int panel4height = numfc * 33;
+ if ( panel4height < 6 * 33 )
+ {
+ Panel4->Height = numfc * 33;
+ }
+ else
+ {
+ Panel4->Height = 6 * 33;
+ }
+
+ for (i = numfc - 1; i >= 0; i-- )
+ {
+ m_FCPanels[i]->Align = alTop;
+ }
+
+ m_numDrawablePanels = SPGetNumDrawables();
+ for (i = 0; i < m_numDrawablePanels; i++ )
+ {
+ AnsiString framename;
+ framename.sprintf("drawframe%i", i );
+ TFrame2* f = new TFrame2( this , i );
+ f->Parent = Panel5;
+ f->Name = framename;
+ m_DrawablePanels[i] = f;
+ }
+ for ( i = m_numDrawablePanels-1; i >= 0; i-- )
+ {
+ m_DrawablePanels[i]->Align = alTop;
+ }
+ g_IsDataSaved = true;
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::P3DPanelMouseDown(TObject *Sender,
+ TMouseButton Button, TShiftState Shift, int X, int Y)
+{
+ int buttons, shift;
+ FVUShiftStateToMouse(Shift, buttons, shift);
+ SPContextMouseDown(buttons, shift, X, Y);
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::P3DPanelMouseMove(TObject *Sender,
+ TShiftState Shift, int X, int Y)
+{
+ int buttons, shift;
+ FVUShiftStateToMouse(Shift, buttons, shift);
+ SPContextMouseMove(buttons, shift, X, Y);
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::P3DPanelMouseUp(TObject *Sender,
+ TMouseButton Button, TShiftState Shift, int X, int Y)
+{
+ int buttons, shift;
+ FVUShiftStateToMouse(Shift, buttons, shift);
+ SPContextMouseUp(buttons, shift, X, Y);
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::FormKeyPress(TObject *Sender, char &Key)
+{
+ switch (Key)
+ {
+ case '.':
+ SPNextState();
+ g_ForceDataUpdate = true;
+ break;
+ case ',':
+ SPPrevState();
+ g_ForceDataUpdate = true;
+ break;
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::PlayButtonClick(TObject *Sender)
+{
+ static bool play = true;
+ SPPause( play );
+ play = !play;
+ if (play)
+ {
+ PlayButton->Caption = "| |";
+ }
+ else
+ {
+ PlayButton->Caption = ">";
+ }
+}
+//---------------------------------------------------------------------------
+
+
+
+void __fastcall TMainForm::PrevStatebuttonClick(TObject *Sender)
+{
+ SPPrevState();
+ g_ForceDataUpdate = true;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::NextStateButtonClick(TObject *Sender)
+{
+ SPNextState();
+ g_ForceDataUpdate = true;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::ForwardStepButtonClick(TObject *Sender)
+{
+ SPAdvanceOneFrame();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::BackStepButtonClick(TObject *Sender)
+{
+ SPBackOneFrame();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::Button1Click(TObject *Sender)
+{
+ SPAddEvent( "" , 0 , 0 , SPGetCurrentState() );
+ UpdateEvents();
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void TMainForm::UpdateStateInfo()
+{
+ AnsiString propname;
+ propname.sprintf( "%s", SPGetPropName() );
+ PropNameLabel->Caption = propname;
+ PropNameLabelTop->Caption = propname;
+
+ AnsiString numstates;
+ numstates.sprintf("%i", SPGetNumberOfStates() );
+ NumPropStatesLabel->Caption = numstates;
+ NumPropStatesLabelTop->Caption = numstates;
+
+ AnsiString curstate;
+ curstate.sprintf("%i" , SPGetCurrentState() + 1 );
+ CurrentStateLabel->Caption = curstate;
+ CurrentStateLabelTop->Caption = curstate;
+ StateStateLabel->Caption = curstate;
+
+ TransitionData transitionData;
+ if ( SPGetTransitionData( SPGetCurrentState() , &transitionData ) )
+ {
+ AutoTransitionCheckBox->Checked = transitionData.autoTransition;
+
+ AnsiString tostate;
+ tostate.sprintf("%i", transitionData.toState + 1);
+ ToStateEditBox->Text = tostate;
+ ToStateEditBox->Enabled = transitionData.autoTransition;
+
+ AnsiString onframe;
+ onframe.sprintf("%0.3f", transitionData.onFrame );
+ OnFrameEditBox->Text = onframe;
+ OnFrameEditBox->Enabled = transitionData.autoTransition;
+ }
+}
+//---------------------------------------------------------------------------
+
+void TMainForm::UpdateFrameControllers()
+{
+ //Set up fc's
+ int i;
+ for ( i = 0; i < m_numFCPanels; i++ )
+ {
+ AnsiString text;
+ text.sprintf("%s",SPGetFrameControllerName( i ));
+ m_FCPanels[i]->FrameControllerNameLabel->Caption = text;
+
+ FrameControllerData fcData;
+ if ( SPGetFrameControllerData( SPGetCurrentState() , i , &fcData ) )
+ {
+ text.sprintf("%0.3f", fcData.minFrame );
+ m_FCPanels[i]->MinFrameEditBox->Text = text;
+
+ text.sprintf("%0.3f",fcData.maxFrame);
+ m_FCPanels[i]->MaxFrameEditBox->Text = text;
+
+ text.sprintf("%0.3f", fcData.relativeSpeed );
+ m_FCPanels[i]->speedEditBox->Text = text;
+
+ if ( fcData.isCyclic )
+ {
+ m_FCPanels[i]->CyclicCheckBox->State = cbChecked;
+ }
+ else
+ {
+ m_FCPanels[i]->CyclicCheckBox->State = cbUnchecked;
+ }
+ m_FCPanels[i]->holdFrameCheckbox->Checked = fcData.holdFrame;
+
+ if ( fcData.numberOfCycles == 0 )
+ {
+ text.sprintf("forever" );
+ m_FCPanels[i]->cycleForEditBox->Text = text;
+ }
+ else
+ {
+ text.sprintf("%i" , fcData.numberOfCycles);
+ m_FCPanels[i]->cycleForEditBox->Text = text;
+ }
+
+ m_FCPanels[i]->cycleForEditBox->Enabled = m_FCPanels[i]->CyclicCheckBox->State != cbUnchecked;
+ }
+ }
+}
+//---------------------------------------------------------------------------
+
+void TMainForm::UpdateDrawables()
+{
+ //Set up drawables
+ int i;
+ for ( i = 0; i < m_numDrawablePanels; i++ )
+ {
+ AnsiString n;
+ n.sprintf("%s",SPGetDrawableName( i ));
+ m_DrawablePanels[i]->NameLabel->Caption = n;
+
+ VisibilityData visData;
+ if ( SPGetVisibilityData( SPGetCurrentState() , i , &visData ) )
+ {
+ if ( visData.isVisible )
+ {
+ m_DrawablePanels[i]->VisibilityCheckBox->State = cbChecked;
+ }
+ else
+ {
+ m_DrawablePanels[i]->VisibilityCheckBox->State = cbUnchecked;
+ }
+ }
+ }
+}
+//---------------------------------------------------------------------------
+
+void TMainForm::UpdateEvents()
+{
+ int i;
+ for ( i = 0; i < m_numEvents; i++ )
+ {
+ //delete old panels
+ delete m_EventPanels[i];
+ m_EventPanels[i] = NULL;
+ }
+ m_numEvents = SPGetNumberOfEvents( SPGetCurrentState() );
+ for ( i = 0; i < m_numEvents; i++ )
+ {
+ //create panels
+ AnsiString framename;
+ framename.sprintf("eventframe%i", i );
+ TFrame3* f = new TFrame3( this , i );
+ f->Parent = Panel6;
+ f->Name = framename;
+
+ //load the events list
+ AnsiString fname = Application->ExeName;
+ fname.SetLength( fname.Length() - 13 );
+ fname.cat_sprintf("data\\events.txt");
+ f->EventComboBox->Items->LoadFromFile(fname);
+
+ //set up events fields
+ EventData eventData;
+ if ( SPGetEventData( SPGetCurrentState() , i , &eventData ) )
+ {
+ AnsiString eventname;
+ eventname.sprintf( eventData.eventName );
+ int eventindex = f->EventComboBox->Items->IndexOf( eventname );
+ f->EventComboBox->ItemIndex = eventindex;
+ AnsiString toState;
+ toState.sprintf("%i", eventData.toState + 1);
+ f->ToFrameEditBox->Text = toState;
+ }
+
+ //add panel to panel list
+ m_EventPanels[i] = f;
+ }
+
+ for ( i = m_numEvents-1; i >= 0 ; i-- )
+ {
+ m_EventPanels[i]->Align = alTop;
+ }
+}
+//---------------------------------------------------------------------------
+
+void TMainForm::UpdateCallbacks()
+{
+ int i;
+ for ( i = 0; i < m_numCallbacks; i++ )
+ {
+ //delete old panels
+ delete m_CallbackPanels[i];
+ m_CallbackPanels[i] = NULL;
+ }
+ m_numCallbacks = SPGetNumberOfCallbacks( SPGetCurrentState() );
+ for ( i = 0; i < m_numCallbacks; i++ )
+ {
+ //create panels
+ AnsiString framename;
+ framename.sprintf("callbackframe%i", i );
+ TFrame4* f = new TFrame4( this , i );
+ f->Parent = CallbackPanel;
+ f->Name = framename;
+
+ //load the callbacks list
+ AnsiString fname = Application->ExeName;
+ fname.SetLength( fname.Length() - 13 );
+ fname.cat_sprintf("data\\callbacks.txt");
+ f->CallbackComboBox->Items->LoadFromFile(fname);
+
+ CallbackData cbData;
+ if ( SPGetCallbackData( SPGetCurrentState() , i , &cbData ) )
+ {
+ //set up events fields
+ AnsiString callbackname;
+ callbackname.sprintf( cbData.callbackName );
+ int cbindex = f->CallbackComboBox->Items->IndexOf( callbackname );
+ f->CallbackComboBox->ItemIndex = cbindex;
+ AnsiString onFrame;
+ onFrame.sprintf("%0.3f", cbData.onFrame );
+ f->OnFrameEditBox->Text = onFrame;
+ }
+ //add panel to panel list
+ m_CallbackPanels[i] = f;
+ }
+
+ for ( i = m_numCallbacks-1; i >= 0 ; i-- )
+ {
+ m_CallbackPanels[i]->Align = alTop;
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::Button2Click(TObject *Sender)
+{
+ SPAddCallback( SPGetCurrentState() , "" , 0 , 0.f );
+ UpdateCallbacks();
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::Save1Click(TObject *Sender)
+{
+ SaveData();
+}
+//---------------------------------------------------------------------------
+
+void TMainForm::SaveData()
+{
+ char buf[256];
+ memcpy( buf , FileName.c_str() , strlen(FileName.c_str()) - 4 );
+ buf[strlen(FileName.c_str()) - 4] = '\0';
+ strcat(buf , "data.p3d");
+
+ int attrib = get_file_attrib( buf );
+
+ if ( ( attrib & FA_RDONLY ) && ( attrib != -1 ) )
+ {
+ AnsiString out;
+ out.sprintf( "%s is read-only.\n" , FileName.c_str() );
+ if ( Application->MessageBox( out.c_str() , "" , MB_RETRYCANCEL ) == IDRETRY )
+ {
+ SaveData();
+ }
+ }
+ else
+ {
+ SPExportStatePropData( FileName.c_str() );
+ g_IsDataSaved = true;
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::FileSaveExecute(TObject *Sender)
+{
+ SaveData();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::AutoTransitionCheckBoxClick(TObject *Sender)
+{
+ bool autotransition = AutoTransitionCheckBox->State == cbChecked ? true : false;
+ SPSetAutoTransition( SPGetCurrentState() , autotransition );
+ g_ForceDataUpdate = true;
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::ToStateEditBoxChange(TObject *Sender)
+{
+ AnsiString toState = ToStateEditBox->Text;
+ int state = 0;
+ try
+ {
+ state = toState.ToInt();
+ }
+ catch (Exception&)
+ {
+ TransitionData tranData;
+ SPGetTransitionData( SPGetCurrentState() , &tranData );
+ state = tranData.toState + 1;
+ }
+ if ( state > SPGetNumberOfStates() || state <= 0 )
+ {
+ state = 1;
+ }
+ SPSetAutoTransitionToState( SPGetCurrentState() , state - 1 );
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::OnFrameEditBoxChange(TObject *Sender)
+{
+ AnsiString toframe = OnFrameEditBox->Text;
+ float frame = 0;
+ try
+ {
+ frame = toframe.ToDouble();
+ }
+ catch (Exception&)
+ {
+ TransitionData tranData;
+ SPGetTransitionData( SPGetCurrentState() , &tranData );
+ frame = tranData.onFrame;
+ }
+
+ SPSetAutoTransitionOnFrame( SPGetCurrentState() , frame );
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::Button4Click(TObject *Sender)
+{
+ AnsiString caption;
+ caption.sprintf("Delete State");
+ AnsiString out;
+ out.sprintf( "Delete State: %i\n It won't come back!", SPGetCurrentState() + 1 );
+ if ( Application->MessageBox(out.c_str() , caption.c_str() , MB_YESNO) != IDOK )
+ {
+ SPDeleteState( SPGetCurrentState() );
+ if ( SPGetCurrentState() - 1 >= 0 )
+ {
+ SPSetState( SPGetCurrentState() - 1 );
+ }
+ g_ForceDataUpdate = true;
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::Button3Click(TObject *Sender)
+{
+ SPInsertState( SPGetCurrentState() );
+ g_ForceDataUpdate = true;
+}
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+void __fastcall TMainForm::Button6Click(TObject *Sender)
+{
+ SPHideAll( SPGetCurrentState() );
+ g_ForceDataUpdate = true;
+ g_IsDataSaved = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::Button7Click(TObject *Sender)
+{
+ SPShowAll( SPGetCurrentState() );
+ g_ForceDataUpdate = true;
+ g_IsDataSaved = false;
+}
+
+//---------------------------------------------------------------------------
+void __fastcall TMainForm::B1Click(TObject *Sender)
+{
+ if ( ColorDialog1->Execute() )
+ {
+ TColor color = ColorDialog1->Color;
+ int blue = (int) ((color & 0x00ff0000) >> 16);
+ int green = (int) ((color & 0x0000ff00) >> 8);
+ int red = (int) ((color & 0x000000ff));
+ SPSetBackgroundColour( red , green , blue );
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::PDDICheckBoxClick(TObject *Sender)
+{
+ SPContextSetIsPDDIStatsEnabled( PDDICheckBox->Checked );
+}
+//---------------------------------------------------------------------------
+
+
+
+void __fastcall TMainForm::ToStateEditBoxExit(TObject *Sender)
+{
+ g_ForceDataUpdate = true;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::OnFrameEditBoxExit(TObject *Sender)
+{
+ g_ForceDataUpdate = true;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TMainForm::P3DBackgroundArt1Click(TObject *Sender)
+{
+ if (OpenDialog1->Execute())
+ {
+ SPLoadBackground( OpenDialog1->FileName.c_str() );
+ }
+}
+//---------------------------------------------------------------------------
+
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/main.dfm b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/main.dfm
new file mode 100644
index 0000000..0b6eee2
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/main.dfm
@@ -0,0 +1,783 @@
+object MainForm: TMainForm
+ Left = 197
+ Top = 118
+ Width = 1262
+ Height = 869
+ Caption = 'State Animation Builder'
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ Menu = MainMenu1
+ OldCreateOrder = False
+ OnClose = FormClose
+ OnKeyPress = FormKeyPress
+ OnShow = FormShow
+ PixelsPerInch = 96
+ TextHeight = 13
+ object Splitter2: TSplitter
+ Left = 0
+ Top = 628
+ Width = 1254
+ Height = 3
+ Cursor = crVSplit
+ Align = alBottom
+ end
+ object Splitter1: TSplitter
+ Left = 230
+ Top = 0
+ Width = 3
+ Height = 628
+ Cursor = crHSplit
+ end
+ object Panel2: TPanel
+ Left = 0
+ Top = 631
+ Width = 1254
+ Height = 192
+ Align = alBottom
+ BevelOuter = bvNone
+ TabOrder = 0
+ object Panel3: TPanel
+ Left = 0
+ Top = 0
+ Width = 1254
+ Height = 33
+ Align = alTop
+ BevelInner = bvLowered
+ TabOrder = 0
+ object Label1: TLabel
+ Left = 2
+ Top = 2
+ Width = 31
+ Height = 29
+ Align = alLeft
+ Caption = ' Prop: '
+ end
+ object PropNameLabel: TLabel
+ Left = 33
+ Top = 2
+ Width = 24
+ Height = 29
+ Align = alLeft
+ Caption = 'none'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clNavy
+ Font.Height = -12
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ end
+ object Label2: TLabel
+ Left = 124
+ Top = 2
+ Width = 26
+ Height = 29
+ Align = alLeft
+ Caption = ' Of: '
+ end
+ object NumPropStatesLabel: TLabel
+ Left = 150
+ Top = 2
+ Width = 6
+ Height = 29
+ Align = alLeft
+ Caption = '0'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clNavy
+ Font.Height = -12
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ end
+ object Label3: TLabel
+ Left = 57
+ Top = 2
+ Width = 61
+ Height = 29
+ Align = alLeft
+ Caption = ' State: '
+ end
+ object CurrentStateLabel: TLabel
+ Left = 118
+ Top = 2
+ Width = 6
+ Height = 29
+ Align = alLeft
+ Caption = '0'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clNavy
+ Font.Height = -12
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ end
+ object Label4: TLabel
+ Left = 720
+ Top = 7
+ Width = 29
+ Height = 13
+ Caption = 'Frame'
+ end
+ object PlayButton: TButton
+ Left = 560
+ Top = 5
+ Width = 30
+ Height = 20
+ Hint = 'Play / Pause'
+ Caption = '| |'
+ ParentShowHint = False
+ ShowHint = True
+ TabOrder = 0
+ OnClick = PlayButtonClick
+ end
+ object ForwardStepButton: TButton
+ Left = 592
+ Top = 5
+ Width = 30
+ Height = 20
+ Hint = 'Step Forward One Frame'
+ Caption = '> |'
+ ParentShowHint = False
+ ShowHint = True
+ TabOrder = 1
+ OnClick = ForwardStepButtonClick
+ end
+ object BackStepButton: TButton
+ Left = 528
+ Top = 5
+ Width = 30
+ Height = 20
+ Hint = 'Step Back One Frame'
+ Caption = '| <'
+ ParentShowHint = False
+ ShowHint = True
+ TabOrder = 2
+ OnClick = BackStepButtonClick
+ end
+ object CurrentFrameWindow: TEdit
+ Left = 760
+ Top = 4
+ Width = 60
+ Height = 21
+ Hint = 'Current Frame, seconds'
+ ParentShowHint = False
+ ShowHint = True
+ TabOrder = 3
+ end
+ object PrevStatebutton: TButton
+ Left = 495
+ Top = 5
+ Width = 30
+ Height = 20
+ Hint = 'Previous State'
+ Caption = '| <<'
+ ParentShowHint = False
+ ShowHint = True
+ TabOrder = 4
+ OnClick = PrevStatebuttonClick
+ end
+ object NextStateButton: TButton
+ Left = 624
+ Top = 5
+ Width = 30
+ Height = 20
+ Hint = 'Next State'
+ Caption = '>> |'
+ ParentShowHint = False
+ ShowHint = True
+ TabOrder = 5
+ OnClick = NextStateButtonClick
+ end
+ end
+ object Panel4: TScrollBox
+ Left = 0
+ Top = 33
+ Width = 1254
+ Height = 159
+ Align = alClient
+ BorderStyle = bsNone
+ TabOrder = 1
+ end
+ end
+ object Panel1: TPanel
+ Left = 0
+ Top = 0
+ Width = 230
+ Height = 628
+ Align = alLeft
+ BevelOuter = bvNone
+ TabOrder = 1
+ object PageControl1: TPageControl
+ Left = 0
+ Top = 0
+ Width = 230
+ Height = 628
+ ActivePage = TabSheet1
+ Align = alClient
+ MultiLine = True
+ TabOrder = 0
+ object TabSheet1: TTabSheet
+ Caption = 'Drawables'
+ object Panel12: TPanel
+ Left = 0
+ Top = 0
+ Width = 222
+ Height = 41
+ Align = alTop
+ BevelOuter = bvNone
+ TabOrder = 0
+ object Button6: TButton
+ Left = 8
+ Top = 8
+ Width = 75
+ Height = 25
+ Caption = 'Hide All'
+ TabOrder = 0
+ OnClick = Button6Click
+ end
+ object Button7: TButton
+ Left = 96
+ Top = 8
+ Width = 75
+ Height = 25
+ Caption = 'Show All'
+ TabOrder = 1
+ OnClick = Button7Click
+ end
+ end
+ object Panel5: TScrollBox
+ Left = 0
+ Top = 41
+ Width = 222
+ Height = 559
+ Align = alClient
+ BorderStyle = bsNone
+ TabOrder = 1
+ end
+ end
+ object TabSheet2: TTabSheet
+ Caption = 'Events'
+ ImageIndex = 1
+ object EventsPanel: TPanel
+ Left = 0
+ Top = 0
+ Width = 222
+ Height = 41
+ Align = alTop
+ BevelOuter = bvNone
+ TabOrder = 0
+ object Button1: TButton
+ Left = 8
+ Top = 8
+ Width = 75
+ Height = 25
+ Caption = 'Add Event'
+ TabOrder = 0
+ OnClick = Button1Click
+ end
+ end
+ object Panel6: TScrollBox
+ Left = 0
+ Top = 41
+ Width = 222
+ Height = 559
+ Align = alClient
+ BorderStyle = bsNone
+ TabOrder = 1
+ end
+ end
+ object TabSheet3: TTabSheet
+ Caption = 'Callbacks'
+ ImageIndex = 2
+ object Panel7: TPanel
+ Left = 0
+ Top = 0
+ Width = 222
+ Height = 600
+ Align = alClient
+ BevelOuter = bvNone
+ TabOrder = 0
+ object Panel8: TPanel
+ Left = 0
+ Top = 0
+ Width = 222
+ Height = 41
+ Align = alTop
+ BevelOuter = bvNone
+ TabOrder = 0
+ object Button2: TButton
+ Left = 8
+ Top = 8
+ Width = 75
+ Height = 25
+ Caption = 'Add Callback'
+ TabOrder = 0
+ OnClick = Button2Click
+ end
+ end
+ object CallbackPanel: TScrollBox
+ Left = 0
+ Top = 41
+ Width = 222
+ Height = 559
+ Align = alClient
+ BorderStyle = bsNone
+ TabOrder = 1
+ end
+ end
+ end
+ object TabSheet4: TTabSheet
+ Caption = 'State'
+ ImageIndex = 3
+ object Panel11: TPanel
+ Left = 0
+ Top = 0
+ Width = 222
+ Height = 265
+ Align = alTop
+ BevelOuter = bvNone
+ TabOrder = 0
+ object Label10: TLabel
+ Left = 7
+ Top = 10
+ Width = 34
+ Height = 16
+ Caption = 'State:'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -15
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ end
+ object StateStateLabel: TLabel
+ Left = 42
+ Top = 10
+ Width = 7
+ Height = 16
+ Caption = '0'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clNavy
+ Font.Height = -15
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ end
+ object Label6: TLabel
+ Left = 8
+ Top = 130
+ Width = 44
+ Height = 13
+ Caption = 'To State:'
+ end
+ object Label8: TLabel
+ Left = 8
+ Top = 154
+ Width = 49
+ Height = 13
+ Caption = 'On Frame:'
+ end
+ object AutoTransitionCheckBox: TCheckBox
+ Left = 8
+ Top = 105
+ Width = 97
+ Height = 17
+ Caption = 'Auto Transition'
+ TabOrder = 0
+ OnClick = AutoTransitionCheckBoxClick
+ end
+ object ToStateEditBox: TEdit
+ Left = 64
+ Top = 126
+ Width = 41
+ Height = 21
+ TabOrder = 1
+ OnChange = ToStateEditBoxChange
+ OnExit = ToStateEditBoxExit
+ end
+ object OnFrameEditBox: TEdit
+ Left = 64
+ Top = 150
+ Width = 41
+ Height = 21
+ TabOrder = 2
+ OnChange = OnFrameEditBoxChange
+ OnExit = OnFrameEditBoxExit
+ end
+ object Button4: TButton
+ Left = 8
+ Top = 64
+ Width = 75
+ Height = 25
+ Caption = 'Delete State'
+ TabOrder = 3
+ OnClick = Button4Click
+ end
+ object Button3: TButton
+ Left = 8
+ Top = 32
+ Width = 75
+ Height = 25
+ Caption = 'Add State'
+ TabOrder = 4
+ OnClick = Button3Click
+ end
+ object PDDICheckBox: TCheckBox
+ Left = 8
+ Top = 184
+ Width = 97
+ Height = 17
+ Caption = 'PDDI Stats'
+ TabOrder = 5
+ OnClick = PDDICheckBoxClick
+ end
+ end
+ end
+ end
+ end
+ object Panel9: TPanel
+ Left = 233
+ Top = 0
+ Width = 1021
+ Height = 628
+ Align = alClient
+ BevelOuter = bvNone
+ Caption = 'Panel9'
+ TabOrder = 2
+ object P3DClientPanel: TPanel
+ Left = 0
+ Top = 33
+ Width = 1021
+ Height = 595
+ Align = alClient
+ BevelInner = bvLowered
+ Caption = 'P3DClientPanel'
+ Color = clCaptionText
+ TabOrder = 0
+ OnResize = P3DClientPanelResize
+ object P3DPanel: TPanel
+ Left = 2
+ Top = 2
+ Width = 1065
+ Height = 793
+ BevelOuter = bvNone
+ Color = clActiveCaption
+ TabOrder = 0
+ OnMouseDown = P3DPanelMouseDown
+ OnMouseMove = P3DPanelMouseMove
+ OnMouseUp = P3DPanelMouseUp
+ end
+ end
+ object Panel10: TPanel
+ Left = 0
+ Top = 0
+ Width = 1021
+ Height = 33
+ Align = alTop
+ BevelInner = bvLowered
+ TabOrder = 1
+ object Label5: TLabel
+ Left = 10
+ Top = 7
+ Width = 41
+ Height = 20
+ Caption = 'Prop: '
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -16
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ end
+ object PropNameLabelTop: TLabel
+ Left = 56
+ Top = 7
+ Width = 36
+ Height = 20
+ Caption = 'none'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clNavy
+ Font.Height = -16
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ end
+ object NumPropStatesLabelTop: TLabel
+ Left = 309
+ Top = 7
+ Width = 9
+ Height = 20
+ Caption = '0'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clNavy
+ Font.Height = -16
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ end
+ object Label9: TLabel
+ Left = 210
+ Top = 7
+ Width = 43
+ Height = 20
+ Caption = 'State:'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -16
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ end
+ object CurrentStateLabelTop: TLabel
+ Left = 256
+ Top = 7
+ Width = 9
+ Height = 20
+ Caption = '0'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clNavy
+ Font.Height = -16
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ end
+ object Label7: TLabel
+ Left = 286
+ Top = 7
+ Width = 21
+ Height = 20
+ Caption = 'Of:'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -16
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ end
+ end
+ end
+ object ApplicationEvents1: TApplicationEvents
+ OnIdle = ApplicationEvents1Idle
+ Left = 1040
+ Top = 72
+ end
+ object MainMenu1: TMainMenu
+ Images = ImageList1
+ Left = 1072
+ Top = 72
+ object N1: TMenuItem
+ Caption = '&File'
+ object Open1: TMenuItem
+ Action = FileOpen
+ end
+ object Save1: TMenuItem
+ Action = FileSave
+ end
+ object Exit1: TMenuItem
+ Action = FileExit
+ end
+ end
+ object Edit1: TMenuItem
+ Caption = '&Edit'
+ object B1: TMenuItem
+ Caption = '&Background Color'
+ OnClick = B1Click
+ end
+ object P3DBackgroundArt1: TMenuItem
+ Caption = '&P3D Background Art'
+ OnClick = P3DBackgroundArt1Click
+ end
+ end
+ object Help1: TMenuItem
+ Caption = '&Help'
+ object About1: TMenuItem
+ Action = HelpAbout
+ end
+ end
+ end
+ object ActionList1: TActionList
+ Left = 1136
+ Top = 72
+ object FileOpen: TAction
+ Category = 'File'
+ Caption = '&Open'
+ Hint = 'Open File'
+ ImageIndex = 0
+ OnExecute = FileOpenExecute
+ end
+ object FileSave: TAction
+ Category = 'File'
+ Caption = '&Save'
+ Hint = 'Save File'
+ ImageIndex = 1
+ OnExecute = FileSaveExecute
+ end
+ object FileExit: TAction
+ Category = 'File'
+ Caption = '&Exit'
+ Hint = 'Exit Application'
+ end
+ object HelpAbout: TAction
+ Category = 'Help'
+ Caption = '&About'
+ end
+ end
+ object ImageList1: TImageList
+ Left = 1104
+ Top = 72
+ Bitmap = {
+ 494C010102000400040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
+ 0000000000003600000028000000400000001000000001002000000000000010
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000008484000084
+ 8400000000000000000000000000000000000000000000000000C6C6C600C6C6
+ C600000000000084840000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000008484000084
+ 8400008484000084840000848400008484000084840000848400008484000000
+ 0000000000000000000000000000000000000000000000000000008484000084
+ 8400000000000000000000000000000000000000000000000000C6C6C600C6C6
+ C600000000000084840000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000FFFF00000000000084
+ 8400008484000084840000848400008484000084840000848400008484000084
+ 8400000000000000000000000000000000000000000000000000008484000084
+ 8400000000000000000000000000000000000000000000000000C6C6C600C6C6
+ C600000000000084840000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000000000000FFFFFF0000FFFF000000
+ 0000008484000084840000848400008484000084840000848400008484000084
+ 8400008484000000000000000000000000000000000000000000008484000084
+ 8400000000000000000000000000000000000000000000000000000000000000
+ 0000000000000084840000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000FFFF00FFFFFF0000FF
+ FF00000000000084840000848400008484000084840000848400008484000084
+ 8400008484000084840000000000000000000000000000000000008484000084
+ 8400008484000084840000848400008484000084840000848400008484000084
+ 8400008484000084840000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000000000000FFFFFF0000FFFF00FFFF
+ FF0000FFFF000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000008484000084
+ 8400000000000000000000000000000000000000000000000000000000000000
+ 0000008484000084840000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000FFFF00FFFFFF0000FF
+ FF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00000000000000
+ 0000000000000000000000000000000000000000000000000000008484000000
+ 0000C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6
+ C600000000000084840000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000000000000FFFFFF0000FFFF00FFFF
+ FF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF00000000000000
+ 0000000000000000000000000000000000000000000000000000008484000000
+ 0000C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6
+ C600000000000084840000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000FFFF00FFFFFF0000FF
+ FF00000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000008484000000
+ 0000C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6
+ C600000000000084840000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000008484000000
+ 0000C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6
+ C600000000000084840000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000008484000000
+ 0000C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6
+ C600000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000008484000000
+ 0000C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6C600C6C6
+ C60000000000C6C6C60000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000424D3E000000000000003E000000
+ 2800000040000000100000000100010000000000800000000000000000000000
+ 000000000000000000000000FFFFFF00FFFFFFFF00000000FFFFC00100000000
+ 001F800100000000000F80010000000000078001000000000003800100000000
+ 00018001000000000000800100000000001F800100000000001F800100000000
+ 001F8001000000008FF1800100000000FFF9800100000000FF75800100000000
+ FF8F800100000000FFFFFFFF0000000000000000000000000000000000000000
+ 000000000000}
+ end
+ object OpenDialog1: TOpenDialog
+ DefaultExt = 'p3d'
+ Filter = 'P3D|*.p3d|All files|*.*'
+ Title = 'Open File'
+ Left = 1042
+ Top = 112
+ end
+ object ColorDialog1: TColorDialog
+ Ctl3D = True
+ Left = 1075
+ Top = 115
+ end
+end
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/main.h b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/main.h
new file mode 100644
index 0000000..23fc13d
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/main.h
@@ -0,0 +1,163 @@
+//---------------------------------------------------------------------------
+
+#ifndef mainH
+#define mainH
+//---------------------------------------------------------------------------
+#include <Classes.hpp>
+#include <Controls.hpp>
+#include <StdCtrls.hpp>
+#include <Forms.hpp>
+#include <AppEvnts.hpp>
+#include <ExtCtrls.hpp>
+#include <ComCtrls.hpp>
+#include <Menus.hpp>
+#include <ActnList.hpp>
+#include <ImgList.hpp>
+#include <Dialogs.hpp>
+#include <CheckLst.hpp>
+#include "fcframe.h"
+#include "visframe.h"
+#include "eventsframe.h"
+#include "callbacksframe.h"
+
+//---------------------------------------------------------------------------
+class TMainForm : public TForm
+{
+__published: // IDE-managed Components
+ TApplicationEvents *ApplicationEvents1;
+ TSplitter *Splitter2;
+ TPanel *Panel2;
+ TPanel *Panel1;
+ TSplitter *Splitter1;
+ TMainMenu *MainMenu1;
+ TMenuItem *N1;
+ TMenuItem *Open1;
+ TMenuItem *Save1;
+ TActionList *ActionList1;
+ TImageList *ImageList1;
+ TAction *FileOpen;
+ TAction *FileSave;
+ TAction *FileExit;
+ TAction *HelpAbout;
+ TMenuItem *Exit1;
+ TMenuItem *Edit1;
+ TMenuItem *Help1;
+ TMenuItem *About1;
+ TOpenDialog *OpenDialog1;
+ TPanel *Panel3;
+ TLabel *Label1;
+ TLabel *PropNameLabel;
+ TLabel *Label2;
+ TLabel *NumPropStatesLabel;
+ TLabel *Label3;
+ TLabel *CurrentStateLabel;
+ TButton *PlayButton;
+ TButton *ForwardStepButton;
+ TButton *BackStepButton;
+ TEdit *CurrentFrameWindow;
+ TButton *PrevStatebutton;
+ TButton *NextStateButton;
+ TLabel *Label4;
+ TPageControl *PageControl1;
+ TTabSheet *TabSheet1;
+ TTabSheet *TabSheet2;
+ TTabSheet *TabSheet3;
+ TPanel *EventsPanel;
+ TButton *Button1;
+ TPanel *Panel7;
+ TPanel *Panel8;
+ TButton *Button2;
+ TPanel *Panel9;
+ TPanel *P3DClientPanel;
+ TPanel *P3DPanel;
+ TPanel *Panel10;
+ TLabel *Label5;
+ TLabel *PropNameLabelTop;
+ TLabel *NumPropStatesLabelTop;
+ TLabel *Label9;
+ TLabel *CurrentStateLabelTop;
+ TTabSheet *TabSheet4;
+ TPanel *Panel11;
+ TLabel *Label10;
+ TLabel *StateStateLabel;
+ TCheckBox *AutoTransitionCheckBox;
+ TLabel *Label6;
+ TEdit *ToStateEditBox;
+ TLabel *Label8;
+ TEdit *OnFrameEditBox;
+ TButton *Button4;
+ TButton *Button3;
+ TLabel *Label7;
+ TPanel *Panel12;
+ TButton *Button6;
+ TButton *Button7;
+ TScrollBox *Panel5;
+ TScrollBox *Panel6;
+ TScrollBox *CallbackPanel;
+ TScrollBox *Panel4;
+ TMenuItem *B1;
+ TColorDialog *ColorDialog1;
+ TCheckBox *PDDICheckBox;
+ TMenuItem *P3DBackgroundArt1;
+ void __fastcall ApplicationEvents1Idle(TObject *Sender,
+ bool &Done);
+ void __fastcall FormShow(TObject *Sender);
+ void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
+ void __fastcall P3DClientPanelResize(TObject *Sender);
+ void __fastcall FileOpenExecute(TObject *Sender);
+ void __fastcall P3DPanelMouseDown(TObject *Sender,
+ TMouseButton Button, TShiftState Shift, int X, int Y);
+ void __fastcall P3DPanelMouseMove(TObject *Sender,
+ TShiftState Shift, int X, int Y);
+ void __fastcall P3DPanelMouseUp(TObject *Sender,
+ TMouseButton Button, TShiftState Shift, int X, int Y);
+ void __fastcall FormKeyPress(TObject *Sender, char &Key);
+ void __fastcall PlayButtonClick(TObject *Sender);
+ void __fastcall PrevStatebuttonClick(TObject *Sender);
+ void __fastcall NextStateButtonClick(TObject *Sender);
+ void __fastcall ForwardStepButtonClick(TObject *Sender);
+ void __fastcall BackStepButtonClick(TObject *Sender);
+ void __fastcall Button1Click(TObject *Sender);
+ void __fastcall Button2Click(TObject *Sender);
+ void __fastcall Save1Click(TObject *Sender);
+ void __fastcall FileSaveExecute(TObject *Sender);
+ void __fastcall AutoTransitionCheckBoxClick(TObject *Sender);
+ void __fastcall ToStateEditBoxChange(TObject *Sender);
+ void __fastcall OnFrameEditBoxChange(TObject *Sender);
+ void __fastcall Button4Click(TObject *Sender);
+ void __fastcall Button3Click(TObject *Sender);
+ void __fastcall Button6Click(TObject *Sender);
+ void __fastcall Button7Click(TObject *Sender);
+ void __fastcall B1Click(TObject *Sender);
+ void __fastcall PDDICheckBoxClick(TObject *Sender);
+ void __fastcall ToStateEditBoxExit(TObject *Sender);
+ void __fastcall OnFrameEditBoxExit(TObject *Sender);
+ void __fastcall P3DBackgroundArt1Click(TObject *Sender);
+private: // User declarations
+ int m_CurrentPropState;
+ int m_numFCPanels;
+ TFrame1* m_FCPanels[250];
+ int m_numDrawablePanels;
+ TFrame2* m_DrawablePanels[250];
+ int m_numEvents;
+ TFrame3* m_EventPanels[250];
+ int m_numCallbacks;
+ TFrame4* m_CallbackPanels[250];
+ int m_numForces;
+
+ void UpdateStateInfo();
+ void UpdateFrameControllers();
+ void UpdateDrawables();
+ void UpdateEvents();
+ void UpdateCallbacks();
+ void SaveData();
+
+public: // User declarations
+ __fastcall TMainForm(TComponent* Owner);
+
+ AnsiString FileName;
+};
+//---------------------------------------------------------------------------
+extern PACKAGE TMainForm *MainForm;
+//---------------------------------------------------------------------------
+#endif
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/visframe.cpp b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/visframe.cpp
new file mode 100644
index 0000000..66f224e
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/visframe.cpp
@@ -0,0 +1,24 @@
+//---------------------------------------------------------------------------
+
+#include <vcl.h>
+#include <sp/interface.hpp>
+#pragma hdrstop
+
+#include "visframe.h"
+//---------------------------------------------------------------------------
+#pragma package(smart_init)
+#pragma resource "*.dfm"
+TFrame2 *Frame2;
+//---------------------------------------------------------------------------
+__fastcall TFrame2::TFrame2(TComponent* Owner , int dindex )
+ : TFrame(Owner),
+ m_DrawableIndex( dindex )
+{
+}
+//---------------------------------------------------------------------------
+void __fastcall TFrame2::VisibilityCheckBoxClick(TObject *Sender)
+{
+ SPSetVisible( SPGetCurrentState() , m_DrawableIndex , this->VisibilityCheckBox->State != cbUnchecked );
+}
+//---------------------------------------------------------------------------
+
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/visframe.dfm b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/visframe.dfm
new file mode 100644
index 0000000..c9010d2
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/visframe.dfm
@@ -0,0 +1,42 @@
+object Frame2: TFrame2
+ Left = 0
+ Top = 0
+ Width = 152
+ Height = 43
+ TabOrder = 0
+ object Panel1: TPanel
+ Left = 0
+ Top = 0
+ Width = 152
+ Height = 43
+ Align = alClient
+ BevelInner = bvLowered
+ TabOrder = 0
+ object NameLabel: TLabel
+ Left = 8
+ Top = 5
+ Width = 26
+ Height = 13
+ Caption = 'name'
+ Color = clSilver
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clNavy
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentColor = False
+ ParentFont = False
+ end
+ object VisibilityCheckBox: TCheckBox
+ Left = 8
+ Top = 21
+ Width = 97
+ Height = 17
+ Caption = 'Visible'
+ ParentShowHint = False
+ ShowHint = False
+ TabOrder = 0
+ OnClick = VisibilityCheckBoxClick
+ end
+ end
+end
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/builder/visframe.h b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/visframe.h
new file mode 100644
index 0000000..aacf3da
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/builder/visframe.h
@@ -0,0 +1,28 @@
+//---------------------------------------------------------------------------
+
+
+#ifndef visframeH
+#define visframeH
+//---------------------------------------------------------------------------
+#include <Classes.hpp>
+#include <Controls.hpp>
+#include <StdCtrls.hpp>
+#include <Forms.hpp>
+#include <ExtCtrls.hpp>
+//---------------------------------------------------------------------------
+class TFrame2 : public TFrame
+{
+__published: // IDE-managed Components
+ TPanel *Panel1;
+ TCheckBox *VisibilityCheckBox;
+ TLabel *NameLabel;
+ void __fastcall VisibilityCheckBoxClick(TObject *Sender);
+private: // User declarations
+ int m_DrawableIndex;
+public: // User declarations
+ __fastcall TFrame2(TComponent* Owner , int dindex );
+};
+//---------------------------------------------------------------------------
+extern PACKAGE TFrame2 *Frame2;
+//---------------------------------------------------------------------------
+#endif
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/engine/aicollisionsolveragent.cpp b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/aicollisionsolveragent.cpp
new file mode 100644
index 0000000..2c10a5b
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/aicollisionsolveragent.cpp
@@ -0,0 +1,59 @@
+
+
+#include "aicollisionsolveragent.hpp"
+#include "simcollision/collisionanalyserdata.hpp"
+
+AICollisionSolverAgent::AICollisionSolverAgent()
+{
+ EnableCollisionAnalyser();
+}
+
+AICollisionSolverAgent::~AICollisionSolverAgent()
+{
+ DisableCollisionAnalyser();
+}
+
+
+// =======================================================
+// PRE_COLLISION_EVENT
+//
+sim::Solving_Answer AICollisionSolverAgent::PreCollisionEvent(sim::Collision& inCollision, int inPass)
+{
+ return sim::Solving_Continue;
+}
+
+
+// =======================================================
+// COLLISION_EVENT
+//
+sim::Solving_Answer AICollisionSolverAgent::CollisionEvent(
+ sim::SimState* inSimStateA, int indexA,
+ sim::SimState* inSimStateB, int indexB,
+ const rmt::Vector& inPos, float inDvN, float inDvT)
+{
+
+ return sim::Solving_Continue;
+}
+
+
+// =======================================================
+// TEST_IMPULSE
+//
+sim::Solving_Answer AICollisionSolverAgent::TestImpulse(rmt::Vector& mImpulse,
+ sim::Collision& inCollision)
+{
+ sim::SimState* inSimStateA = inCollision.mCollisionObjectA->GetSimState();
+ sim::SimState* inSimStateB = inCollision.mCollisionObjectB->GetSimState();
+
+ return sim::Solving_Continue;
+}
+
+// =======================================================
+// END_OBJECT_COLLISION
+//
+sim::Solving_Answer AICollisionSolverAgent::EndObjectCollision(
+ sim::SimState* inSimState,
+ int inIndex)
+{
+ return sim::Solving_Continue;
+} \ No newline at end of file
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/engine/aicollisionsolveragent.hpp b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/aicollisionsolveragent.hpp
new file mode 100644
index 0000000..10097a8
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/aicollisionsolveragent.hpp
@@ -0,0 +1,43 @@
+#ifndef _AICOLLISIONSOLVERAGENT_HPP_
+#define _AICOLLISIONSOLVERAGENT_HPP_
+
+#include "simcommon/tlist.hpp"
+#include "simcollision/impulsebasedcollisionsolver.hpp"
+#include "simcollision/collisionanalyser.hpp"
+#include "simcollision/collisionanalyserdata.hpp"
+
+class AICollisionSolverAgent
+: public sim::CollisionSolverAgent
+{
+public:
+ AICollisionSolverAgent();
+ ~AICollisionSolverAgent();
+
+ //
+ // this method is called at the beginning before anything is done with the collision
+ // returning Solving_Aborted would cause the collision to be ignored.
+ //
+ sim::Solving_Answer PreCollisionEvent(sim::Collision& inCollision, int inPass);
+
+ //
+ // this method allows to trigger sounds, animation and modify the objects state.
+ //
+ sim::Solving_Answer CollisionEvent( sim::SimState* inSimStateA, int indexA,
+ sim::SimState* inSimStateB, int indexB,
+ const rmt::Vector& inPos, float inDvN, float inDvT);
+
+ //
+ // this is called everytime an impulse is computed, before it gets added to the objects
+ //
+ sim::Solving_Answer TestImpulse(rmt::Vector& mImpulse, sim::Collision& inCollision);
+
+ //
+ // the impulse has been added to the object's cache, testing that cache tells
+ // the consequence of adding the cache to the object's state. It is also a good
+ // time for adding the cache of the root node of an articulated object to its
+ // virtual center of mass.
+ //
+ sim::Solving_Answer EndObjectCollision(sim::SimState* inSimState, int inIndex);
+};
+
+#endif \ No newline at end of file
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/engine/context.cpp b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/context.cpp
new file mode 100644
index 0000000..f994e0d
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/context.cpp
@@ -0,0 +1,792 @@
+/*
+ * sp/engine/context.cpp
+ */
+
+
+#include <SP/engine/workspace.hpp>
+#include <SP/engine/context.hpp>
+#include <SP/interface/context.hpp>
+
+
+//#include <SP/engine/project.hpp>
+//#include <choreo/load.hpp>
+
+#include <p3d/context.hpp>
+#include <p3d/utility.hpp>
+#include <p3d/view.hpp>
+#include <p3d/directionallight.hpp>
+#include <p3d/pointcamera.hpp>
+#include <p3d/geometry.hpp>
+#include <p3d/anim/drawablepose.hpp>
+#include <radload/radload.hpp>
+
+#include <radtime.hpp>
+#include <radplatform.hpp>
+
+#include <shlwapi.h>
+
+#include <typeinfo>
+
+
+#ifdef RAD_DEBUG
+static const char* pddiDLL = "pddidx8d.dll";
+#endif
+
+#ifdef RAD_TUNE
+static const char* pddiDLL = "pddidx8t.dll";
+#endif
+
+#ifdef RAD_RELEASE
+static const char* pddiDLL = "pddidx8r.dll";
+#endif
+
+
+// global SPContext reference
+SPContext* g_SPContext = 0;
+
+extern Workspace* g_Workspace;
+
+
+//---------------------------------------------------------------------------
+// class SPContext - implementation
+//---------------------------------------------------------------------------
+
+SPContext::SPContext(HWND hwnd):
+ m_HWnd(hwnd),
+
+ m_Context(0),
+ m_View(0),
+ m_Camera(0),
+ m_Light(0),
+ m_Shader(0),
+
+ m_CurrentTime(-1.0f),
+ m_FPSIndex(0),
+ m_SimRate(1.0f),
+
+ m_MouseCapture(0),
+ m_MouseX(0),
+ m_MouseY(0),
+
+ m_IsCameraLocked(false)
+{
+ memset(m_FPS, 0, sizeof(m_FPS));
+}
+
+SPContext::~SPContext()
+{
+ tRefCounted::Release(m_Shader);
+ tRefCounted::Release(m_Light);
+ tRefCounted::Release(m_Camera);
+ tRefCounted::Release(m_View);
+}
+
+bool SPContext::Open()
+{
+ // p3d context init
+ RECT wndRect;
+ GetWindowRect(m_HWnd, &wndRect);
+
+ tContextInitData init;
+ init.hwnd = m_HWnd;
+ init.displayMode = PDDI_DISPLAY_WINDOW;
+ init.bufferMask = PDDI_BUFFER_COLOUR | PDDI_BUFFER_DEPTH;
+ int wndWidth = wndRect.right - wndRect.left;
+ int wndHeight = wndRect.bottom - wndRect.top;
+ init.xsize = wndWidth;
+ init.ysize = wndHeight;
+ init.bpp = 32;
+ strcpy(init.PDDIlib, pddiDLL);
+
+ //p3d::platform->SetActiveContext(0);
+ m_Context = p3d::platform->CreateContext(&init);
+ if (m_Context == 0)
+ return false;
+
+ p3d::platform->SetActiveContext(m_Context);
+
+ // Call into PDDI to enable Z-buffering.
+ p3d::pddi->EnableZBuffer(true);
+
+
+ radLoadInitialize();
+
+ // This call installs chunk handlers for all the primary chunk types that
+ // Pure3D supports. This includes textures, materials, geometries, and the
+ // like.
+ p3d::InstallDefaultLoaders();
+
+ // install default choreo loaders
+ //choreo::InstallDefaultLoaders();
+
+ // p3d view init
+ m_View = new tView;
+ m_View->AddRef();
+
+ m_View->SetBackgroundColour(tColour(64, 64, 128));
+ m_View->SetAmbientLight(tColour(40, 40, 40));
+
+ // p3d light init
+ m_Light = new tDirectionalLight;
+ m_Light->AddRef();
+
+ m_Light->SetDirection(0.0f, 0.0f, 1.0f);
+ m_Light->SetColour(tColour(255, 255, 255));
+ m_View->AddLight(m_Light);
+
+ // p3d camera init
+ m_Camera = new tPointCamera;
+ m_Camera->AddRef();
+ m_Camera->SetNearPlane(0.01f);
+ m_Camera->SetFarPlane(5000.0f);
+ m_Camera->SetFOV(rmt::DegToRadian(90.0f), (float)wndWidth / (float)wndHeight);
+ m_View->SetCamera(m_Camera);
+
+ m_CameraTarget.Clear();
+ m_CameraRotateX = rmt::DegToRadian(-45.0f);
+ m_CameraRotateY = 0.0f;
+ m_CameraDistance = 5.0f;
+
+ // pddi shader
+ m_Shader = p3d::device->NewShader("simple");
+ m_Shader->AddRef();
+ m_Shader->SetInt(PDDI_SP_ISLIT, 0);
+
+ // workspace create
+ if (g_Workspace == 0)
+ {
+ g_Workspace = new Workspace;
+ g_Workspace->AddRef();
+ }
+
+ return true;
+}
+
+bool SPContext::Close()
+{
+ // p3d release stuff
+ tRefCounted::Release(m_Shader);
+ tRefCounted::Release(m_Light);
+ tRefCounted::Release(m_Camera);
+ tRefCounted::Release(m_View);
+
+ // p3d context destroy
+ if (m_Context != 0)
+ {
+ p3d::platform->DestroyContext(m_Context);
+ m_Context = 0;
+ }
+
+ radLoadTerminate();
+
+ return true;
+}
+
+bool SPContext::ViewResize(int w, int h)
+{
+ if (w <= 0)
+ w = 1;
+ if (h <= 0)
+ h = 1;
+
+ RECT wndRect;
+ GetWindowRect(m_HWnd, &wndRect);
+ int wndWidth = wndRect.right - wndRect.left;
+ if (wndWidth <= 0)
+ wndWidth = 1;
+ int wndHeight = wndRect.bottom - wndRect.top;
+ if (wndHeight <= 0)
+ wndHeight = 1;
+
+ if (w > wndWidth)
+ w = wndWidth;
+ if (h > wndHeight)
+ h = wndHeight;
+
+ m_View->SetWindow(0.0f, 0.0f, (float)w / (float)wndWidth, (float)h / (float)wndHeight);
+ m_Camera->SetFOV(rmt::DegToRadian(90.0f), (float)w / (float)h);
+
+ return true;
+}
+
+bool SPContext::Advance()
+{
+ // do time
+ float deltaTime;
+ {
+ float newTime = (float)radTimeGetMilliseconds() / 1000.0f;
+
+ if (m_CurrentTime < 0.0f)
+ {
+ deltaTime = 0.0f;
+ m_CurrentTime = newTime;
+ }
+ else
+ {
+ deltaTime = newTime - m_CurrentTime;
+
+ if (deltaTime < 0.0f)
+ {
+ deltaTime = 0.0f;
+ }
+ else
+ {
+ m_CurrentTime = newTime;
+ }
+
+ // for debugging
+ if (deltaTime > 1.0f)
+ {
+ deltaTime = 1.0f / 60.0f;
+ }
+ else
+ {
+ // do fps
+ m_FPS[m_FPSIndex] = deltaTime;
+ m_FPSIndex = (m_FPSIndex + 1) % MAX_FPS_COUNT;
+ }
+ }
+ }
+
+ float simDeltaTime = m_SimRate * deltaTime;
+ if ( g_Workspace )
+ {
+ g_Workspace->Advance(simDeltaTime * 1000.0f);
+ }
+
+ // update camera & light
+ {
+ /*if (m_IsCameraLocked)
+ {
+ rmt::Vector desiredTarget = m_CVPuppet->GetCameraTarget();
+
+ rmt::Vector delta = desiredTarget;
+ delta.Sub(m_CameraTarget);
+ float mag = delta.NormalizeSafe();
+
+ static const float cameraSpeed = 1.5f; // m/s
+ float maxMag = cameraSpeed * deltaTime * mag;
+ if (mag > maxMag)
+ {
+ mag = maxMag;
+ }
+
+ delta.Scale(mag);
+ m_CameraTarget.Add(delta);
+ m_CameraTarget.x = desiredTarget.x;
+ m_CameraTarget.z = desiredTarget.z;
+ }*/
+
+ m_Camera->SetTarget(m_CameraTarget);
+ rmt::Matrix mY;
+ mY.FillRotateY(m_CameraRotateY);
+ rmt::Matrix mX;
+ mX.FillRotateX(m_CameraRotateX);
+ rmt::Vector cameraPos(0.0f, 0.0f, m_CameraDistance);
+ cameraPos.Rotate(mX);
+ cameraPos.Rotate(mY);
+ cameraPos.Add(m_CameraTarget);
+ m_Camera->SetPosition(cameraPos);
+
+ rmt::Vector lightDir;
+ lightDir = m_CameraTarget;
+ lightDir.Sub(cameraPos);
+ m_Light->SetDirection(lightDir);
+ }
+
+ //return rc;
+ return true;
+}
+
+bool SPContext::Display()
+{
+ m_Context->BeginFrame();
+ m_View->BeginRender();
+
+ // render game context
+ if ( g_Workspace )
+ {
+ g_Workspace->Display(m_Context);
+ }
+
+ // draw origin
+ {
+ rmt::Matrix m;
+ m.Identity();
+ DrawAxes(m, 0.5f);
+ }
+
+ m_View->EndRender();
+ m_Context->EndFrame();
+
+ //return rc;
+ return true;
+}
+
+void SPContext::DrawAxes(const rmt::Matrix& m, float radius)
+{
+ rmt::Vector oldVtx[4] =
+ {
+ rmt::Vector(0,0,0),
+ rmt::Vector(radius,0,0),
+ rmt::Vector(0,radius,0),
+ rmt::Vector(0,0,radius)
+ };
+ rmt::Vector newVtx[4];
+ m.Transform(4, oldVtx, newVtx);
+
+ pddiPrimStream* stream = p3d::pddi->BeginPrims(m_Shader, PDDI_PRIM_LINES, PDDI_V_C , 6);
+
+ stream->Vertex((pddiVector*)newVtx, pddiColour(255,0,0));
+ stream->Vertex((pddiVector*)(newVtx + 1), pddiColour(255,0,0));
+
+ stream->Vertex((pddiVector*)newVtx, pddiColour(0,255,0));
+ stream->Vertex((pddiVector*)(newVtx + 2), pddiColour(0,255,0));
+
+ stream->Vertex((pddiVector*)newVtx, pddiColour(0,0,255));
+ stream->Vertex((pddiVector*)(newVtx + 3), pddiColour(0,0,255));
+
+ p3d::pddi->EndPrims(stream);
+}
+
+void SPContext::DrawLine(const rmt::Vector& a, const rmt::Vector& b, tColour c)
+{
+ pddiPrimStream* stream = p3d::pddi->BeginPrims(m_Shader, PDDI_PRIM_LINES, PDDI_V_C , 2 );
+ stream->Vertex((pddiVector*)(&a), c);
+ stream->Vertex((pddiVector*)(&b), c);
+ p3d::pddi->EndPrims(stream);
+}
+
+void SPContext::RenderPose(tPose* pose)
+{
+ pose->Evaluate();
+
+ int i;
+ int startJoint = 0;
+ for (i = startJoint; i < pose->GetNumJoint(); ++i)
+ {
+ tPose::Joint* joint = pose->GetJoint(i);
+ tPose::Joint* parent = joint->parent;
+
+ if (parent != 0)
+ {
+ DrawLine(parent->worldMatrix.Row(3), joint->worldMatrix.Row(3), tColour(255,255,255));
+ DrawAxes(parent->worldMatrix, 0.02f);
+ }
+ }
+}
+
+void SPContext::MouseDown(int button, int shift, int x, int y)
+{
+ if (m_MouseCapture == 0)
+ {
+ SetCapture(m_HWnd);
+ m_MouseCapture = 1;
+ }
+
+ m_MouseX = x;
+ m_MouseY = y;
+}
+
+void SPContext::MouseMove(int button, int shift, int x, int y)
+{
+ if (m_MouseCapture == 0)
+ return;
+ if (GetCapture() != m_HWnd)
+ return;
+
+ int dx = x - m_MouseX;
+ int dy = y - m_MouseY;
+ m_MouseX = x;
+ m_MouseY = y;
+
+ if ((button & MK_LBUTTON) != 0)
+ {
+ if ((button & MK_MBUTTON) != 0)
+ {
+ CameraZoom(dx * 10);
+ }
+ else
+ {
+ CameraRotate(dx, dy);
+ }
+ }
+ else if ((button & MK_MBUTTON) != 0)
+ {
+ CameraPan(dx, dy);
+ }
+}
+
+void SPContext::MouseUp(int button, int shift, int x, int y)
+{
+ MouseMove(button, shift, x, y);
+
+ if (m_MouseCapture == 0)
+ return;
+
+ ReleaseCapture();
+ m_MouseCapture = 0;
+}
+
+void SPContext::MouseWheel(int scroll)
+{
+ CameraZoom(scroll);
+}
+
+void SPContext::CameraPan(int dx, int dy)
+{
+ RECT wndRect;
+ GetWindowRect(m_HWnd, &wndRect);
+
+ rmt::Vector v((float)-dx / (float)(wndRect.right - wndRect.left),
+ (float)dy / (float)(wndRect.bottom - wndRect.top), 0.0f);
+ rmt::Vector a, b;
+ m_Camera->ViewToWorld(v, &a, &b);
+ b.Sub(a);
+ b.NormalizeSafe();
+ b.Scale(m_CameraDistance - m_Camera->GetNearPlane());
+ b.Add(a);
+ m_CameraTarget = b;
+}
+
+void SPContext::CameraZoom(int dz)
+{
+ m_CameraDistance += ((float)-dz * 0.001f * m_CameraDistance);
+
+ if (m_CameraDistance < 0.1f)
+ {
+ m_CameraDistance = 0.1f;
+ }
+}
+
+void SPContext::CameraRotate(int dx, int dy)
+{
+ m_CameraRotateX += ((float)-dy * 0.01f);
+
+ if (m_CameraRotateX > rmt::DegToRadian(89.9f))
+ {
+ m_CameraRotateX = rmt::DegToRadian(89.9f);
+ }
+
+ if (m_CameraRotateX < rmt::DegToRadian(-89.9f))
+ {
+ m_CameraRotateX = rmt::DegToRadian(-89.9f);
+ }
+
+ m_CameraRotateY += ((float)dx * 0.01f);
+}
+
+float SPContext::SimulationGetFPS() const
+{
+ float fps = 0.0f;
+
+ for (int i = 0; i < MAX_FPS_COUNT; ++i)
+ {
+ fps += m_FPS[i];
+ }
+
+ fps /= (float)MAX_FPS_COUNT;
+
+ if (!rmt::Epsilon(fps, 0.0f))
+ {
+ fps = 1.0f / fps;
+ }
+
+ return fps;
+}
+
+void SPContext::SimulationSetRate(float simRate)
+{
+ m_SimRate = simRate;
+
+ if (m_SimRate < 0.0f)
+ {
+ m_SimRate = 0.0f;
+ }
+}
+
+bool SPContext::GetEntityName(tEntity* entity, char* name, int maxLen)
+{
+ if (maxLen > 0)
+ {
+ name[0] = 0;
+ }
+
+ if (entity == 0)
+ return false;
+
+ if (entity->GetName() != 0)
+ {
+ _snprintf(name, maxLen, "%s", entity->GetName());
+ }
+ else
+ {
+ _snprintf(name, maxLen, "0x%016I64x", entity->GetUID());
+ }
+
+ if (maxLen > 0)
+ {
+ name[maxLen - 1] = 0;
+ }
+
+ return true;
+}
+
+void SPContext::InventoryClear()
+{
+ if (m_Context != 0)
+ {
+ m_Context->GetInventory()->RemoveAllElements();
+ }
+}
+
+int SPContext::InventoryGetEntityCount() const
+{
+ if (m_Context == 0)
+ return 0;
+
+ int entityCount = 0;
+ /*
+ for (int s = 0; s < m_Context->GetInventory()->GetSectionCount(); ++s)
+ {
+ entityCount += m_Context->GetInventory()->GetSectionByIndex(s)->GetElementCount();
+ }
+ */
+
+ return entityCount;
+}
+
+bool SPContext::InventoryGetEntityName(int index,
+ char* name, int nameLen,
+ char* type, int typeLen) const
+{
+ int entityCount = 0;
+
+ /*
+ for (int s = 0; s < m_Context->GetInventory()->GetSectionCount(); ++s)
+ {
+ tEntityTable::RawIterator itor(m_Context->GetInventory()->GetSectionByIndex(s));
+
+ tEntity* obj = itor.First();
+ while (obj)
+ {
+ if (entityCount == index)
+ {
+ GetEntityName(obj, name, nameLen);
+ _snprintf(type, typeLen, "%s", typeid(*obj).name());
+ type[typeLen - 1] = '\0';
+
+ return true;
+ }
+
+ ++entityCount;
+ obj = itor.Next();
+ }
+ }
+ */
+
+ return false;
+}
+
+void SPContext::SetBackgroundColour(int r , int g , int b )
+{
+ m_View->SetBackgroundColour( tColour( r , g , b ) );
+}
+
+
+//---------------------------------------------------------------------------
+// SPContext - DLL interface
+//---------------------------------------------------------------------------
+
+int SP_CALLCONV SPContextOpen(HWND hwnd)
+{
+ P3DASSERT(g_SPContext == 0);
+ if (g_SPContext != 0)
+ return -1;
+
+ g_SPContext = new SPContext(hwnd);
+ if (!g_SPContext->Open())
+ {
+ delete g_SPContext;
+ g_SPContext = 0;
+ return -1;
+ }
+
+ return 1;
+}
+
+int SP_CALLCONV SPContextClose()
+{
+ if (g_SPContext == 0)
+ return 0;
+
+ if (!g_SPContext->Close())
+ {
+ delete g_SPContext;
+ g_SPContext = 0;
+ return -1;
+ }
+
+ delete g_SPContext;
+ g_SPContext = 0;
+ return 1;
+}
+
+int SP_CALLCONV SPContextViewResize(int w, int h)
+{
+ if (g_SPContext == 0)
+ return -1;
+
+ g_SPContext->ViewResize(w, h);
+ return 1;
+}
+
+int SP_CALLCONV SPContextIsPDDIStatsEnabled()
+{
+ if (p3d::pddi == 0)
+ return -1;
+ return p3d::pddi->IsStatsOverlayEnabled();
+}
+
+int SP_CALLCONV SPContextSetIsPDDIStatsEnabled(int statsEnabled)
+{
+ if (p3d::pddi == 0)
+ return -1;
+ p3d::pddi->EnableStatsOverlay(statsEnabled != 0);
+ return 1;
+}
+
+int SP_CALLCONV SPContextAdvance()
+{
+ if (g_SPContext == 0)
+ return -1;
+
+ return g_SPContext->Advance();
+}
+
+int SP_CALLCONV SPContextDisplay()
+{
+ if (g_SPContext == 0)
+ return -1;
+
+ return g_SPContext->Display();
+}
+
+int SP_CALLCONV SPContextMouseDown(int button, int shift, int x, int y)
+{
+ if (g_SPContext == 0)
+ return -1;
+
+ g_SPContext->MouseDown(button, shift, x, y);
+ return 0;
+}
+
+int SP_CALLCONV SPContextMouseMove(int button, int shift, int x, int y)
+{
+ if (g_SPContext == 0)
+ return -1;
+
+ g_SPContext->MouseMove(button, shift, x, y);
+ return 0;
+}
+
+int SP_CALLCONV SPContextMouseUp(int button, int shift, int x, int y)
+{
+ if (g_SPContext == 0)
+ return -1;
+
+ g_SPContext->MouseUp(button, shift, x, y);
+ return 0;
+}
+
+int SP_CALLCONV SPContextMouseWheel(int scroll)
+{
+ if (g_SPContext == 0)
+ return -1;
+
+ g_SPContext->MouseWheel(scroll);
+ return 0;
+}
+
+float SP_CALLCONV SPSimulationGetFPS()
+{
+ if (g_SPContext == 0)
+ return 0.0f;
+
+ return g_SPContext->SimulationGetFPS();
+}
+
+float SP_CALLCONV SPSimulationGetRate()
+{
+ if (g_SPContext == 0)
+ return 0.0f;
+
+ return g_SPContext->SimulationGetRate();
+}
+
+int SP_CALLCONV SPSimulationSetRate(float rate)
+{
+ if (g_SPContext == 0)
+ return -1;
+
+ g_SPContext->SimulationSetRate(rate);
+ return 0;
+}
+
+int SP_CALLCONV SPContextGetCameraLock()
+{
+ if (g_SPContext == 0)
+ return -1;
+
+ return g_SPContext->IsCameraLocked();
+}
+
+int SP_CALLCONV SPContextSetCameraLock(int cameraLock)
+{
+ if (g_SPContext == 0)
+ return -1;
+
+ g_SPContext->SetIsCameraLocked(cameraLock != 0);
+ return 0;
+}
+
+int SP_CALLCONV SPInventoryClear()
+{
+ if (g_SPContext == 0)
+ return -1;
+
+ g_SPContext->InventoryClear();
+ return 0;
+}
+
+int SP_CALLCONV SPInventoryGetEntityCount()
+{
+ if (g_SPContext == 0)
+ return -1;
+
+ return g_SPContext->InventoryGetEntityCount();
+}
+
+int SP_CALLCONV SPInventoryGetEntityName(int index, char* name, int nameLen, char* type, int typeLen)
+{
+ if (g_SPContext == 0)
+ return -1;
+
+ if (!g_SPContext->InventoryGetEntityName(index, name, nameLen, type, typeLen))
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+int SP_CALLCONV SPSetBackgroundColour( int r , int g , int b )
+{
+ if (g_SPContext == 0)
+ return 0;
+
+ g_SPContext->SetBackgroundColour( r , g , b );
+ return 1;
+}
+
+// End of file.
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/engine/context.hpp b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/context.hpp
new file mode 100644
index 0000000..faf88c0
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/context.hpp
@@ -0,0 +1,119 @@
+/*
+ * sp/engine/context.hpp
+ */
+
+
+#ifndef SP_ENGINE_CONTEXT_HPP
+#define SP_ENGINE_CONTEXT_HPP
+
+
+#define WIN32_LEAN_AND_MEAN
+#define WIN32_EXTRA_LEAN
+#include <windows.h>
+
+#include <radmath/radmath.hpp>
+#include <p3d/p3dtypes.hpp>
+
+
+class tEntity;
+class tContext;
+class tView;
+class tPointCamera;
+class tDirectionalLight;
+class tPose;
+class pddiShader;
+
+
+//---------------------------------------------------------------------------
+// class SPContext
+//---------------------------------------------------------------------------
+
+class SPContext
+{
+public:
+
+ enum
+ {
+ MAX_FPS_COUNT = 10
+ };
+
+ SPContext(HWND hwnd);
+ virtual ~SPContext();
+
+ tContext* GetContext()
+ { return m_Context; }
+
+ bool Open();
+ bool Close();
+
+ bool ViewResize(int w, int h);
+
+ bool Advance();
+ bool Display();
+
+ void MouseDown(int button, int shift, int x, int y);
+ void MouseMove(int button, int shift, int x, int y);
+ void MouseUp(int button, int shift, int x, int y);
+ void MouseWheel(int scroll);
+
+ float SimulationGetFPS() const;
+ float SimulationGetRate() const
+ { return m_SimRate; }
+ void SimulationSetRate(float simRate);
+
+ bool IsCameraLocked() const
+ { return m_IsCameraLocked; }
+ void SetIsCameraLocked(bool cameraLock)
+ { m_IsCameraLocked = cameraLock; }
+ tPointCamera* GetCamera() const
+ { return m_Camera; }
+
+ static bool GetEntityName(tEntity* entity, char* name, int maxLen);
+
+ void InventoryClear();
+ int InventoryGetEntityCount() const;
+ bool InventoryGetEntityName(int index,
+ char* name, int nameLen,
+ char* type, int typeLen) const;
+
+ void RenderPose(tPose* pose);
+ void DrawAxes(const rmt::Matrix& m, float radius);
+ void DrawLine(const rmt::Vector& a, const rmt::Vector& b, tColour c);
+
+ void SetBackgroundColour( int r , int g , int b );
+
+private:
+
+ void CameraPan(int dx, int dy);
+ void CameraZoom(int dz);
+ void CameraRotate(int dx, int dy);
+
+ HWND m_HWnd;
+
+ tContext* m_Context;
+ tView* m_View;
+ tPointCamera* m_Camera;
+ tDirectionalLight* m_Light;
+ pddiShader* m_Shader;
+
+ float m_CurrentTime;
+ float m_FPS[MAX_FPS_COUNT];
+ int m_FPSIndex;
+ float m_SimRate;
+
+ rmt::Vector m_CameraTarget;
+ float m_CameraRotateX;
+ float m_CameraRotateY;
+ float m_CameraDistance;
+ bool m_IsCameraLocked;
+
+ int m_MouseCapture;
+ int m_MouseX;
+ int m_MouseY;
+};
+
+
+extern SPContext* g_SPContext;
+
+
+#endif // SP_ENGINE_CONTEXT_HPP
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/engine/dllmain.cpp b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/dllmain.cpp
new file mode 100644
index 0000000..5d2df57
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/dllmain.cpp
@@ -0,0 +1,43 @@
+/*
+ * fightviewer/code/engine/dllmain.cpp
+ */
+
+
+#include <windows.h>
+
+
+HINSTANCE SPHInstance = 0;
+
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,
+ DWORD reason,
+ LPVOID reserved)
+{
+ SPHInstance = hinstDLL;
+
+ // Perform actions based on the reason for calling.
+ switch (reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ // Initialize once for each new process.
+ // Return FALSE to fail DLL load.
+ break;
+
+ case DLL_THREAD_ATTACH:
+ // Do thread-specific initialization.
+ break;
+
+ case DLL_THREAD_DETACH:
+ // Do thread-specific cleanup.
+ break;
+
+ case DLL_PROCESS_DETACH:
+ // Perform any necessary cleanup.
+ break;
+ }
+
+ return TRUE;
+}
+
+
+// End of file.
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/engine/platform.cpp b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/platform.cpp
new file mode 100644
index 0000000..c27a39e
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/platform.cpp
@@ -0,0 +1,94 @@
+/*
+ * sp/engine/platform.cpp
+ */
+
+
+#include <sp/interface/platform.hpp>
+
+#include <radmemory.hpp>
+#include <radplatform.hpp>
+#include <radtime.hpp>
+#include <radfile.hpp>
+#include <radthread.hpp>
+
+#include <p3d/utility.hpp>
+
+
+extern HINSTANCE SPHInstance;
+
+//---------------------------------------------------------------------------
+// SPPlatform - DLL interface
+//---------------------------------------------------------------------------
+
+int SP_CALLCONV SPPlatformOpen(HWND hwnd)
+{
+ // ftt thread init
+ radThreadInitialize();
+
+ // ftt memory init
+ radMemoryInitialize();
+
+ // ftt platform init
+ radPlatformInitialize(hwnd, SPHInstance);
+
+ // ftt time init
+ radTimeInitialize();
+
+ // ftt file init
+ radFileInitialize();
+
+ // p3d platform init
+ tPlatform* platform = tPlatform::Create(SPHInstance);
+ if (platform == 0)
+ return -1;
+
+ // game project create
+ /*
+ if (g_SPProject == 0)
+ {
+ g_SPProject = SP_PROC_NEWPROJECT();
+ P3DASSERT(g_SPProject != 0);
+ if (g_SPProject == 0)
+ return -1;
+ g_SPProject->AddRef();
+ g_SPProject->ProjectInit();
+ }
+ */
+
+ return 0;
+}
+
+int SP_CALLCONV SPPlatformClose()
+{
+ // destroy game project
+ //tRefCounted::Release(g_SPProject);
+
+ // destroy workspace
+ //tRefCounted::Release(g_SPWorkspace);
+
+ // p3d platform destroy
+ if (p3d::platform != 0)
+ {
+ tPlatform::Destroy(p3d::platform);
+ }
+
+ // ftt file destroy
+ radFileTerminate();
+
+ // ftt time destroy
+ radTimeTerminate();
+
+ // ftt platform destroy
+ radPlatformTerminate();
+
+ // ftt memory destroy
+ radMemoryTerminate();
+
+ // ftt thread destroy
+ radThreadTerminate();
+
+ return 0;
+}
+
+
+// End of file.
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/engine/stateprop.cpp b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/stateprop.cpp
new file mode 100644
index 0000000..cbfa84d
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/stateprop.cpp
@@ -0,0 +1,445 @@
+#include <p3d/utility.hpp>
+#include <p3d/matrixstack.hpp>
+#include <p3d/anim/multicontroller.hpp>
+#include <p3d/anim/compositedrawable.hpp>
+#include <p3d/anim/animatedobject.hpp>
+#include <p3d/anim/animate.hpp>
+
+#include <toollib/chunks16/inc/tlStatePropChunk.hpp>
+#include <toollib/inc/tlFile.hpp>
+#include <toollib/inc/tlFileByteStream.hpp>
+
+#include "stateprop.hpp"
+#include "statepropdata.hpp"
+
+CStateProp* CStateProp::CreateCStateProp( CStatePropData* statePropData , unsigned int state )
+{
+ tAnimatedObjectFactory* objectFactory = statePropData->m_ObjectFactory;
+
+ if ( !objectFactory )
+ {
+ objectFactory = p3d::find<tAnimatedObjectFactory>( statePropData->m_FactoryName );
+ if ( objectFactory )
+ {
+ statePropData->m_ObjectFactory = objectFactory;
+ statePropData->m_ObjectFactory->AddRef();
+ }
+ }
+
+ if ( objectFactory )
+ {
+ tAnimatedObject* animatedObject = objectFactory->CreateObject(NULL);
+ CStateProp* stateProp = new CStateProp( animatedObject , statePropData , state );
+ return stateProp;
+ }
+
+ return NULL;
+}
+
+CStateProp::CStateProp( tAnimatedObject* animatedObject , CStatePropData* statePropData , unsigned int state ) :
+ m_StatePropData( NULL ),
+ m_AnimatedObject( NULL ),
+ m_BaseFrameController( NULL ),
+ m_StatePropListener( NULL ),
+ m_CurrentState( state )
+{
+ //set state data
+ P3DASSERT( statePropData );
+ m_StatePropData = statePropData;
+ m_StatePropData->AddRef();
+
+ //set animated object
+ P3DASSERT( animatedObject );
+ m_AnimatedObject = animatedObject;
+ m_AnimatedObject->AddRef();
+
+ //base frame controller is run in milliseconds (ie the 1 is the timer)
+ m_BaseFrameController = new tMultiController(0 , 1000.f);
+ m_BaseFrameController->AddRef();
+ m_BaseFrameController->Reset();
+
+ //initilize transform
+ rmt::Matrix identity;
+ identity.Identity();
+ SetTransformationMatrix( identity );
+
+ //initialize the state
+ SetState( state );
+}
+
+CStateProp::~CStateProp()
+{
+ if ( m_BaseFrameController )
+ m_BaseFrameController->Release();
+ if ( m_StatePropData )
+ m_StatePropData->Release();
+ if ( m_AnimatedObject )
+ m_AnimatedObject->Release();
+}
+
+void CStateProp::Update( float dt )
+{
+ unsigned int i;
+
+ float lastFrame = m_BaseFrameController->GetFrame();
+ m_BaseFrameController->Advance( dt );
+ float newFrame = m_BaseFrameController->GetFrame();
+
+ //Check out transition
+ TransitionData tansdata = m_StatePropData->GetTransitionData( m_CurrentState );
+ if ( tansdata.autoTransition )
+ {
+ if (tansdata.onFrame >= lastFrame && tansdata.onFrame < newFrame)
+ {
+ SetState( tansdata.toState );
+ }
+ }
+
+ //Check callback events
+ if ( m_StatePropListener )
+ {
+ for ( i = 0; i < m_StatePropData->GetNumberOfCallbacks( m_CurrentState ); i++ )
+ {
+ CallbackData callbackData = m_StatePropData->GetCallbackData( m_CurrentState , i );
+ if ( callbackData.onFrame >= lastFrame && callbackData.onFrame < newFrame)
+ {
+ m_StatePropListener->RecieveEvent( callbackData.callbackID , this );
+ }
+ }
+ }
+
+ //update frame controllers
+ unsigned int numFrameControllers = GetNumberOfFrameControllers();
+ for ( i = 0; i < numFrameControllers; i++ )
+ {
+ FrameControllerData fcData = m_StatePropData->GetFrameControllerData( m_CurrentState , i );
+
+ //if we need to update
+ if ( fcData.minFrame != fcData.maxFrame )
+ {
+ tFrameController* fc = GetFrameControllerByIndex( i );
+
+ //if the min frame is greater than the max frame then reverse the update
+ if ( fcData.minFrame > fcData.maxFrame )
+ {
+ fc->Advance( -dt , false );
+ }
+ else
+ {
+ fc->Advance( dt , false );
+ }
+
+ if ( fcData.isCyclic && fcData.numberOfCycles > 0 )
+ {
+ unsigned int currentNumberOfCycles = fc->LastFrameReached();
+ if ( currentNumberOfCycles >= fcData.numberOfCycles )
+ {
+ fc->SetCycleMode( FORCE_NON_CYCLIC );
+ fc->SetFrame( fcData.maxFrame );
+ }
+ }
+ }
+ }
+}
+
+void CStateProp::Render()
+{
+ p3d::stack->Push();
+ p3d::stack->Multiply( m_Transform );
+
+ m_AnimatedObject->Display();
+
+ p3d::stack->Pop();
+}
+
+void CStateProp::UpdateFrameControllersForRender()
+{
+ unsigned int numFrameControllers = GetNumberOfFrameControllers();
+ for ( unsigned int i = 0; i < numFrameControllers; i++ )
+ {
+ GetFrameControllerByIndex( i )->Advance( 0.f , true );
+ }
+}
+
+unsigned int CStateProp::GetState()
+{
+ return m_CurrentState;
+}
+
+void CStateProp::NextState()
+{
+ if ( m_CurrentState + 1 >= m_StatePropData->GetNumberOfStates() )
+ {
+ SetState( 0 );
+ }
+ else
+ {
+ SetState( m_CurrentState + 1 );
+ }
+}
+
+void CStateProp::PrevState()
+{
+ if ( m_CurrentState - 1 < 0 )
+ {
+ SetState( m_StatePropData->GetNumberOfStates() - 1 );
+ }
+ else
+ {
+ SetState( m_CurrentState - 1 );
+ }
+}
+
+void CStateProp::SetState( unsigned int state )
+{
+ if ( state < m_StatePropData->GetNumberOfStates() && state >= 0 )
+ {
+ m_CurrentState = state;
+ }
+
+ m_BaseFrameController->SetFrame(0.f);
+
+ unsigned int i;
+
+ //reset the FC for new state
+ unsigned int numFrameControllers = GetNumberOfFrameControllers();
+ for ( i = 0; i < numFrameControllers; i++ )
+ {
+ FrameControllerData frameControllerData = m_StatePropData->GetFrameControllerData( m_CurrentState , i );
+ tFrameController* fc = GetFrameControllerByIndex(i);
+
+ //if we are holding a frame over from last state dont reset
+ if ( !frameControllerData.holdFrame )
+ {
+ //Reset() MUST come first or it will trounce frame ranges etc...
+ fc->Reset();
+ }
+ fc->SetRelativeSpeed( frameControllerData.relativeSpeed );
+ fc->SetCycleMode( (frameControllerData.isCyclic == 1) ? FORCE_CYCLIC : FORCE_NON_CYCLIC );
+ if ( frameControllerData.minFrame > frameControllerData.maxFrame )
+ {
+ fc->SetFrameRange( frameControllerData.maxFrame , frameControllerData.minFrame );
+ }
+ else
+ {
+ fc->SetFrameRange( frameControllerData.minFrame , frameControllerData.maxFrame );
+ }
+
+ if ( !frameControllerData.holdFrame )
+ {
+ fc->SetFrame( frameControllerData.minFrame );
+ }
+ }
+
+ //Set visibility for new state
+ unsigned int numElements = m_AnimatedObject->GetBaseObject()->GetNumDrawableElement();
+ for ( i = 0; i < numElements; i++ )
+ {
+ tCompositeDrawable::DrawableElement* de = GetDrawableElement(i);
+
+ de->SetLockVisibility(false);
+ VisibilityData visibilityData = m_StatePropData->GetVisibilityData( m_CurrentState , i );
+ bool visible = visibilityData.isVisible == 1;
+ de->SetVisibility( visible );
+
+ //lock visibility if visiblility if false
+ de->SetLockVisibility(!visible);
+ }
+}
+
+void CStateProp::OnEvent( unsigned int eventID )
+{
+ unsigned int i;
+ unsigned int numEvents = m_StatePropData->GetNumberOfEvents( m_CurrentState );
+ for ( i = 0; i < numEvents; i++ )
+ {
+ EventData eventData = m_StatePropData->GetEventData( m_CurrentState , i );
+ if ( eventData.eventID == eventID )
+ {
+ SetState( eventData.toState );
+ }
+ }
+}
+
+void CStateProp::UpdateOnDataEdit()
+{
+ //Update without reseting the current frame or current state info
+ unsigned int i;
+
+ //update frame controllers
+ unsigned int numFrameControllers = GetNumberOfFrameControllers();
+ for ( i = 0; i < numFrameControllers; i++ )
+ {
+ FrameControllerData frameControllerData = m_StatePropData->GetFrameControllerData( m_CurrentState , i );
+ tFrameController* fc = GetFrameControllerByIndex(i);
+ float frame = fc->GetFrame();
+ fc->Reset();
+ fc->SetRelativeSpeed( frameControllerData.relativeSpeed );
+ fc->SetCycleMode( (frameControllerData.isCyclic == 1) ? FORCE_CYCLIC : FORCE_NON_CYCLIC );
+ if ( frameControllerData.minFrame > frameControllerData.maxFrame )
+ {
+ fc->SetFrameRange( frameControllerData.maxFrame , frameControllerData.minFrame );
+ }
+ else
+ {
+ fc->SetFrameRange( frameControllerData.minFrame , frameControllerData.maxFrame );
+ }
+
+ fc->SetFrame( frame );
+ }
+
+ //set visibilites
+ unsigned int numDrawableElements = GetNumberOfDrawableElements();
+ for ( i = 0; i < numDrawableElements; i++ )
+ {
+ tCompositeDrawable::DrawableElement* de = GetDrawableElement(i);
+
+ de->SetLockVisibility(false);
+ VisibilityData visibilityData = m_StatePropData->GetVisibilityData( m_CurrentState , i );
+ bool visible = visibilityData.isVisible == 1;
+ de->SetVisibility( visible );
+
+ //lock visibility if visiblility if false
+ de->SetLockVisibility(!visible);
+ }
+}
+
+float CStateProp::GetBaseFrameControllerFrame()
+{
+ return m_BaseFrameController->GetFrame();
+}
+
+CStatePropData* CStateProp::GetCStatePropData()
+{
+ return m_StatePropData;
+}
+
+unsigned int CStateProp::GetNumberOfFrameControllers()
+{
+ return m_AnimatedObject->GetCurrentAnimation()->GetNumFrameControllers();
+}
+
+tFrameController* CStateProp::GetFrameControllerByIndex( unsigned int i )
+{
+ return m_AnimatedObject->GetCurrentAnimation()->GetFrameControllerByIndex(i);
+}
+
+unsigned int CStateProp::GetNumberOfDrawableElements()
+{
+ return m_AnimatedObject->GetBaseObject()->GetNumDrawableElement();
+}
+
+tCompositeDrawable::DrawableElement* CStateProp::GetDrawableElement( unsigned int i )
+{
+ return m_AnimatedObject->GetBaseObject()->GetDrawableElement( i );
+}
+
+const char* CStateProp::GetDrawableName( unsigned int i )
+{
+ return m_AnimatedObject->GetBaseObject()->GetDrawableElement( i )->GetDrawable()->GetName();
+}
+
+const char* CStateProp::GetPropName( )
+{
+ return GetName();
+}
+
+//Export the CStatePropData
+void CStateProp::ExportChunk( const char* filename )
+{
+ //create the outchunk data chunk
+ tlDataChunk* outchunk = new tlDataChunk;
+
+ //create smart prop chunk
+ char buf[256];
+ tlStatePropChunk* statepropchunk = new tlStatePropChunk;
+
+ //version one has extra floats and ints
+ statepropchunk->SetVersion( 1 );
+
+ statepropchunk->SetName( m_StatePropData->GetName() );
+ statepropchunk->SetObjectFactoryName( m_StatePropData->GetName() );
+ statepropchunk->SetNumStates( m_StatePropData->GetNumberOfStates() );
+
+ unsigned int state;
+ int j;
+ //create state subchunks
+ for ( state = 0; state < m_StatePropData->GetNumberOfStates(); state++ )
+ {
+ tlStatePropStateDataChunk* statechunk = new tlStatePropStateDataChunk;
+ sprintf(buf, "state%i", state );
+ statechunk->SetName( buf );
+ TransitionData tData = m_StatePropData->GetTransitionData( state );
+ statechunk->SetAutoTransition( tData.autoTransition );
+ statechunk->SetOutFrame( tData.onFrame );
+ statechunk->SetOutState( tData.toState );
+
+ int numDrawables = GetNumberOfDrawableElements();
+ statechunk->SetNumDrawables( numDrawables );
+ for ( j = 0; j < numDrawables; j++ )
+ {
+ tlStatePropVisibilitiesDataChunk* visibilitychunk = new tlStatePropVisibilitiesDataChunk;
+ VisibilityData vData = m_StatePropData->GetVisibilityData( state , j );
+ visibilitychunk->SetName( GetDrawableElement(j)->GetDrawable()->GetName() );
+ visibilitychunk->SetVisible( vData.isVisible );
+ statechunk->AppendSubChunk( visibilitychunk );
+ }
+
+ int numFrameControllers = GetNumberOfFrameControllers();
+ statechunk->SetNumFrameControllers( numFrameControllers );
+ for ( j = 0; j < numFrameControllers; j++ )
+ {
+ tlStatePropFrameControllerDataChunk* framecontrollerchunk = new tlStatePropFrameControllerDataChunk;
+ FrameControllerData fData = m_StatePropData->GetFrameControllerData( state , j );
+ framecontrollerchunk->SetName( GetFrameControllerByIndex(j)->GetName() );
+ framecontrollerchunk->SetCyclic( fData.isCyclic );
+ framecontrollerchunk->SetMinFrame( fData.minFrame );
+ framecontrollerchunk->SetMaxFrame( fData.maxFrame );
+ framecontrollerchunk->SetRelativeSpeed( fData.relativeSpeed );
+ framecontrollerchunk->SetHoldFrame( fData.holdFrame );
+ framecontrollerchunk->SetNumberOfCycles( fData.numberOfCycles );
+ statechunk->AppendSubChunk( framecontrollerchunk );
+ }
+
+ int numEvents = m_StatePropData->GetNumberOfEvents( state );
+ statechunk->SetNumEvents( numEvents );
+ for ( j = 0; j < numEvents; j++ )
+ {
+ tlStatePropEventDataChunk* eventdatachunk = new tlStatePropEventDataChunk;
+ EventData eData = m_StatePropData->GetEventData( state , j );
+ eventdatachunk->SetName( eData.eventName );
+ eventdatachunk->SetState( eData.toState );
+ eventdatachunk->SetEventEnum( eData.eventID );
+ statechunk->AppendSubChunk( eventdatachunk );
+ }
+
+ int numCallbacks = m_StatePropData->GetNumberOfCallbacks( state );
+ statechunk->SetNumCallbacks( numCallbacks );
+ for ( j = 0; j < numCallbacks; j++ )
+ {
+ tlStatePropCallbackDataChunk* callbackChunk = new tlStatePropCallbackDataChunk;
+ CallbackData cData = m_StatePropData->GetCallbackData( state , j );
+ callbackChunk->SetName( cData.callbackName );
+ callbackChunk->SetOnFrame( cData.onFrame );
+ callbackChunk->SetEventEnum( cData.callbackID );
+ statechunk->AppendSubChunk( callbackChunk );
+ }
+
+ //append the sate chunk
+ statepropchunk->AppendSubChunk( statechunk );
+ }
+
+ outchunk->AppendSubChunk( statepropchunk );
+
+ // create the new output file
+ tlFile output(new tlFileByteStream(filename,omWRITE), tlFile::CHUNK32);
+
+ if(!output.IsOpen())
+ {
+ printf("Could not open %s for writing\n", filename);
+ return ;
+ }
+
+ outchunk->Write(&output);
+ output.Close();
+} \ No newline at end of file
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/engine/stateprop.hpp b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/stateprop.hpp
new file mode 100644
index 0000000..c72b76b
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/stateprop.hpp
@@ -0,0 +1,120 @@
+#ifndef _STATEPROP_HPP_
+#define _STATEPROP_HPP_
+
+#include "radmath/radmath.hpp"
+
+//=============================================================================
+// Forward Class/Struct Declarations
+//=============================================================================
+
+class tFrameController;
+class tAnimatedObject;
+class CStatePropData;
+class CStateProp;
+class tCompositeDrawable;
+
+
+//=============================================================================
+// Class Declarations
+// PropListener
+//=============================================================================
+
+class CStatePropListener : public tRefCounted
+{
+public:
+ virtual void RecieveEvent( int event , CStateProp* stateProp ) = 0;
+};
+
+//=============================================================================
+// Definitions
+//=============================================================================
+
+
+//=============================================================================
+// Class Declarations
+// CStateProp
+//=============================================================================
+class CStateProp : public tEntity
+{
+public:
+
+ static CStateProp* CreateCStateProp( CStatePropData* statePropData , unsigned int state );
+
+ CStateProp( tAnimatedObject* animatedObject , CStatePropData* statePropData , unsigned int state = 0 );
+ ~CStateProp();
+
+ //Per frame update
+ void Update( float dt );
+
+ //Render
+ void Render();
+
+ //call before render
+ void UpdateFrameControllersForRender();
+
+ unsigned int GetState();
+ void SetState( unsigned int state );
+ void NextState();
+ void PrevState();
+
+ void OnEvent( unsigned int eventID );
+
+ void SetTransformationMatrix( const rmt::Matrix &tm);
+ const rmt::Matrix& GetTransformationMatrix() const;
+
+ void SetPosition( const rmt::Vector& pos );
+ const rmt::Vector& GetPosition() const;
+
+ //Get State Prop Data
+ CStatePropData* GetCStatePropData();
+
+ // Update for new data
+ void UpdateOnDataEdit();
+
+ //accessors
+ float GetBaseFrameControllerFrame();
+ unsigned int GetNumberOfFrameControllers();
+ tFrameController* GetFrameControllerByIndex( unsigned int i );
+ unsigned int GetNumberOfDrawableElements();
+ tCompositeDrawable::DrawableElement* GetDrawableElement( unsigned int i );
+ const char* GetDrawableName( unsigned int i );
+ const char* GetPropName();
+
+ //Export the SmartPropData
+ void ExportChunk( const char* filename );
+
+
+private:
+
+ // Orientation and location
+ rmt::Matrix m_Transform;
+
+ //Private members
+ CStatePropData* m_StatePropData;
+ tAnimatedObject* m_AnimatedObject;
+ tFrameController* m_BaseFrameController;
+ unsigned int m_CurrentState;
+
+ CStatePropListener* m_StatePropListener;
+};
+
+
+inline void CStateProp::SetPosition( const rmt::Vector& pos )
+{
+ m_Transform.FillTranslate( pos );
+}
+inline const rmt::Vector& CStateProp::GetPosition() const
+{
+ return const_cast< RadicalMathLibrary::Matrix & >( m_Transform ).Row(3);
+}
+
+inline void CStateProp::SetTransformationMatrix(const rmt::Matrix& tmx)
+{
+ m_Transform = tmx;
+}
+inline const rmt::Matrix& CStateProp::GetTransformationMatrix() const
+{
+ return m_Transform;
+}
+
+#endif //_STATEPROP_HPP_ \ No newline at end of file
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/engine/statepropdata.cpp b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/statepropdata.cpp
new file mode 100644
index 0000000..eb88194
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/statepropdata.cpp
@@ -0,0 +1,509 @@
+#include <string.h>
+#include <p3d/utility.hpp>
+#include <p3d/anim/animatedobject.hpp>
+#include <constants/chunkids.hpp>
+#include <p3d/chunkfile.hpp>
+
+#include "statepropdata.hpp"
+
+//=============================================================================
+// Class Declarations
+// Prop
+//=============================================================================
+
+CStatePropData::CStatePropData( tAnimatedObjectFactory* factory ) :
+ tEntity(),
+ m_NumStates(1)
+{
+ P3DASSERT ( factory );
+ m_ObjectFactory = factory;
+ m_ObjectFactory->AddRef();
+ SetName( m_ObjectFactory->GetName() );
+
+ ResetData();
+}
+
+CStatePropData::CStatePropData( ) :
+ tEntity(),
+ m_NumStates(1),
+ m_ObjectFactory( NULL )
+{
+ ResetData();
+}
+
+CStatePropData::~CStatePropData()
+{
+ m_ObjectFactory->Release();
+}
+
+//=============================================================================
+//State Data
+//=============================================================================
+
+//Get
+unsigned int CStatePropData::GetNumberOfStates()
+{
+ return m_NumStates;
+}
+StateData CStatePropData::GetStateData( unsigned int state )
+{
+ return m_StateData[ state ];
+}
+
+//Set
+void CStatePropData::InsertState( unsigned int state )
+{
+ if ( m_NumStates >= MAX_STATES - 1)
+ return;
+
+ //increase the number of states and copy all the data up a state
+ m_NumStates++;
+
+ unsigned int i , j;
+ for ( i = m_NumStates - 1; i > state + 1; i-- )
+ {
+ //transition data for each state
+ m_StateData[i].transitionData.autoTransition = m_StateData[i-1].transitionData.autoTransition;
+ m_StateData[i].transitionData.onFrame = m_StateData[i-1].transitionData.onFrame;
+ m_StateData[i].transitionData.toState = m_StateData[i-1].transitionData.toState;
+
+ //visibility data for each drawable in each state
+ for (j = 0; j < MAX_VISIBILITIES; j++ )
+ {
+ m_StateData[i].visibilityData[j].isVisible = m_StateData[i-1].visibilityData[j].isVisible;
+ }
+
+ //framecontroller data in each state
+ for (j = 0; j < MAX_FRAMECONTROLLERS; j++ )
+ {
+ m_StateData[i].frameControllerData[j].isCyclic = m_StateData[i-1].frameControllerData[j].isCyclic;
+ m_StateData[i].frameControllerData[j].maxFrame = m_StateData[i-1].frameControllerData[j].maxFrame;
+ m_StateData[i].frameControllerData[j].minFrame = m_StateData[i-1].frameControllerData[j].minFrame;
+ m_StateData[i].frameControllerData[j].relativeSpeed = m_StateData[i-1].frameControllerData[j].relativeSpeed;
+ m_StateData[i].frameControllerData[j].holdFrame = m_StateData[i-1].frameControllerData[j].holdFrame;
+ m_StateData[i].frameControllerData[j].numberOfCycles = m_StateData[i-1].frameControllerData[j].numberOfCycles;
+ }
+
+ //event data for each state
+ m_StateData[i].numEvents = m_StateData[i-1].numEvents;
+ m_StateData[i].numCallbacks = m_StateData[i-1].numCallbacks;
+ for (j = 0; j < MAX_EVENTS; j++ )
+ {
+ strcpy( m_StateData[i].eventData[j].eventName , m_StateData[i-1].eventData[j].eventName );
+ m_StateData[i].eventData[j].toState = m_StateData[i-1].eventData[j].toState;
+ m_StateData[i].eventData[j].eventID = m_StateData[i-1].eventData[j].eventID;
+
+ strcpy( m_StateData[i].callbackData[j].callbackName , m_StateData[i-1].callbackData[j].callbackName );
+ m_StateData[i].callbackData[j].onFrame = m_StateData[i-1].callbackData[j].onFrame;
+ m_StateData[i].callbackData[j].callbackID = m_StateData[i-1].callbackData[j].callbackID;
+ }
+ }
+
+ //Initialize the newly added state
+
+ //transition data for each state
+ m_StateData[state + 1].transitionData.autoTransition = 0;
+ m_StateData[state + 1].transitionData.onFrame = 0.f;
+ m_StateData[state + 1].transitionData.toState = 0;
+
+ //visibility data for each drawable in each state
+ for (j = 0; j < MAX_VISIBILITIES; j++ )
+ {
+ m_StateData[state + 1].visibilityData[j].isVisible = 1;
+ }
+
+ //framecontroller data in each state
+ for (j = 0; j < MAX_FRAMECONTROLLERS; j++ )
+ {
+ m_StateData[state + 1].frameControllerData[j].isCyclic = 0;
+ m_StateData[state + 1].frameControllerData[j].maxFrame = 0.f;
+ m_StateData[state + 1].frameControllerData[j].minFrame = 0.f;
+ m_StateData[state + 1].frameControllerData[j].relativeSpeed = 1.f;
+ m_StateData[state + 1].frameControllerData[j].holdFrame = 0;
+ m_StateData[state + 1].frameControllerData[j].numberOfCycles = 0;
+ }
+
+ //event data for each state
+ m_StateData[state + 1].numEvents = 0;
+ m_StateData[state + 1].numCallbacks = 0;
+}
+
+void CStatePropData::DeleteState( unsigned int state )
+{
+ if ( m_NumStates == 1 )
+ {
+ ResetData();
+ return;
+ }
+
+ int i;
+ int j;
+
+ for ( i = state; i < m_NumStates - 1; i++ )
+ {
+ //transition data for each state
+ m_StateData[i].transitionData.autoTransition = m_StateData[i+1].transitionData.autoTransition;
+ m_StateData[i].transitionData.onFrame = m_StateData[i+1].transitionData.onFrame;
+ m_StateData[i].transitionData.toState = m_StateData[i+1].transitionData.toState;
+
+ //visibility data for each drawable in each state
+ for (j = 0; j < MAX_VISIBILITIES; j++ )
+ {
+ m_StateData[i].visibilityData[j].isVisible = m_StateData[i+1].visibilityData[j].isVisible;
+ }
+
+ //framecontroller data in each state
+ for (j = 0; j < MAX_FRAMECONTROLLERS; j++ )
+ {
+ m_StateData[i].frameControllerData[j].isCyclic = m_StateData[i+1].frameControllerData[j].isCyclic;
+ m_StateData[i].frameControllerData[j].maxFrame = m_StateData[i+1].frameControllerData[j].maxFrame;
+ m_StateData[i].frameControllerData[j].minFrame = m_StateData[i+1].frameControllerData[j].minFrame;
+ m_StateData[i].frameControllerData[j].relativeSpeed = m_StateData[i+1].frameControllerData[j].relativeSpeed;
+ m_StateData[i].frameControllerData[j].holdFrame = m_StateData[i+1].frameControllerData[j].holdFrame;
+ m_StateData[i].frameControllerData[j].numberOfCycles = m_StateData[i+1].frameControllerData[j].numberOfCycles;
+ }
+
+ //event data for each state
+ m_StateData[i].numEvents = m_StateData[i+1].numEvents;
+ m_StateData[i].numCallbacks = m_StateData[i+1].numCallbacks;
+ for (j = 0; j < MAX_EVENTS; j++ )
+ {
+ strcpy( m_StateData[i].eventData[j].eventName , m_StateData[i+1].eventData[j].eventName );
+ m_StateData[i].eventData[j].toState = m_StateData[i+1].eventData[j].toState;
+ m_StateData[i].eventData[j].eventID = m_StateData[i+1].eventData[j].eventID;
+
+ strcpy( m_StateData[i].callbackData[j].callbackName , m_StateData[i+1].callbackData[j].callbackName );
+ m_StateData[i].callbackData[j].onFrame = m_StateData[i+1].callbackData[j].onFrame;
+ m_StateData[i].callbackData[j].callbackID = m_StateData[i+1].callbackData[j].callbackID;
+ }
+ }
+
+ m_NumStates--;
+}
+
+//=============================================================================
+//Transition Data
+//=============================================================================
+
+//Get
+TransitionData CStatePropData::GetTransitionData( int state )
+{
+ return m_StateData[state].transitionData;
+}
+
+//Set
+void CStatePropData::SetAutoTransition( int state, bool b )
+{
+ m_StateData[state].transitionData.autoTransition = b;
+}
+void CStatePropData::SetAutoTransitionOnFrame( int state, float onFrame )
+{
+ m_StateData[state].transitionData.onFrame = onFrame;
+}
+void CStatePropData::SetAutoTransitionToState( int state, int toState )
+{
+ m_StateData[state].transitionData.toState = toState;
+}
+
+//=============================================================================
+//Visibility Data
+//=============================================================================
+
+//Get
+VisibilityData CStatePropData::GetVisibilityData( int state , int index)
+{
+ return ( m_StateData[state].visibilityData[index] );
+}
+
+//Set
+void CStatePropData::SetVisible( int state , int index , bool b )
+{
+ m_StateData[state].visibilityData[index].isVisible = b;
+}
+void CStatePropData::SetAllVisibilities( int state , bool b )
+{
+ for ( int i = 0; i < MAX_VISIBILITIES; i++ )
+ {
+ m_StateData[state].visibilityData[i].isVisible = b;
+ }
+}
+void CStatePropData::ShowAll(int state)
+{
+ SetAllVisibilities( state , true );
+}
+void CStatePropData::HideAll(int state)
+{
+ SetAllVisibilities( state , false );
+}
+
+//=============================================================================
+//Frame controller data
+//=============================================================================
+
+//Get
+FrameControllerData CStatePropData::GetFrameControllerData( int state, int fc )
+{
+ return m_StateData[state].frameControllerData[fc];
+}
+
+//Set
+void CStatePropData::SetCyclic( int state ,int fc, bool isCyclic )
+{
+ m_StateData[state].frameControllerData[fc].isCyclic = isCyclic;
+}
+void CStatePropData::SetRelativeSpeed( int state ,int fc, float speed )
+{
+ m_StateData[state].frameControllerData[fc].relativeSpeed = speed;
+}
+void CStatePropData::SetFrameRange( int state , int fc, float min, float max )
+{
+ m_StateData[state].frameControllerData[fc].minFrame = min;
+ m_StateData[state].frameControllerData[fc].maxFrame = max;
+}
+void CStatePropData::SetHoldFrame( int state , int fc , bool holdFrame )
+{
+ m_StateData[state].frameControllerData[fc].holdFrame = holdFrame;
+}
+void CStatePropData::SetNumberOfCycles( int state , int fc , unsigned int numberOfCycles )
+{
+ m_StateData[state].frameControllerData[fc].numberOfCycles = numberOfCycles;
+}
+
+
+//=============================================================================
+//Event data
+//=============================================================================
+
+//Get
+unsigned int CStatePropData::GetNumberOfEvents( int state )
+{
+ return m_StateData[state].numEvents;
+}
+EventData CStatePropData::GetEventData( int state , int eventindex )
+{
+ return m_StateData[state].eventData[eventindex];
+}
+
+//Set
+void CStatePropData::AddEvent( const char* event , int eventEnum , int toState , int fromState )
+{
+ int n_events = m_StateData[fromState].numEvents;
+
+ strcpy( m_StateData[fromState].eventData[n_events].eventName , event );
+ m_StateData[fromState].eventData[n_events].toState = toState;
+ m_StateData[fromState].eventData[n_events].eventID = eventEnum;
+
+ m_StateData[fromState].numEvents = n_events + 1;
+}
+void CStatePropData::EditEvent( int state, int EventIndex, char* eventName, int eventID , int toState )
+{
+ strcpy( m_StateData[state].eventData[EventIndex].eventName , eventName );
+ m_StateData[state].eventData[EventIndex].toState = toState;
+ m_StateData[state].eventData[EventIndex].eventID = eventID;
+}
+void CStatePropData::DeleteEvent( int state , int index )
+{
+ int numEvents = m_StateData[state].numEvents;
+ for ( int i = index; i < numEvents - 1; i++ )
+ {
+ strcpy( m_StateData[state].eventData[i].eventName , m_StateData[state].eventData[i+1].eventName );
+ m_StateData[state].eventData[i].toState = m_StateData[state].eventData[i+1].toState;
+ m_StateData[state].eventData[i].eventID = m_StateData[state].eventData[i+1].eventID;
+ }
+
+ strcpy( m_StateData[state].eventData[numEvents - 1].eventName , "" );
+ m_StateData[state].eventData[numEvents - 1].toState = 0;
+ m_StateData[state].eventData[numEvents - 1].eventID = 0;
+
+ m_StateData[state].numEvents = numEvents - 1;
+}
+
+//=============================================================================
+//Callback Data
+//=============================================================================
+
+//Get
+unsigned int CStatePropData::GetNumberOfCallbacks( int state )
+{
+ return m_StateData[state].numCallbacks;
+}
+CallbackData CStatePropData::GetCallbackData( int state , int eventindex )
+{
+ return m_StateData[state].callbackData[eventindex];
+}
+
+//Set
+void CStatePropData::AddCallback( int state , const char* callback , int callbackID , float onFrame )
+{
+ int n_callbacks = m_StateData[state].numCallbacks;
+
+ strcpy( m_StateData[state].callbackData[n_callbacks].callbackName , callback );
+ m_StateData[state].callbackData[n_callbacks].onFrame = onFrame;
+ m_StateData[state].callbackData[n_callbacks].callbackID = callbackID;
+
+ m_StateData[state].numCallbacks = n_callbacks + 1;
+}
+void CStatePropData::EditCallback( int state, int CBIndex, char* callbackname, int callbackID , float onFrame )
+{
+ strcpy( m_StateData[state].callbackData[CBIndex].callbackName , callbackname );
+ m_StateData[state].callbackData[CBIndex].onFrame = onFrame;
+ m_StateData[state].callbackData[CBIndex].callbackID = callbackID;
+}
+void CStatePropData::DeleteCallback( int state , int index )
+{
+ int numCallbacks = m_StateData[state].numCallbacks;
+ for ( int i = index; i < numCallbacks - 1; i++ )
+ {
+ strcpy( m_StateData[state].callbackData[i].callbackName , m_StateData[state].callbackData[i+1].callbackName );
+ m_StateData[state].callbackData[i].onFrame = m_StateData[state].callbackData[i+1].onFrame;
+ m_StateData[state].callbackData[i].callbackID = m_StateData[state].callbackData[i+1].callbackID;
+ }
+
+ strcpy( m_StateData[state].callbackData[numCallbacks - 1].callbackName , "" );
+ m_StateData[state].callbackData[numCallbacks - 1].onFrame = 0.f;
+ m_StateData[state].callbackData[numCallbacks - 1].callbackID = 0;
+
+ m_StateData[state].numCallbacks = numCallbacks - 1;
+}
+
+
+
+//=============================================================================
+//Utility
+//=============================================================================
+void CStatePropData::ResetData()
+{
+ unsigned int state;
+ unsigned int j;
+
+ for ( state = 0; state < MAX_STATES; state++ )
+ {
+ //transition data
+ m_StateData[state].transitionData.autoTransition = 0;
+ m_StateData[state].transitionData.onFrame = 0.f;
+ m_StateData[state].transitionData.toState = 0;
+
+ //framecontrollers
+ for ( j = 0; j < MAX_FRAMECONTROLLERS; j++ )
+ {
+ m_StateData[state].frameControllerData[j].isCyclic = false;
+ m_StateData[state].frameControllerData[j].minFrame = 0.f;
+ m_StateData[state].frameControllerData[j].maxFrame = 0.f;
+ m_StateData[state].frameControllerData[j].relativeSpeed = 1.f;
+ m_StateData[state].frameControllerData[j].holdFrame = 0;
+ m_StateData[state].frameControllerData[j].numberOfCycles = 0;
+
+ }
+
+ //visibilites
+ for ( j = 0; j < MAX_VISIBILITIES; j++ )
+ {
+ m_StateData[state].visibilityData[j].isVisible = true;
+ }
+
+ //events && callbacks
+ m_StateData[state].numEvents = 0;
+ m_StateData[state].numCallbacks = 0;
+ for ( j = 0; j < MAX_EVENTS; j++ )
+ {
+ strcpy( m_StateData[state].eventData[j].eventName , "" );
+ m_StateData[state].eventData[j].toState = 0;
+ m_StateData[state].eventData[j].eventID = 0;
+
+ strcpy( m_StateData[state].callbackData[j].callbackName , "" );
+ m_StateData[state].callbackData[j].onFrame = 0.f;
+ m_StateData[state].callbackData[j].callbackID = 0;
+ }
+ }
+}
+
+
+
+//=============================================================================
+// Class Declarations
+// PropLoader
+//=============================================================================
+CStatePropDataLoader::CStatePropDataLoader() :
+ tSimpleChunkHandler(StateProp::STATEPROP)
+{
+}
+
+//-------------------------------------------------------------------------
+tEntity* CStatePropDataLoader::LoadObject(tChunkFile* f, tEntityStore* store)
+{
+ unsigned int version = f->GetLong();
+
+ CStatePropData* statePropData = new CStatePropData();
+ statePropData->ResetData();
+
+ char buf[256];
+
+ f->GetPString(buf);
+ statePropData->SetName(buf);
+
+ strcpy( statePropData->m_FactoryName , f->GetPString(buf) );
+ statePropData->m_ObjectFactory = p3d::find<tAnimatedObjectFactory>(store, statePropData->m_FactoryName);
+ if ( statePropData->m_ObjectFactory )
+ {
+ statePropData->m_ObjectFactory->AddRef();
+ }
+
+ statePropData->m_NumStates = f->GetLong();
+
+ for ( int currState = 0; currState < statePropData->m_NumStates; currState++ )
+ {
+ f->BeginChunk();
+
+ f->GetPString(buf);
+ statePropData->m_StateData[currState].transitionData.autoTransition = ( f->GetLong() != 0 );
+ statePropData->m_StateData[currState].transitionData.toState = f->GetLong();
+ int numDrawables = f->GetLong();
+ int numFrameControllers = f->GetLong();
+ statePropData->m_StateData[currState].numEvents = f->GetLong();
+ statePropData->m_StateData[currState].numCallbacks = f->GetLong();
+ statePropData->m_StateData[currState].transitionData.onFrame = f->GetFloat();
+
+ for ( int currDrawable=0; currDrawable < numDrawables; currDrawable++ )
+ {
+ f->BeginChunk();
+ f->GetPString(buf);
+ statePropData->m_StateData[currState].visibilityData[currDrawable].isVisible = ( f->GetLong() != 0 );
+ f->EndChunk();
+ }
+
+ for ( int currFrameController=0; currFrameController < numFrameControllers; currFrameController++ )
+ {
+ f->BeginChunk();
+ f->GetPString(buf);
+ statePropData->m_StateData[currState].frameControllerData[currFrameController].isCyclic = ( f->GetLong() != 0 );
+ statePropData->m_StateData[currState].frameControllerData[currFrameController].numberOfCycles = f->GetLong();
+ statePropData->m_StateData[currState].frameControllerData[currFrameController].holdFrame = ( f->GetLong() != 0 );
+ statePropData->m_StateData[currState].frameControllerData[currFrameController].minFrame = f->GetFloat();
+ statePropData->m_StateData[currState].frameControllerData[currFrameController].maxFrame = f->GetFloat();
+ statePropData->m_StateData[currState].frameControllerData[currFrameController].relativeSpeed = f->GetFloat();
+ f->EndChunk();
+ }
+
+ for ( unsigned int currEvent=0; currEvent < statePropData->m_StateData[currState].numEvents; currEvent++ )
+ {
+ f->BeginChunk();
+ strcpy( statePropData->m_StateData[currState].eventData[currEvent].eventName , f->GetPString(buf) );
+ statePropData->m_StateData[currState].eventData[currEvent].toState = f->GetLong();
+ statePropData->m_StateData[currState].eventData[currEvent].eventID = f->GetLong();
+ f->EndChunk();
+ }
+
+ for ( unsigned int currCallback=0; currCallback < statePropData->m_StateData[currState].numCallbacks; currCallback++ )
+ {
+ f->BeginChunk();
+ strcpy( statePropData->m_StateData[currState].callbackData[currCallback].callbackName , f->GetPString(buf) );
+ statePropData->m_StateData[currState].callbackData[currCallback].callbackID = f->GetLong();
+ statePropData->m_StateData[currState].callbackData[currCallback].onFrame = f->GetFloat();
+ f->EndChunk();
+ }
+
+ f->EndChunk();
+ }
+
+ return statePropData;
+} \ No newline at end of file
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/engine/statepropdata.hpp b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/statepropdata.hpp
new file mode 100644
index 0000000..f6cf691
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/statepropdata.hpp
@@ -0,0 +1,139 @@
+#ifndef _STATEPROPDATA_HPP_
+#define _STATEPROPDATA_HPP_
+
+
+#include <radmath/radmath.hpp>
+#include <p3d/loadmanager.hpp>
+
+#include "statepropdatatypes.hpp"
+
+//=============================================================================
+// Forward Class/Struct Declarations
+//=============================================================================
+
+class CStateProp;
+class tAnimatedObjectFactory;
+class CStatePropDataLoader;
+
+//=============================================================================
+// Definitions
+//=============================================================================
+#define MAX_STATES 50
+#define MAX_FRAMECONTROLLERS 250
+#define MAX_VISIBILITIES 250
+#define MAX_EVENTS 50
+
+//State data
+struct StateData
+{
+ TransitionData transitionData;
+ VisibilityData visibilityData[MAX_VISIBILITIES];
+ FrameControllerData frameControllerData[MAX_FRAMECONTROLLERS];
+ EventData eventData[MAX_EVENTS];
+ CallbackData callbackData[MAX_EVENTS];
+
+ unsigned int numEvents;
+ unsigned int numCallbacks;
+};
+
+//=============================================================================
+// Class Declarations
+// Prop
+//=============================================================================
+
+class CStatePropData : public tEntity
+{
+
+public:
+
+ friend class CStateProp;
+ friend class CStatePropDataLoader;
+
+ CStatePropData( tAnimatedObjectFactory* factory );
+ CStatePropData();
+ ~CStatePropData();
+
+ // State Data =====================================================================================
+ //Get
+ unsigned int GetNumberOfStates();
+ StateData GetStateData( unsigned int state );
+ //Set
+ void InsertState( unsigned int state );
+ void DeleteState( unsigned int state );
+
+ //Transition Data ==================================================================================
+ //Get
+ TransitionData GetTransitionData( int state );
+ //Set
+ void SetAutoTransition( int state, bool b );
+ void SetAutoTransitionOnFrame( int state, float onFrame );
+ void SetAutoTransitionToState( int state, int toState );
+
+ //Visibility Data ==================================================================================
+ //Get
+ VisibilityData GetVisibilityData( int state , int index);
+ //Set
+ void SetVisible( int state , int index , bool b );
+ void SetAllVisibilities( int state , bool b );
+ void ShowAll(int state);
+ void HideAll(int state);
+
+ //Frame Controller Data =============================================================================
+ //Get
+ FrameControllerData GetFrameControllerData( int state, int fc );
+ //Set
+ void SetCyclic( int state ,int fc, bool isCyclic );
+ void SetRelativeSpeed( int state ,int fc, float speed );
+ void SetFrameRange( int state ,int fc, float min, float max );
+ void SetHoldFrame( int state , int fc , bool holdFrame );
+ void SetNumberOfCycles( int state , int fc , unsigned int numberOfCycles );
+
+ //Event Data ========================================================================================
+ //Get
+ unsigned int GetNumberOfEvents( int state );
+ EventData GetEventData( int state , int eventindex );
+ //Set
+ void AddEvent( const char* event , int eventEnum , int toState , int fromState );
+ void EditEvent( int state, int EventIndex, char* eventName, int eventEnum , int toState );
+ void DeleteEvent( int fromState , int index );
+
+ //Callback Data ======================================================================================
+ //Get
+ unsigned int GetNumberOfCallbacks( int state );
+ CallbackData GetCallbackData( int state , int eventindex );
+ //Set
+ void AddCallback( int state , const char* event , int eventEnum , float frame );
+ void EditCallback( int state, int CBIndex, char* eventname, int eventEnum , float frame );
+ void DeleteCallback( int state , int index );
+
+private:
+
+ //reset the prop data
+ void ResetData();
+
+ //animated object factory
+ char m_FactoryName[64];
+ tAnimatedObjectFactory* m_ObjectFactory;
+
+ //total number of states
+ int m_NumStates;
+ StateData m_StateData[MAX_STATES];
+
+};
+
+
+//=============================================================================
+// Class Declarations
+// PropLoader
+//=============================================================================
+class CStatePropDataLoader : public tSimpleChunkHandler
+{
+public:
+ CStatePropDataLoader();
+ tEntity* LoadObject(tChunkFile* file, tEntityStore* store);
+
+protected:
+ ~CStatePropDataLoader() {};
+};
+
+#endif //_STATEPROPDATA_HPP_
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/engine/statepropdatatypes.hpp b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/statepropdatatypes.hpp
new file mode 100644
index 0000000..4d035af
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/statepropdatatypes.hpp
@@ -0,0 +1,45 @@
+#ifndef _STATEPROPDATATYPES_HPP_
+#define _STATEPROPDATATYPES_HPP_
+
+//Transition data
+struct TransitionData
+{
+ unsigned int autoTransition;
+ unsigned int toState;
+ float onFrame;
+};
+
+//Visibility data
+struct VisibilityData
+{
+ unsigned int isVisible;
+};
+
+//Frame controller data
+struct FrameControllerData
+{
+ unsigned int isCyclic;
+ unsigned int numberOfCycles;
+ unsigned int holdFrame;
+ float minFrame;
+ float maxFrame;
+ float relativeSpeed;
+};
+
+//Event data
+struct EventData
+{
+ char eventName[64];
+ unsigned int eventID;
+ unsigned int toState;
+};
+
+//Callback data
+struct CallbackData
+{
+ char callbackName[64];
+ unsigned int callbackID;
+ float onFrame;
+};
+
+#endif //_STATEPROPDATATYPES_HPP_
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/engine/workspace.cpp b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/workspace.cpp
new file mode 100644
index 0000000..2d31863
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/workspace.cpp
@@ -0,0 +1,879 @@
+/*===========================================================================
+Workspace.cpp - Pure3D testbed
+
+
+ Copyright (c) 1995-1999 Radical Entertainment, Inc.
+ All rights reserved.
+===========================================================================*/
+#include <windows.h>
+
+#include <assert.h>
+#include <string.h>
+#include <typeinfo.h>
+#include <ctype.h> //for isdigit
+#include <stdlib.h> //for atoi
+
+#include <p3d/pure3d.hpp>
+#include <p3d/anim/animatedobject.hpp>
+#include <p3d/anim/poseanimation.hpp>
+#include <p3d/anim/skeleton.hpp>
+#include <p3d/geometry.hpp>
+#include <p3d/anim/polyskin.hpp>
+#include <p3d/utility.hpp>
+#include <p3d/drawable.hpp>
+
+#include <simcommon/simutility.hpp>
+#include <simcommon/simenvironment.hpp> // for SimUnits
+#include <simcommon/simulatedobject.hpp>
+#include <simcollision/collisionmanager.hpp>
+#include <simcollision/collisiondisplay.hpp>
+#include <simcollision/proximitydetection.hpp>
+
+#include <sp/interface.hpp>
+#include "workspace.hpp"
+
+#include "stateprop.hpp"
+#include "statepropdata.hpp"
+
+void RegisterExtraChunks(void)
+{ //do nothing
+}
+
+bool g_DrawCollision = true;
+bool g_IsPaused = false;
+bool g_DebugPhysicsDisplay = false;
+float g_TotalTime_sec = 0.f;
+
+const char c_StatePropExtension[] = "_spdata.p3d";
+
+
+Workspace* g_Workspace = NULL;
+CStateProp* g_CStateProp = NULL;
+
+template <class T> class TemplateIterator : public ViewerIterator
+{
+public:
+ TemplateIterator(T* t)
+ {
+ iterator = t;
+ current = iterator->First();
+ }
+
+ ~TemplateIterator()
+ {
+ delete iterator;
+ }
+
+ tEntity* First(void)
+ {
+ current = iterator->First();
+
+ return current;
+ }
+
+ tEntity* Current(void)
+ {
+ if(!current)
+ current = iterator->First();
+
+ return current;
+ }
+
+ tEntity* Next(bool loop = false)
+ {
+ current = iterator->Next();
+ if(loop && !current)
+ current = iterator->First();
+ return current;
+ }
+
+ tEntity* Prev(void)
+ {
+ current = iterator->Prev();
+ if(!current)
+ current = iterator->Last();
+ return current;
+
+ }
+
+private:
+ T* iterator;
+ tEntity* current;
+};
+
+class DrawIterator : public tInventory::Iterator<tDrawable> {};
+class ObjectFactoryIterator : public tInventory::Iterator<tAnimatedObjectFactory> {};
+class CStatePropDataIterator : public tInventory::Iterator<CStatePropData> {};
+
+
+//Get allocated memory
+unsigned int GetAllocatedMemory()
+{
+ // on windows can't rely on the total physical memory so we must walk over
+ // each heap and accumulate all the memory allocated in it. there is stack
+ // overhead too but that should be minimal.
+ HANDLE heaps[128];
+
+ int numHeaps = GetProcessHeaps(sizeof(heaps)/sizeof(heaps[0]), heaps);
+ if(numHeaps > sizeof(heaps)/sizeof(heaps[0]))
+ {
+ numHeaps = sizeof(heaps)/sizeof(heaps[0]);
+ }
+
+ unsigned int total = 0;
+ int i;
+ for(i=0; i<numHeaps; i++)
+ {
+ PROCESS_HEAP_ENTRY heapEntry;
+
+ heapEntry.lpData = NULL;
+ if(!HeapLock(heaps[i]))
+ {
+ //HC_DEBUGPRINT(("could not lock heap %d", i));
+ continue;
+ }
+ while(HeapWalk(heaps[i], &heapEntry))
+ {
+ if(heapEntry.wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE)
+ {
+ // don't count non-committed pages as some of pure3d seems to
+ // mmap or allocate large ranges that never actually get paged
+ // in
+ //total += heapEntry.cbData;
+ }
+ else
+ {
+ total += heapEntry.cbData;
+ }
+ }
+ HeapUnlock(heaps[i]);
+ }
+
+ return total;
+}
+
+//-------------------------------------------------------------------
+// Workspace class
+// derive from Testbed.
+//
+//-------------------------------------------------------------------
+
+Workspace::Workspace() :
+ m_CStateProp(NULL),
+ m_CollisionManager(NULL),
+ m_CollisionSolver(NULL),
+ m_DrawableFloor(NULL),
+ m_SimStateFloor(NULL)
+{
+ sim::InstallSimLoaders();
+
+ //draw outlines for debug render
+ sim::SetDrawVolumeMethod( sim::DrawVolumeShape );
+
+ Init();
+}
+
+
+Workspace::~Workspace()
+{
+ ResetAll();
+
+ if ( m_CStateProp )
+ m_CStateProp->Release();
+
+ p3d::loadManager->RemoveAllHandlers(); // should be in testbed
+}
+
+void Workspace::Init()
+{
+ // get path to exe
+ GetModuleFileName(NULL, m_Path, sizeof(m_Path) - 1);
+ m_Path[ strlen(m_Path) - 13 ] = '\0';
+
+ m_DrawableIterator = new TemplateIterator<DrawIterator>(new DrawIterator);
+ m_ObjectFactoryIterator = new TemplateIterator<ObjectFactoryIterator>(new ObjectFactoryIterator);
+ m_CStatePropDataIterator = new TemplateIterator<CStatePropDataIterator>(new CStatePropDataIterator);
+
+ // install loader for Prop
+ tP3DFileHandler* p3d = p3d::loadManager->GetP3DHandler();
+ if(p3d)
+ {
+ p3d->AddHandler( new CStatePropDataLoader );
+ }
+
+ if (!sim::SimUnits::UnitSet())
+ {
+ sim::InitializeSimulation( sim::MetersUnits );
+ }
+
+ if (!m_CollisionManager)
+ {
+ float MAX_UPDATEAI_TIME_ms = 1000.0f*1.0f/30.0f; // 30 fps
+ //sim::SimulatedObject::SetMaxTimeStep(MAX_UPDATEAI_TIME_ms/1000.0f);
+ float collisionDistanceCGS = 2.0f; // cm
+ m_CollisionManager = sim::CollisionManager::GetInstance();
+ m_CollisionManager->AddRef();
+ sim::SimEnvironment* simEnvironment = sim::SimEnvironment::GetDefaultSimEnvironment();
+ simEnvironment->SetCollisionDistanceCGS(collisionDistanceCGS);
+ m_CollisionManager->SetCollisionManagerAttributes( sim::CM_DetectAll | sim::CM_SolveAll );
+
+ P3DASSERT(m_CollisionSolver == NULL);
+ m_CollisionSolver = new AICollisionSolverAgent();
+ m_CollisionSolver->AddRef();
+ m_CollisionManager->GetImpulseBasedCollisionSolver()->SetCollisionSolverAgent(m_CollisionSolver);
+ }
+}
+
+void Workspace::LoadFloor( const char* p3dfilename )
+{
+ if ( m_DrawableFloor )
+ m_DrawableFloor->Release();
+
+ if ( m_SimStateFloor )
+ m_SimStateFloor->Release();
+
+ //check that a data file exist
+ FILE* p = fopen( p3dfilename , "r" );
+ if ( p )
+ {
+ p3d::inventory->RemoveAllElements();
+
+ (void) p3d::load(p3dfilename);
+
+ m_DrawableFloor = p3d::find<tDrawable>("floorShape");
+ if ( m_DrawableFloor )
+ m_DrawableFloor->AddRef();
+
+ fclose(p);
+ }
+}
+
+void Workspace::ResetAll(bool emptyInventory)
+{
+ if (emptyInventory)
+ {
+ delete m_DrawableIterator;
+ delete m_ObjectFactoryIterator;
+ delete m_CStatePropDataIterator;
+
+ p3d::inventory->RemoveAllElements();
+ }
+
+ ResetProp();
+
+
+ if ( m_CollisionSolver )
+ {
+ m_CollisionSolver->Release();
+ m_CollisionSolver = NULL;
+ }
+
+ if ( m_CollisionManager )
+ {
+ m_CollisionManager->ResetAll();
+ m_CollisionManager->Release();
+ m_CollisionManager = NULL;
+ }
+
+ this->Init();
+}
+
+void Workspace::Advance(float dt_ms)
+{
+ g_TotalTime_sec += dt_ms / 1000.f;
+ float inDt_Sec = dt_ms / 1000.f;
+
+ if ( !g_IsPaused )
+ {
+ if ( m_CStateProp )
+ {
+ m_CStateProp->Update(dt_ms);
+ }
+ if ( m_CollisionManager )
+ {
+ m_CollisionManager->Update( inDt_Sec , g_TotalTime_sec );
+ }
+ }
+}
+
+void Workspace::Display(tContext* context)
+{
+ if ( m_DrawableFloor )
+ {
+ m_DrawableFloor->Display();
+ }
+
+ if ( m_CStateProp )
+ {
+ m_CStateProp->UpdateFrameControllersForRender();
+ m_CStateProp->Render();
+ }
+
+ if ( g_DrawCollision )
+ {
+ sim::DisplayCollisionObjects(sim::CollisionManager::GetInstance());
+ }
+}
+
+void Workspace::ResetProp()
+{
+ if ( m_CStateProp )
+ {
+ m_CStateProp->Release();
+ }
+
+ m_CStateProp = NULL;
+ g_CStateProp = NULL;
+}
+
+int Workspace::Load( const char* name )
+{
+ ResetAll();
+
+ (void) p3d::load(name);
+
+ //Search for object factories
+ m_ObjectFactoryIterator->First();
+ m_CStatePropDataIterator->First();
+
+ if ( m_ObjectFactoryIterator->Current() && m_CStatePropDataIterator->Current() )
+ {
+ //if we have an objectfactory and a prop we are good (1 file with all chunks)
+ CStatePropData* statePropData = ((CStatePropData*)m_CStatePropDataIterator->Current());
+ m_CStateProp = CStateProp::CreateCStateProp( statePropData , 0 );
+ m_CStateProp->AddRef();
+ }
+ else if( m_ObjectFactoryIterator->Current() )
+ {
+ //if we just have the factory we need the file with the prop data so load it
+ char buf[256];
+ memcpy( buf , name , strlen(name) - strlen(".p3d") );
+ buf[strlen(name) - strlen(".p3d")] = '\0';
+ strcat(buf , c_StatePropExtension );
+
+ //check that a data file exist
+ FILE* p = fopen( buf , "r" );
+ if ( p )
+ {
+ (void) p3d::load(buf);
+
+ m_CStatePropDataIterator->First();
+ if ( m_CStatePropDataIterator->Current() )
+ {
+ //if we have an objectfactory and a prop we are good (1 file with all chunks)
+ CStatePropData* statePropData = ((CStatePropData*)m_CStatePropDataIterator->Current());
+ m_CStateProp = CStateProp::CreateCStateProp( statePropData , 0 );
+ m_CStateProp->AddRef();
+ }
+ fclose(p);
+ }
+ else
+ {
+ //Create a new prop
+ CStatePropData* statePropData = new CStatePropData( (tAnimatedObjectFactory*)m_ObjectFactoryIterator->Current() );
+ if ( statePropData )
+ {
+ m_CStateProp = CStateProp::CreateCStateProp( statePropData , 0 );
+ m_CStateProp->AddRef();
+ }
+ }
+ }
+ else if( m_CStatePropDataIterator->Current() )
+ {
+ //if we just have the prop we need the file with the factory
+ char buf[256];
+ memcpy( buf , name , strlen(name) - strlen(c_StatePropExtension) );
+ buf[strlen(name) - strlen(c_StatePropExtension)] = '\0';
+ strcat(buf , ".p3d");
+
+ //check that a data file exist
+ FILE* p = fopen( buf , "r" );
+ if ( p )
+ {
+ (void) p3d::load(buf);
+
+ m_ObjectFactoryIterator->First();
+ if ( m_ObjectFactoryIterator->Current() )
+ {
+ CStatePropData* statePropData = ((CStatePropData*)m_CStatePropDataIterator->Current());
+ m_CStateProp = CStateProp::CreateCStateProp( statePropData , 0 );
+ m_CStateProp->AddRef();
+ }
+ fclose(p);
+ }
+ else
+ {
+ //no file associated with this prop data...
+ ResetAll();
+ }
+ }
+
+ if ( m_CStateProp )
+ {
+ g_CStateProp = m_CStateProp;
+ }
+ else
+ {
+ g_CStateProp = NULL;
+ }
+
+
+ return 1;
+}
+
+
+//=============================================================================
+// CStateProp - DLL interface
+//=============================================================================
+//Load a pure3D file with art for the background===============================
+int SP_CALLCONV SPLoadBackground( const char* filename )
+{
+ if ( g_Workspace )
+ {
+ g_Workspace->LoadFloor( filename );
+ return 1;
+ }
+ return 0;
+}
+
+//Load pure3D file ============================================================
+int SP_CALLCONV SPLoad( const char* filename )
+{
+ if ( g_Workspace )
+ {
+ g_Workspace->Load( filename );
+ return 1;
+ }
+ return 0;
+}
+
+//Export the SmartPropData ====================================================
+int SP_CALLCONV SPExportStatePropData( const char* filename )
+{
+ if ( g_CStateProp )
+ {
+ char buf[256];
+ memcpy( buf , filename , strlen(filename) - strlen(".p3d") );
+ buf[strlen(filename) - strlen(".p3d")] = '\0';
+ strcat( buf , c_StatePropExtension );
+ g_CStateProp->ExportChunk( buf );
+ return 1;
+ }
+ return 0;
+}
+
+//Display collision ==========================================================
+int SP_CALLCONV SPShowCollision( int show )
+{
+ g_DrawCollision = ( show == 1 );
+ return 1;
+}
+
+//Prop name ===================================================================
+const char* SP_CALLCONV SPGetPropName()
+{
+ if ( g_CStateProp )
+ {
+ return g_CStateProp->GetCStatePropData()->GetName();
+ }
+ return NULL;
+}
+
+//advance ====================================================================
+int SP_CALLCONV SPPause( bool b )
+{
+ g_IsPaused = b;
+ return 1;
+}
+int SP_CALLCONV SPAdvanceOneFrame()
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->Update( 100.f );
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPBackOneFrame()
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->Update( -100.f );
+ return 1;
+ }
+ return 0;
+}
+
+// State Data =================================================================
+unsigned int SP_CALLCONV SPGetNumberOfStates()
+{
+ if ( g_CStateProp )
+ {
+ return g_CStateProp->GetCStatePropData()->GetNumberOfStates();
+ }
+ return 0;
+}
+
+int SP_CALLCONV SPInsertState( unsigned int state )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->InsertState( state );
+ g_CStateProp->UpdateOnDataEdit();
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPDeleteState( unsigned int state )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->DeleteState( state );
+ g_CStateProp->UpdateOnDataEdit();
+ return 1;
+ }
+ return 0;
+}
+
+int SP_CALLCONV SPGetCurrentState()
+{
+ if ( g_CStateProp )
+ {
+ return g_CStateProp->GetState();
+ }
+ return 0;
+}
+int SP_CALLCONV SPNextState()
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->NextState();
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPPrevState()
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->PrevState();
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPSetState( unsigned int state )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->SetState( state );
+ return 1;
+ }
+ return 0;
+}
+
+//Transition Data =============================================================
+bool SP_CALLCONV SPGetTransitionData( int state , TransitionData* transitionData )
+{
+ if ( g_CStateProp )
+ {
+ transitionData->autoTransition = g_CStateProp->GetCStatePropData()->GetTransitionData( state ).autoTransition;
+ transitionData->onFrame = g_CStateProp->GetCStatePropData()->GetTransitionData( state ).onFrame;
+ transitionData->toState = g_CStateProp->GetCStatePropData()->GetTransitionData( state ).toState;
+ return true;
+ }
+ return false;
+}
+int SP_CALLCONV SPSetAutoTransition( int state, bool b )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->SetAutoTransition( state , b );
+ g_CStateProp->UpdateOnDataEdit();
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPSetAutoTransitionOnFrame( int state, float onFrame )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->SetAutoTransitionOnFrame( state , onFrame );
+ g_CStateProp->UpdateOnDataEdit();
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPSetAutoTransitionToState( int state, int toState )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->SetAutoTransitionToState( state , toState );
+ g_CStateProp->UpdateOnDataEdit();
+ return 1;
+ }
+ return 0;
+}
+
+//Visibility Data =============================================================
+bool SP_CALLCONV SPGetVisibilityData( int state , int index , VisibilityData* visibilityData )
+{
+ if ( g_CStateProp )
+ {
+ visibilityData->isVisible = g_CStateProp->GetCStatePropData()->GetVisibilityData( state , index ).isVisible;
+ return true;
+ }
+ return false;
+}
+int SP_CALLCONV SPSetVisible( int state , int index , bool b )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->SetVisible( state , index , b );
+ g_CStateProp->UpdateOnDataEdit();
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPSetAllVisibilities( int state , bool b )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->SetAllVisibilities( state , b );
+ g_CStateProp->UpdateOnDataEdit();
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPShowAll(int state)
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->ShowAll( state );
+ g_CStateProp->UpdateOnDataEdit();
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPHideAll(int state)
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->HideAll( state );
+ g_CStateProp->UpdateOnDataEdit();
+ return 1;
+ }
+ return 0;
+}
+
+SP_IMPORT int SP_CALLCONV SPGetNumDrawables()
+{
+ if ( g_CStateProp )
+ {
+ return g_CStateProp->GetNumberOfDrawableElements();
+ }
+ return 0;
+}
+
+const char* SP_CALLCONV SPGetDrawableName( int index )
+{
+ if ( g_CStateProp )
+ {
+ return g_CStateProp->GetDrawableName( index );
+ }
+ return NULL;
+}
+
+//Frame Controller Data =======================================================
+bool SPGetFrameControllerData( int state, int fc , FrameControllerData* fcData )
+{
+ if ( g_CStateProp )
+ {
+ fcData->holdFrame = g_CStateProp->GetCStatePropData()->GetFrameControllerData( state , fc ).holdFrame;
+ fcData->isCyclic = g_CStateProp->GetCStatePropData()->GetFrameControllerData( state , fc ).isCyclic;
+ fcData->maxFrame = g_CStateProp->GetCStatePropData()->GetFrameControllerData( state , fc ).maxFrame;
+ fcData->minFrame = g_CStateProp->GetCStatePropData()->GetFrameControllerData( state , fc ).minFrame;
+ fcData->numberOfCycles = g_CStateProp->GetCStatePropData()->GetFrameControllerData( state , fc ).numberOfCycles;
+ fcData->relativeSpeed = g_CStateProp->GetCStatePropData()->GetFrameControllerData( state , fc ).relativeSpeed;
+ return true;
+ }
+ return false;
+}
+int SP_CALLCONV SPSetCyclic( int state ,int fc, bool isCyclic )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->SetCyclic( state , fc , isCyclic );
+ g_CStateProp->UpdateOnDataEdit();
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPSetRelativeSpeed( int state ,int fc, float speed )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->SetRelativeSpeed( state , fc , speed );
+ g_CStateProp->UpdateOnDataEdit();
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPSetFrameRange( int state ,int fc, float min, float max )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->SetFrameRange( state , fc , min , max );
+ g_CStateProp->UpdateOnDataEdit();
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPSetHoldFrame( int state , int fc , bool holdFrame )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->SetHoldFrame( state , fc , holdFrame );
+ g_CStateProp->UpdateOnDataEdit();
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPSetNumberOfCycles( int state , int fc , unsigned int numberOfCycles )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->SetNumberOfCycles( state , fc , numberOfCycles );
+ return 1;
+ }
+ return 0;
+}
+
+int SP_CALLCONV SPGetNumFrameControllers()
+{
+ if ( g_CStateProp )
+ {
+ return g_CStateProp->GetNumberOfFrameControllers();
+ }
+ return 0;
+}
+float SP_CALLCONV SPGetBaseFrameControllerFrame()
+{
+ if ( g_CStateProp )
+ {
+ return g_CStateProp->GetBaseFrameControllerFrame();
+ }
+ return 0.f;
+}
+float SP_CALLCONV SPGetFrameControllerFrame( int index )
+{
+ if ( g_CStateProp )
+ {
+ return g_CStateProp->GetFrameControllerByIndex( index )->GetFrame();
+ }
+ return 0.f;
+}
+const char* SP_CALLCONV SPGetFrameControllerName( int index )
+{
+ if ( g_CStateProp )
+ {
+ return g_CStateProp->GetFrameControllerByIndex( index )->GetName();
+ }
+ return NULL;
+}
+
+//Event Data ==================================================================
+unsigned int SP_CALLCONV SPGetNumberOfEvents( int state )
+{
+ if ( g_CStateProp )
+ {
+ return g_CStateProp->GetCStatePropData()->GetNumberOfEvents( state );
+ }
+ return 0;
+}
+bool SP_CALLCONV SPGetEventData( int state , int eventindex , EventData *eventData)
+{
+ if ( g_CStateProp )
+ {
+ EventData ed = g_CStateProp->GetCStatePropData()->GetEventData( state , eventindex );
+ eventData->eventID = ed.eventID;
+ strcpy( eventData->eventName , ed.eventName );
+ eventData->toState = ed.toState;
+ return true;
+ }
+ return false;
+}
+int SP_CALLCONV SPAddEvent( const char* event , int eventEnum , int toState , int fromState )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->AddEvent( event , eventEnum , toState , fromState );
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPEditEvent( int state, int EventIndex, char* eventName, int eventEnum , int toState )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->EditEvent( state , EventIndex , eventName , eventEnum , toState );
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPDeleteEvent( int fromState , int index )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->DeleteEvent( fromState , index );
+ return 1;
+ }
+ return 0;
+}
+
+//Callback Data ===============================================================
+unsigned int SP_CALLCONV SPGetNumberOfCallbacks( int state )
+{
+ if ( g_CStateProp )
+ {
+ return g_CStateProp->GetCStatePropData()->GetNumberOfCallbacks( state );
+ }
+ return 0;
+}
+bool SP_CALLCONV SPGetCallbackData( int state , int index , CallbackData* callbackData )
+{
+ if ( g_CStateProp )
+ {
+ callbackData->callbackID = g_CStateProp->GetCStatePropData()->GetCallbackData( state , index ).callbackID;
+ strcpy( callbackData->callbackName , g_CStateProp->GetCStatePropData()->GetCallbackData( state , index ).callbackName );
+ callbackData->onFrame = g_CStateProp->GetCStatePropData()->GetCallbackData( state , index ).onFrame;
+ return true;
+ }
+ return false;
+}
+int SP_CALLCONV SPAddCallback( int state , const char* event , int eventEnum , float frame )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->AddCallback( state , event , eventEnum , frame );
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPEditCallback( int state, int CBIndex, char* eventname, int eventEnum , float frame )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->EditCallback( state , CBIndex , eventname , eventEnum , frame );
+ return 1;
+ }
+ return 0;
+}
+int SP_CALLCONV SPDeleteCallback( int state , int index )
+{
+ if ( g_CStateProp )
+ {
+ g_CStateProp->GetCStatePropData()->DeleteCallback( state , index );
+ return 1;
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/engine/workspace.hpp b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/workspace.hpp
new file mode 100644
index 0000000..e476ebf
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/engine/workspace.hpp
@@ -0,0 +1,67 @@
+#ifndef _WORKSPACE_HPP_
+#define _WORKSPACE_HPP_
+
+#include <radmath/radmath.hpp>
+#include <simcollision/collisionmanager.hpp>
+
+#include "aicollisionsolveragent.hpp"
+
+class CStateProp;
+class tDrawable;
+
+//=============================================================================
+// Class Declarations
+// ViewerIterator
+//=============================================================================
+class ViewerIterator
+{
+public:
+ virtual ~ViewerIterator() {}
+ virtual tEntity* Current(void) = 0;
+ virtual tEntity* Next(bool loop = false) = 0;
+ virtual tEntity* Prev(void) = 0;
+ virtual tEntity* First(void) = 0;
+};
+
+
+//=============================================================================
+// Class Declarations
+// Workspace
+//=============================================================================
+class Workspace : public tRefCounted
+{
+public:
+ Workspace();
+ ~Workspace();
+
+ void Init();
+ void ResetAll( bool emptyInventory = true );
+ void Advance(float dt_ms);
+ void Display(tContext* context);
+
+ int Load( const char* name );
+ int Pause(bool b);
+
+ void LoadFloor( const char* p3dfilename );
+
+private:
+
+ void ResetProp();
+ CStateProp* m_CStateProp;
+
+ AICollisionSolverAgent *m_CollisionSolver;
+ sim::CollisionManager* m_CollisionManager;
+
+ ViewerIterator* m_DrawableIterator;
+ ViewerIterator* m_ObjectFactoryIterator;
+ ViewerIterator* m_CStatePropDataIterator;
+
+ tDrawable* m_DrawableFloor;
+ sim::SimState* m_SimStateFloor;
+
+ char m_Path[256];
+};
+
+
+
+#endif
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/interface/base.hpp b/tools/statepropbuilder/apps/spbuilder/code/sp/interface/base.hpp
new file mode 100644
index 0000000..dd8fe32
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/interface/base.hpp
@@ -0,0 +1,25 @@
+/*
+ * fv/interface/base.hpp
+ */
+
+
+#ifndef SP_INTERFACE_BASE_HPP
+#define SP_INTERFACE_BASE_HPP
+
+
+#define WIN32_LEAN_AND_MEAN
+#define WIN32_EXTRA_LEAN
+#include <windows.h>
+
+
+#ifdef SMARTPROP_ENGINE
+# define SP_IMPORT __declspec(dllexport)
+#else
+# define SP_IMPORT __declspec(dllimport)
+#endif
+
+
+#define SP_CALLCONV __cdecl
+
+
+#endif // SP_INTERFACE_BASE_HPP
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/interface/context.hpp b/tools/statepropbuilder/apps/spbuilder/code/sp/interface/context.hpp
new file mode 100644
index 0000000..72da9a0
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/interface/context.hpp
@@ -0,0 +1,50 @@
+/*
+ * sp/interface/context.hpp
+ */
+
+
+#ifndef SP_INTERFACE_CONTEXT_HPP
+#define SP_INTERFACE_CONTEXT_HPP
+
+#include <sp/interface/base.hpp>
+
+
+extern "C"
+{
+
+ SP_IMPORT int SP_CALLCONV SPContextOpen(HWND hwnd);
+ SP_IMPORT int SP_CALLCONV SPContextClose();
+
+ SP_IMPORT int SP_CALLCONV SPContextViewResize(int w, int h);
+
+ SP_IMPORT int SP_CALLCONV SPContextIsPDDIStatsEnabled();
+ SP_IMPORT int SP_CALLCONV SPContextSetIsPDDIStatsEnabled(int statsEnabled);
+
+ SP_IMPORT int SP_CALLCONV SPContextAdvance();
+ SP_IMPORT int SP_CALLCONV SPContextDisplay();
+
+ SP_IMPORT int SP_CALLCONV SPContextMouseDown(int button, int shift, int x, int y);
+ SP_IMPORT int SP_CALLCONV SPContextMouseMove(int button, int shift, int x, int y);
+ SP_IMPORT int SP_CALLCONV SPContextMouseUp(int button, int shift, int x, int y);
+ SP_IMPORT int SP_CALLCONV SPContextMouseWheel(int scroll);
+
+ SP_IMPORT float SP_CALLCONV SPSimulationGetFPS();
+ SP_IMPORT float SP_CALLCONV SPSimulationGetRate();
+ SP_IMPORT int SP_CALLCONV SPSimulationSetRate(float rate);
+
+ SP_IMPORT unsigned int SP_CALLCONV SPGetMemoryUsage();
+
+ SP_IMPORT int SP_CALLCONV SPContextGetCameraLock();
+ SP_IMPORT int SP_CALLCONV SPContextSetCameraLock(int cameraLock);
+
+ SP_IMPORT int SP_CALLCONV SPInventoryClear();
+ SP_IMPORT int SP_CALLCONV SPInventoryGetEntityCount();
+ SP_IMPORT int SP_CALLCONV SPInventoryGetEntityName(int index, char* name, int nameLen, char* type, int typeLen);
+
+ SP_IMPORT int SP_CALLCONV SPSetBackgroundColour( int r , int g , int b );
+
+
+} // extern "C"
+
+
+#endif // SP_INTERFACE_CONTEXT_HPP
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/interface/platform.hpp b/tools/statepropbuilder/apps/spbuilder/code/sp/interface/platform.hpp
new file mode 100644
index 0000000..8a2ba13
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/interface/platform.hpp
@@ -0,0 +1,24 @@
+/*
+ * fv/interface/platform.hpp
+ */
+
+
+#ifndef SP_INTERFACE_PLATFORM_HPP
+#define SP_INTERFACE_PLATFORM_HPP
+
+
+#include <sp/interface/base.hpp>
+
+
+extern "C"
+{
+
+
+SP_IMPORT int SP_CALLCONV SPPlatformOpen(HWND hwnd);
+SP_IMPORT int SP_CALLCONV SPPlatformClose();
+
+
+} // extern "C"
+
+
+#endif // SP_INTERFACE_PLATFORM_HPP
diff --git a/tools/statepropbuilder/apps/spbuilder/code/sp/interface/workspace.hpp b/tools/statepropbuilder/apps/spbuilder/code/sp/interface/workspace.hpp
new file mode 100644
index 0000000..210ac8a
--- /dev/null
+++ b/tools/statepropbuilder/apps/spbuilder/code/sp/interface/workspace.hpp
@@ -0,0 +1,89 @@
+/*
+ * fv/interface/platform.hpp
+ */
+
+#ifndef SP_INTERFACE_WORKSPACE_HPP
+#define SP_INTERFACE_WORKSPACE_HPP
+
+#include <sp/interface/base.hpp>
+#include <sp/engine/statepropdatatypes.hpp>
+
+extern "C"
+{
+ //Load Background =============================================================
+ SP_IMPORT int SP_CALLCONV SPLoadBackground( const char* filename );
+
+ //Load ========================================================================
+ SP_IMPORT int SP_CALLCONV SPLoad( const char* filename );
+
+ //Export ======================================================================
+ SP_IMPORT int SP_CALLCONV SPExportStatePropData( const char* filename );
+
+ //Draw collision ==============================================================
+ SP_IMPORT int SP_CALLCONV SPShowCollision( int show );
+
+ //Prop name ===================================================================
+ SP_IMPORT const char* SP_CALLCONV SPGetPropName();
+
+ //Advance =====================================================================
+ SP_IMPORT int SP_CALLCONV SPPause( bool b );
+ SP_IMPORT int SP_CALLCONV SPAdvanceOneFrame();
+ SP_IMPORT int SP_CALLCONV SPBackOneFrame();
+
+ // State Data =================================================================
+ SP_IMPORT unsigned int SP_CALLCONV SPGetNumberOfStates();
+ SP_IMPORT int SP_CALLCONV SPInsertState( unsigned int state );
+ SP_IMPORT int SP_CALLCONV SPDeleteState( unsigned int state );
+
+ SP_IMPORT int SP_CALLCONV SPGetCurrentState();
+ SP_IMPORT int SP_CALLCONV SPNextState();
+ SP_IMPORT int SP_CALLCONV SPPrevState();
+ SP_IMPORT int SP_CALLCONV SPSetState( unsigned int state );
+
+ //Transition Data =============================================================
+ SP_IMPORT bool SP_CALLCONV SPGetTransitionData( int state , TransitionData* transitionData );
+ SP_IMPORT int SP_CALLCONV SPSetAutoTransition( int state, bool b );
+ SP_IMPORT int SP_CALLCONV SPSetAutoTransitionOnFrame( int state, float onFrame );
+ SP_IMPORT int SP_CALLCONV SPSetAutoTransitionToState( int state, int toState );
+
+ //Visibility Data =============================================================
+ SP_IMPORT bool SP_CALLCONV SPGetVisibilityData( int state , int index , VisibilityData* visibilityData );
+ SP_IMPORT int SP_CALLCONV SPSetVisible( int state , int index , bool b );
+ SP_IMPORT int SP_CALLCONV SPSetAllVisibilities( int state , bool b );
+ SP_IMPORT int SP_CALLCONV SPShowAll(int state);
+ SP_IMPORT int SP_CALLCONV SPHideAll(int state);
+
+ SP_IMPORT int SP_CALLCONV SPGetNumDrawables();
+ SP_IMPORT const char* SP_CALLCONV SPGetDrawableName( int index );
+
+ //Frame Controller Data =======================================================
+ SP_IMPORT bool SPGetFrameControllerData( int state, int fc , FrameControllerData* fcData );
+ SP_IMPORT int SP_CALLCONV SPSetCyclic( int state ,int fc, bool isCyclic );
+ SP_IMPORT int SP_CALLCONV SPSetRelativeSpeed( int state ,int fc, float speed );
+ SP_IMPORT int SP_CALLCONV SPSetFrameRange( int state ,int fc, float min, float max );
+ SP_IMPORT int SP_CALLCONV SPSetHoldFrame( int state , int fc , bool holdFrame );
+ SP_IMPORT int SP_CALLCONV SPSetNumberOfCycles( int state , int fc , unsigned int numberOfCycles );
+
+ SP_IMPORT int SP_CALLCONV SPGetNumFrameControllers();
+ SP_IMPORT float SP_CALLCONV SPGetBaseFrameControllerFrame();
+ SP_IMPORT float SP_CALLCONV SPGetFrameControllerFrame( int index );
+ SP_IMPORT const char* SP_CALLCONV SPGetFrameControllerName( int index );
+
+ //Event Data ==================================================================
+ SP_IMPORT unsigned int SP_CALLCONV SPGetNumberOfEvents( int state );
+ SP_IMPORT bool SP_CALLCONV SPGetEventData( int state , int eventindex , EventData *eventData);
+ SP_IMPORT int SP_CALLCONV SPAddEvent( const char* event , int eventEnum , int toState , int fromState );
+ SP_IMPORT int SP_CALLCONV SPEditEvent( int state, int EventIndex, char* eventName, int eventEnum , int toState );
+ SP_IMPORT int SP_CALLCONV SPDeleteEvent( int fromState , int index );
+
+ //Callback Data ===============================================================
+ SP_IMPORT unsigned int SP_CALLCONV SPGetNumberOfCallbacks( int state );
+ SP_IMPORT bool SP_CALLCONV SPGetCallbackData( int state , int index , CallbackData* callbackData );
+ SP_IMPORT int SP_CALLCONV SPAddCallback( int state , const char* event , int eventEnum , float frame );
+ SP_IMPORT int SP_CALLCONV SPEditCallback( int state, int CBIndex, char* eventname, int eventEnum , float frame );
+ SP_IMPORT int SP_CALLCONV SPDeleteCallback( int state , int index );
+}
+
+
+#endif // SP_INTERFACE_WORKSPACE_HPP
+
diff --git a/tools/statepropbuilder/art/BombBlloon.p3d b/tools/statepropbuilder/art/BombBlloon.p3d
new file mode 100644
index 0000000..2077297
--- /dev/null
+++ b/tools/statepropbuilder/art/BombBlloon.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/BombBlloon_spdata.p3d b/tools/statepropbuilder/art/BombBlloon_spdata.p3d
new file mode 100644
index 0000000..a62b052
--- /dev/null
+++ b/tools/statepropbuilder/art/BombBlloon_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/Bouncy_Ape.p3d b/tools/statepropbuilder/art/Bouncy_Ape.p3d
new file mode 100644
index 0000000..90a12c0
--- /dev/null
+++ b/tools/statepropbuilder/art/Bouncy_Ape.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/Bouncy_Ape_spdata.p3d b/tools/statepropbuilder/art/Bouncy_Ape_spdata.p3d
new file mode 100644
index 0000000..56d5ab8
--- /dev/null
+++ b/tools/statepropbuilder/art/Bouncy_Ape_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/air_pump_1.p3d b/tools/statepropbuilder/art/air_pump_1.p3d
new file mode 100644
index 0000000..9ae0c3b
--- /dev/null
+++ b/tools/statepropbuilder/art/air_pump_1.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/air_pump_1_collision.p3d b/tools/statepropbuilder/art/air_pump_1_collision.p3d
new file mode 100644
index 0000000..d0469a5
--- /dev/null
+++ b/tools/statepropbuilder/art/air_pump_1_collision.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/air_pump_1_spdata.p3d b/tools/statepropbuilder/art/air_pump_1_spdata.p3d
new file mode 100644
index 0000000..a92e52a
--- /dev/null
+++ b/tools/statepropbuilder/art/air_pump_1_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/ball_rebounder.p3d b/tools/statepropbuilder/art/ball_rebounder.p3d
new file mode 100644
index 0000000..7c8325c
--- /dev/null
+++ b/tools/statepropbuilder/art/ball_rebounder.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/ball_rebounder_collision.p3d b/tools/statepropbuilder/art/ball_rebounder_collision.p3d
new file mode 100644
index 0000000..0552a78
--- /dev/null
+++ b/tools/statepropbuilder/art/ball_rebounder_collision.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/ball_rebounder_spdata.p3d b/tools/statepropbuilder/art/ball_rebounder_spdata.p3d
new file mode 100644
index 0000000..5e59b10
--- /dev/null
+++ b/tools/statepropbuilder/art/ball_rebounder_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/ball_target.p3d b/tools/statepropbuilder/art/ball_target.p3d
new file mode 100644
index 0000000..71b1894
--- /dev/null
+++ b/tools/statepropbuilder/art/ball_target.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/ball_target_spdata.p3d b/tools/statepropbuilder/art/ball_target_spdata.p3d
new file mode 100644
index 0000000..48997fb
--- /dev/null
+++ b/tools/statepropbuilder/art/ball_target_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/barrel.p3d b/tools/statepropbuilder/art/barrel.p3d
new file mode 100644
index 0000000..4206759
--- /dev/null
+++ b/tools/statepropbuilder/art/barrel.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/barrel_collision.p3d b/tools/statepropbuilder/art/barrel_collision.p3d
new file mode 100644
index 0000000..83ed542
--- /dev/null
+++ b/tools/statepropbuilder/art/barrel_collision.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/barrel_spdata.p3d b/tools/statepropbuilder/art/barrel_spdata.p3d
new file mode 100644
index 0000000..1aebe2f
--- /dev/null
+++ b/tools/statepropbuilder/art/barrel_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/big_gulp_of_pop.p3d b/tools/statepropbuilder/art/big_gulp_of_pop.p3d
new file mode 100644
index 0000000..30c82b3
--- /dev/null
+++ b/tools/statepropbuilder/art/big_gulp_of_pop.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/big_gulp_of_pop_spdata.p3d b/tools/statepropbuilder/art/big_gulp_of_pop_spdata.p3d
new file mode 100644
index 0000000..778c19d
--- /dev/null
+++ b/tools/statepropbuilder/art/big_gulp_of_pop_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/biker_chick_temp.p3d b/tools/statepropbuilder/art/biker_chick_temp.p3d
new file mode 100644
index 0000000..02a8679
--- /dev/null
+++ b/tools/statepropbuilder/art/biker_chick_temp.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/biker_chick_temp_spdata.p3d b/tools/statepropbuilder/art/biker_chick_temp_spdata.p3d
new file mode 100644
index 0000000..7be8b7c
--- /dev/null
+++ b/tools/statepropbuilder/art/biker_chick_temp_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/box_of_chips.p3d b/tools/statepropbuilder/art/box_of_chips.p3d
new file mode 100644
index 0000000..fad2970
--- /dev/null
+++ b/tools/statepropbuilder/art/box_of_chips.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/box_of_chips_spdata.p3d b/tools/statepropbuilder/art/box_of_chips_spdata.p3d
new file mode 100644
index 0000000..40b8d00
--- /dev/null
+++ b/tools/statepropbuilder/art/box_of_chips_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/box_wooden.p3d b/tools/statepropbuilder/art/box_wooden.p3d
new file mode 100644
index 0000000..1df915a
--- /dev/null
+++ b/tools/statepropbuilder/art/box_wooden.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/box_wooden_spdata.p3d b/tools/statepropbuilder/art/box_wooden_spdata.p3d
new file mode 100644
index 0000000..fd6fa29
--- /dev/null
+++ b/tools/statepropbuilder/art/box_wooden_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/cage_collision.p3d b/tools/statepropbuilder/art/cage_collision.p3d
new file mode 100644
index 0000000..bd93544
--- /dev/null
+++ b/tools/statepropbuilder/art/cage_collision.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/cameraTrigger.p3d b/tools/statepropbuilder/art/cameraTrigger.p3d
new file mode 100644
index 0000000..01ec9ad
--- /dev/null
+++ b/tools/statepropbuilder/art/cameraTrigger.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/camera_test.p3d b/tools/statepropbuilder/art/camera_test.p3d
new file mode 100644
index 0000000..a4e70ac
--- /dev/null
+++ b/tools/statepropbuilder/art/camera_test.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/camera_test_collision.p3d b/tools/statepropbuilder/art/camera_test_collision.p3d
new file mode 100644
index 0000000..827d415
--- /dev/null
+++ b/tools/statepropbuilder/art/camera_test_collision.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/camera_test_spdata.p3d b/tools/statepropbuilder/art/camera_test_spdata.p3d
new file mode 100644
index 0000000..aaa8c80
--- /dev/null
+++ b/tools/statepropbuilder/art/camera_test_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/carney_A.p3d b/tools/statepropbuilder/art/carney_A.p3d
new file mode 100644
index 0000000..1122f49
--- /dev/null
+++ b/tools/statepropbuilder/art/carney_A.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/carney_A_collisions.p3d b/tools/statepropbuilder/art/carney_A_collisions.p3d
new file mode 100644
index 0000000..813a25a
--- /dev/null
+++ b/tools/statepropbuilder/art/carney_A_collisions.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/carney_A_spdata.p3d b/tools/statepropbuilder/art/carney_A_spdata.p3d
new file mode 100644
index 0000000..6d1ec2f
--- /dev/null
+++ b/tools/statepropbuilder/art/carney_A_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/carney_stall_1.p3d b/tools/statepropbuilder/art/carney_stall_1.p3d
new file mode 100644
index 0000000..ba8af88
--- /dev/null
+++ b/tools/statepropbuilder/art/carney_stall_1.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/carney_stall_1_collision.p3d b/tools/statepropbuilder/art/carney_stall_1_collision.p3d
new file mode 100644
index 0000000..8792c08
--- /dev/null
+++ b/tools/statepropbuilder/art/carney_stall_1_collision.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/carney_stall_1_spdata.p3d b/tools/statepropbuilder/art/carney_stall_1_spdata.p3d
new file mode 100644
index 0000000..b4186f0
--- /dev/null
+++ b/tools/statepropbuilder/art/carney_stall_1_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/carney_stall_2.p3d b/tools/statepropbuilder/art/carney_stall_2.p3d
new file mode 100644
index 0000000..e57b0b2
--- /dev/null
+++ b/tools/statepropbuilder/art/carney_stall_2.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/carney_stall_2_collision.p3d b/tools/statepropbuilder/art/carney_stall_2_collision.p3d
new file mode 100644
index 0000000..3c73667
--- /dev/null
+++ b/tools/statepropbuilder/art/carney_stall_2_collision.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/carney_stall_2_spdata.p3d b/tools/statepropbuilder/art/carney_stall_2_spdata.p3d
new file mode 100644
index 0000000..6b7dfb4
--- /dev/null
+++ b/tools/statepropbuilder/art/carney_stall_2_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/carney_stall_2_spdata_spdata.p3d b/tools/statepropbuilder/art/carney_stall_2_spdata_spdata.p3d
new file mode 100644
index 0000000..136a89d
--- /dev/null
+++ b/tools/statepropbuilder/art/carney_stall_2_spdata_spdata.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/stateprop.p3d b/tools/statepropbuilder/art/stateprop.p3d
new file mode 100644
index 0000000..d81b1ee
--- /dev/null
+++ b/tools/statepropbuilder/art/stateprop.p3d
Binary files differ
diff --git a/tools/statepropbuilder/art/weapon.p3d b/tools/statepropbuilder/art/weapon.p3d
new file mode 100644
index 0000000..8c5c9ce
--- /dev/null
+++ b/tools/statepropbuilder/art/weapon.p3d
Binary files differ
diff --git a/tools/statepropbuilder/build/win32/stateprop.dsp b/tools/statepropbuilder/build/win32/stateprop.dsp
new file mode 100644
index 0000000..b6e2fe2
--- /dev/null
+++ b/tools/statepropbuilder/build/win32/stateprop.dsp
@@ -0,0 +1,108 @@
+# Microsoft Developer Studio Project File - Name="stateprop" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 60000
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=stateprop - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "stateprop.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "stateprop.mak" CFG="stateprop - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "stateprop - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "stateprop - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "stateprop"
+# PROP Scc_LocalPath "..\..\.."
+CPP=snCl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "stateprop - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../pure3d" /I "../../../radmath" /I "../../../radcore/inc" /I "../../../radcontent/inc" /I "../../../stateprop/inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "RAD_RELEASE" /D "RAD_PC" /D "RAD_WIN32" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=snLib.exe
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "stateprop - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GR /ZI /Od /I "../../../pure3d" /I "../../../radmath" /I "../../../radcore/inc" /I "../../../radcontent/inc" /I "../../../stateprop/inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "RAD_DEBUG" /D "RAD_PC" /D "RAD_WIN32" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=snLib.exe
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "stateprop - Win32 Release"
+# Name "stateprop - Win32 Debug"
+# Begin Group "src"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\src\stateprop.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\inc\stateprop\stateprop.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\statepropdata.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\inc\stateprop\statepropdata.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\inc\stateprop\statepropdatatypes.hpp
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/tools/statepropbuilder/inc/stateprop/stateprop.hpp b/tools/statepropbuilder/inc/stateprop/stateprop.hpp
new file mode 100644
index 0000000..4c0c766
--- /dev/null
+++ b/tools/statepropbuilder/inc/stateprop/stateprop.hpp
@@ -0,0 +1,86 @@
+#ifndef _STATEPROP_HPP_
+#define _STATEPROP_HPP_
+
+#include <radmath/radmath.hpp>
+
+#include <p3d/anim/compositedrawable.hpp>
+
+//=============================================================================
+// Forward Class/Struct Declarations
+//=============================================================================
+
+class tFrameController;
+class tAnimatedObject;
+class CStatePropData;
+class CStateProp;
+
+
+//=============================================================================
+// Class Declarations
+// PropListener
+//=============================================================================
+
+class CStatePropListener
+{
+public:
+ virtual void RecieveEvent( int callback , CStateProp* stateProp ) = 0;
+};
+
+//=============================================================================
+// Definitions
+//=============================================================================
+#define MAX_LISTENERS 10
+
+const int STATEPROP_CHANGE_STATE_EVENT = -1;
+
+//=============================================================================
+// Class Declarations
+// CStateProp
+//=============================================================================
+class CStateProp : public tEntity
+{
+public:
+
+ //Static function to create a new CStateProp instance
+ static CStateProp* CreateStateProp( CStatePropData* statePropData , unsigned int state = 0 );
+
+ CStateProp( tAnimatedObject* animatedObject , CStatePropData* statePropData , unsigned int state = 0 );
+ ~CStateProp();
+
+ //Per frame update
+ void Update( float dt );
+
+ //call before render
+ void UpdateFrameControllersForRender();
+
+ unsigned int GetState();
+ void SetState( unsigned int state );
+ void NextState();
+ void PrevState();
+
+ void OnEvent( unsigned int eventID );
+
+ void AddStatePropListener( CStatePropListener* statePropListener );
+ void RemoveStatePropListener( CStatePropListener* statePropListener );
+
+ tDrawable* GetDrawable();
+
+private:
+
+ //accessor helpers
+ unsigned int GetNumberOfFrameControllers();
+ tFrameController* GetFrameControllerByIndex( unsigned int i );
+ unsigned int GetNumberOfDrawableElements();
+ tCompositeDrawable::DrawableElement* GetDrawableElement( unsigned int i );
+
+ //Private members
+ CStatePropData* m_StatePropData;
+ tAnimatedObject* m_AnimatedObject;
+ tFrameController* m_BaseFrameController;
+ unsigned int m_CurrentState;
+
+ unsigned int m_NumStatePropListeners;
+ CStatePropListener* m_StatePropListener[MAX_LISTENERS];
+};
+
+#endif //_STATEPROP_HPP_ \ No newline at end of file
diff --git a/tools/statepropbuilder/inc/stateprop/statepropdata.hpp b/tools/statepropbuilder/inc/stateprop/statepropdata.hpp
new file mode 100644
index 0000000..b454f34
--- /dev/null
+++ b/tools/statepropbuilder/inc/stateprop/statepropdata.hpp
@@ -0,0 +1,99 @@
+#ifndef _STATEPROPDATA_HPP_
+#define _STATEPROPDATA_HPP_
+
+
+#include <radmath/radmath.hpp>
+#include <p3d/loadmanager.hpp>
+
+#include "stateprop/statepropdatatypes.hpp"
+
+//=============================================================================
+// Forward Class/Struct Declarations
+//=============================================================================
+
+class CStateProp;
+class tAnimatedObjectFactory;
+class CStatePropDataLoader;
+
+//=============================================================================
+// Definitions
+//=============================================================================
+
+//State data
+struct StateData
+{
+ TransitionData transitionData;
+ VisibilityData* visibilityData;
+ FrameControllerData* frameControllerData;
+ EventData* eventData;
+ CallbackData* callbackData;
+
+ unsigned int numEvents;
+ unsigned int numCallbacks;
+};
+
+//=============================================================================
+// Class Declarations
+// Prop
+//=============================================================================
+
+class CStatePropData : public tEntity
+{
+
+public:
+
+ friend class CStatePropDataLoader;
+
+ CStatePropData();
+ ~CStatePropData();
+
+ // State Data =====================================================================================
+ unsigned int GetNumberOfStates();
+ StateData GetStateData( unsigned int state );
+
+ //Transition Data ==================================================================================
+ TransitionData GetTransitionData( int state );
+
+ //Visibility Data ==================================================================================
+ VisibilityData GetVisibilityData( int state , int index);
+
+ //Frame Controller Data =============================================================================
+ FrameControllerData GetFrameControllerData( int state, int fc );
+
+ //Event Data ========================================================================================
+ unsigned int GetNumberOfEvents( int state );
+ EventData GetEventData( int state , int eventindex );
+
+ //Callback Data ======================================================================================
+ unsigned int GetNumberOfCallbacks( int state );
+ CallbackData GetCallbackData( int state , int eventindex );
+
+ tAnimatedObjectFactory* GetAnimatedObjectFactory() { return m_ObjectFactory; }
+
+private:
+
+ //animated object factory
+ char m_FactoryName[64];
+ tAnimatedObjectFactory* m_ObjectFactory;
+
+ //total number of states
+ unsigned int m_NumStates;
+ StateData** m_StateData;
+};
+
+
+//=============================================================================
+// Class Declarations
+// PropLoader
+//=============================================================================
+class CStatePropDataLoader : public tSimpleChunkHandler
+{
+public:
+ CStatePropDataLoader();
+ tEntity* LoadObject(tChunkFile* file, tEntityStore* store);
+
+protected:
+ ~CStatePropDataLoader() {};
+};
+
+#endif //_STATEPROPDATA_HPP_
diff --git a/tools/statepropbuilder/inc/stateprop/statepropdatatypes.hpp b/tools/statepropbuilder/inc/stateprop/statepropdatatypes.hpp
new file mode 100644
index 0000000..4d035af
--- /dev/null
+++ b/tools/statepropbuilder/inc/stateprop/statepropdatatypes.hpp
@@ -0,0 +1,45 @@
+#ifndef _STATEPROPDATATYPES_HPP_
+#define _STATEPROPDATATYPES_HPP_
+
+//Transition data
+struct TransitionData
+{
+ unsigned int autoTransition;
+ unsigned int toState;
+ float onFrame;
+};
+
+//Visibility data
+struct VisibilityData
+{
+ unsigned int isVisible;
+};
+
+//Frame controller data
+struct FrameControllerData
+{
+ unsigned int isCyclic;
+ unsigned int numberOfCycles;
+ unsigned int holdFrame;
+ float minFrame;
+ float maxFrame;
+ float relativeSpeed;
+};
+
+//Event data
+struct EventData
+{
+ char eventName[64];
+ unsigned int eventID;
+ unsigned int toState;
+};
+
+//Callback data
+struct CallbackData
+{
+ char callbackName[64];
+ unsigned int callbackID;
+ float onFrame;
+};
+
+#endif //_STATEPROPDATATYPES_HPP_
diff --git a/tools/statepropbuilder/lib/dummy.txt b/tools/statepropbuilder/lib/dummy.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/statepropbuilder/lib/dummy.txt
diff --git a/tools/statepropbuilder/lib/stateproppd.a b/tools/statepropbuilder/lib/stateproppd.a
new file mode 100644
index 0000000..e95eb24
--- /dev/null
+++ b/tools/statepropbuilder/lib/stateproppd.a
Binary files differ
diff --git a/tools/statepropbuilder/lib/stateproppt.a b/tools/statepropbuilder/lib/stateproppt.a
new file mode 100644
index 0000000..a4e67f5
--- /dev/null
+++ b/tools/statepropbuilder/lib/stateproppt.a
Binary files differ
diff --git a/tools/statepropbuilder/src/stateprop.cpp b/tools/statepropbuilder/src/stateprop.cpp
new file mode 100644
index 0000000..fed8204
--- /dev/null
+++ b/tools/statepropbuilder/src/stateprop.cpp
@@ -0,0 +1,299 @@
+#include <p3d/utility.hpp>
+#include <p3d/anim/multicontroller.hpp>
+#include <p3d/anim/compositedrawable.hpp>
+#include <p3d/anim/animatedobject.hpp>
+#include <p3d/anim/animate.hpp>
+
+#include "stateprop/stateprop.hpp"
+#include "stateprop/statepropdata.hpp"
+
+CStateProp* CStateProp::CreateStateProp( CStatePropData* statePropData , unsigned int state )
+{
+ tAnimatedObjectFactory* objectFactory = statePropData->GetAnimatedObjectFactory();
+
+ P3DASSERT( objectFactory );
+
+ if ( objectFactory )
+ {
+ tAnimatedObject* animatedObject = objectFactory->CreateObject(NULL);
+ CStateProp* stateProp = new CStateProp( animatedObject , statePropData , state );
+ stateProp->SetName( statePropData->GetName() );
+ return stateProp;
+ }
+
+ return NULL;
+}
+
+CStateProp::CStateProp( tAnimatedObject* animatedObject , CStatePropData* statePropData , unsigned int state ) :
+ m_StatePropData( NULL ),
+ m_AnimatedObject( NULL ),
+ m_BaseFrameController( NULL ),
+ m_CurrentState( state ),
+ m_NumStatePropListeners( 0 )
+{
+ //set state data
+ P3DASSERT( statePropData );
+ m_StatePropData = statePropData;
+ m_StatePropData->AddRef();
+
+ //set animated object
+ P3DASSERT( animatedObject );
+ m_AnimatedObject = animatedObject;
+ m_AnimatedObject->AddRef();
+
+ //base frame controller is run in milliseconds (ie the 1 is the timer)
+ m_BaseFrameController = new tMultiController(0 , 1000.f);
+ m_BaseFrameController->AddRef();
+ m_BaseFrameController->Reset();
+
+ //initialize the state
+ SetState( state );
+}
+
+CStateProp::~CStateProp()
+{
+ if ( m_BaseFrameController )
+ m_BaseFrameController->Release();
+ if ( m_StatePropData )
+ m_StatePropData->Release();
+ if ( m_AnimatedObject )
+ m_AnimatedObject->Release();
+}
+
+void CStateProp::Update( float dt )
+{
+ unsigned int i;
+
+ float lastFrame = m_BaseFrameController->GetFrame();
+ m_BaseFrameController->Advance( dt );
+ float newFrame = m_BaseFrameController->GetFrame();
+
+ //Check out transition
+ TransitionData tansdata = m_StatePropData->GetTransitionData( m_CurrentState );
+ if ( tansdata.autoTransition )
+ {
+ if (tansdata.onFrame >= lastFrame && tansdata.onFrame < newFrame)
+ {
+ SetState( tansdata.toState );
+ }
+ }
+
+ //Check callback events
+ if ( m_NumStatePropListeners > 0 )
+ {
+ for ( i = 0; i < m_StatePropData->GetNumberOfCallbacks( m_CurrentState ); i++ )
+ {
+ CallbackData callbackData = m_StatePropData->GetCallbackData( m_CurrentState , i );
+ if ( callbackData.onFrame >= lastFrame && callbackData.onFrame < newFrame)
+ {
+ unsigned int i;
+ for ( i = 0; i < m_NumStatePropListeners; i++ )
+ {
+ m_StatePropListener[i]->RecieveEvent( callbackData.callbackID , this );
+ }
+ }
+ }
+ }
+
+ //update frame controllers
+ unsigned int numFrameControllers = GetNumberOfFrameControllers();
+ for ( i = 0; i < numFrameControllers; i++ )
+ {
+ FrameControllerData fcData = m_StatePropData->GetFrameControllerData( m_CurrentState , i );
+
+ //if we need to update
+ if ( fcData.minFrame != fcData.maxFrame )
+ {
+ tFrameController* fc = GetFrameControllerByIndex( i );
+
+ //if the min frame is greater than the max frame then reverse the update
+ if ( fcData.minFrame > fcData.maxFrame )
+ {
+ fc->Advance( -dt , false );
+ }
+ else
+ {
+ fc->Advance( dt , false );
+ }
+
+ if ( fcData.isCyclic && fcData.numberOfCycles > 0 )
+ {
+ unsigned int currentNumberOfCycles = fc->LastFrameReached();
+ if ( currentNumberOfCycles >= fcData.numberOfCycles )
+ {
+ fc->SetCycleMode( FORCE_NON_CYCLIC );
+ fc->SetFrame( fcData.maxFrame );
+ }
+ }
+ }
+ }
+}
+
+void CStateProp::UpdateFrameControllersForRender()
+{
+ unsigned int numFrameControllers = GetNumberOfFrameControllers();
+ for ( unsigned int i = 0; i < numFrameControllers; i++ )
+ {
+ GetFrameControllerByIndex( i )->Advance( 0.f , true );
+ }
+}
+
+unsigned int CStateProp::GetState()
+{
+ return m_CurrentState;
+}
+
+void CStateProp::NextState()
+{
+ if ( m_CurrentState + 1 >= m_StatePropData->GetNumberOfStates() )
+ {
+ SetState( 0 );
+ }
+ else
+ {
+ SetState( m_CurrentState + 1 );
+ }
+}
+
+void CStateProp::PrevState()
+{
+ if ( m_CurrentState - 1 < 0 )
+ {
+ SetState( m_StatePropData->GetNumberOfStates() - 1 );
+ }
+ else
+ {
+ SetState( m_CurrentState - 1 );
+ }
+}
+
+void CStateProp::SetState( unsigned int state )
+{
+ if ( state < m_StatePropData->GetNumberOfStates() && state >= 0 )
+ {
+ m_CurrentState = state;
+ }
+
+ m_BaseFrameController->SetFrame(0.f);
+
+ unsigned int i;
+
+ //reset the FC for new state
+ unsigned int numFrameControllers = GetNumberOfFrameControllers();
+ for ( i = 0; i < numFrameControllers; i++ )
+ {
+ FrameControllerData frameControllerData = m_StatePropData->GetFrameControllerData( m_CurrentState , i );
+ tFrameController* fc = GetFrameControllerByIndex(i);
+
+ //if we are holding a frame over from last state dont reset
+ if ( !frameControllerData.holdFrame )
+ {
+ //Reset() MUST come first or it will trounce frame ranges etc...
+ fc->Reset();
+ }
+ fc->SetRelativeSpeed( frameControllerData.relativeSpeed );
+ fc->SetCycleMode( (frameControllerData.isCyclic == 1) ? FORCE_CYCLIC : FORCE_NON_CYCLIC );
+ if ( frameControllerData.minFrame > frameControllerData.maxFrame )
+ {
+ fc->SetFrameRange( frameControllerData.maxFrame , frameControllerData.minFrame );
+ }
+ else
+ {
+ fc->SetFrameRange( frameControllerData.minFrame , frameControllerData.maxFrame );
+ }
+
+ if ( !frameControllerData.holdFrame )
+ {
+ fc->SetFrame( frameControllerData.minFrame );
+ }
+ }
+
+ //Set visibility for new state
+ unsigned int numElements = m_AnimatedObject->GetBaseObject()->GetNumDrawableElement();
+ for ( i = 0; i < numElements; i++ )
+ {
+ tCompositeDrawable::DrawableElement* de = GetDrawableElement(i);
+
+ de->SetLockVisibility(false);
+ VisibilityData visibilityData = m_StatePropData->GetVisibilityData( m_CurrentState , i );
+ bool visible = visibilityData.isVisible == 1;
+ de->SetVisibility( visible );
+
+ //lock visibility if visiblility if false
+ de->SetLockVisibility(!visible);
+ }
+
+ //notify listeners of a state change
+ for ( i = 0; i < m_NumStatePropListeners; i++ )
+ {
+ m_StatePropListener[i]->RecieveEvent( STATEPROP_CHANGE_STATE_EVENT , this );
+ }
+}
+
+void CStateProp::OnEvent( unsigned int eventID )
+{
+ unsigned int i;
+ unsigned int numEvents = m_StatePropData->GetNumberOfEvents( m_CurrentState );
+ for ( i = 0; i < numEvents; i++ )
+ {
+ EventData eventData = m_StatePropData->GetEventData( m_CurrentState , i );
+ if ( eventData.eventID == eventID )
+ {
+ SetState( eventData.toState );
+ }
+ }
+}
+
+
+void CStateProp::AddStatePropListener( CStatePropListener* statePropListener )
+{
+ if ( m_NumStatePropListeners < MAX_LISTENERS )
+ {
+ m_StatePropListener[m_NumStatePropListeners] = statePropListener;
+ m_NumStatePropListeners++;
+ }
+}
+void CStateProp::RemoveStatePropListener( CStatePropListener* statePropListener )
+{
+ unsigned int i = 0;
+ //find this entry
+ for ( i = 0; i < m_NumStatePropListeners; i++ )
+ {
+ if ( m_StatePropListener[i] == statePropListener )
+ {
+ m_NumStatePropListeners--;
+ break;
+ }
+ }
+
+ //copy other entries back over
+ for ( i; i < m_NumStatePropListeners; i++ )
+ {
+ m_StatePropListener[i] = m_StatePropListener[i+1];
+ }
+}
+
+tDrawable* CStateProp::GetDrawable()
+{
+ return m_AnimatedObject->GetBaseObject();
+}
+
+unsigned int CStateProp::GetNumberOfFrameControllers()
+{
+ return m_AnimatedObject->GetCurrentAnimation()->GetNumFrameControllers();
+}
+
+tFrameController* CStateProp::GetFrameControllerByIndex( unsigned int i )
+{
+ return m_AnimatedObject->GetCurrentAnimation()->GetFrameControllerByIndex(i);
+}
+
+unsigned int CStateProp::GetNumberOfDrawableElements()
+{
+ return m_AnimatedObject->GetBaseObject()->GetNumDrawableElement();
+}
+
+tCompositeDrawable::DrawableElement* CStateProp::GetDrawableElement( unsigned int i )
+{
+ return m_AnimatedObject->GetBaseObject()->GetDrawableElement( i );
+}
diff --git a/tools/statepropbuilder/src/statepropdata.cpp b/tools/statepropbuilder/src/statepropdata.cpp
new file mode 100644
index 0000000..d5f93e9
--- /dev/null
+++ b/tools/statepropbuilder/src/statepropdata.cpp
@@ -0,0 +1,249 @@
+#include <string.h>
+#include <p3d/utility.hpp>
+#include <p3d/anim/animatedobject.hpp>
+#include <constants/chunkids.hpp>
+#include <p3d/chunkfile.hpp>
+
+#include "stateprop/statepropdata.hpp"
+
+//=============================================================================
+// Class Declarations
+// Prop
+//=============================================================================
+CStatePropData::CStatePropData( ) :
+ m_ObjectFactory( NULL ),
+ m_NumStates(0),
+ m_StateData(NULL)
+{
+}
+
+CStatePropData::~CStatePropData()
+{
+ if (m_ObjectFactory)
+ {
+ m_ObjectFactory->Release();
+ }
+
+ unsigned int i = 0;
+ for( i; i < m_NumStates; i++ )
+ {
+ delete m_StateData[i];
+ }
+ delete m_StateData;
+}
+
+//=============================================================================
+//State Data
+//=============================================================================
+
+//Get
+unsigned int CStatePropData::GetNumberOfStates()
+{
+ return m_NumStates;
+}
+StateData CStatePropData::GetStateData( unsigned int state )
+{
+ return ( * (m_StateData[ state ]) ) ;
+}
+
+//=============================================================================
+//Transition Data
+//=============================================================================
+
+//Get
+TransitionData CStatePropData::GetTransitionData( int state )
+{
+ return m_StateData[state]->transitionData;
+}
+
+//=============================================================================
+//Visibility Data
+//=============================================================================
+
+//Get
+VisibilityData CStatePropData::GetVisibilityData( int state , int index)
+{
+ return ( m_StateData[state]->visibilityData[index] );
+}
+
+//=============================================================================
+//Frame controller data
+//=============================================================================
+
+//Get
+FrameControllerData CStatePropData::GetFrameControllerData( int state, int fc )
+{
+ return m_StateData[state]->frameControllerData[fc];
+}
+
+//=============================================================================
+//Event data
+//=============================================================================
+
+//Get
+unsigned int CStatePropData::GetNumberOfEvents( int state )
+{
+ return m_StateData[state]->numEvents;
+}
+EventData CStatePropData::GetEventData( int state , int eventindex )
+{
+ return m_StateData[state]->eventData[eventindex];
+}
+
+//=============================================================================
+//Callback Data
+//=============================================================================
+
+//Get
+unsigned int CStatePropData::GetNumberOfCallbacks( int state )
+{
+ return m_StateData[state]->numCallbacks;
+}
+CallbackData CStatePropData::GetCallbackData( int state , int eventindex )
+{
+ return m_StateData[state]->callbackData[eventindex];
+}
+
+//=============================================================================
+// Class Declarations
+// PropLoader
+//=============================================================================
+CStatePropDataLoader::CStatePropDataLoader() :
+ tSimpleChunkHandler(StateProp::STATEPROP)
+{
+}
+
+//-------------------------------------------------------------------------
+tEntity* CStatePropDataLoader::LoadObject(tChunkFile* f, tEntityStore* store)
+{
+
+ CStatePropData* statePropData = new CStatePropData();
+
+ unsigned int version = f->GetLong();
+
+ //get the name
+ char buf[256];
+ f->GetPString(buf);
+ statePropData->SetName(buf);
+
+
+ //get the object factory
+ f->GetPString(buf);
+ statePropData->m_ObjectFactory = p3d::find<tAnimatedObjectFactory>(store, buf);
+ if ( statePropData->m_ObjectFactory )
+ {
+ statePropData->m_ObjectFactory->AddRef();
+ }
+
+ //get the num states
+ statePropData->m_NumStates = f->GetLong();
+
+ statePropData->m_StateData = new StateData*[statePropData->m_NumStates];
+ memset(statePropData->m_StateData,0,statePropData->m_NumStates*sizeof(StateData*));
+
+ unsigned int currState;
+ unsigned int i;
+ for ( currState = 0; currState < statePropData->m_NumStates; currState++ )
+ {
+ f->BeginChunk();
+
+ //get name
+ f->GetPString(buf);
+
+ bool autoTransition = ( f->GetLong() != 0 );
+ unsigned int toState = f->GetLong();
+ unsigned int numDrawables = f->GetLong();
+ unsigned int numFrameControllers = f->GetLong();
+ unsigned int numEvents = f->GetLong();
+ unsigned int numCallbacks = f->GetLong();
+ float onFrame = f->GetFloat();
+
+ //give me memory dammit
+ int memsize = ( sizeof(StateData) ) +
+ ( sizeof(VisibilityData) * numDrawables ) +
+ ( sizeof(FrameControllerData) * numFrameControllers ) +
+ ( sizeof(EventData) * numEvents ) +
+ ( sizeof(CallbackData) * numCallbacks );
+
+ unsigned char* memptr = new unsigned char[ memsize ];
+
+ memset( memptr,0, memsize );
+
+ statePropData->m_StateData[currState] = (StateData*)memptr;
+
+ statePropData->m_StateData[currState]->numEvents = numEvents;
+ statePropData->m_StateData[currState]->numCallbacks = numCallbacks;
+
+ //Transition data
+ statePropData->m_StateData[currState]->transitionData.autoTransition = autoTransition;
+ statePropData->m_StateData[currState]->transitionData.onFrame = onFrame;
+ statePropData->m_StateData[currState]->transitionData.toState = toState;
+
+ //Visibility data
+ statePropData->m_StateData[currState]->visibilityData = (VisibilityData*) ( memptr + sizeof(StateData) );
+ for ( i=0; i < numDrawables; i++ )
+ {
+ f->BeginChunk();
+ f->GetPString(buf);
+ VisibilityData *p = &(statePropData->m_StateData[currState]->visibilityData[i]);
+ p->isVisible = (f->GetLong() != 0);
+ f->EndChunk();
+ }
+
+ //FrameController data
+ statePropData->m_StateData[currState]->frameControllerData = (FrameControllerData*)
+ ( memptr + sizeof(StateData) +
+ ( sizeof(VisibilityData) * numDrawables ) );
+
+ for ( i=0; i < numFrameControllers; i++ )
+ {
+ f->BeginChunk();
+ f->GetPString(buf);
+ FrameControllerData* p = &(statePropData->m_StateData[currState]->frameControllerData[i]);
+ p->isCyclic = ( f->GetLong() != 0 );
+ p->numberOfCycles = f->GetLong();
+ p->holdFrame = ( f->GetLong() != 0 );
+ p->minFrame = f->GetFloat();
+ p->maxFrame = f->GetFloat();
+ p->relativeSpeed = f->GetFloat();
+ f->EndChunk();
+ }
+
+ //Event data
+ statePropData->m_StateData[currState]->eventData = (EventData*)
+ ( memptr + sizeof(StateData) +
+ ( sizeof(VisibilityData) * numDrawables ) +
+ ( sizeof(FrameControllerData) * numFrameControllers ) );
+
+ for ( i=0; i < numEvents; i++ )
+ {
+ f->BeginChunk();
+ EventData* p = &(statePropData->m_StateData[currState]->eventData[i]);
+ memcpy( p->eventName , f->GetPString(buf) , 64 );
+ p->toState = f->GetLong();
+ p->eventID = f->GetLong();
+ f->EndChunk();
+ }
+
+ //Callback data
+ statePropData->m_StateData[currState]->callbackData = (CallbackData*)
+ ( memptr + sizeof(StateData) +
+ ( sizeof(VisibilityData) * numDrawables ) +
+ ( sizeof(FrameControllerData) * numFrameControllers ) +
+ ( sizeof(EventData) * numEvents ) );
+
+ for ( i=0; i < numCallbacks; i++ )
+ {
+ f->BeginChunk();
+ CallbackData* p = &(statePropData->m_StateData[currState]->callbackData[i]);
+ memcpy( p->callbackName , f->GetPString(buf) , 64 );
+ p->callbackID = f->GetLong();
+ p->onFrame = f->GetFloat();
+ f->EndChunk();
+ }
+
+ f->EndChunk();
+ }
+
+ return statePropData;
+}