A couple of weeks ago I was contacted by Laurent (SEGA Dreamcast Info) who informed me he’d come in contact with some special betas which he’d like me to take a look at. What arrived next was 10 builds of Vectorman for PS2, a previously unreleased title by Pseudo Interactive.

Pseudo Interactive had made their name in the early-2000s with the release of Cel Damage and were working on a Vectorman title just for the PS2. Unfortunately, it was never released and all we currently have is gameplay footage and various quotes around the Internet, so it was obvious that this needed some care to inspect what we have.

In this post I’ll document the findings and research I encountered while going through these builds, but you can also find further information in the main release over on Sega Dreamcast Info’s website (which I’d definitely recommend!).

Moreover, if you’re a beginner or are just interested in seeing how the more technical aspects of this sort of thing is done, then this first post as part of a series of future posts might also be worth reading, here.

Again, many thanks to Comby Laurent for working with me on this!

A Brief Analysis

As a software engineer and game programmer, I’m always drawn to searching for any logic that I can find, no matter where it is or what I’m looking at. So the first thing I did when receiving these prototypes was to extract each build and collate them into a neatly organised “working environment” and progressing onto the static analysis of the main executable.

Picking the very first build sent to me, I booted it up using an emulator and sought to look out for anything that might be useful. At first glance, it seems like a debug/QA build… some debug or placeholder info can be seen or toggled and the rest of the game seemed to be in a fairly complete state.

After this brief 30-second test, it was time to open up the executable and take a look for anything interesting.

hmm.. this seems interesting.. it seems as though the games initialisation procedure sets up a sort of “debugging level” which is used to log or enable various parts of the debug/QA functionality, except here it seems to be turned off. Taking a further look, we can see that the initialisation procedure checks for certain conditions, and if only they are met, will it enable the appropriate debugging level.

In this case, the game seemed to check for the existence of “ProView”, and if found, it would enable said functionality:

  if ( sub_24C4C8("Found Proview\n") >= 0 )
    *(v6 - 0x5E50) = 1;

From here, the value which is stored at *(v6 - 0x5E50) is later tested against non-zero values, and then if non-zero, sets the real debugging level: “pitaDebug“.

However, if the Proview test fails, it will set pitaDebug to zero. So in this case, we can simply reverse the operation, and instead change the instruction to set pitaDebug to 1, when it fails, effectively forcing the debugging level to non-zero values, regardless of whether or not the test succeeded or not:

sb           $zero, -0x733F($gp)

to:

sb           $v0, -0x733F($gp)

With the patch in place, it works! Booting the game with the patch, you will now see extra debugging information you’d normally never see, and a plethora of in-game debugging utilities are at your disposal!

loadmodule: id 31, ret 0
randomSeed 373001396
Starting piLaunch, pitaDebug = 2
initTime: 1.35
Load rtd/dwVecpil.pix start
Load rtd/dwVecpil.pix done
LoadTime 0.67
startup 0.425
Tex 0.026
Wav 0.024
Pack 0.526
Batch 0.000
Level 0.000

Loading level dw_fact2
Load rtd/dw_fact2.pix start
Load rtd/dw_fact2.pix done
LoadTime 1.82
startup 0.174
Tex 0.422
Wav 0.000
Pack 0.385
Batch 0.009
Level 0.018

Loading playerCars
Error: File mising piLaunch/talkToMe.dat
activate level dw_fact2
Level0: 0
Level1: 7492048
Level2: 7492048
Room TreeSize: 0.049
ActivateLevelComplete
GosJoysticks=4

Boom!

Taking a look at some of the debug options:

A very cool debug feature is the ability to enable AI on the player themselves:

This was a huge success, so naturally, I progressed onto the other builds that I’d received and was able to find or otherwise enable the same debug menu across all of the builds (with the exception of a specific in-game menu which seems to be stripped from the other builds).

Moving on and taking a look at the root filesystem, we see a pretty minimal setup, with only a few files and directories present:

The IOP directory is mostly required by the platform holders, but inside I noticed a memory card icon file!

Some textures, residing in PILAUNCH are named “RETRO.PSM” which sound interesting..

These appear to be textures, but at this point I was still researching the file format, so I couldn’t get clear outputs from them, but I started to notice some peculiarities, in general.


Hmm. Retro?! This seems like placeholder! And looking over another title from Pseudo Interactive, starts to show something else..

Archives

At this point, I’d located a file named “SMALLF.DAT” which was actually an archive format for some of the game assets… and inside, there were some very interesting discoveries to be found.

Firstly, it seems like a large portion of this game was built on the back of Cel Damage, another title developed by Pseudo Interactive.

CelText.txt in this case even contains plenty of strings from Cel Damage:

Wild Wooly West

Death Valley

Mesa Madness

Swamp Stomp

Temple of Boom

Shmoe vs. the Volcano 

Monster Mosh

Very interesting, but we’ll come back to Cel Damage a bit later.

Changelogs

Also present within the archives, appears to be a huge changelist of changes that were made to the game engine over the years it was in development, so here it is, in its entirety:

Click the text below to view the text file (very large!)

moD_update_jan-apr99.txt
//
//  revised: Tue Apr 4, 2000 12:48:04 PM
//  .dsw
//
 
 ---
 
  you can now determine which libs are debug builds by usings the cmd function:  find "DEBUG" mod2k.exe

  each debug lib will emit a string, e.g. [DEBUG:physics]


 ---

  __itf_start_all_level_obs()

  has been replaced with:

  __itf_start_all_level_packs()
 

  the iteration variable is now rt_ pack * pk;
  previously it was frame_batch * ob, not it is the root pack of this batch.


 ---

//
//  revised: Tue Apr 4, 2000 4:34:03 AM
//  .dsw
//
---
 new gameos, you will need to copy s:\w\assets\bin over your local versions

---

 new console_var:
   
   assert_level

   range is 0..4 
   4 (default) means include all
   3 means include 0..3
   2 means include 0..2
   etc.

   4 is an assert that is handled
   3 is a numeric tolerance assert
   2 is a severe assert (but not fatal)
   1 is likely fatal

---







added a few specialized vector classes.  The main purpose for these is to catch silly bugs 
and help explain ambiguous operations
see <alg\vec.h> (bottom of file) for specifics.

e.g.:

vec3f_c   // global position
vec3f_cp  // global positional derivative  (with respect to time if not otherwise specified)
vec3f_cpp // global positional 2nd derivative
vec3f_cu  // global unit length (norrmalized) positional derivative
vec3f_cd  // global positional delta or difference or offset

nomenclature:

  'c'  geometric/positional vector set 
  'u'   // position (weights) in a specific function space
        // has no meaning outside of the context of the function
		// e.g.:   c = spline( u )  evaluates world position at a 
													   
  'p'  // "prime" deriviative w/r/t an implied variable
 	   // usually time or a specific dof (e.g. u on a 1 dof line"
  'd'  // finite difference or delta
  'u'  // unit or normalized quantity.  Orthanormal basis



If you need to convert from one type to another, use:

__vec3f_c() for a reference or
  vec3f_c()	for an initialization or immdediate.

They should be used only when needed
(there are situations in which this is necessary)

---

  	   




feb 15
---

added macro to room.h:

__itf_start_all_level_and_virtual_obs()
{
}__itf_end_all_level_and_virtual_obs


this enumerates all_level_obs and virtual obs

(thanks for pointing that out rich!)

---
 bug fix:  find_spawn_point() used __itf_start_all_level_obs()

 (thanks rich!)


---


feb 12
---

fixed crash in rh_ces, 


something  is wrong with the integtor  :\


---
---


collisions more workable


tip: there is a psc op:

contact_kd_friction

the default is 16
increasing it will make everything have higher friction  (except anything with a material friction constant of < 0.25 )
this var will likely be removed/replaced in the future so do not count on it


---


Updated to newer version of gameos



---
(new gos)
you will need to update the shared\w\assets directory



----

 Note on importor:  (new gos)
   as it turns out, it is illegal to call crt functions from PROCESS_ATTACH 
   
 Solution (hack):
   remove the init code from dllmain and put it in function like this:


 void ensure_initialized()
 {
  static bool g_initialized = false;
  
  //  ensure_initialized() has already been called if this flag is true
  if( g_initialized )
  {
    return;
  }

  g_initialized = true;

  //
  // insert init code here, e.g. "do_mod_init()"
  //
}
      

at the beginning of all externally called max functions insert:

 ensure_initialized();

at the first line to make sure things are initializde before any mod or gos functions are called


---

various pack drag bug features fixed (replace pack, paste etc)

note:
right click -> replace surfaces was been replaced by dragging a mesh onto another mesh


---


feb 11
---

Random crash on start fixed (l1_rt_player would overwrite its memory bound on load)

---

auto align for check points fixed (I think)

---

rich re link errors:
 
   please use the edi_include.def added to S:\piapi\  in the future this will be updated with mod2k.exe (my mistake)
   changes batch_add_ref_w	to __fastcall batch_add_ref_w (fixes link problems where exporter thought it was __cdecl

---
tip:

 if you cannot continue because of a float exception set the following in your psc:

   disable_fpu_exceptions 1

  this will not save you from all fpu exceptions, it it should save you from most

---

 ffd animation time and active motion id moved to sim_config (from ed_dof)

---

 removed dof status messages regarding incompatible ffds

---

New for L1 pack:

m_road_mode
//? behaviour when we are on a road
//? "shift with road":  position is updated when road is updated
//?	"road section":  pack is used to create the road, pack will be warped, tiled or deleted as necessary
//?	"warp with road":  applys the ffd from the road to the pack, by the pack is not considered to when road sections
//? are "tiled"	appropriate for things like side rails, scenery or decoration along the road
//?
//? previous mapping:
//?	"shift with road"  :  warp_to_road == false
//?	"road section"  :  warp_to_road == true
//? "warp with road":  new


---

new for ef_path:

enum_road
//? creates windows showing packs bound to road and 
//? paths that make up road for this stop_id and this road_id
---

updated road section tiling 

it should now work for different sized pieces


(rich)
---


feb 10
---

when you start a level with bridge turner you will get a message saying that the custom rtf is gone

bridge turner changed the class from which it was derived and this caused a crash during load.

fix:

  add a dw_bridge_turner to the bridge pack
  transfer messages to the old one to the new one
  delete the old one



---


added to rt_pack.h
		//
		// pack_lock Helper functions. 
		//
		// a (resource) lock is used to disable collisions driving or drawing
		// when you would like to destroy the lock (renable resource)
		// use use lock.null();
		// You must keep track of locks.   Store them in your class or a helper agent
		// do not delcare them globally or on the stack  (if you create them on the stack they lock will be
		// destroyed when the var goes out of scorpe.
		//
		// For compatibility, priority is always set to highest
		//
		// returns true on successs and sets p_lock
		__inertia_export bool create_lock( 	bool b_disable_collsions,
																    		bool b_disable_draw,
                                        bool b_disable_driver,
			                                  lock_ptr_s<rt_pack_lock> * p_lock );
		
		//
		// this calls the above funtion and creates a timed event that keeps the lock alive until it has timed out
		//
		__inertia_export bool create_timed_lock( 	bool _b_disable_collisions,
																    		bool _b_disable_draw,
                                        bool _b_disable_driver,
			                                  float duration  );



for compatilbity set b_disable_driver == false  and leave your code that 
calls set_control_mode)



feb 9
---

Collision Notification update:

 to process collisions you must include:
 
 <func\rtm_collision.h>




Please read <func\rtm_collision.h> for a description of changes
---

---


feb 8
---

There have been a number of clean ups, consolidations etc.
I have included legacy_snr.txt which states most of the sntax changes necessary

I have also included my_macros.dsm wich you can bind to a button in VC++ and it will automatically search and replace
a set of names in the active file.
(run this on each of your files)

certain functions that previously took references to non-const objects now take pointers to those objects
if a function explicitly writes to an object it feels more intuitive that the object be passed by pointer



feb 3
---
bug note:

 as Dan pointed out, 1 strip along y and z do not work (only x does)
 0 strip should work

---
I put a sample usertype.dat autoexp.dat in S:\piapi\
You might find these useful for VC6

to use, copy to your directory:   C:\VS6\Common\MSDev98\Bin

"C:\VS6" is likely different on your computer
---
pack enumeration:

numerous functions have been added to simplify pack enumeration

see <phy\room.h> for complete level scans

  void g_level::enumerate_packs(	const rt_pack_filter * p_filter,						// if this 
		                        const kdop_extents & ext, 
		             			 darray_buf_ls<rt_pack*> * p_result );

This will enumerate all packs in the level overlapping the specified kdop, and passing the user 
defined pack filter.  (e.g. rt_pfilter_car, rt_pfilter_player, etc ) 

---
Pack filters:  (rt_pack_filter)

  These are user derivable filters that may be passed to pack enumeration functions
  Each pack must pass the filter before the geometry overlap computation takes place


---
new for rt_pack:

 void rt_pack::enumerate_packs_in_contact(	const rt_pack_filter * p_filter,
			                                darray_buf_ls<rt_pack*> * p_result );

// enumerates packs in contact with this pack.

 if the pack is virtual, this function may be used to emulate a more detailed sensor.
 The sensor volume is defined by the collision rep of the pack
  

---
when rt texture is queryied for an uncached texture, it will not put the request through to gameos if

!g_gameos_initialized

I believe that g_gameos_initialized is always false for the dll 
(mod sets it in its implementation of InitializeGameEngine)

This should prevent the call to gos_NewTexture in the exporter.
please let me know if this works!

----









feb 1
---

 - exported dwtracktest1
    this has a road which has a driving compatible collision rep and FFD

	FFD is X
	strip count is 1

    Collision rep is a hull
	  used make_box()
	  set extents
	  extrude radius 0
	  normal_fixed = true


---
updated pack list to include:

 "npc"
 "weapon"
 "weapon_shot"

There are a few classes that should no longer be used:
 light 
 rubbish
 obstacle


jan 31
---



Most pack/batch flags have been consolidated to rt_pack.
Queries should be made using the root pack.

e.g.

 pk->is_part_of_world()
 pk->is_class(pack_power_up)
 pk->is_player()
 pk->get_team()

 etc.


Additionally, 
all classes enumerated in phy\pack_classes.h have a corresponding is_[CLASS]() member function in rt_pack.


<phy\pack_classes.h>

__dec_class(misc) 
__dec_class(world)
__dec_class(road)
__dec_class(decoration)
__dec_class(light_source)
__dec_class(gag)
__dec_class(car)
__dec_class(virtual)
__dec_class(power_up)
__dec_class(rubbish)
__dec_class(obstacle)
__dec_class(animal)
__dec_class(weapon)
__dec_class(weapon_shot)


functions are:
 pk->is_misc();
 pk->is_road(); 
 pk->is_weapon(); 
 // etc




a few members have been renamed.  If something seems missing, try adding an m_
e.g.
pk->owner
to
pk->m_owner
or
pk->get_batch()


Additionally, certain pack_flags have been added to a structure referenced via pk->m_flags

e.g.
 pk->b_disable_draw
to
 pk->m_flags.b_disable_draw



If you can't find what you are looking for, please ask.

---




jan 30
---


new_step_hook_id for l1_funcs:

   step_hook_step_start,         // At the very beginning of a step.
                                 // objects activated at this time will become active this frame
																																


jan 29
---


please convert all occurances of:
 basisf::I to basisf::get_I()
 mat_miser::mats to mat_miser::get_mats()
 


Jan 26, 2e3
-----
rtd\  directory was always used as a relative path.  
This caused problems if the active directory was changed.
Now it is always based from: 

 ("%srtd\\",  g_mod2k_path.s )

---

Jan 27
---

To access g_level and dy_eng, you will need to do the following:

replace

  g_level.YADDA
  get_g_level()->YADDA


replace

  dy_eng.YADDA
  get_dy_eng()->YADDA


replace
  get_g_level()->enumerate_objects_in_exents(&obs, ext)
  get_g_level()->enumerate_objects(ext, &obs)


---

jan 28
---

fixed missing export problem for dy_eng()


 be careful:  this required some aggressive use of macros.   Starting to look like the CRT  :o


---

Drawing cld reps:

You can use the following options:

  kdop_draw_refine
    this only has an effect of the kdop has subdivisions > 0 
	e.g. if a kdop has subdivisions set to 16
	  kdop_draw_refine 0 will draw 1 hull
	  kdop_draw_refine 1 will draw 4 hulls
	  kdop_draw_refine 2 will draw 16

	each division splits the dkop in 4

  kdop_draw_mode
    0: siloette
	1: default axis count (13) 
	2: higher detail
	3: too high

  They will only draw if the camera is within 64 meters of them 

This is located in a file named “moD_update_jan-apr99.txt” and is referenced to by another text file named mod_update.txt, which simply states:

2:34 PM 9/18/2000
- Old mod_update.txt moved to mod_update_jan-apr99.txt

… and luckily, they also leftover “moD_update_99.txt”!!

Click the text below to view the text file (very large!)

moD_update_99.txt


dec 24
---


new psc op:

 print_active

 prints a list of sleeping and non sleeping objects

---

In the test level, the following is a typical active list:  (no weapons going off)

notes:
  
  can objects with * have can_rest set?
  there are a lot of dustpuffs, is this many necessary?


*rh_100_ton_weight_large
*rh_bridge
* rh_target1
* rh_target1
* rh_cactus_collapsed
* rh_cactus_collapsed
* rh_cactus_collapsed
* rh_cactus_collapsed
* rh_cactus_collapsed
> rh_oil_pump
> rh_DES_MRPE_LOD0
* rh_cactus_collapsed
* rh_target1
* rh_DES_SKA_LOD0
* rh_DES_SKB_LOD0
* rh_DES_SKC_LOD0
* rh_DES_SKD_LOD0
> el_Max_jalopy_bits1
> el_Max_jalopy_bits1
> el_Max_jalopy_bits1
> el_Max_jalopy_bits1
> dp_tornado3
> el_Max_jalopy_bits1
> SR_DustPuff7
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff1
> SR_DustPuff3
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff1
> SR_DustPuff3
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff1
> SR_DustPuff3
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff1
> SR_DustPuff3
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff1
> SR_DustPuff3
> SR_DustPuff2
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff1
> SR_DustPuff3
> SR_DustPuff2
> SR_DustPuff6
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff1
> SR_DustPuff3
> SR_DustPuff2
> SR_DustPuff6
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff1
> SR_DustPuff3
> SR_DustPuff2
> SR_DustPuff4
> SR_DustPuff6
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff1
> SR_DustPuff3
> SR_DustPuff2
> SR_DustPuff4
> SR_DustPuff5
> SR_DustPuff6
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff1
> SR_DustPuff3
> SR_DustPuff2
> SR_DustPuff4
> SR_DustPuff5
> SR_DustPuff6
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff1
> SR_DustPuff3
> SR_DustPuff2
> SR_DustPuff4
> SR_DustPuff5
> SR_DustPuff6
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff1
> SR_DustPuff3
> SR_DustPuff2
> SR_DustPuff4
> SR_DustPuff5
> SR_DustPuff6
> SR_DustPuff7
> SR_DustPuff8
> SR_DustPuff1
> SR_DustPuff3
> SR_DustPuff2
> SR_DustPuff4
> SR_DustPuff5
> SR_DustPuff6
> SR_DustPuff7
> SR_DustPuff8

---

profile info for mod events is now part of gameos profile data





---


dec 22
---

fixed:  when set_control_mode() was called with high priority, the car would never recover


---

smoosh_handler::apply_flatten works

---

smoosh_handler::apply_dent works


---

fixed: "too many stars and birds" 

---


misc psc ops for stunned camera:

 float,cam_stunned_max_dist,(16.0f),
      "when stunned, the camera will ensure that it is at most this distance from the player" );

 float,cam_stunned_min_dist,  (6.0f),0);
	  "when stunned, the camera will ensure that it is at least this distance from the player" );

 float,cam_stunned_min_height,(6.0f),0);
	  "when stunned, the camera will ensure that it is at least this hight above the player" );



---


fix:  ffd 0z, 0y, 1z, 1y did not work


fix:  ffds with extent offsets were not supported, now they are
	  to deform the legs of the figure while maintaining connection to the chest, 
	  position the ffd box s.t. the top ffd points are on the connection plane  
	  and ensure that they are fixed

---

 bridge turner now disables driving and ffds

 (rich)
---
 
stars and birds work again

---

 holding shown shift while using the dof->select_* functions will apend selected but not unselect other ffd points

 (rich)
 

---

fix: 
 bridge turner updated to use actuate_Vd()

---

new for key frame:

 clear()

  - clears current transform



---

fix:

  start sim/end sim with a mounted pack open would hide the mounted pack

 (e.g. max would disappear in editor after end sim )

---

fix: 
  max's mount type was weapon
  he was droped when the user picked up other weapons

---

edm spawn has a new member:

 orient_mode:
   
    orient with source
	orient with world
	orient with velocity


e.g. the birds and stars are passed a link orientation (collision normal) when they are spawned. 
 this enables them to always stay upright


dw_smoosh_handler.dwp has been updated to use this setting for the stars and birds

 
---


new flag for ed_dof: 
 
  draw_ffd


 the dof's ffd will be drawn if it is active.

 previously they would only draw their ffd if they were selected and the ffd was active.


dec 21
---


new psc op:

 reset_camera

this will restore the camera from a go_to() that was never terminated with
restore_normal_control()

this should not be necessary, but might come in handy to cover up a cam control bug

---


 rt_camera::set_stunned()
  and
 rt_camera::go_to() 
 
 fixed


---


you can now edit ffds of mounted packs

(rich)

---


ffd points can have damping and ineritia:

 each point has a setting
 the setting has 3 scales, (x,y,z) for a uniform force, make this equal.
 (in some cases you may want to constrain points, e.g headlight having damping only in z)

 to set persistant damping effects: 
    -add_key on dof
	-click on the dof->ffd_point menu (or right click on the ffd points on screen, they should have mouse overs and dialogs)
	-set the appropriate values
    -set the key to have travel time of 0.5 (lower for higher frequency, or higher for lower frequency)
	-set hold to 999999	 (hold forever
	-set the sub target to none
	-set the l0 active flag to true


example:

 dw_max_jalopy1:
 
   max's head has inertia effects.  when you bake it tilts forward, etc.
   
   canopy has damping effects, this similates drag like a parachute
   


---



 I mounted a test max in his car

   - added a mount to the car at the position of the rtf_car_funtional
   - added the max pack to this mount
   - changed his root to fixed
   - set no mass for all frames
   - set inherits warp for root
   - removed rtf_figure functional

---



dof_03 saves its orientation


---


show dofs() dialog now includes ffd info


---

l1_frame::b_inherits_warp has been replaced with:

 l1_frame::m_warp_inherit with the following options:
  
   none
   full 
   position offset only

   if the flag was previously set, this will be "full", otherwise it will be none.


   position offset shifts the frame s.t. the dof origin remains fixed in the parents cordinates
   rotation, scale and bend are not applied.

  
 e.g. if you set this for the players shoulder, it will not strech and bend with the parent, however it
   will stay attached, and you can set it's ffd worrying about cancelling out the effects of the parent


---

fix:  stun birds orbit about car origin


---

when a pack is destroyed, its driver, if any, is also destroyed.

when it is respawned, the driver will also be respawned.


---

 collision detection:

   - all spline driving surfaces should be planes  (4 points)
   
   in general, this is the best cld rep to use:
   

    - 1 hull
	- call make_rect()
	- set "scale" to 32, 16, 1
	- set extrude r to 0.75
	- set c to 0 0 -0.75
	- set "flat" to true
	- max z for mesh verts should be 0.0

	test cases: 
	- rh_canyon_jump
	- rh_road_pavement


   use "draw_wheel_contacts 1"	 (psc op) to view the surface normals
   of what you are driving on.  Use this to test the level

---

  wheel collision rep:
 
    - the distance from the bottom of the wheel spheres to the bottom of the mesh should be 0.5 meters
    - max_jalopy wheel centers need to be changed from  z = -0.25  to z = -0.40

	- for consistant driving, the wheel radius - wheel_z should be 1.15  (the same disance of the test cars)
	  other values should work, but having the cofm shifting may have side effects.

	- exported dw_max_jalopy1.dwb
---



psc op reeneabled:
 profile 1

this will give you a profile of where time in physics is being spent

(gos reports this as game logic)

note:  the gos readout "game logic" also includes loading textures and file access.



---

 transform dialog update:

   you can now specify a transform origin 
     rotation and scaling will take place about this point
	 
   order of operations is:  
   
     rotate, scale, translate
	was:
	 scale, rotate, translate

   tip:  select ffds points
         use vec stack->average_selected()
		 load_to_stack on transform origin
		 now rotation and scaling will not shift your ffd 


	

dec 20
---

 fix:  key frames with high frequency would not reach their targets.
 this was due to numerical integration inaccuracy for very key ks,kd
 (frequency of 16 and damping of 1 would only reach about 50% of its intended displacement)

 this is why for example flatten would not completely flatten meshes in recent builds

---
added sub_target_ids:

    "motion_flatten_from_top",
    "motion_flatten_from_side",
    "motion_flatten_from_front",

(daniel)
---

new for batch:
 
 show_key_frames()

 shows all key frames in the active motion in all packs within batch

 note:  this dialog will not maintain its sort order (e.g. if you change the duration of a key, close the 
 dialog and reopen for it to resort)



---


 bug fix:  only four bits were allocated for sub target, new sub_targets (motion_1 .. etc) were above this number
 and they would wrap

---



 All articulated motion for dw_figure_1 has been removed.
 
 The only force that is applied is a 6 dof potential to keep the character in place.


---


 new psc op:  player_motion "motion_accelerate"

 player_motion "motion_brake"

 .. etc  any sub target_id will work

for fast testing you could add the following to your psc:

 bind 4  player_motion "motion_accelerate"
 bind 5  player_motion "motion_brake"



---

b_disable_draw and b_disable_collisions are automatically copied from 
a root car to the driver.  (this may be changed in the future, but accomodates the mole)

---
new for pack:

    // if this is a car and it has a figure driving it, 
   // the figure is returned;
   __inertia_export rt_pack * get_driver() const;


---


 frame_warper::get( f )

has been replaced with:

 f->get_warper() 

 f->get_warper_always()    will bypass the can_warp flag
  

 f->get_warper_if_exists() will query for a warper, if none exists it returns null
 						   the default bevahiour is to create one if can_warp is set and return this


---

 warpers now have an actuate_priority similar to dofs.

 set_pdk() requires an actuate priority.

 before applying a deform you can use  test_actuate(), or actuate() to check to see if you 
 have priviledge to actuate the warper.
 
 // this will apply a non-exclusive actuate
 // it will not prevent subsequent calls

 if( warp->test_actuate(frame::ap_default) )
   warp->apply_deform();


 // this will apply an exclusive actuate
 // it will prevent subsequent calls if the specified priority is higher
 // than that of subsequant calls

 if( warp->actuate(frame::ap_default) )
   warp->apply_deform();


---


batches now display a list of active key frames
you can shift click on the member "active_key_frames" to keep the list open while you edit


(rich)
---
rich click precision fixed

(rich)
---

new for dof:   auto shear

rotates ends of a 1 strip ffd to make them perpendicular to the spine

---



dec 19
---
new for mesh_view->options:

 bool draw_ffds
 draws all active ffds

---




dec 17
---

bug fix:

  mouse over the screen when editing text would often erase what you were typing
(gary)
---



dec 16
---

new for ef_rod:

bool 1,7,b_no_force_on_other)
 If set, the object that I am attached to is not forced
 using for following objects

bool 1,8,b_no_force_on_owner)
 If set, the object that I am in to is not forced
 using for  attracting objects

bool 1,9,b_attach_on_spawn)
 if set, I attach to the link object when I am spawned

bool 1,10,b_draw_line)
 if set, line is drawn

---

stun effect updated (smoosh handler)

sonya and sasha rule!


---

fpu math exceptions can now be ignored 
note:  if you click yes on the message box, all fpu exceptions will be ignored until you restart.

---

new psc op: 

draw_ffds 1

( forgot to mention it before  :o )

---

bug fix: sub_target_ids for funcs were clamped to weapon_max
 
---

bug fix: key_frame save_load was not compiled, object class would not save
                 y1,z1 members

(daniel)
---

new psc op:  disable_sleeping	1

for debugging only
sleeping objects may have bugs.  e.g. they may not dispatch messages when they should, update their ffds, etc.

if this fixes an object that doesn't do what it should, please let me know.


---

bug fix:   static and sleeping objects would not properly update their cvs


---





dec 15
---

ffd shear is now an l1 member of l1_ed_dof


---

mouse overs fixed

---

pack_warper.h renamed frame_warper.h

---
rtf_cars now have a "control mode"


This is used to actuate a vehicle and disable specific driving functionality.


example  flip corrector:
  //
  // set acceleration
  //
  f->actuate_Vd( acc, f->ap_manuever_1, false);
 
  rtf_car * car = car->get(f->get_pack());
  if( car )
   {
      rtf_car::control_mode cm(2.f);  // disable for at most 2 seconds
     
	  // disable all driving behaviour
	  cm.disable_driving= true;
      cm.disable_flight_stabilizer =true;

      cm.end_on_contact = true;		  // restore control it I touch the ground
      car->set_control_mode( cm );
    }
    




rtf_car.h


 // 
  // control mode
  //
  enum control_mode_priority
  {
   cm_pri_none,  // no explicit controller
  
   cm_pri_low,
 
   cm_pri_default,
 
   cm_pri_high,
 
  };


  struct control_mode
  {
   float speed_scale;   // default 1.0, 0.5 limits the car to half of its max speed/acceleration
   
   u8  priority;
   u8  steps_left;    // see reset(duration)
   u8  steps_active;    // // internal use
   
     
   bool disable_ffd : 1;                  // if set, I do not modify the ffd
   bool disable_driving: 1;               // prevents any driving related behaviour
   bool disable_flight_stabilizer: 1;     // when not in contact, prevents the car from trying to correct itself

   
   bool spinout: 1;                       // causes car to spinout
										  // not yet implemented
   bool end_on_contact: 1;     // if this is true, the control mode will end and restore normal control
                               // as soon as the car is in contact with the world


  
   
   __inertia_export void reset(
            float duration,    // determines when this control mode ends.  After this time, 
                                // control mode is set to default
                                // note:  see "end_on_contact"
             control_mode_priority priority ); 
 
   inline control_mode(float duration, control_mode_priority _priority = cm_pri_default )
   {
    reset(duration, _priority );
   }
   
   inline void disable_all()
   {
    disable_ffd =true;
    disable_driving =true;   
    disable_flight_stabilizer =true;
   }
  };


  
  control_mode m_control_mode;
 
  // returns true if successful, false otherwise
  virtual bool set_control_mode( const  control_mode & mode );

  inline void  set_default_control_mode() { set_control_mode(control_mode(0, cm_pri_default)); }


---


dec 14
---

shadows and silos draw again.


---


bug fix:  ffd's that are created, but never touched would crash (e.g. cactus)
 

---

cld hulls and other prims will be transformed by road warping

if you pretesstate with hulls, there should be no gaps.

e.g.

 ----  -----  ----  ----- 
|    ||     ||    ||     |
 ----  -----  ----  -----

---


you can now call right_click->more()  on any 3d vector

- this will create a dialong for the vector	with 3 sliders and buttons
- the grid settings in editor_config control the granularty

---

You can test FFDs on dofs through the property window of the dof (non shared)
set the dof type to 1x,1y or 1z (1x is main axis for cars)

0,8,m_ffd_mode,ffd_mode_toggles)
//? Sets the ffd more fo the dof
//? for testing only

float,ffd_shear)
//? ffd shear
//? controls how much auto shear is applied to the FFd in 1d modes.
//? 1 causes the ffd to rotate, 0 causes a pure shear

10,vec3f,ffd_c[0], "c0" )
//?   o   o    ^
//?   |   |    Z
//? --o-o-O  <X

11,vec3f,ffd_c[1], "c1" )
//?   o   o    ^
//?   |   |    Z
//? --o-O-o  <X

12,vec3f,ffd_c[2], "c2" )
//?   o   o    ^
//?   |   |    Z
//? --O-o-o  <X


13,vec3f,ffd_c[3], "y0" )
//? --o-o-o  < X
//?   |   |     Y
//?   o   O     \/

14,vec3f,ffd_c[4], "z0" )
//?   o   O    ^
//?   |   |    Z
//? --o-o-o  <X


15,vec3f,ffd_c[5], "y1" )
//? --o-o-o  < X
//?   |   |      Y
//?   O   o     \/

16,vec3f,ffd_c[6], "z1" )
//?   O   o    ^
//?   |   |    Z
//? --o-o-o  <X




---

shadow's and silos do not currently draw properly
---

you may need to set	the can_warp flag your car and its children dofs
(you can use copy to selected)

---

Psc op for camera:

view_pitch_0 ==(-5)     // pitch for default view mode (degrees)
view_pitch_1 ==(-12)    // pitch 2nd view mode (degrees)
view_pitch_2 ==(-24)    // pitch 3rd view mode (degrees)


float view_distance_0=(5) // distance from camera to focal point in meters 
float view_distance_1=(8)	// for mode 1
float view_distance_2=(16)// for mode 2


float ang_v_use=(0.0) 	// how much angular velocity of car is compenstated for in camera motion
						// 1 is complete compensation, when turning, the camera will be behind car 
						// rather than lagging





float cam_min_height=(2.25)	        // lowest camera is allowed to travel above the ground
							        // this should prevent the camera from going through the ground

float cam_min_dist=(4.f)		 	   // camera always stays at least this far away form whatever it is watching

float camera_stunned_max_dist=(16.0f)  // when camera is stunned, it will lag behind, but be at most this distance
                                       // from focal point

float slow_height_offset=(1.f)			 // when the focal point is moving slowly, this is added to the cameras rest height
float slow_height_offset_max_speed=(8.f) // the offset decays as the focal point accelerates, reaching 0 at 8m/s

float player_max_height=(8)      // max height above the ground that the player can be before the camera considers 
                                 // the player to be out of control

float player_view_height=(2.5)   // the focal point of the camera (center of screen) is this distance
                                 // above the driver (puts the car at the bottom of the screen )
float camera_damp_ratio=(1.25f)	 // damping for camera motion

//
// various spring constants controlling camera acceleration
// 
float cam_dt_y_default=(0.325f)
float cam_dt_x_default=(0.325f)
float cam_dt_z_default=(0.325f)

float cam_dt_too_close=(0.25f)


float cam_dt_lin_out_of_control=(1.5f)
float cam_dt_lin_out_of_control_catchup=(1.f)
float cam_dt_lin_brake=(0.75f)


float cam_dt_ang_default=(0.25f)

float cam_dt_ang_out_of_control=(0.325f)

float cam_dt_turn=(0.25f)



---




dec 13
---

 warping now occurs on a per frame basis

 all occurances of pack_warper_ffd should be replaced with frame_warper

 calls to frame_warper::get( ) use a frame (rather than pack)

 you can replace ::get(pack) with ::get(pack->get_root());

 warping is inherited by children frames  (unless a flag in the dof is disabled)

---

 bug fix:  rtf_key_frame, command->start() would fail
  


---

---

Car shock ranges have been moved to the wheel frame dof_ranges:

dof_range[2][0] == how far down it can go  (default was -0.125 )
dof_range[2][1] == how far up it can go (default was   1.0 )


---

new memebers for car:

vec2f,shock_lin_ks)
//?  linear shock [ frequency, damp_ratio ] 
//?  governs up down motion of car

vec2f,shock_ang_ks)
//?  angular shock [ frequency, damp_ratio ] 
//?  governs pitch and roll stabilization

---
new for dof:

bool b_can_warp
//? if set, the dof supports ffds

bool b_inherit_warp
//? if set, the dof is transformed by its parent ffd

---

batches and levels set the view to them when they are selected.

if this is annoying, let me know and I will remove it.
this is remove the necessary click - tree open close to view a batch

---

dw_max_car, saved as and updated:

 - ffd_exents
 - wheel dof ranges
 - environment maps removed	 (some where out of order)
 - some wheel spokes are not bound the the wheel dof


---

 camera now sets the focal point to the player or Ai, if there is one
 if both player and AI are in the car, put them in the same position (it will use the first it finds)

---

patches draw their circle as white if collisions are disabled.


---
 


cld_prim hook priority update:
 
  - scalar value from 0 .. 399
  -  0   is top priority
  -  350 is default
  -  399 is lowest


  convention:
   
   A-0 ==  100
   B-0 ==  200
   C-0 ==  300

   A-1 ==  101
   B-1 ==  201
   C-1 ==  301

   A-N ==  100 + N
   B-N ==  200 + N
   C-N ==  300 + N


(Daniel)
---


dec 12
---

fov shift based on speed removed


---

Camera control improved.  

Angular velocity feedback was removed (it did not exist in prototype), this caused the camera to align with
the orientation of the car too quickly when turning.  (jerky camera motion when you swerve)

---

legacy actuate_kd remove (daniel)

---

These mod2k.psc settings might be useful:


disable_driver_warning 1
// Andy would hate me


show_player_input 1
//
// this will show steer, and thrust.
//
// If you use a gamepad, see if these values reach 1.0, if they do not, your game pad needs
// calibration
//


(dan,rich)
---
new for l1 car:


28,vec3f,ffd_inertia_default)
//? Inertia effects on ffd  (rear, mid, front)
//? 1.0 means that an acceleration of 16 m/s/s will 
//? apply a force to the ffd_points sufficient to deform the ffd
//? by "1 ffd unit"


29,vec3f,ffd_inertia_acc)
//? see ffd_inertia_default
//? Applied when in flight

30,vec3f,ffd_offset_acc)
//? when car is in this state,
//? the z components of the ffd will be deformed
//? by this amount  (rear, mid, front )
//? e.g. 1,0,0 will raise the rear of the car



31,vec3f,ffd_inertia_turn)
//? see ffd_inertia_default
//? Applied when in flight

32,vec3f,ffd_offset_turn)
//? see ffd_offset_acc



33,vec3f,ffd_inertia_brake)
//? see ffd_inertia_default
//? Applied when in flight

34,vec3f,ffd_offset_brake)
//? see ffd_offset_acc

  
35,vec2f,ffd_drive_ks)
//? { frequency, damping }
//? sets spring constacts for ffd when car is driving

36,vec2f,ffd_flight_ks)
//? { frequency, damping }
//? sets spring constacts for ffd when car is flying


37,float,roll_wheel_offset)
//? determines how much cars bank when accelerating sideways

---

CES todo:


* Acceleration from a stop needs to do a wheelie and compress, 
  currently it only does an exaggerated wheelie (needs to return to prototype functionality)

 - ffd_inertia_acc
 - ffd_offset_acc



* General acceleration needs to function exactly like the prototype
  - reduce acceleration in l1_rtf_car	 functional


* Car braking needs to be EXACTLY like the prototype.  
     (squashing, stretching, etc) (but keep the fix for spinouts when braking.

  - ffd_inertia_brake
  - ffd_offset_brake
  - modify brake rate in l1_rtf_car functional


* Sliding and Skidding needs to be EXACTLY like the prototype.
  - adjust friciton setting in l1_rtf_car
  - cars are faster to friction needs to be higher


* Car should only bend around corners as much as it did in the prototype.
 - ffd_inertia_turn
 - ffd_offset_turn
 - roll_wheel_offset


* On turn, cars need to pop up on two wheels and then bend, currently neither is happening correctly 
  (go back to the prototype!)
 - ffd_inertia_turn
 - ffd_offset_turn
 - roll_wheel_offset







dec 9
---
materials.dat updated.
added stickyness, 
removed various legacy materials, params 
----



dec 8
---


bug fix:

right mouse click was inaccurate

(rich)
---


car spinout disabled

---

make_hull fixed

---

tip for fast lods:
 
 set silo_gain to 0
 it may not be as good, but it will be WAY faster, and suiteable as a placeholder
 some meshes look better this way/


---

new var: cld_draw_mode

 0,  // lowest_detail, fastest: 54  faces
 1,  // lowest_detail, fastes150 faces
 2;	 // lowest_detail, fastest: 300 faces



 previous default was 1, now it is 0

---

new:

 make_from_mesh_2

another way to make a hull;
similar to make_from_mesh() except that it autosimplifies in some cases.

The faces output should have little to do with the number selected
good for high vert meshes


---

mouse right click bug fixed, new gameos
did not rethrow rbutton as "menu"

---
exported g_max weapons:

 add this line to your code to use:
// declare 
__inertia_export extern int g_max_weapons;

// then use g_max_weapons
// g_max_weapons is the max pickups that you can carry, total max weapons is g_max_weapons+1 (tennis gun)

default for  g_max_weapons is now 1

(rich)
---

new flag for ed_patch: b_collisions

(rich)
---

mounts auto replace

---

new exes up, including demo.exe	 and demo_profile.exe

demo profile should be used for profiling

(daniel)
---



dec 3
----

gameos update.  GameOS now supports DX7.

Good luck


You will need to update your assets dir with S:\w\assets  
---
there are updated psc files on S:\w\ with useless stuff removed

---


dec 2
----
New for pack:
  
   extents_3d rt_pack::compute_local_extents() const;

	computes combined extents of all frames;


(daniel)
---
New for rt_func:

 enum say_targets
 {
  say_log,  // the console window
  say_file, // writen to toon/mod.log
  //
  // text bubbles drawn on screen
  // say_bubble_N replaces the last say_bubble_N message
  // say_bubble_0 is , say_bubble_1 is top right, say_bubble_2 is bottom right, say_bubble_3 is bottom left

  say_bubble_0,  // top left 
  say_bubble_1,  // top right
  say_bubble_2,  // bottom right
  say_bubble_3,  // bottom left
 };
//
// usage:   __say(("Hello %s %.1f", pack->get_name().s, dy_eng.t() ))
//          __say_2(file, ("Ammo: %d", ammo_left))
// note the bracket style

 __say_2(target, msg )
 __say(msg)


---
New for ed_func:

bool b_verbose;
/*?
This flag enables the say() function for funcs, if verbose is not set, say() will have no effect
*/
---
You will need to wipe rtd
---
bug fix: 
 sprites with blend_mode == pseudo_alpha
 would not draw

----



dec 1
---

small fixes to pickups/weapons


---



nov 29
---

New driving model:

 Please try out:  dwtracktest0
 
 dw_sasha_baby0 is the ONLY car that will drive properly now.
 First thing tomorrow morning I will update others.

 Most levels should work, but they are not yet tested :\


(david)
---


Wheels now modulate their friciton scale by the combine friction of the world and the wheel



materials.dat updated:

Toon Wheel friction index id changes to 6	 ('med tire')
I set its friction vs most materials to 1

- Update, actually this is not implemented yet, but it will be

---

new psc op:

 smooth_inputs 0 // use this if you have an analog game pad
 or
 smooth_inputs 1 // use this if you have a digital pad.
                 // steering will be smothed out
				 // e.g. when you press left it will take 0.25 seconds to reach the max turn angle

  
---



nov 26
---
update for dofs:

  rather than  

    frame::b_at_joint_limit
  
  use

    frame::is_at_joint_limit()

rt_dof->actuate_qd()  and 
rt_dof->actuate_qdd() now take a priority.

choose a priority in rt_frame.h	that is suitable

(see enum actuate_priority )

e.g. f->actuate_qdd(  qdd, 	 frame::ap_character_0 );


---


nov 25
---


Mounts:
---------

The following new members determine mount allocation:




rt_pack:

mount_type
mount_locations[4];



rtf_mount:

m_type
//? A filter specifying what can be mounted here
//? a pack can only be mounted here if pk->get_l1()->mount_type ==  mount->m_type


m_location
//? describes where I am, this is used by packs for them to select a mount that they like
//? each pack stores up to 4 mount locations ordered by preference.
//? if none of the pack locations matches the mounts location, the mount will not be considered
// the l1_pack::mount_locations[0] which have precedence over l1_pack::mount_locations[1] and so on

m_capacity
//? describes how much I can carry


examples:


dw_sasha_baby0 has mounts set up:

dw_hammer has the following setup

 mount_type  == weapoon
 
 mount_location[0] == top
 mount_location[1] == misc	(not used)
  mount_location[2] == misc	(not used)
 mount_location[3] == misc	(not used)



dw_weapon_buzz_saw has the following setup

 mount_type  == weapoon
 
 mount_location[0] == left_hand
 mount_location[1] == right_hand
 mount_location[2] == misc	(not used)
 mount_location[3] == misc	(not used)
 
						  


---




nov 24
---



---

new psc ops:
  speed_up	(real_time_rate *= 2)
  slow_down	(real_time_rate *= 0.5)
  pause  (brings up dialog)

---
joystick buttons can now be bound to function calls in addition to signals

e.g.

bind joy_5 speed_up
bind joy_6 slow_down

---

the compile date is now printed on toon.exe title bar

---


fix: setting a meshes data did not set it's pack to modified

(rich)
---
updates to get_name() functions:

There is a "w" (unicode) and an "a" (ansi) version.
use the ansi version, until gos supports unicode


Name functions:

rt_pack::get_name_a();
rt_pack::get_short_a();

rt_func::get_name_a()   (verbose, for debugging)

rt_frame::get_name_a()  (verbose, for debugging)

frame_bacth::get_name_a()


you will need to del rtd
---

When testing the build, please do not disable warnings until

the zip is made (and check log for errors)
---

errors created by toon.psc (or mod.psc) 
will be written to:

init.log

(this be b/c GOS is not yet initialized)

---

 
 new psc op:
  d3d_device 0

  (0 is d3d_hardware, 
   1 is d3d_software (unstable), 
   2 is d3d_software (stable),
   3 is fast software (Blade) )

 new psc op:
  antialias 1





nov 23
---

bug fix:  cld reps for children frames would draw in an incorrect coorindate system

---

Updates to Silos and Shadows:

Shadows and silo's are taking up a lot of the rendering time, I've added functionality to
optimize their usage.

- surfaces can set or disable shadows (used to be pack)
- surfaces can set or disable silo (used to be pack)
- surfaces can specify a silo color
- surfaces can specify a silo thickness (default == 1.5 pixels)

- Meshes can specify how close the mesh must be for the silo to draw
- Meshes can specify how close the mesh must be for the shadow to draw

---



nov 22
---

I recompiled with an updated version of GameOS.  
Please let me know if find any problems.


Thanks!

Also, Rich:  if the DLL crashes let me know  (!)


---


bug fix:

"remove from list" only worked if the container was at the root of the tree.


 e.g. textures::remove_from_list()  didn't work
---

New and exciting behaviour for A, S keys	(with or without shift)

---


you can now set the focal_distance distance in the mesh view
(this is how far out you stay when you zoom)

---

control-W will plant a watch point ahead of you points.

---

'z' zooms in your view

multiple presses will toggle between scales of focal_distance

---


mouse drag motion filtered to zero all but one axis.

if( drag_z )
{
// Wheel
 drag_x=0;
 drag_y=0;
}
else
{
	if(  abs(drag_x) > abs(drag_y) )
	  drag_y=0;
	 else
	  drag_x=0;

}

if your mouse doesn't work well, please let me know

this is to mitigate the extreme difficulty of moving the mouse along only one axis

---



nov 21
---

ed_surface::selece_verts
ed_dof::select_verts

if all verts in the dof/surface are selected, they will all be unselected.
Otherwise they will all be selected.


if some verts in a dof are selected, if you call this twice they will all become deselected

this replaced ed_dof::unselect() 

---
ed_dof::select_verts_tree()
selects all verts in the dof and any of the dofs children

---


Levels now have an "ambient" value
this is written when the level starts sim

you can set ambient with psc ops using:

ambient_r 0.5
ambient_g 0.3
ambient_b 0.1


---

cld rep draw updated.  slower but more accurate
---
surface combining now takes place at run time.  

This allows you to keep extra surfaces in the editor with the performance benefit of
combining.

Texture combining still takes place in the editor
---

to transfer faces from one surface to another:
clear selected (press 'Q')
right click on surface A, choose select_faces()
right click on surface B, choose add_selected()


---

The order in which dofs appear in their parents list at run time is determined
by alphabetical order.

In cupid I named the chest's children:

0 right arm
1 left arm
2 head 

e.g:

const int dof_id_head = 2;
children[dof_id_head ] would predictably be the head.


---
Certain common vec_stack operation are now available on the right click menu of vectors:

zero()
negate()
normalize()
rotate_z() 
rotate_x() 
---

added unselect_verts() to dof

---

added select_reflected to ed_mesh

(selects verts that are reflections in Y of selected vert)

---

added select_connected_1  to ed_mesh
added select_connected_10 to ed_mesh


incremental verts of select_connected()	 [ e.g. select only 1, or select up to 10 ]

prioritization is assinged based on edge legth.  (closer verts are selected first


---

if you attach half the verts of a simetric figure to verts you can do this:

clear_selected()
left_arm->select_verts()
mesh->select_reflected()
left_arm->unselect_verts()
right_arm->add_selected()



---


nov 20
---

Wheels for vehicles are no longer separate packs

Recommended setup for cars:

 Single mesh containing car and all wheels (ideally sharing a texture)
 
 4 Wheel Frames set to "[33k] kinematic" (the last one on the drop list)
 each with:
   special == wheel
   mass == 1
   I == 1 1 1
   no_mass   true
   kinematic true
   local_sim true
   range_wraps true
 
 These are for visuals ONLY, they do not have collision reps  

  
 4 wheel cld_spheres in the ROOT (not the wheel frames)
 each marked with special==wheel
 radius = 0.5



 see dw_sasha_baby for an example

---

 if you set draw_extents in the camera and you have set explicit ffd extents for a pack, they will be drawn
 as a white extent box


---

 dw_spy_car:

  FFD extents set
  
  Pack Centered	s.t. Wheels are symettric in X and at -0.19 in Z  (as per previous Spy Car)

  cld hull scaled a bit smaller in Y (to avoid hitting your side so often

  mass from 128 to 712

  wheel verts bound to appropriate dofs

  max draw distance 512

  Daniels slide smoke replaces blue smoke

  car l1 data reverted to Daniels dp_spy_car

  made brighter	(higher ambient)
 
  lods created
  

---

 ed_mesh->filter() now removes overlapping faces

(rich)
---





nov 19
---



changed
 
 rt_message::s_collision

   msg->b_cancel_collision = true;

 has been replaced by:

   inline void skip_prim() { action_flag = action_skip_prim; };  // skips the contact between this prim and the other
   inline void skip_frame() { action_flag = action_skip_frame; };// skips all contacts between this frame and the other

   inline void skip_tree() { action_flag = action_skip_tree; };  // skips all contacts between this frame and
                                                                 // all of its children frames
                                                                 // and the other



  use  skip_frame() for the behaviour of msg->b_cancel_collision = true;
  
  skip_tree() may be more appropriate for most weapons
 

---

 each collision prim has a 	"hook_priority"
 The rtm_collision is sent first to the prim with the higher priority.  
 If the collision is canceled, the other prim will not recieve notification messages. 

 Proirities for weapons/effects should be decided on by designer


(Daniel)
---
 
cars:

 ffd extents should coincide with wheel contact points

 wheel prims should have "special wheel" set 
 wheel frames should have "special wheel" set
  
 wheel frames are for visuals only;
 
 Please see: dw_sasha_baby for an example


---

 rt_pack::find_first_func() now supports custom_funcs
 
 you can use the macro:
   
    __find_custom_func( pk, _name_ );
 or 
    __find_custom_func_tree( pk, _name_ ) if you want to recurse through the packs children.

 _name_ is the name of you functional without rtf_

 e.g.

  rtf_dw_mole * mole = __find_custom_func_tree( pk, mole );

 returns 0 if no custom functional of that type exists.

--


 
 

						  
nov 18
---

Setting up Spew:

  In mod (and in next mayhem build) you can set the debug output in the psc:

  Use the following format:

  spew "groupA groupB groupC ..."
  
  Where "groupA" is a spew type.
  
  This is the default setting:

    spew "physics game net collision_detection editor david"

  To debug directinput stuff use:

    spew "GameOS_DirectX GameOS_DirectInput physics game net collision_detection editor david"


The following are supported

#define GROUP_FILES				"GameOS_Files"			// File functions
#define GROUP_MEMORY			"GameOS_Memory"			// Leak notification only
#define GROUP_MEMORYVERBOSE		"GameOS_MemoryVerbose"	// Heap create / destroy functions
#define GROUP_TEXTURE			"GameOS_Texture"		// Texture enumeration and creation
#define GROUP_GAMEOS			"GameOS_Core"
#define GROUP_NETWORK			"GameOS_Network"		// Networking messages (DPlay layer is lower level)
#define GROUP_DIRECTX			"GameOS_DirectX"
#define GROUP_DIRECTDRAW		"GameOS_DirectDraw"
#define GROUP_DIRECT3D			"GameOS_Direct3D"
#define GROUP_DIRECTINPUT		"GameOS_DirectInput"
#define GROUP_DIRECTSOUND		"GameOS_DirectSound"
#define GROUP_DIRECTSHOW		"GameOS_DirectShow"
#define GROUP_DIRECTPLAY		"GameOS_DirectPlay"
#define GROUP_WINDOWSMESSAGES	"Windows_Messages"		// WM_ messages from windows



nov 17
---
Optimization:

 for dofs that don't require dynamics, and that are very light, you should set:
  
  kinematic =  true
 and 
  no_mass   = true

This will speed it up, but the childs inertia will not effect the parent.
Also, these dofs will not accept external forces they must be moved using 
an input signal or by calling actuate_qdd() on the dof


Good Candidates:
  
   "light" weapons
   kinematic animation parts  (currently all of the cupid's parts has this setting)





nov 16
---

new for frame:  void scale_collision_rep(const vec3f & scale );

this internally calls f->shared_to_custom();
if you want to restore the original frame, use

f->custom_to_shared();

(daniel)



nov 14
---

 If you are bored, try this:
 
   set you car to:   conent\david!\batches\scars\dw_sasa_baby.dwb
   run:  conent\david!\levels\dwtracktest.dwl
  
---

 you will need to wipe rtd and recompile your dlls, 
 thanks!

---


nov 12
---

edge reps will need to be regenerated due to a format change

---

if you use l1_frame::composite_mass in your dll, 
you need to replace this with get_mass()

e.g.

   f->get_l1()->composite_mass
 
 to 

   f->get_mass();

 
---


update to rtf_weapon::ammo_info

   struct ammo_info
   {
    enum type
    {
      type_none,  // invalid, ammo not relevant
      type_int, 
      type_float,
    };
    type m_type;

    union
    {
     float f_count;
     int   i_count;
    };
    union
    {
     float f_max;
     int   i_max;
    };


    inline void set( float count, float max ) { f_count = count; 
                                                f_max = max; 
                                                m_type = type_float; }
    inline void set( int   count ) { i_count = count; 
                                     i_max   = max; 
                                     m_type = type_int; }

    //
    // returns between 0..1.0, 0 is empty, 1 is full
    //
    inline float get_ratio()
    {
     if( (type == type_none)||((i_max<<1)==0) )
     {
      // error
      return 0;
     }
     else if( type == type_int )
     {
      return float(i_count)/float(i_max);
     }
     else
     {
      return float(f_count)/float(f_max);
     }
    }

   };

(rich)
---


nov 11
---

bug fix: target_lc was not saved for packs
 
---

new setting for texture map blend:
 
  pseudo_alpha:
  	 This is for color keys
	 and textures with alphas that are usually 0 or full.
	 This is slightly more efficient that normal alpha
---

New for texture:

 bool  auto_set_blend_mode,tab_other
  
  If this is set and the texture has alpha or a color key,
  the blend mode will be set to pseudo_alpha

---


nov 10
----
new setting for psc:

 background_color  0x0000c0

 (or any rgb combination)

 this is only used in toon.exe, mod2k overrides it with the user setting


---
bug fix: save_as did not set the modified flag

(rich)
---

bug fix:  physics step rate was not set properly in toon.exe

---

file system optimizations, better caching and faster export

---
if files are stored as bmps and tgas, the older file will be deleted.
this avoids conflicts where you update a bmp, but it loads the tga at run time.


---



nov 9
---
new for pack warper:


 //
  // read/write positions
  //
  // to use reads:  declare a coordinate system that you want to use, and pass a
  // typed ffd_q to the function
  //
  // e.g.  ffd_q_type<ffd_q_3> result;
  //  ffd->read_q( &result );
  //
  __inertia_export void read_q( ffd_q_typed_header * p_result ) const;
  //
  // to use writes for modify:
  // 
  // - deflare an ffd_q
  // - if you want to modify values,
  //     - call ffd->read(&q)
  //     - modify values
  //     - call ffd->write( q );
  //  if you want to write values and you don't care what they used to be.
  //     - set values 
  //
  //
  __inertia_export void write_q(const ffd_q_typed_header & values );
 
(rich)
---

cropped environment maps seem to work, but they are very subtle so I am not completely sure


(rich)
---

 weapons have a new l1 flag:  
 
 bool b_uses_targeting
//?  set this flag if the weapon uses targeting and 
//?  approriate information should be displayed on the hud


---

 weapons have a new l1 member:  


  texture m_hud_image
//? Specifies the texture that the weapon uses to draw on the hud

---

   //
   // new for rtf_weapon:
   //

   struct ammo_info
   {
    enum type
    {
      type_none,  // invalid, ammo not relevant
      type_int, 
      type_float,
    };
    type m_type;

    union
    {
     float f_count;
     int   i_count;
    };

    inline void set( float count ) { f_count = count; m_type = type_float; }
    inline void set( int   count ) { i_count = count; m_type = type_int; }


   };
   

  //
  // if the weapon supports ammo, this function should be overwritten.
  // call p_result->set(ammo_count), pass an ammo type as either a float 
  // or an int
  //
  virtual void get_ammo_info(ammo_info * p_result); 


---

rtf_weapon::do_i_have_ammo() is obsolete, use get_ammo_info() instead

---




nov 7
---

environment map first pass, please see dw_spy_car_blue and dwtesttrack for an example


Environment maps how to:
 
  - environment must must be the second texture of a surface
  - the first texture must be solid or color keyed
 
   - the environment map should have a fill mode of add or alpha
   - the environment map should have a uv_gen_function that is not "Vertex Values"
   [mod2k: uv_gen_function drop box ]
   [piapi:. you can use tex->get_rt()->m_uv_gen_function   = rt_texture::uv_gen_sphere; ]
  
  - specify cropping if applicable 
   [mod2k: crop_origin, crop_span ]
   [piapi: tex->get_rt()->crop_origin ]
   [piapi: tex->get_rt()->crop_span   ]

  - currenlty all gen modes use sphereical projection.
    this allows for cropped textures (it does not need clamp or tile)
	

Sharing textures:

  on cards with 2 texture units (most cards out right now)
  you are best off having as many objects as possible sharing a common environment map.



---

a few of the ed_texture members are now only stored in the rt_texture;

for example, insteading of setting a textures fill mode, do this:

from:
 tex->fill_mode = rt_texture::blend_replace
to
 tex->get_rt()->blend_mode = rt_texture::blend_replace


some added members are:
 
 tex->get_rt()->crop_origin
 tex->get_rt()->crop_span
 tex->get_rt()->m_uv_gen_function



(Rich)

---

 FFD's sould be pretty functional right now.
 please let me know if you notice any problems


example use from dw_thunder_cloud.cpp:

 
 pack_warper_ffd * ffd = pack_warper_ffd::get( pk );
 //
 // only apply force if this can warp
 //
 if( ffd )
 {

  static const acceleration_to_ffd_force = 2.5f; // q'' -> force gain
  static const ffd_period = 1.0f;                // period of 1 second
  static const ffd_damp_ratio = 0.5f;            // damp ratio of 0.5 (under damped
  
  ffd_q_typed<ffd_q_1x> F;  // declare a force pertubing a 1d spline along x

                              
  // set spring damper constants
  ffd->set_from_dt( ffd_period   , ffd_damp_ratio );
 
  svecf acc = f->m_dof->get_acceleration();  // get acceleration
 
  vec3f ffd_acc =  t_dot( f->m_gb.A, acc.lin ) * (- acceleration_to_ffd_force );    // transform linear component
                                                                                    // into local coordinates of the frame
                                                                                    // negative because the middle
                                                                                    // point should move opposite to the
                                                                                     // acceleration of the frame

  F.q[1] = ffd_acc;            // write the force to the middle point
                               // this makes it bend

  ffd->apply_force( F );       // apply the force


 }



---



nov 4
---
many changes to the deform API, if you have ffd calls in your code, please #if 0 these until we meet this afternoon,
and discuss everything

Thanks,

---

nov 3 
---
Multiple power ups, new implementation:

Weapons that are powers that may be assigned to arbitary triggers should set their sub_target_id to
"Weapon [Free]". 

Pickups will not replace already mounted packs.

Funcs now store an l0 copy of l1->sub_target_id
This will be reassigned when a mounted weapon is mounted.  
based on whichever trigger is available. 

New psc op:  "max_weapons 3"
This sets the max weapons per car.  3 means up to 2 powers and a primary.

Remember to add an extra mount to your cars (just copy and paste)
and to add trigger_2 to controls.psc

---

recommended setting for pickup crates:
 
 root frame:

   6 dof
   16 kg mass

 pack:

  normal collision mode
  can_be_sliced
  can_deform





nov 1
----
ai targeting etc has requires some updates to weapons:

in l1_rtf_weapon  please set:

vec2f,target_range
//? Min and Max range at which target should be for us to shoot

target_cone_radius
//? Radius of targeting cone, if target is outside of a cone along this cars X axis of radius 
//? target_cone_radius, the target is considered to be out of range
---


oct 30
---

Normals are now shared for verts that have the same position but are part of the same surface with different uvs.

---
---


oct 29
---

Updates to l1_rt_pack:

bool cast_shadows

 If this is set, the pack will cast shadows
 When the mesh is changed you must call "update edge rep"
 in order for shadows to be drawn correctly.
 If cast_shadowss and draw_silo are false the pack will clear
 any current edge reps as they are not needed
 


bool draw_silo

 If this is set, the pack will draw its siloette (edge outline)
 When the mesh is changed you must call "update edge rep"
 in order the siloette to be drawn correctly.
 If cast_shadows and draw_silo are false the pack will clear
 any current edge reps as they are not needed


vec3f silo_color

 Color of the siloette for this pack
 only used of draw_silo is true



I know that max supports a "cast shadows" flag for meshes, I am not sure if it supports any bonus
flags that could be used to specifiy whether or not silo should be drawn.

(minimal support might be a check box in the export dialog box?)
---
A few of my weapons were too heavy:
 
  - buzz saw was about 64 kg, has been reduced to 24
  - booser rocket was 128 kg

---
Improved generating of edges for collision rep and shadow rep.
Note: this it is now a N^2 process and it is recomputed at load, so it may be slow.

---

I've added silo's to my objects and exported my track.
Please let me know what you think of the way in which it looks

Thanks.

---

Eraser gun:

 Mark when eraser misses is now white
 The mark has a portable hole functional in it so it will suck you down 
 (unless of course, you have the mole functional)
 Eraser gun will seek if you have a target


---

 Your current target is now highlighted with a 
 cube.  The is a temp placeholder

---

 


oct 28
---

 piapi:
   "frame_i.h" has been renamed "rt_dof.h"
   you may need to change your include files

  
---

  Weapon updates:

	Mole now has a limited number of uses (default is 4)

    Portable hole has a limited number of objects that it can suck up. (default is 4) 
	and a limited maximum existance time (30 sec)

	Booster rocket a little faster and smoother flying

    Portable hole does not play uh-oh when the user has the mole


	When the mole resurfaces, it creates a temporary hole that acts as a portable hole for 8 seconds



---

Hazard Avoidance 


avoidance

 Avoidance flag used by ai's to determine what to avoid
 This should only be set for Hazards that are serious, otherwise the
 Ai's racing ability will be compromised.
 Examples might include:   Portable Hole, maybe Tornado
 stationary dropped weapons (e.g. bombs)


radius_as_obstacle

 When avoiding hazards, ai's will attempt to ensure that 
 the "obstacle sphere" of the AI and the "obstacle sphere" of the hazard
 do not intercept.
 The "obstacle sphere" is defined by the origin of the root pack with a 
 radius of "radius_as_obstacle"
 e.g. if a portable hole has radius == 2 and an AI has radius == 1, the
 AI will ensure that her center of mass is at least 3 metters to the left or 
 right of the hazards center of mass
 Default for Packs is 2.0  (This is the current setting for AI packs)

---




oct 27
---

Smoosh handler has been updated, new waves have been added.

Please replace your level smoosth_handler_pack with the pack in 
content\david!\batches\dw_smoosh_handler.dwb

---

first pass on mole

please see dw_crate_mole

---
first pass on painted tunnel (needs a LOT of work)


please see dw_painted_tnnel.dwb or dwtracktest.dwl for a level
with the painted_tunnel in it.

---

First pass on Quake hammer, 

please see dwtracktest.dwl for a level
with the hammer in it.

---
war.exe is now toon.exe

you will need to:

  change your dll to *_toon.dll from *_war.dll
  link it with toon.lib rather than war.lib

  rename war.psc toon.psc

---



oct 26
---
new api for g_level:
 
   //
  // enumerates all objects whose extents touch the extents specified
  // applies no filters
  //

 void enumerate_objects_in_extents( darray_buf_ls<rt_pack*> * p_result,  const extents_3d & ext );


---

 ed_mesh::filter() no longer requires an active view

---



oct 25
---

first pass on dw_booster_rocket, 

david!\bactch\weapons\dw_crate_booster_rocket

---

update to quatf::set_x() method

Previous this aligned the x axis of the basis to the specified axis using the minmum rotation from the identity.
Now it aligns the x axis of the basis using a rotation that minimizes roll. 

This tends to be applicable more often (e.g. if you set the heading of a car, you want the Z axis to be as close 
to up as possible)

the function has singularities, namely straight up or straight down. x ==   (0,0,+/-1)




oct 21
---
There have been a few minor changes to the API rt_func::set_switch() api

All code should compile as is, it if does not, please let me know.  
(To my knowledge, no one is	using the changed functions)

All calls to set_switch() will be passed through the rt_message_proc, to provide you with the 
opportunity to hook the messages before they reach rt_func.

The default behaviour of the rt_func when it recieves this message is to call set_switch_i()
if the operation is not on its "ignore list"

Previously funcs have the following trigger actions:
ignore
turn on and off
turn on 
toggle

These have been replaced by two bools:

 bool b_ignore_turn_on  : 1; // if this is set, the func will regject the set_switch() message
                             // if the operation is sso_on

 bool b_ignore_turn_off : 1; // if this is set, the func will regject the set_switch() message
                             // if the operation is sso_off


Required changes:

 All weapons that were previously set to anything other than turn_on_and_off() will need to be updated.

 If the previous setting was "turn_on" (e.g. tennis ball gun) the new settings should be:

b_ignore_turn_on: false
b_ignore_turn_off: true

the default is false for both.


(Dan)
---




oct 20
---
you will need to remake shadow reps (sorry format change)
just call "make shadow rep"

---

alpha and add mode should work for packs

---

the render pipline was rewritten for alpha and add mode packs, please let me know if you
find anything broken.

---

bug fix:  case sensitivity in network folder name comparison


---
update to rt_pack api:
    //
    // destroys the pack, if it has a spawn point set it will reappear at that point
    // if respawn_delay is left at 0, the default respawn delay is used, otherwise it passed value is used
    // the default is about 4 seconds.
    // 
     __inertia_export void __fastcall self_destruct(float respawn_delay = 0.0f );

---
bug fix:

mayhem is no longer terminated when pack should respawn

---

first pass on portable hole
(dw_portable_hole_crate)

---

first pass on eraser gun
(dw_eraser_crate)

---



oct 20
---
minor updates to camera scripting functions:

rt_camera methods:


 void go_to(const vec3f & position, 
                              const vec3f * focal_point=0, // if this is set, the focal point will be set to a 
                                                           // fixed point
                                                           // otherwise it will be the players car
                              bool instantaneous=false );   // instantaneous will cause a teleport

  
  // this should be called after using go_to() or set_stunned to return the camera to its default control
  // system

  void restore_normal_control(); 
   (was do_normal_control() )



global:

  extern  rt_camera * get_camera(struct rt_pack * pk ); 





oct 19
---

New rt_pack export:  


    //
    // this returns true if any wheels are in contact.
    // always returns false for packs that do not have wheels
    //
    __inertia_export bool are_wheels_in_contact() const;

(melina)
---
phyiscs optimizations on, so it should run faster
(daniel)
---


oct 18
---

accelerators emulated
please let me know if you see cases in which they don't work

(rich)
---
quirk fyi:

  if you spawn a pack from host startup messages, its position will be relative to the player
  as the player is passed as the link ob.  To avoid this, add a delay of 0.125 and the message
  will loose its link object and spawn in global coordinates.


 
---

first pass on dw_tornado

---





oct 17
---

New for ed_mesh:
filter()

does the following:
{
 undo_frame __frame("filter");

 combine_equal_verts(this);
 remove_degen_faces(this);
 combine_textures(this);
 filter_surfaces(this);
 remove_degen_faces(this);
 remove_unused_verts(this);
}


Filter surfaces is new, it will combine surfaces that have the exact same list of textures.
Occasionally textures will be unique because color values are slightly different, this could be avoiced
if possible.

e.g. 
 surface_0 and surface_1 use the same image.


 surface_0 has diffuse of 0.5 0.5 0.51
 surface_1 has diffuse of 0.5 0.5 0.5

 solution: clamp values

---

If you move a local file into a new directory and start mod, it will automatically remove the file on shared
with the same name but having the old directory.  It will claim that the file is obsolete.

This is to prevent the name comflicts that occur when moving batches and packs between directories

---
First pass on dw_lightning_cloud and 
              dw_buzz_saw

Source is updated, batches are on S:\w\david!\batch\weapons

---




oct 16
---

 new flag for pack:

  is_racer

This should be set for all packs that may participate in a race 
(e.g. cars)
This will be used to filtering targets and race_experts enumerating
participants  

---

 flag used for back:  can_be_sliced
 
 Packs should set this if they want to be sliced in half by the buzzsaw
 
 packs that get sliced MUST have a cld hull as their collision rep



---

improved path planning, it was failing in a number of cases  
that were not exposed by rh_pit_race (or worked around by clever designers)


---

 Changed race_expert to cure problems that would arise when the AI
 planned a backward path (most common in short races with <= 5 check points)
 and in races where ais started in random spots rather than the start like.

 The set_next_check_point only tracks one check point ahead if the racer is on the path that she should
 be on and   (p.position.path_position > 32768)  (which in fixed point notation is 0.5.

 So if the ai is on track and more than halfway along its current path, she will plan to the
 end check point of the NEXT path, otherwise she will plan for the end check point of the current path.
 
Rich
----

New pack exports:


    //
    //  returns our closest target, if any
    //  0 if there is no target
    //
    __inertia_export rt_pack  * get_target() const;
   
    //
    //  returns the point on this pack that should be targeted, 
    //  usually close to the center of mass.
    //
    __inertia_export vec3f get_point_on_me_to_target() const;


New level export:


  //
  // enumerates all objects in the world with is_racer set
  //
  __inertia_export void enumerate_all_racers( darray_buf_ls<rt_pack*> * p_result );


	(e.g. g_level.enumerate_all_racers() )

----
 




oct 14
---


 fixed crash on tile road sections

 (rex, dan)


---

 'Q' will self destruct your car.
 you may have to hold it for about 1/2 second



oct 12
---


Spawn/Respawn:

 Packs with a planner in them (an AI or a Player) will store respawn points that are used of they are destroyed.
 If a pack has a respawn point set and it is destroyed, it will be recreated 3 sec at its last set spawn point.


 Use this to destroy a pack:

    //
    // destroys the pack, if it has a spawn point set it will reappear at that point
    //
     __inertia_export void __fastcall self_destruct( u32 reserved =0);
 
 Use to set/get spawn point:
 
    //
    // write the spawn point to this pack.
    // If there is no planner in the pack it will not be registered, and false will
    // be returned.
    // Otherwise the planner will store it and return true;
    //
   __inertia_export bool set_spawn_point(const basisf_q & m_lb);
    //
    // reads the spawn point from this pack.
    // If there is no planner in the pack it will set the result to the identity and return false
    // Otherwise it will return the value stored by the planner
    //
   __inertia_export bool get_spawn_point(basisf_q * p_result);
 



 When player is created its spawn point is set to the start position.  Race experts should update the spawn point
 as cars pass check points

---
 new for ef_check_point

 b_disable_spawn)
//? If this is set, the check point will not be used as a spawn
//? point.  (e.g. for check points above jumps)
//? Note: the race expert must respect this flag when overwriting 
//? spawn points

---

 race_expert.cpp has been updated to set spawn points;

   Spawn position is updated when:

    Any car passes a check point with b_disable_spawn not set

    A car is added to the race


 race_expert dispatches l1 and l0_passed messages when you a car passes a check point 
   (I should have done this before)

 race_expert only removes packs that are closed, not just inactive packs.
 when packs are destroyed, they are temporarilty inactive until they are respawned, the race should not 
 loose track of them.


---


api change:

 You should no longer access the material of a cld prim directly, as this may change if the prim is re-used
 (for example, height fields)
 
 for collision_message

 use: 


     msg->material_other
   instead of 
     msg->p_other->material_id

     msg->material_me
   instead of 
     msg->p_me->material_id


---

new psc op:

open "name"

"name" can be a batch or a level

easy way to find a file without opening filters

e.g. open "dw_pit_race8"

----

new psc op:

update "name"

"name" can be a batch or a level

e.g. update "dw_pit_race8"


new command:
 
  file->update_all()

This will execute the psc script update_all.psc
there is a sample on S:\w\update_all.psc that contains what is needed for the m1 drop


 In order to us update_all, update_all.psc MUST be in the mayhem root dir
 update_all calls the psc op (you could type it in) execute_psc "update_all"

(rex)

---

exported two new functions for packs:

   /*
    
      Applys a dent to a pack
      A dented mesh can still drive

    */
    __inertia_export bool apply_dent( 
                         const vec3f & _cld_point,  //  point at which dent occured in local coordinates
                                                    // e.g 0, 0,  1 is above pack and will apply a dent downwards
                                                    //     1, 0,  0 will dent from behind
                         float duration,            // how long to remained dented
                         float distance  );       // scales the amount that verts move from the dent
                                                  // usually in the range 0..4


    /*
   
     Flattens a pack
     A flattened pack cannot do anything, 
     it just topples arround

    */
    __inertia_export bool apply_flatten( 
                           int axis_0,          // axis along which to flatten
                                                // 0 is from the front or back
                                                // 1 is from the side
                                                // 2 is from the top or bottom
                           float duration);     // after the pack comes to rest it will wait this long on the ground
                                                // before popping back up

   /*
   
     Removes all child packs on weapon mounts
     this its usually called before apply_flatten 
     (if you want the player to loose her current power ups)

   */
    __inertia_export int drop_pickups();  

(daniel)
---



oct 11
---



collision sound tuning/tweaking (change to exes)

---

Smoosh handler has been updated with new volume settings


---

objects cannot have coordinates outside of 1023.
they will automatically get clampped
---

smoosh_handler updated to support collision sounds

please update from dw_smoosh_handler. 
 (you may want to remove the func from your level's pack and add the dw_smoosh_handler pack)

---

Boxing gloves reimported from dp_boxing_gloves
sounds added to weapon_boxer 
sounds added in mod to dw_boxing_gloves

---

sounds added to weapon_hammer 
sounds added in mod to dw_hammer

---

sound playback functionality added to bridge turner (actual sound must be dragged in as I don't own the pack)


---

skid sound in flight fixed

---

sound action items:


 (rich) please drag bridge_spin.wav into rh_bridge->turner 
		please set range to 64,128


 (daniel)  please set skid and engine ranges to 8,16

 (daniel)  please removed the engine sound temp  from dp_spy_car
		  
		  the sound should be in the rtf_car functional



The following entries need to be bound in mod:
 use a tab stop of 24 to view.
 fGain is the setting for the waves volume
 TB3DSINGLE must be set to 3d
 TB2DSINGLE must be set to 2d 


 iPID	1 - pszName	2 - cType	3 - fGain	4 - pszWave	5 - bStream	6 - bHide	7 - cRnd	8 - Loop[0]	9 - Loop[1]	10 - MinDist	11 - MaxDist	12 - bRndStart



F launch bouncyball	TB3DSINGLE	0.4	launch_bouncy				-1		16		


R weight drop	TB3DSINGLE	0.25	weight_drop				-1		16	
R swinging hammer whack	TB3DSINGLE	0.4	swinger_whack				-1		16	64
R crate destroyed	TB3DSINGLE	0.4	crate_destroyed				-1		16	
R race start	TB2DSINGLE	0.55	race_start				-1			

? cooked by lava	TB2DSINGLE	0.4	lavadeath				-1			
? cha-ching	TB3DSINGLE	0.6	chaching				-1		16		


 

oct 10.5
---
rtf_car has two new members:

 engine sound
 skid sound
 exported dw_spy_car_blue with sounds set up.  You can copy these
 (the signal binding must stay, the wafves can change)

 you currenlty need my smoosh handler to hear certain side effect sounds (e.g. brake)



oct 10
---

The driving surface for a road must be a rectangle (4 points only)

 To create the driving surface please use something like the following procudre:

  call make_rect()
  set the hull scale to 32 16 1	   (64 meters long, 32 wide)
  set flat to true
  set extrude radius to about 0.125
  set the hulls position to 0 0 -0.125 ( -extrude_radius )

---


There are occasional data synch problems with shared data for road sections.

Current workaround:
If you notice data not being propagated (e.g. collision mode),close your level
open the road section, set the data and reopen the level


---


When you update your dll's please update your .pdbs are well, thanks.
alternative you can change your "C++ option" "debug info" from 	program data base to c7 compatible, in which case
debug info will be put in the dll.

---


updated comment in header file:

  //
  // This will returns 0 if the pack is not able to deform (deform flag is not set)
  // Otherwise it will create a ffd if none exists or return an existing ffd for this pack
  // do not cache an ffd pointer between frames
  //
static pack_warper_ffd * get( rt_pack * pk );

(Dan)

---

bug fix: when 2 unmovable objects collided there would be a divde by zero.

(Dan)

---

New tool on mouse right click menu:

make check point
//? make check points:
//? works well with the grid visible and "disable height field" set to true

help:
b_join_points
//?  If this is set any check point made will be connected to "last_check_point"
//?  last check point will be set to this new check point

last_check_point
//? Be careful about replacing a check point in this box, if you drag a check point
//? onto another check point it will connect them with a path, you have to drag the 
//? new check point to somewhere just at the very bottom of the box where the current 
//? point in the box does not become highlighted

pack
//? This is the pack into which check points will be put.  if last checkpoint is set, this 
//? is not needed



---

Fixed a potential FPU divide by 0 bug in AI targeting.


(daniel)
---

When you drag a pack that is attached to a road, it would recompute its position in road
coordinates.
To move a pack relative to a road, use the road_gb directly.  (e.g. sliding along X will moving it along the road,
z is up and down, +y is left relative to the road)

---

new for ed_patch:

b_use_default_material
//? If this is true, the material set in the height field is used.
//? Otherwise a custom material may be assigned

material_id
custom material, only used oif use_default_material is false


--

you will need to delete rtd.

--



oct 11
---

When you get mod and war, please copy mod2k.pdb and war.pdb as well (same dir) 

When we make builds of war, please include war.pdb in the war dir.


oct 10
---

New: "Replace Pack"

Drag a pack or a batch onto a pack in a level and it will be replaced.
(you can also drag a .dwb from windows, as long as it has 1 root pack)


The following occurs:

  "old" is the pack that was in the level
  "new" is the pack that has been dragged into the level

  old l0 data is copied to new (position, road_id info, etc)
  each func in old tries to find a match in new.  A match is a func with the same name and class
  if a match is found, l0 data is copyed from the old func to the new func.
  (this will copy outgoing l0 messages)
  
  All references to old and old's funcs are remapped to the corresponding new and new's func
  
  e.g. a message in host startup messages sent to an old func will be redirected to the new func if a match was
  found.  

---

Support For Themes:

  Themed packs must use the following nameing convention:
  
  INITIALS_THEME_PACKID_whatever


e.g. dw_hell_dude_00

	 There MUST be a _ before theme and a _ after pack_id
	  
	e.g.  dw_hell_dude00 is not valid



If the theme were changed to farm, the pack would look for:


     *_farm_dude_*.dwb

	 There should only be one batch with a matching mid section	(theme and pack id)

note note note:	Each theme pack must be owned by a batch with a name that "matches" the packs
by matches, I mean that the middle two sections are equal

all comparisons are case sensitive, make all theme and packid names lower case

packids must be aggreed on by designers

Theme packs should that require remaps must have funcs with the same name.

e.g. if farm_dude has a timer called "pulse_me" that gets pulsed, hell_dude should have a timer
called "pulse_me", that way if farm_dude->pulse_me has incoming messages, they will be redirected to
hell_dude->pulse_me
 

Each level stores its current theme. (in a drop box)
When you change the theme, all theme packs will search for replacements based on the new theme.

Here is a partial list of theme names, as this list changes it will be updated in the drop
box of levels, please refer to this for an up to date list 

farm
hell
dessert
tran  (transylvania)
jungle
space



---

New members for edit options:

pack_view_filters[0]
//? If this is not set to "misc" only packs fo this class will
//? be displayed in the level's tree view
//? (you can always view all of the levels packs by exlicitly opening
//? the level's "packs" folder
//? This filter applies to level tree view

pack_view_filters[1]
//? filter for packs in right center property window

pack_view_filters[2]
//? filter for packs in bottom center property window

pack_view_filters[3]
//? filter for packs in bottom right property window


---

Morphed Meshes use the following system:

  A pack has a morph_input_signal, if this is set to anything other than "none"
  the pack is a morph pack.
   
  A pack stores a series of Meshs, each representing the mesh at a given point in time
  This list takes the place of the LOD list for meshes, morph Meshes cannot have LODs (this may be added later)
  
  A morph mesh will display a mesh based on the value for the specified signal.

  If there are 32 morph meshes, 

  signal == 0    will select mesh 0
  signal == 0.5  will select mesh 16
  signal == 1.0  will select mesh 31

  Signal values are wrapped, so 2.5 == 1.5

  If a morph has a duration of 4 seconds, you can set the signal to time*0.25
  (note, you will have to offset this value if you want it to start at a specific time rather than continiously 
  looping)

  The max exportor is used to create morphed meshes, set the sample frame rate to something appropriate
  (more samples looks better but uses more memory)

  see dw_bend0 for an example

---

New for ef_key_frame:

remove_useless_keys

//? This should be called at least once on all imported animations
//? removes all keys that apply no transformation
//? (keys that have no effect)

---

Tip for running Max and Mod without reboots in 98:

 always close msdev before running Max
 always close mod   before running Max and vice versa
 pray and save often



---






oct 9
---

rectangular textures will be loaded and resized as appropriate.

---

window layout changed.

In all of the object "Tree" views you can drag objects into the empty space to show a tree
view of that object
Right click drag will allow you to "append"	or "replace".

Shift->click creates a prop window at the bottom center of the screen
control->click creates a prop window at the bottom left corner of the screen

---

Pack class names updated

"Misc", 
"World",
"Road",
"Decoration",
"Light",
"Gag",
"Car",
"Virtual",
"Power Up",
"Rubbish",
			  
There is a new "hot_keys.txt" that has these bound to the tool bar in S:\w
---

---



oct 8
---

											 
func tree views are now sorted alphabetically
---

new func for check points:  update_names

---

You can now select and transform check points doing this:

watch the pack containing the check points
select the check points (if you use "select", make sure to turn on the "components" check box
Use "Move Selected" 

---

Check points now draw a line that extends to z == 0
to view heights for check points, disable draws on terrain, roads etc and draw_check_points

(rich)

---

New flag for ef_height_field: auto_update

If this is set, the terrain will auto update when check points are moved around


---

You can now explictly set the dimensions for your height fields. 
Write numbers to patch_dim[0] and patch_dim[1]

(rich)
---


New flag for view:  draw_orgin

(rich)
---

you may get a message telling you to update your video drivers

---

Gos now lets you set text alignment/justification (Rich's request and Andy got it in)
	  
	  ?gos_TextSetAttributes@@YGXPAU_FontInfo@@KM_N111K@Z


(rich)


oct 8
---


paths:

  compute lengths and align sections have been replaced with "tile sections"
  
  If you call this on a road the following occurs:

  The length of the path is computed (all paths with the same road_id up to the next road_start )
  This number is rounded to the nearest multiple of 64
  Road sections are aligned starting from the beginning.
  if there are too many sections (e.g. 3 64 m sections when the length is 128) extras are removed
  if there are too few sections, the last section is duplicated until the road is full.


--

New flags in view->options:  disable terrain, toggles draw terrain on off
this can also be set with the psc ops  (disable_terrain 1 )
(rich)
---


oct 6
----

new for l1_ef_height field:
 
 road_z_offset, default -1
 this adds a bias to terrain, shifting all hights by this amount relative to the check point loop.
 Make sure to set the radius of check points accordingly. (eg. 16 for a 32 meter wide road like the bridge)


---

Lock down for paths:

   Previously all roads were defined but a series of paths with the same road_id, and the first path marked
   as b_road_start

   Now road "sections" have a road id and a "stop_id".  The stop_id is computed automatically by the number of 
   road_starts that take place on a path.
   
   For example, say you have four sections joined together to form a loop.
   
   path 0->1 is marked as road_start, it will have road_id == 1, stop_id == 1
   path 1->2 is not marked, it has road_id ==1, stop_id ==0;
   path 2->3 is marked as road_start, it will have road_id == 1, stop_id == 2
   path 3->0 is not marked,  it will have road_id == 1, stop_id == 2

  Each pack stores a road_id and a stop_id
  dragging a pack onto a path will assign it the appropriate road_id


  Example:  4 paths, path 1->2 is a bridge that you want to put a 64m mesh across:

  path 0->1 is not set as a road_start
  path 1->2 is marked as a road_start (it is the bridge)
  path 1->2 has a rest length of 64m and quantize is turned off
  path 2->3 is a road_start too
  path 3->0 is not a road_start.

  That way you have a road starting at the end of the bridge and ending at the bridge, and another
  road which is only the bridge.

 
 road starts draw in green
 normal paths draw in grey
 selected paths draw in red 

(design)
---   

 warped packs will deform their shadow rep


(design)
---

 Grid is now drawn using a dp_big_grid pack.
 It is drawn at z ==0 and extents +- 512 in x,y


(design)
---




oct 1
----


New class: ed_sound:


/*?

  A sound, one of three types:

   2d:  2d sounds are played at full volume without panning.
        they are only played if the location at which they are is
        within the range
        set the range to 1e6,1e7 if you do not want them localized
        Many cartoon effects that happen at specific locations can use this play mode as 
        they should only be heard if the player is close, but they are not really
        3d sounds

   
   3d:  Standard 3d sound

   
   Music:  only one music can be playing at any time.
           playing another music will stop the first
           Music is always heard no matter where the player is


  Dragging a wav will create a 2d or 3d sound
  Dragging an asf or mp3 will create a music.  asf is preferred as it
  is more efficient in terms of processing and space.  At a given bit rate
  the quality is usually higher than mp3.


  Ways to play sound:

  Open Loop Playback:

    edm_play_sound:  A simple sound once, if sent to global it will be played at the origin
                     if sent to an rt_func it will be played where the functional is
                     Dragging a wav onto a message batch will create an edm_play_sound

    
    ef_custom:   declare a sound_ptr member (e.g. sound_ptr m_sound) and call m_sound->play();

    

  Feedback:

    ef_sound:        Turning it on will start the sound, turning it off will end it.
                     These sounds update their positions and velocities over time
                     They can also update volume if a signal is set up

*/


string,name)
//? file name of sound

float,volume.v)
//? volume for  playback

float,base_priority)
//?  base priority, when there are too many sounds playing, the lowest 
//? priority sounds are dropped
//? priority is calculated as:
//? volume * base_priority * distance_modifier*(1 - completion_ratio  )
//? distance modifier is 1 when distance from player to sound is <= range[0]
//? it drops linearly to 0 when distance from player to sound is >= range[1]
//? completeion ration is how far along the sound is, 0 means just started (or looping)
//? 1 means finished


float,reverb_gain)
//? gain applied to reverb, 0 is no reverb

bool b_is_looped)
//? if set, the sound will play continuously, otherwise it will stop after one playback

bool apply_doppler)
//? wheter or not doppler should be applied

bool is_streamed)
//?  A streamed wave will not be loaded immediated, this is for very big waves


vec2f,range)
//? range from which this sound is audiable
//? if distance <= range[0], sound is at full volume
//? if distance >= range[1], sound is silent



Sept 30
---

Changes to the API for gameos:

 Fonts must be done though game os.  see gameos.hpp for an example
 DrawSprite,line,etc use an exlicit blend mode rather than implicitly setting it in the color.

 For solid colors, always set alpha to 255.
 e.g. red is rgba(255,0,0,255)




sep 20
----

 when modifying a path, the road_length will not change until you call "compute_road_length" on the path
 This prevents the poping that you get when deforming a road.
 after calling compute_road_length you may need to add /remove road sections as appropriate

---


 - objects stuck to splines now store an oritention in addition to a  position
 - When you drag a non-warp object onto a path, it will compute a the orientation and position s.t. the
   object is not initially moved (from this point on, it will move with the road)
 
 - The easiest way to move one of these objects is to click on the pack.  non-shared - misc will have a path_gb
   you can use the arrows, and sliders to move the pack.
 - +x moves the pack forward along the road
 - +y moves the pack to the left on the road
 - +z move the pack up relative to the road




sep 19
----


changed everything.

-  use generate_lods on a pack to generate lods

----


Certain coordinate schemes have chanaged.  When you open a mesh with dofs you will likely find
that dofs are out of place

call pack->other->upgrade_positions and everything should be fixed.

Note:  if the dofs of a child pack are incorrect and you open the parent, the child will not update its mesh on
upgrade_positions()
You will need to open the pack as a root;
				  s
----


There is a file called max_to_mod.dle that when dropped into a Max plugin dir will allow you
to export .dwe files.
dwe files can be dragged directly into mod and will create packs

---

Exported new functions for frame:

void frame::set_frozen();
void frame::clear_frozen();

Every call to set_frozen should be matched with one call to clear_frozen

e.g. set_frozen(p_frame   );
wait 10 seconds 
 
     clear_frozen( p_frame );


(rex)
---

Minor improves to camera and driving on spline paths, please see dwtracktest


----

New flag for cld hull:  flat

If this is set, and the hull is a quad, it will be stretched along the spline.
This is the ideal setting for a road surface.  
Use make_rect, set extrude radius to something like .125 (larger numbers will work too
Make sure that the Z axis is up and the X axis is forward.

see dwtracktest.dwl for an example

The road and sides of the road are marked as flat.

----



Spline assisted Level Creation:
---


 Goal:   [inappropriate remark removed]
 


Road Sections:
--------------
  
  These are used to construct the primary driving surface
  
  Making a Road Section:
  
    Solicit Mesh from Artist
	Make a pack out of this 
	
	Road should travel in X, up is Z, left is Y

	Z == 0 should be the height at which you can drive
	
	Set the meshes road_section length.
	This should be a multiple of 16.
	
	The length is the total span of the Mesh along X.  The support verts in X should be at
	 
	 [ -road_section/2, y,z ] ,  [ road_section/2, y,z ]	 
  	

	Collision rep:
	 
	  Only hulls can be used
	  These should be Rects (make_rect) or boxes (make_box)
	  These will be tesselated as needed

   
  
	shared -> warp_to_road:  this should be set for road pieces, it will cause the mesh to deform based on the
							 road spline

	shared -> tesselate_mesh:  This should be set for road pieces with minimum verts, verts will automatically be 
							   inserted based on the curvature of the patch
							   Certain Road pieces (bridge) are already tesselated, and do not need this option


	l0->road_id:   Index of road in which this is embedded, 0 for none.
	               This is set automatically in most cases (see Building a Race)

	l0->road_c:    Position of Pack on Road.  X is distance along spline from start to the cofm of the pack
											  Y is horizontal offset, Z is vertical offset (both are usually 0)
				   This is set automatically in most cases (see Building a Race)



	For an  example:  see dwtracktest.dwl
	 
	  dwBridge1	(pretesselated)
	  dw_brick_barrier (tesselated by spline)




Building a Race:

Step 1:  Construct splined Path:


	Create three check points 
	drag them onto each other sequentially to create paths
	mark each path as road_id == 1 (1 is main race)
	
	set road_start == true in the first path

	Drag around points and use "split" on the path to add control points, "remove" on check points
	to remove them


Step 2:	 Apply road sections

  Drag and drop road sections onto the Road Path until it is full.
  Dropping a pack onto a road will:
    Append pack at the empty of the current road
	Set the packs road_id
	set the packs road_c

  Draging a road pack onto another road pack will allow you to replace the road
  section with a new one (e.g. replace a brick road with a bridge)
  
  Alternatively, you chould remove the original piece, and copy in a new pack, setting its road_c and road_id to
  that of the previous pack


Step 2:	 Apply road scenery


   Drag non road packs onto path
   
   path_c combined with the road spline will determine the position and orientation of the object
   in order to move the pack, you must set path_c rather than gb.c

   When the path is moved, scenery will be moved to follow

   
   (e.g. rh_hammer in dwtesttrack)





Todo:
 
  - Collision detection is not good for driving on hulls
  - Camera has problems

  - Improve scenery positioning interface, allow for orientation and easily setting path_c
    



---





---
new message:  edm_set_scalar

 can be used to set signal registers  in packs
 packs maintain the last signal written to them 

 all signals start out at 0
(sonya)
---


Mon sept 9
---


note: rtm_custom has not yet been tested

note: path_location::get_only_race()


---

New message added:  rtm_custom

 This is used for sending custom events locally and across the net.
 see race_expert for an example implementation that uses an rtm_custom to synchronize race positions and 
 participant lists

(Rich)

---
 

new flag in psc:  disable_read_only 1
use this only for testing purposes
it will allow you to change data owned by other people
use sparingly

---

Font problems fixed 


(Rich)
---

new function: 

 path_location::get_only_race
 
 just like 	path_location::get
 
 but filters for race paths only


(Rich)
---



sept 8

---

if you add profile 1 to your psc and press tab-F4 you will get a better breakdown of where time is going

 note:  in mod2k (but not in war) two important overview categories are missing (draw and step)

---


For future builds you should use:  back_buffers 2 on most cards (as long as the card is not short of video memory)


--
recommended setting for damage to dent_scale in smoosh_handler: 6.00

---


added hooks for  tbid_mallet_trigger
				 tbid_mallet_miss
---

remote objects that you flatten that think they have not been flattened will stay flat and be allowed to drive
rather than popping right back up

---

Dent scales and such changed

---

Birds only appear when damage > bird_damage_scale

 This can be set in the smoosh handler (default is .6)

---


un flatten plays proper sound

---


New for rt_func:   apply_warp_to_gc

//? If this is set, a warp will be applied to the global coordindates of this if
//? the pack is currently warped (e.g. sloshing around)
//? useful for things like particle emitters that should be pegged to a mesh


---

 sloshing of car when stunned

---

 birds and stars appear on more smooshes
  
---

3 smoosh level thresholds


---
ef timer:

//? supported messages:
//? set_switch->pulse()
//? dispatches messages
//? Link position is location at which func is located
//? link object is the source link object if the message was a pulse, the frame in which the timer
//? is located otherwise 


(rich)
---
For 3d sounds, the position at which the sound is played is as follows:
 if the message is sent to an rt_func, it is played at the funcs location
 if the message is sent to pie, it is played at the link objects position (delay must be 0 )

(rich)
---

damage needed to smoosh should be set to 0.25
in smoosh handler

(rich)

---
new for level:  remote_object_created_flags

	using this you can pulse your race expert and add the object to your race
	if the object is a vehicle.

	Note:  your race expert must be able to elegantly handle remote objects disappearing and then reappearing
	
	When a pack changes, the pack that you are storing will become inactive and a new pack will be created.
	simply removing inactive packs and adding then as needed will handle this to some degree, but will not work in the 
	following cases:

	 - a remote object is no longer present in the world because it is too far from you to notify you of its existance 
	   (and waste your bandwidth)
	
	 - messages indicating that a racer is gone may not be appropriate if the object is being replaced (and was not destroyed)


---

you must delete rtd

---
Fix


  Bird and star
   - duration lengthened
  
   -  root orientation stays in aliged with the global bases
	
---

Possible Fix (need to test)

  hammer staying visible
  
---

Possible Fix (need to test)

  driving while flattened
  
---

new flag for l1_ef_pack:

  simulate_if_virtual
  
  if set the object will simulate (let dofs move) even if virtual (it will not do collision detection)

  This is used for dw_stars and birds which is marked as virtual but still simulates so that the revolutes birds roate

---
new flag for pack:  b_is_disabled
this will be set when the pack is stunned

---

Network runs some what decently on high latency or low bandwidth

---

anything that is out of synch by > 8 meters is teleproted

---

changed network update settings
anything that is out of synch by > 4 meters is teleproted


---


decreased ks,kd when camera is stunned

---


added calls for reflate sound and stunned sound


---

draw race track on radar only draws paths marked as race

race track thickness can be set with "radar_track_thickness"
									  
default is 4 pixels (was 2)

---

 removed message in hammer that played sound

---

 removed connection button from multi player screen
 
---

 changed hammer material from swinging hammer to pickup hammer for proper sound id


---

 fix for cards with only 1 texture state (banshee)
---


flatten from sides and front makes you completely flatt.


setting "net_tcpip 1"  in war.psc will connect you to tcpip

note:  this will form the net connection before war is initialized.  If you are playing single player
you will have a net connection that does nothing.
ordinarily the connection is only made if you press "multi player"

net_tpcip 1 worked on my machines.  We should use this in all future net builds
(possible a batch file with more than 1 .psc so that single player does not auto connect.




sept 1
---

---

tbsetcarweelspeed now passes 0 for acceleration and thrust for thrust

(thrust is 1 when full forward is pressed, 
  0 if nothing is pressed
  -1 if full reverse is pressed)

acc is not yet set because it is unavailble.

tbsetplayerskid is supported

tbstart/stop engine supported


---

new for pickup:

 pid

 if this is set and auto mount is set, the pid is loaded and mounted

(daniel)


aug 31
---
car with pitch in flight if you use forward or reverse.
flight_pitch_kd 0 to zero


aug 30
---



---

note:  In order for the camera to consider something drivable, you need to give it collision mode == world.
This is why in many levels, the camera thinks the car is out of control.



---

new state: ef_state_attack

see dw_bounder2 for example
try playing him into 6the sim options player and run dwMPtest

---

set_state w link ob fixed (I hope)

(rich)
---

race expert accepts the command->start message
this will add all controlled packs to the race


---

editor_config->b_tv_paths

//? if set, paths are drawn in the tree view of packs


editor_config->b_tv_check_points

//? if set, check_points are drawn in the tree view of packs


aug 29
---

Accelerate, brake and slide sounds are played by the smoosh_handler.


---

Bridge implementation/changes:

 removed signals from pack
 
 added a bridge_turner functional (See bridge_turner.cpp)
  this functional gets turned on by the target, it will automatically turn itself off

 added a camera_stunner functional (See camera_stunner.cpp)
   this stuns the camera when the user is on the bridge

  
 
 see dw_pit_race0.dwl


---

weapon hammer.cpp updated

 when not in use:
   - the hammer is shrunk to a small size
   - collisions for the hammer are disabled.


---

new event:  car slide

played when a car starts into a slide

---
new collision mode:	 world


none collides with nothing
particle do not collide with one another
world    do not collide with one another

          none particle world normal
none        no   no        no     no
particle    no   no        yes   yes
world       no   yes       no    yes
normal      no   yes       yes   yes


aug 28
---

driving model updates

---

new flag for sensors: only_vehicles

--- 

texture generate fixes (filtered a few bad cases)

---

 event hooks added for accelleate, turn and brake. 
 These should dispatch sounds and such

---

update_listener is called by a "wheel speed" of car.

- When on the ground and brakes are not applied, this is the speed of the car
- When in flight, speed slowly decays over time.   If thrust is pressed, speed increases
- Whenever brakes are applied ( > 0.5 ), speed will be 0.  (visually, wheels will freeze)

(Andrew)
---

Sound is played by directly invoking tbapi

\sound\tbiapi\*.h is where the header files are stored
\w\tbapi.lib must be included into your project to use tbapi
\sound\tb_coordinator.h  is a few helpful things 
(sound id enumeration and vector conversion)


see david\weapon_hammer.cpp for an example.  (plays a single shot sound when you use the hammer)

Currently I hear no sound.  This may be my fault.

---

Hight field texturing:

  drag a texture onto the height field for road_texture
  drag a texture onto the height field for grass_texture
  
  specify a texture_name: e.g. 'yadda' 	will create yadda_GGG, Yadda_GGSG, etc.

  specify a mask_name: e.g. 'mask' 	(default is on shared, mask_*.bmp, you can edit this to create 
                                       wavey images and do color blending)
									

  call "gen textures"

  call "update track"

  see riches email for what these things mean

  tip:  you may get patches of texture that are white.  These reference textures that do not exist (e.g. yadd_GSGS)
  
  these will be added soon.  A workaround is to make you road a little wider so that these cases do not occur.



  see dwMPtest for an example
  textures\terrain\mask2_GGSS is an example of a blended mask

aug 27
---

each check point has a "roll gain" this will cause the road to bank around corners.
setting to 0 eliminates the effects, >1 exaggerates it.

(rich)

---

Terrain editor update:

recommendended procedure:

add "draw_path_splines 1" to your mod2k.psc
 
Create a race loop (ef_check_points)
 you can now call "split" on a path to insert a new check point between the previous points
 you can now call "remove" on a check point, and the paths will attempt to repair themselves

Create a height field that will represent the terrain

set the height fields road and off road textures
call update_track on the height field

update track does the following:
		  
  all control points that are not indicated as locked
   get:
     their texture set to off road
	 their height set to high_z or low_z depending on their setting
	 
  Each ef_path marked as "make_road" walks along its spline ensuring all terrain points
  within its radius (defined but the radius of the two check points being joined) are at the same height as 
  the spline at the closest point from the point to the spline
  
  A filtering pass smooths out adjacent terrain points to reduce   

  All patches that are considered "unused" (e.g. tops of mountaints) have their textures removed, and these will be
  used to automatically generate portals and rooms
  (black stips in your height field are good.  they improve performance)



See dwMPtest and dwMPtest2 	for an example



---




new flag in psc:
 draw_path_splines
 
 set to draw path splines


new flag in psc:
   disable_smoosh 

new flag in pack:
   can_deform


new flag no_damage 1



draw_path_splines 1


aug 24
---

new for height field patches:
 "Copy")
/*?
Copies the selected patches to the patch clip board

  Useful for moving hills and such
   e.g.
    select the grid of points that make up the hill
    call copy on a center point

    call paste on another point somewhere else where you want a hill  

*/

 "Paste")
/*?
Pastes the selected patches from the patch clip board

  Useful for moving hills and such
   e.g.
    select the grid of points that make up the hill
    call copy on a center point

    call paste on another point somewhere else where you want a hill  
*/




aug 23
---

new for height field patches:
 "Copy height to selected" )
 "Average height to selected" )

 "flatten selected" )
/*?
Flattens selected points onto a plane computed as a least 
squares solution of the selected points
*/
 "Shear selected" )
/*?
The x y components of the vec stack are the slopes used for the shear
select a number of verts
write an x and y slope to the top of the vector stack
right click on a pivot vert and click shear_selected 

all verts will have height += (Vx - pivotVx) * shear_x 
                             +(Vy - pivotVy) * shear_y;
*/


(rich)
---


Dll's are not read from shared.  you must copy them locally
this is to avoid the "read only" problem

(rich)

---

new psc op: 
 
 print VAR
 
 e.g. 
  print warp_ks


 prints the value of var
   
new psc op: 
 
 help VAR
 
 e.g. 
  help warp_ks


 prints the help for var

---

new psc func:

 save_settings

  "Saves all written vars to settings.psc, you can include this file in your war.psc (note does not yet store bindings)");


---


new for l1_rtf_car:

wheel_radius { rear, front }
This should be set to the approximate radius of the cld rep of the wheels
It is only used for squash and deformation calculations

---
l1_rt_func->b_has_Step_hook has been replaced with:

 step_hook_id 

 enum
 {
  step_hook_none,               // no step hook
  step_hook_0,                  // these step hooks are executed first, should be used for planners (ai, player)
  step_hook_1,                  // these step hooks are executed after hook_0's, should be used for controllers 
                                // (so that they will respond to planner inputs without latency) 
  step_hook_post_integration,   // takes place  after integration and position/object update. 
                                // This is a good time to spawn objects.
                                // Weapons use this

 };

You will need to recompile 


---



aug 18
---


For piapi,
please add the following to your C++ project build options :

 /QIfist

---

The check points use splines

see dwMP test for an example
dwBounder2 is an ai with a race state

I will be adding api extensions to support races this afternoon



---


Check points use this convention:

z up
x forward
y left;

---

you can shift select items in a tree view and all items between wil be selected

---

new function for check_point:

 auto_align

---



Signal mappings (new, old)


  signal_id_pack_0       signal_id_one
  signal_id_pack_1       signal_id_time
  signal_id_pack_2       signal_id_pack_life
  signal_id_pack_3       signal_id_pack_speed
  signal_id_pack_life    signal_id_pack_0
  signal_id_pack_stun    signal_id_pack_1
  signal_id_trigger_0     signal_id_pack_2


 so if a legacy signal references "pack_2" change it to "pack_life"



aug 15
---

 4 modes for local/remote sim (was prviously just a bool )

 local_sim:  least expensive
 local_sim_remote_spawn:  when the object is created, a copy of it is created on remote machines.
						  from then on its on its own

 export_no_transfer:  object is exported, never transfered (useful for player)
 export_transfer: 	 object is exported.  it will be transfered if another player is better off owning it.



mp first pass:

  General recomendations:

  weapons that fire projectiles should have these set to local sim
   they should _not_ have b_disabled_if_remote set

  auto attachments (hammer) should have b_disabled_if_remote

  user car should be set to export_no_transfer



---

This is how the lighting/shadow system currently works:

lighhting is done via shadow maps or vert lighting

Shadows are projections of the objects shadow rep 
drawn (modulated) on any polys that their shadow volume intersects.

The shadow volume for an object is created using the closest light to the object only.
(Two overlapping lights will only cast 1 shadow, so you should try to avoid overlapping lights)


---


aug 14
---
There have been a few changes to the api that may require changes for all using the custom api:

new flag for l1_func:  b_disabled_if_remote

Set this flag on ctor if you would like your custom to never recieve active_change() (or side effects of) 
if the functional is in a remote pack.  (network)

owner_active_change has been superseeded by pack_change

This is called when:

  pack becomes active
  pack becomes inactive
  an auto mount takes place
  an mount is destroyed or broken off
  a network pack changes from local to remote or vice versa

  Please see weapon_hammer.cpp for an example of changes that could be made to accomodate this


---




Aug 13
---
exporting will export pid referenced objects from
ef_customs

(daniel)

Aug 12
---

mod and war automatically search the Shared\customs dir (set in the psc) so you do not need to copy them to your local machine

make sure to include the shared dir in war.psc

(don't forget to remove this for compiles)


Aug 12
---


dwhudexpert.cpp upated.

dwhudexpert sets levels that the user can play (under "arenas") and cars that the player can choose


---


New psc command:  

spawn_virtual "dwhudexpert"

this must be called after init_game and before start_flow

e.g.:



init_game


spawn_virtual "dwhudexpert"


start_flow


//end

----


To run War.exe you will need S:\w\maps\links\*.*

you will need to del rtd and update_rt()

---

fix:  range limits would be used by actuators event if range_wraps was set.

(daniel)
---
exported frame functions

(rich)
---

exported rtf_check_point::dti (class info)
also     rtf_path::dti

(rich)
---


Aug 10
---

david project updated

There is a batch:  david!\batches\dwhudexpert
			 with an ef_hud_expert in it.
			 drop this into a level (its virtual) and it will draw
			 hud stuff 
			 (currently just race trace, speed and health)

You can modify this starting with hud_expert*.* in pipapi\david
make sure to rename it. customs use their name as a class guid

(rich)
---



Aug 9
---
all sorts of little bug fixes

---

mesages with a delay will not store link arguments (ob, position etc)
this is a performance optimization.

If a delayed message requires link arguments there are workarounds using instant 
messages and explicitly caching the link data

---

You must create 2 dlls for linking , for mode and war

e.g.:  david_mod2k.dll
       david_war.exe

see proj\david\*.* for a sample project that has settings for both s.t. batch build makes 2 dlls
---

new for l1_pack: max_draw_distance

This was set to 2048 by default. now 256

---




Aug 8
---

first pass on plunger:  (grappling hook)

Sample is in dw_bounder1


first pass on multi-plunger:  (web gun without web gun artwork so I used plunger)

Sample is in dw_bounder0



---


In order to run this new version you will need to copy:

shared\w\custom\david.dll

to your

[mod2k]\custom\david.dll

---
New weapons:

  Hammer  (see dw_bounder, trigger 0 )
	This needs a little work. 
	
	 Currently uses a rotate about y swing.	 ( comes down to hit the ground )

	The rotate about z swing (hit from the side) was far more effective when I tested it, but it didn't look right
	I tried a compromise (rotate about x - z ) while effective, it didn't look right either
	
	
  Plunger:
    Doesn't have a spring yet.  I plan to finish this up this afternoon
	
	 

  These both use ef_customs
  	

    



Aug 7
---


new for height field points:

paint selected

(Rich)
---

bug fix:  upper case extensions for textures would cause problems on import 
(e.g. "TGA" )

---
Signal system updated and revised.   

Note: unfortunately the signal ids have been been reordered.
  You will need to update all signal regerences (e.g. pack 0, pack life, etc)
  

---




Aug 6
---


new dw_bounder0 with nifty glove.  (courtesy of Rich being a 3d artist)

Specifics/Functionality involved:

 root dof is a 10 (slider)
 range is -0.125 .. 3 (it can extend 2 meters)
 damping is 0
 actuate_kd = 11 (default)
 actuate_ks = 8  (higher than default for more speed)

 Q Max is 0  (which means infinute)
 (this is this max force it can apply internally, if the trajectory specified goes beyond this the dof will fail)

 dof reads input signal 0 
 dof binds signal to position

 an ef_signal amplifies the trigger_0 signal, 
 (linear, v0 =0, v1 = 2, t_input = 1, scale = trigger_0 )
 
 shifting it from 
   not presed == 0
   pressed == 1
 to
   not presed == 0
   pressed == 2

   (so that it extends 2 meters)


 When player or AI presses trigger 0, the arm extends to 2 m, when the trigger is released it goes
 back to 0

---
in order to scale, transform etc meshes, the pack must be selected
(click it once on the tree view)


Aug 5
---


bug fix:  save as would crash if your initials were much longer than the name of the object
---

Right now the bounder has an ai and a player
To drive the bounder, turn off the ai, and turn on the player


---

if you set up links between check points, you will need to remake these

to link two check points, drag the first onto the second (the order matters)
eg for :
point 0 onto point 1
point 1 onto point 2 
point 2 onto point 3 
point 3 onto point 0



Aug 3
---
standard procedure for mapping an old mod object:

select surface
set map mode to cylinder
set z to -1 0 0
set x to  0 0 1
		  
press normalize u
press normalize v

see dw_bounder0 for an example




Aug 2
---
Note:  damping is now applied to dof_30 (particles),  Make sure to set this to 0 for free
flying particles (default kd is 2)


j28
---

height fields now generate hulls on the fly.
don't forget to remove their cld reps (see below)
---
new flag for height field: b_collisions
turns on/off collisions

----
new for height field:

 remove_cld_rep

(rex)
---
These psc vars are used to tweak lods of height fields:

float lod_z_min 24     // distance offset,  between 0..24 there is little change in lod, this reduces poping)
int   lod_max    3    // max subdivions for any given patch, only reached in rare circumstances)   // min detail
float lod_gain  6000  // overall scale of the lod

subdivision for a spline edge are :
 
   curvature_along_edge / ( sqr(distance of mid point of edge to camera ) + square(lod_z_min ) )  * lod_gain 

   clamped to lod_max

   distance is not spherical, but ellipsoidal, x, y are scaled by 2 to place greated emphasis on things closer to the
   center of the screen


---


 


j27
---

new class:  rtf_weapon


The following need to be updated to support:

dw_shot_gun has been updated (saved as on rh_shot_gun_animated)

dw_drone2  has been updated (saved as rh_dron0.dwn)


Shot gun is a little flakey now b/c the recharge time is less than the animation time

---

triggers and jump have both
been converted to signals from pulses

This means that holding them down repeatedly performs the action

You will need to change:
							   
bind space jump 1

bind 1 trigger_0 1
bind 2 trigger_1 1

To:

bind_sig space jump 1

bind_sig 1 trigger_0 1
bind_sig 2 trigger_1 1

(difference based on your bindings)

---


j26
---

first pass on hover flight model

check out:  david!\levels\dw_terrain_test (courtesy of rh)

drag david!\dw_hover.dwb into you sim options 




j25
---
  
  first pass on cld_rep construction
  right click on a height field and call:  make_cld_prep
  It can take some time on large height fields

---

 ef_height_field has material_id 

---

player_height
and
player_step_height

are no longer used
instead the cld_rep of the player must have a "foot"
a "foot" is a cld_prim (should be a sphere)

that has it's "special" flag set to "fps foot"

Normal collision detection is performed
 when there is an intersection, the forces applied are player leg springs 
 rather than rigid collision reaction


See template\player.dwb for an example




---


j24
---

 when growing a height field, height, tetures, etc will be propagated to the new strip

---

 each patch has a 'tile_count' member which controls the texture scale

---
 
 fixes to shadow map generation for tiles

---

 

j23
---

New class:
  ef_height_field
  Currently these draw, but do not cast collisions


Height field/terrain object
lb is ignore, the basis of the frame in which this is located is used.
Use Add/remove strips to resize 

To modify heights:
 Turn on draw_terrain (flag on mesh_view->options)
 select the little white dots that appear
 move them around.  They can only much up and down (height)
for other motions, move the packs/frame


psc_ops:
  terrain_lod_gain (default 12), linearly scales the number of subdivisions for the
  splines.  higher values will create more subdivisions (smoother surface, more polys)


  terrain_max_dim (default 5), 
   Sets the max subdivisions for a given path
   a 5x5 subdivision of a patch yeilds 5*5*2 = 50 triangles


see david!\levels\dwterrainlevel for a sample


---

you set the extents of a level explicitly (member of g_level)
anything outside of the extents	will be destroyed
The number of rooms/sectors created is:
span_x*span_y*span_z * K, so attempt to minimize extents whenever possible.



july 22
---

bug fix:  setting mip_levels to 0 or 1 did not disable mip mapping on TNT


---

Most ai vars move from psc to l1 
All of these should have help
---
exported drone
---
must wipe rtd
---
fixed pointer conflict bug on export
---
added psc op: "reload_materials"  "Re loads materials.dat" 
---



july 21
---

new flag for mesh view:  draw_messages

this is preliminary, and while not really practical, it is kind of neat


---

Copy to clip board did not work when messages were sent outside of the packs copied

The following system is used to resolve external links:
 
 -if a message target is an object contained within the selected packs, 
   it will be re-linked to the newly created object
 -if a message target is a resource ob, it will stay bound to that ob (e.g. l1's PIE)
 -if a message target is an object in the current batch not included in the selected packs, 
  the newly created message will be directed towards the same object in the level.
  When this happens, copy will print "link NAME"

(rich)
---


packs in tree view of level/batches do not show up if their class is invisible
(there is a packs tab, that when opened will show all packs)

---

default operation for draging backs onto batches is copy 
(was move)

---

shift click for property window will place the window lower down

(rich)
---

save as now swaps dir as well as initials

(rich)
---

mouse jerkiness has be reduced
This would occur mainly at low frame rates

(dan)
---

dragging a message batch onto another will append the messages from the source to the dest

(rich)
---

exported dw_drone1
Please let me know where improvements should be made

---

new for edm_spawn:
float,recoil_mass)

Determines the effective mass of what is shot for the purpose of recoil
If this is > 0 the source of the spawn message will take an impulse of:
(spawned_object_v - source_object_v) *recoil_mass


july 18
---


you will need to del rtd

---

bug fix:  sub_target id was lost on save

---

you will need to del rtd

---

hopefully fixed first frame at full problem that sonya was experiencing
---

rtf_sprites have a new member: draw_bound_r
This is used when culling the sprite.  It should be set to the maximum possible size that they sprite will be


---

c_offset added to spawn message

---

negative impulses are filtered and do not call the tb_cld sound api

---

new flag for packs: destroy_on_impact
should be used for all shells

---


july 17
---

new exe's, must del rtd.

foot steps seem not to be played at all (for drone, player works okay)
Could be a bug on my end
also new tbapi.dll and materials.dat


(andrew)
---
messages sent to pie with sub_target_id set will be redirected to the link ob

this can be used for example to turn fire on for another barrel
(daniel)



july 16
---
The following assumptions are currenly made for walkers (subject to change)

 -feet dof's are marked as feet
 -foot dofs have their x axis aligned with the body x axis (forward)
 -and z axis pointing left (to rotate about ankle), y axis is up
 (e.g. take root dof and rotate it 90 degrees about x and you have the lb.A of the foot)
 -the cofm of the foot is approximately where the foot touches the ground
  (usually a little below the ankle rotation point)
 -the cofm of the root is fairly close to the cofm of the object
 -the root is heavy compared to the legs

---

july 16
---

messages print out their name, type and target on message_buffer_overflow
this might help in debugging

(daniel)
---
rtd must be wiped

---


sound and music names are loaded from tbapi.dll

note:  if use_sound is zero, this will not work

---
bug fix:  messages to  function



---
new psc op: (float,player_step_height,(0.65),"Max height of things that player and step onto")
note:  if player_height -  player_step_height > negative z extent of the players collision rep, you can get stuck in the ground
---
the player flag is set for the player, so the drone should attack you instead of anyone else,.

---


july 14
---
new for set_state: b_relative
(rich)
---


july 13
---


fix: export did not export packs referenced by edm_spawn bundles

---
new function:  file->"Aggressive Save All"

Saves all open objects, ignores modified flag.

Use this when save_all does not cooperate
---


july 12
---

for good time, try:  w\david!\level\dwtiger lkevel

the drone has a built in sensort that turns itself on when an object enters and off when an
object leaves

particle starts inside a sensor and immediately turns drone on
---

new func: sensor

-only extent sensor is suppored.

example is inside drone.
---

A few objects have default messages, (func's, batches, pids).
dragging these into a message batch will add the default message
(e.g. start and animation or turn on a func)

---

new funcs for packs: "select equal verts")
"select connected")
useful for added verts to dofs
Note: these functions will bridge accross duplicated verts used for surfaces

---
bug fix: export did not export message dependancies (edm_spawn)
---
reminder:  changes to Ir vary moments of inertia in a quadratic manner 
 		   small changes will have dramatic effects on the motion of the object

---
updates to sound and damge generation.
previously I used the computed accelerations based on contact force, to determine 
the threshold.  

Now I use the initial conditions (initial velocity)

the problem with the former system is that it did not take into account force cancellelation from
multiple contacts

the problem with the latter system is that it does not take into account force cancellelation from multiple contacts,
but it handles it way that seems to work better.

(e.g. __max(a,b,c) rather than |a|+|b|+|c|/3 )

---


july 8
---

Tips for setting stable and accurage moments of inertia:


Ir should be max(0.4,distance of vert farthest from cofm )




cofm close to volume centroid of cld rep


requests on crate:

Ir to .5 .5 .5
cofm up 0.0625

some of the debris has Ir that is a little large 
too large Ir leads to large angular momemtum and slow wobbling.
too small Ir leads vibration, shaking, and never resting


too large  similar to cannibis
too small similar to methamphetamine sulphate



---


psc scriping in.  
See war.psc for a sample implementation

not thoroughly tested

---
fog functionality/hack is in.
set the far_z for the level, this is where fog will be at 100%
set the fog color.
check use_fog.
---
new tbapi is in

---

july 8
---

new function:  remove usessless dofs
using all the remove *.* functions can significantly improve preformance on some models.

(Rich)
---
you can now remove dofs that have motions attached without destroying the motion (keyframes for those frames will be
removed, but in certain cases they are unnessary anyway) (e.g. superman)

(rich)
---

bug fix: help was broken

(daniel)
---

previously the player and dof_30 (particles) had 0 friction
this has been removed.  You can emulate the behaviour using a material with 0 friction
---
Certain prims would not draw 
such as the cld rep
del rtd to fix this;.

(Daniel)
---

on packs you can select:  "dofs"
and "cld_rep"
to see a number of common members together
---

july 7
---

pack->remove_unused surfaces removes unused surfaces (good idea)
---
you can remove a tree of dofs by rick clicking "remove tree"

---
export exports edm_spawn bundles
---
edm_play_sound switched to a number
---

frames can accept an edm_play_sound message (playback is at cofm of frame)
---
message baches have a right click "empty" function to remove all messages
---
animation can "load motion cues"

- procedure:  place "soundmotioncues.txt" in your mod dir. (from s\w\)
- edit file as necessary
- click on each animation and call load motion cues
- take a break and a shot of rye

editing the file:

  - frame names may need to be changed ("I used frm-lankle")
  - motion names need to be changed (I used 1-115,.. etc )


(rich, andrew)

---
new message for packs:  edm_set_state (position, velocity)
---

camera roll tightened
---
l1 messages can exist between objects in a pack if the following conditions hold:

the message is in any l1 member of the pack (func, frame, etc)
the target of the message is a func, dof or pack in the pack
the dispatcher of the message is a func, dof or pack in the pack
(most l1 message batches are dispatched by the l0)

An example of this is:

edm_command sent to pack on complete messages of an animation
edm_command sent to an animation on complete messages of an animation


---

bug fix: decay works for fixed objects

---

bug fix:  l0 's would occasionally print their pack name as l1_[class]


---
new message:  edm_move_camera

drag this from pie to host startup messages
set its name to intro_pi
copy intro_pi.pi into your mod dir
click "load"

success!  go get a coffee and a kit kat - you deserve it.


(rich)
---
new func: ef_sound

plays a looping sound

(andrew)
---

- added a check for closed loop finding in signals

A signal should not directly or indirectly reference itself.
eg. a signal of id 0 should not reference pack 0
eg. a signal of id 1 should not reference pack 1

(daniel)
---
new func:  ef_timer

(daniel)
---
import testing:
1-115 : okay
115-230: not okay
230-300: okay
300-380: okay (looks like 1-115)
380 550: okay
655 810: maybe okay
810 820: looks like 1-115

please see dwmsbed.dwl on david\levels for an example

most .txt files are not vald.

Motion names must be surrounded by quotes eg."run"
Motion ranges must map to frame ranges. 
 e.g. in 890 920 , the motion frame go from 1 .. 100 or so

deleting them solves the problem.



---


july 6
---

when search for frames, animations will do partial name searches

(rich,mikeo)
---

Remeber to zero_all_dofs before transferring anyting from one pack to another

(rich,mikeo)
---
bug fix: ref ptr.h assertion on select vert

---
bug fix: collision damage_scale not always applied

(rich)
---
when dragging packs onto packs you can use "replace surfaces"

(rich)
---
threshold distances for vert combine reduced

(rich,sonya)
---



july 5
---

New toggle for packs:

collision mode:
"normal", "none", "particle"

normal collides with normal and particle
particle collides only with normal

(rich)
---

collision speed sound threshold decreased to 1.0m/s (was 3 m/s)

(andrew)
---

Resolutions that do not have square pixels (e.g. 1280x1024 and 640x400) did not do mouse selection properly
Just about every other supported resolution is okay.  (y_res/x_res should be 0.75)
I could caution against these resolutions as they distort the way in which images appear

(everything is wider than it should be)
---

new command:  view->watch_selected
watches the point at the average of all selected verts and objects

hot_keys.dat on S:\w\ has this command linked to a tool bar bottom

---
packs have l0_destroyed_messages and l1_destoyed_messages
they are both dispatched on destruction

l1's should be used whenever the messages are shared.

(rich)
---
dm subdir copied form s on init, this prevents the crash

(andrew, rich)
---
edm_play sound can now play 2d, 3d or music

(rich, andrew)
---

The follow material collision sound ids are valid:

  material_cobbles	= 4,

  material_barrel = 6,
  material_crate = 1,


---

bug fix on cld_hull
---

- improvements to collision system for fast moving objects
- new prims:

Ellipse
Cone.

Note:  something seems to be wrong with the current cone,.   I am not entirely sure what it is


---

july 3
---
					   
Prelimary scalar signal spec:

Various parameters can be assigned signals.

You will see too settings for a signal e.g:
scale.v  [ 1.0	]
scale.id [ none	]

The V term is used if id = none, other wise the signal identified by id is used

The following signals are implemented:

"one"             v = 1
"pack_speed"	  v = speed of pack in m/s
"pack_life"       v = life of pack (1 == full, 0 == gone), 
					  packs with a "life time" set linearly loose life until they reach 0, 
					  then they are destroyed
					  Particles with add fill mode might hook this to their brightness signal
					  The brightness of the particle will linearly decay until the pack is gone.\

"pack_0..pack_7"  v = ef_signal(id)->read()
					  The pack is searched for a signal with the appropriate id, this functional 
					  provides the input

---
new class: ef_signal


 This is currenly a periodic
 I will later add support for envelopes and splines.


 Algorithm to compute value:

 float t = t.read() * frequency + offset;
 // wrap to 0..1 range.
 wrap( t, 0 .. 1 )
 
 float scale =  >scale.read();


 switch(function)
 {
  case flat : 
  {
   return t < 0.5f ? v0 * scale : v1*scale;
  }
  case linear : 
  {
   return  scale*(v0  + (v1-v0)*t);
  }
  case sin : 
  {
   return  scale * 0.5f *( (v0 + v1) +  (v1-v0)*fsin( t  * __2_pi_f ) );
  }
  case triangle : 
  {
   return  scale*(v1 + ffabs( t*2.0f- 1.f ) * (v0 - v1) );
  };
  default :
  {
   __assume(0);
  };
 };

---

structure points normalized to 1  == max

Objects by default, should always have <= 1 structure point
< 1 is for damaged.
> 1 is only for special occasions (such as power ups)

Make objects harder/easier to destroy by using a material
 

collision_impulse_to_structure_points_scale decreased to 1/16k 

---
Collision reps now have collision_messages
These are good for:

 - edm_apply_damage	 (not implemented)
 - hit effect spawn
  
---

collision_impulse_to_structure_points_scale decreased to 1/2k (from 1/256)

---
New class:  ef_sprite

Supports much of the functionality of the legacy ede_particles.

To set its texture, you can drag an existing mod2k texture into it 
or you can drag an image file from windows. 
 
Note:  image files that alias batches and levels cannot be dragged onto a texture pointer.

A sample sprite is now used in dw_particle_test
This will be apparent if you use the dw_shot_gun

---	 

Event handers:

- new class ef_event_handler
- multiple globally defined events
- ef_event_handlers register themselves to catch certain event, on these events they dispatch their messages
- there will likely be 1 or 2 global event handles packs that are used in all levels
- dw_event_handler is a sample that catches all damage events and prints "damage!! to the log
- a more sophisticated behaviour will be created by designers/artists/andrew to create such things as particles and sounds
- the following are currently supported:
  damage_xxx
  destroyed_xxx

---
new message:
 edm_play_sound
  supported by:  
    PIE
	ed_func	(supplys position)

dw_shot_gun makes shot_gun sounds again(!)
---
bug fix: merge textures would occasionally duplicate textures
---
You can now drag surfaces from one pack to another.
rigth click dragging a pack onto another allow you to "append surfaces" which copies each surface 1 by one
When you are done, remember to remove the source surface and unused verts

Update procedure:
  
  
  0 Import new object
  1 load old object
  2 zero dofs on the old object
  3 right click drag the new ob onto the old, selected "append surfaces"
  4 go get some coffee while the operation executes
  5	remove old surfaces surfaces
  6 remove unused verts
  7 save and get out before it crashes


---


july 2
---
copy to selected works again
---
gravity scale for packs now
---
message->enum_sources works again
---
show messages_to works again
---
writing to a message will set any object referencing the message to modified
---

Factory/Spawn Spec 0.0:

	ef_factory is obsolete (bet you didn't even get a chance to try it out)

	objects are created using the edm_spawn message
	an edm_spawn sent by a timer is equivalent to the previous ef_factory

Tip:  you can drag a batch into a message list and it will create a default edm_spawn

The dw_shot_gun now uses an edm_spawn message dispached from the start_messages of the
shoot motion

---

july1 
---
alpha works on shadow maps
---
near z clip is at 1/16 m.  Let me know if this is a problem for the shot gun.						 
---
set_switch(off) can be sent to packs to turn them off
---
You can copy cld reps and between packs (or drag onto same pack to make a copy)
---
preliminary damage system:

Many principles (damage calculation) same as for gladiator

Changes (will be improved in future)

- each pack has 1 structure point.   You can set the health of an object with the "structure points" l0 data member of
ed_pack

- Each cld_prim has a material
- The impulse to structure point scale is 256 Newton Seconds = 1 structure point (was 16k in gladiator)

---



jun 30
---
tbapi update
---
vrml export for batches (levels) 
right click and export
name.wrl should be in root
---
vrml .wrl import 
- not robust, only tested on mod created exports
- use .x for importation, .wrl for importing old mod objects and groups
---


jun 28
---

rtm_command now has complete messages
These are only used for commands that take time to complete

if start_animation is sent, success or failure messages are dispatched immediately 
 (depending on whether or not animation could be started)
 complete messages are then dispatched when the playback is done

 (if the messages was not interrupted)

----

new psc ops:
player_name
level_name


jun 28
---

Packs can "add vert"
---
verts can be deleted (delete key)
---



jun 25
---


This is what I did to set up an animation playback test bed:


[ setting up shot gun ]
 
  import shot_gun_animation.x
  move cofm down, the right and foward a little (writting offsets to the root dof lb.c )
  save()
  write_rt_batch()
  export()


  shot_gun_animation.x comes with  shot_gun_animation.txt which
  describes the animations encoded in the one playback
  1 ef_key_frame is created for each animation
  each ef_key_frame is given a sequential sub_target_id, starting at "motion 0"
  So shoot has sub_target_id == "motion 0"
     reload has sub_target_id == "motion 1"


[ setting up level ]

- add these lines to controls.psc
  bind 1 trigger_0 1
  bind 2 trigger_1 1

- new level
- click menu->view->PIe Messages
- drag text message into host startup messages
- set text to "give_player_weapon "dw_shot_gun""
- set output_id to console

sim options->do_player sim (true)

start sim

Player will have shot gun on start.  
pressing 1 will trigger shoot animation
pressing 2 will trigger reload animation


rtf_player sends a rtm_command with a sub_target of "motion 0" to the weapon pack when trigger 0 is pressed
this message is redirected to the rtf_key_frame with the "motion 0"  sub_target_id

rtf_player sends a rtm_command with a sub_target of "motion 1" to the weapon pack when trigger 1 is pressed



---
New .psc function

give_player_weapon "weapon"

e.g.
 
 give_player_weapon "dw_shot_gun"
 
 [loads rtd\dw_shot_gun.drb and gives to player]


This is a hack

---
mouse binding fixed

You can invert mouse pitch with

bind_sig mouse_y pitch -1
---

Help on edf_key_frame:


Key frame animation:
 Provides kinematic input for animations
 
 edf_key_frame stores a number of animations
 each with motion curves for each frame that it controls

 motions are started/stopped with edm_command message
 
 do not use edm_set_switch


Messaging:

  edm_command 
  
    animation_id = msg->process_id
    priority = msg->priority;

    if( msg->command == start )
    {
     if( there is a motion playing back )
     {
       if( current_motion->priority <= priority )
        {
         current motion continues
         msg->failure_messages is dispatched 
         return;
        }
        else
        {
          current_motion is terminated
          current_motion->failure_messages is dispatched 
        }
     }

     animation_id is started
     
     when animation is complete, and it was not cancelled,
     sucess_messages are dispatched
    }
    else if( msg->command == stop )
    {
     if( there is a motion playing back )
     {
       if( current_motion->priority <= priority )
        {
         current motion continues
         msg->failure_messages is dispatched 
         return;
        }
        else
        {
          current_motion is terminated
          current_motion->failure_messages is dispatched 
        }
     }
     msg->success_messages is dispatched

    }
    else if( msg->command == query )
    {
     if( there is a motion playing back )
     {
      msg->success_messages is dispatched
     }
     else
     {
      msg->failure_messages is dispatched
     }
    } 
  // end edm_command

---

jun 24
---

you can set the fov with "fov 0.5" in the .psc or console.

0.5  is 90 degrees
1.0  is 45 degrees
0.25 is 126 degrees 
...
---


---
	  



june 22
---


shot gun will show up in the player view.
I am note completely pleased with the current implementation, but it is okay to prototype 
art (and animations soon)

---
reminder:  If your level is dark during, drag in david!\template\editor_lights.dwb  

This is a dir light that should light everything
---
currently, dof_02 is unstable.  It does not conserve energy

---

fa.ini is now obsolete
instead you will need:
mod2k.psc
controls.psc 
(templates are in \\shared\\W)


basic format:
- 1 command per line
- comments are removed
- case sensitive, just about everything is lower case

Commands:

- value assignment

   [variable] [value]
   e.g.  jump_acc 4.5

- function call

   [function] [argument]  (argument is not always required)
    e.g.  toggle_full_screen 
		  set_physics_rate 30

(value assignments and function calls are idential internally, function is set_value() )
       

- bind function or value assignment 
   
   bind [key]   [variable] [value]
   or
   bind [key]+[key]  [variable] [value]
   or
   bind [key]-[key]  [variable] [value]
 
 [key]       function will be triggered when the key is pressed
 [key]+[key1] function will be triggered when the key is pressed and [key1] is down
 [key]-[key1] function will be triggered when the key is pressed and [key1] is up

   e.g. bind space jump 1


        bind space+shift jump 1

- bind signal

    bind_sig [key] [signal] [scale]
   or 
    bind_sig [key]+[key] [signal] [scale]
   or 
    bind_sig [key]-[key] [signal] [scale]
    

   bind_sig up_arrow        thrust  +1
   bind_sig up_arrow+shift  thrust  -1

---




june 21
---
new funcions:

 pack->combine_equal_verts
   combines verts with the same position, uv and dof

 surface->break_up
   breaks up a surface into a number of surfaces
    each sub surfaces is created by computing the connected set of faces and verts.
	if the surface is completely connected it will not be borken up
	if it is disjoint it will.


On all buildings use: 
   combine equal verts
if the building has shadow map errors, select the apropriate surfaces and call break_up



---


june 20
---
In the last update, config was initialized to set all pack classes as hidden
This has been fixed


---
functionality update:

  added a new class owned by textures that allow different textures to share the same image file
  added function to pack: remove duplicate textures 

  without these the tripod rtd is 25 meg

---
you will need to remove certain lines from fa.ini dealing with sound 

sound_freq 22050
sound_write_lead 100
b_disable_dsound_3d 1

---
Footsteps and jump sounds thanks to the new and ultra fast programmer Andrew;

You will need TBAPI.dll	in your mod dir.

---



june 19
---
Tab-4 then Tab-5 to get visible poly count works again.
This does not include polys for multitexture prims, and it
does not include backfacing or culled polys.]

---

fa.ini has been updated.  There are a few fps related parameters at the bottom that you can muck
around with



---

mouse look and strafe first pass
current keys:
  up arrow -> forward
  down arrow -> back
  shift -> toggle strafe (for left, right keys)
  , -> strafe left
  . -> strafe right
  left arrow -> turn left / strafe
  right arrow -> turn right / strafe

  space -> jump
  c -> crouch
  mouse -> look about

---
new func:  ef_spawn_point 

just like ef_start_position.

You can draw david\batches\dwStartPoint.dwb into your level

---
---




june 14
---
use  file->update_rt if your spheres, cones, cubes are not showing 
(must restart mod to see effects)
---
animation playback is temporarily broken

---
fps_player is  temporarily broken
---
fps_player is fixed
---
export exports textures if they are newer than the version on shared.
---




june 13
----
if mod crashes when you open, del your rtd dir.
if it still crashes come and yell at me.
---
 


june 10

New for Pack:

Class

The class of the class is used primarily to facilitate edit operations
and organize packs.
Each class can be toggled to hidden or visible, and can be disabled or enabled as 
a mouse target.
(e.g. most of the time you do not want to drag road sections.


Nifty new buttons and sliders to facilitate moving objects






mod2k is rtm  :o

- Please get latest fa.ini and hot_keys.data

- Various changes to undo sytem

- surface limit bug fix.

- sim_options->shadow map only and texture_map_only fixed.

It’s extremely rare to come across such detailed information such as this, and it’s really great insight into the development of this game.

In this archive, I’ve effectively uncovered all aspects of the game, .PSC files are plain-text Pseudo Interactive Script files (… which can be edited!) and BTE files appear to be track/level/mesh data and .PSM files are textures.

pitaDebug 1
simVerbose 1
//dxDrawShadow 1
nukeAis 1
use_sound 0  // disable for no sound
drawHullFaceAlpha 128
useMouse 0
disable_reload 1
dsUseAdpcm 1
//doIntroSequence 0
isSuperUser 1
shared "s:\w2"  
//shared "s:\dev\gangbusters" 
//enableSurfaceBreakup 1
drawAiPaths 0
drawOtherPaths 0
drawRoadPaths 0

dxPreCompressTextures 1
ModFileNameVerbose 0
fpuVerbose 1
cameraVerbose 1
dxDrawSilo 0
dxDrawShadow 0
bind delete view_left 0
bind pgup  view_right 0
bind insert view_distance 0
//carVerbose 1
//toonVerbose 1
bind t toggleWatch 0
bind e toggleAi 0
//carVerbose 1

Before moving on I decided to implement my findings with the archive format, and now you can fully extract and create your own “SMALLF” archive files… and better yet, this doesn’t just apply to this game..

Debug!

I decided to look into Cel Damage, just to see if there were any correlations at all, and to my surprise, I was able to find almost the exact same structure!

Amazingly, after this many years, we can actually enable full debug menu functionality, hidden away within Cel Damage for PS2 – and using the exact same method discussed earlier!

And, as if that wasn’t enough, the exact same archives are used in Cel Damage!

An interesting point is that the debug menu for Cel Damage says compiled on Jan 25 2003… but Cel Damage was released in December 2002. This implies that the developers found a bug or perhaps wanted to change something after the initial versions of the game were released.

Conclusion

The Vectorman builds opened the doors to a lot of new information, detailed debug menus locked away in multiple titles & builds, and ultimately modding support, through the tools created during the initial analysis and research undertaken so far.

The Pseudo Engine appears to be a highly competent engine with a deep emphasis on physics simulation, complete with its own custom scripting language and memory-optimised asset management systems. Overall, what the team was able to achieve is impressive, especially for the time and my respect goes to the developers who worked on these games, and above all, to David Wu, who died tragically as a result of an unexpected diabetic shock. Cel Damage shown a great application of his works and despite Vectorman never releasing, it’s nice to imagine what could have been, especially with how complex their engine was.