Voice acting, sound editing, etc.
-
- Elite
- Posts: 7243
- Joined: Mon Apr 18, 2005 2:40 pm
- Location: LS87, Buenos Aires, República Argentina
-
- Elite
- Posts: 8014
- Joined: Fri Sep 05, 2003 4:03 am
- Location: Montreal
- Contact:
I'm using inches for the four input parameters. From holo.h,
The derivative quantities are non-units specific. From holo.cpp,
In the end I'm switching to meters, also in holo.cpp
So, super easy to change if need be.
Code: Select all
//Constant assumptions ;-):
//dimensions in inches unless otherwise noted
#define distance_between_ears 6.0
#define distance_from_monitor 25.0
#define width_of_the_monitor 18.0
#define width_of_a_speaker 4.0
Code: Select all
//computed constants:
#define distance_between_speakers ((width_of_the_monitor+width_of_a_speaker))
#define speaker_overwidth ((distance_between_speakers-distance_between_ears))
#define same_side_lateral ((0.5*speaker_overwidth))
#define cross_side_lateral ((same_side_lateral+distance_between_ears))
#define square_of(x) ((((x))*((x))))
#define same_side_distsqr \
((square_of(same_side_lateral)+square_of(distance_from_monitor)))
#define cross_side_distsqr \
((square_of(cross_side_lateral)+square_of(distance_from_monitor)))
#define nominal_atenuation ((same_side_distsqr/cross_side_distsqr))
#define same_side_dist ((sqrt(same_side_distsqr)))
#define cross_side_dist ((sqrt(cross_side_distsqr)))
#define distance_diff ((cross_side_dist-same_side_dist))
Code: Select all
//here we switch to meters
#define d_diff_m ((distance_diff*0.0254))
#define speed_of_sound 332.0
#define time_diff_s ((d_diff_m/speed_of_sound))
static const double time_diff_seconds = time_diff_s;
static const double atenuation_factor = nominal_atenuation;
Latest version of Cinemut Opaque
Latest version of LaGrande noodleworks (scroll down).
An evolving La Grande How-To...
The non-working, but latest, CineMut test_bike
PU (Privateer: Parallel Universe's Home). WC or Privateer Drayman for you?
WCpedia --The Wing Commander Encyclopedia-- From Angel Deveraux through Belisarius to Zachary Banfeld...
WC Nexus forum, the Moonbase Tycho of WC fans.
Latest version of LaGrande noodleworks (scroll down).
An evolving La Grande How-To...
The non-working, but latest, CineMut test_bike
PU (Privateer: Parallel Universe's Home). WC or Privateer Drayman for you?
WCpedia --The Wing Commander Encyclopedia-- From Angel Deveraux through Belisarius to Zachary Banfeld...
WC Nexus forum, the Moonbase Tycho of WC fans.
-
- Elite
- Posts: 8014
- Joined: Fri Sep 05, 2003 4:03 am
- Location: Montreal
- Contact:
Ok, klauss, here's the reflections code, for dashboard mounted switches, buttons, beeps and clicks. Only HUD and window reflections are modeled.
There's a way to specify a flat window model, such as for a Tarsus, and a bubble-top, round dome accoustic type such as for the Centurion.
I haven't tried compiling this yet...
Example:
cockpit_dash cd_Tarsus(30.0,11.0,0.5,9.0,72.0,0.0);
cockpit_dash cd_Centur(25,0,13.0,1.0,0.0,0.0,22.0);
There's a way to specify a flat window model, such as for a Tarsus, and a bubble-top, round dome accoustic type such as for the Centurion.
I haven't tried compiling this yet...
Code: Select all
#ifndef _DASH_H_
#define _DASH_H_
//Constant assumptions ;-):
//dimensions in inches unless otherwise noted
#define dist_between_ears (6.0)
#define meters_per_inch (0.0254)
#define speed_o_sound (332.0)
#define bubble_top_amplification (3.0)
#define sqr(x) ((((x))*((x))))
//note: bubble top is when a round glass bubble cockpit is used, and "amplification" denotes
//the fact that the round top reflects waves re-concentrating them; so, the amplification is
//a number to experiment with; might need to be higher, to really sound like a round, hollow
//chamber.
//key_xy is the structure used for input. It places the key on the dashboard. The idea is to
//have one sound for momentary pushbuttons, a pair of sounds for toggle switches on and off
//and to reuse these sounds for momentary and toggle functions, then to place them on the
//dashboard in x and y, so as to more or less track the key bindings on the keyboard. The view
//function keys may need the recording of one of those types of buttons that cause neighboring
//buttons to be released, such as the speed buttons on many kitchen blenders. Then place them
//across the top row: Say F1 at -5,3; F2 at -4,3; and so on.
struct key_xy //x,y pos of a key on dash (inches)
{
double x_;
double y_;
key_xy() : x_(0.0), y_(0.0) {}
key_xy( double x, double y ) : x_(x), y_(y) {}
};
//reflections is the struct used as output. Direct are the direct path to the ears from the
//switch sound on the dashboard. At least one of direct_left- or -right_ear_time will be
//returned as 0.0, as the first sound to arrive is not treated as a reflection. Both the
//direct and HUD-reflected waves for each ear are low-pass-filtered if they come at an
//angle such that waves must curve around the cheek-bone. Secondary reflections are the side
//window or bubble-top reflections. Bubble-top reflections are amplified but very low-pass-
//-filtered.
struct reflections // times in seconds, amplitudes are multiplying
// factors referenced to a sound coming from a key at (0,0) on dash
{
double direct_left_ear_time;
double direct_left_ear_ampl;
double direct_rite_ear_time;
double direct_rite_ear_ampl;
double hud_refl_left_ear_time;
double hud_refl_left_ear_ampl;
double hud_refl_rite_ear_time;
double hud_refl_rite_ear_ampl;
double dir_and_hud_left_lpfreq;
double dir_and_hud_rite_lpfreq;
double secondrfl_left_ear_time;
double secondrfl_left_ear_ampl;
double secondrfl_left_ear_lpfreq;
double secondrfl_rite_ear_time;
double secondrfl_rite_ear_ampl;
double secondrfl_rite_ear_lpfreq;
reflections(){ memfill(this,0,sizeof(reflections); }
};
//instantiate this class for each cockpit model. Give the left and right
//windows a distance of zero to select bubble dome cockpit model. Give a
//bubble top radius of zero to select left and right flat windows instead.
//If flat windows are used, the roof is considered absorbent.
//Might be good to give HUD reflections a high-pass-filter corner of say
//500 to 700 Hz to make it sound like it's thin, like a thick mylar material.
//"process_new_key_pos(x,y)" is the input function. The output function is
//"presults()", which returns a pointer to a "reflections" struct. Enjoy.
class cockpit_dash
{
//all distances in inches, angles in radians
double forward_dist_to_hud;
double vert_dist_hud_to_dash;
double dashboard_angle;
double dist_to_right_window;
double dist_to_left_window;
double bubble_top_radius;
key_xy const * mutable pkey_xy;
reflections * mutable presult;
mutable double key_x;
mutable double key_y;
public:
cockpit_dash
(
double fd2hud,
double vd2dash,
double dashang,
double d2rwind,
double d2lwind,
double bubtrad
)
: forward_dist_to_hud( fd2hud )
, vert_dist_hud_to_dash( vd2dash )
, dashboard_angle( dashang )
, dist_to_right_window( d2rwind )
, dist_to_left_window( d2lwind )
, bubble_top_radius( bubtrad )
, pkey_xy(0)
, presult(0)
{}
~cockpit_dash()
{
delete pkey_xy; pkey_xy = 0;
delete presult; presult = 0;
}
private:
cockpit_dash();
public:
void process_new_key_pos( double x, double y ) const
{
delete pkey_xy; pkey_xy = 0;
pkey_xy = new key_xy( x, y );
delete presult; presult = 0;
presult = new reflections();
recompute_reflections();
}
reflections * presults() const { return presult; }
private:
//common private functions:
double reference_distance_to_dash() const
{
return sqrt( sqr(forward_dist_to_hud) + sqr(vert_dist_hud_to_dash) );
}
double fwd_key_offset() const
{
assert( pkey_xy );
return pkey_xy->y_ * cos( dashboard_angle );
}
double vert_key_offset() const
{
assert( pkey_xy );
return pkey_xy->y_ * sin( dashboard_angle );
}
double side_view_horiz_dist_to_key() const
{
return forward_dist_to_hud + fwd_key_offset();
}
double side_view_vert_dist_to_key() const
{
return vert_dist_hud_to_dash - vert_key_offset();
}
double lateral_left_ear_dist_to_key_sqr() const
{
assert( pkey_xy );
return sqr( pkey_xy->x_ + ( 0.5 * dist_between_ears ) );
}
double lateral_rite_ear_dist_to_key_sqr() const
{
assert( pkey_xy );
return sqr( pkey_xy->x_ - ( 0.5 * dist_between_ears ) );
}
static double time( double inches ){ return (0.0254/332.0)*inches; } //seconds
//DIRECT path:
double side_view_diagonal_dist_to_key() const
{
return sqrt(
sqr( side_view_horiz_dist_to_key() ) +
sqr( side_view_vert_dist_to_key() ) );
}
double left_ear_dist_to_key() const
{
return sqrt( lateral_left_ear_dist_to_key_sqr()
+ sqr( side_view_diagonal_dist_to_key() );
}
double rite_ear_dist_to_key() const
{
return sqrt( lateral_rite_ear_dist_to_key_sqr()
+ sqr( side_view_diagonal_dist_to_key() );
}
//HUD reflection:
double side_view_hud_refl_dist_to_key() const
{
return side_view_horiz_dist_to_key() + side_view_vert_dist_to_key();
}
double left_ear_hud_reflect_dist() const
{
return sqrt( lateral_left_ear_dist_to_key_sqr()
+ sqr( side_view_hud_refl_dist_to_key() );
}
double rite_ear_hud_reflect_dist() const
{
return sqrt( lateral_left_ear_dist_to_key_sqr()
+ sqr( side_view_hud_refl_dist_to_key() );
}
//DIRECT & HUD low-pass frequency corner
double dir_and_hud_left_lpf() const
{
if( pkey_xy->x_ > 1.0 )
{
return 20000.0 - 1000 * (pkey_xy->x_ - 1.0);
}
else
{
return 20000.0
}
}
double dir_and_hud_rite_lpf() const
{
if( pkey_xy->x_ < -1.0 )
{
return 20000.0 - 1000 * (-pkey_xy->x_ + 1.0);
}
else
{
return 20000.0
}
}
//LEFT-window:
double lateral_left_ear_dist_to_window() const
{
return dist_to_left_window - ( 0.5 * dist_between_ears );
}
double lateral_left_key_dist_to_window() const
{
return dist_to_left_window + pkey_xy->x_;
}
double lateral_left_window_reflect_dist() const
{
return lateral_left_key_dist_to_window() + lateral_left_ear_dist_to_window();
}
double left_window_reflect_dist() const
{
return sqrt(
sqr( lateral_left_window_reflect_dist() +
sqr( side_view_diagonal_dist_to_key() );
}
//RITE-window:
double lateral_rite_ear_dist_to_window() const
{
return dist_to_rite_window - ( 0.5 * dist_between_ears );
}
double lateral_rite_key_dist_to_window() const
{
return dist_to_rite_window - pkey_xy->x_;
}
double lateral_rite_window_reflect_dist() const
{
return lateral_rite_key_dist_to_window() + lateral_rite_ear_dist_to_window();
}
double rite_window_reflect_dist() const
{
return sqrt(
sqr( lateral_left_window_reflect_dist() +
sqr( side_view_diagonal_dist_to_key() );
}
//BUBBLE-top reflections:
double lateral_ear_dist_to_bubble() const
{
return bubble_top_radius - ( 0.5 * dist_between_ears );
}
double lateral_left_key_dist_to_bubble() const
{
return bubble_top_radius + pkey_xy->x_;
}
double lateral_left_bubble_reflect_dist() const
{
return lateral_ear_dist_to_bubble() + lateral_left_key_dist_to_bubble();
}
double lateral_rite_key_dist_to_bubble() const
{
return bubble_top_radius - pkey_xy->x_;
}
double lateral_rite_bubble_reflect_dist() const
{
return lateral_ear_dist_to_bubble() + lateral_rite_key_dist_to_bubble();
}
double left_bubble_reflect_dist() const
{
return sqrt(
sqr( lateral_left_bubble_reflect_dist() +
sqr( side_view_diagonal_dist_to_key() );
}
double rite_bubble_reflect_dist() const
{
return sqrt(
sqr( lateral_rite_bubble_reflect_dist() +
sqr( side_view_diagonal_dist_to_key() );
}
double left_ear_horizontal_misalignment_sqr() const
{
return sqr( pkey_xy->x_ - ( 0.5 * dist_between_ears ) );
}
double rite_ear_horizontal_misalignment_sqr() const
{
return sqr( pkey_xy->x_ + ( 0.5 * dist_between_ears ) );
}
double vert_misalignment_sqr() const
{
return sqr( 0.5 * side_view_vert_dist_to_key() );
}
double left_ear_misalignment_sqr() const
{
return left_ear_horizontal_misalignment_sqr() + vert_misalignment_sqr();
}
double rite_ear_misalignment_sqr() const
{
return rite_ear_horizontal_misalignment_sqr() + vert_misalignment_sqr();
}
void recompute_reflections() const
{
assert( presult );
presult->direct_left_ear_time = time( left_ear_dist_to_key() );
presult->direct_left_ear_ampl = sqr( reference_dist_to_dash() / left_ear_dist_to_key() );
presult->direct_rite_ear_time = time( rite_ear_dist_to_key() );
presult->direct_rite_ear_ampl = sqr( reference_dist_to_dash() / rite_ear_dist_to_key() );
presult->hud_refl_left_ear_time = time( left_ear_hud_reflect_dist() );
presult->hud_refl_left_ear_ampl = sqr( reference_dist_to_dash() / left_ear_hud_reflect_dist() );
presult->hud_refl_rite_ear_time = time( rite_ear_hud_reflect_dist() );
presult->hud_refl_rite_ear_ampl = sqr( reference_dist_to_dash() / rite_ear_hud_reflect_dist() );
presult->dir_and_hud_left_lpfreq = dir_and_hud_left_lpf();
presult->dir_and_hud_rite_lpfreq = dir_and_hud_rite_lpf();
if( bubble_top_radius < dist_to_right_window + dist_to_left_window )
{
//side-windows it is
presult->secondrfl_left_ear_time = time( left_window_reflect_dist() );
presult->secondrfl_left_ear_ampl = sqr( reference_dist_to_dash() / left_window_reflect_dist() );
presult->secondrfl_left_ear_lpfreq = 20000.0;
presult->secondrfl_rite_ear_time = time( rite_window_reflect_dist() );
presult->secondrfl_rite_ear_ampl = sqr( reference_dist_to_dash() / rite_window_reflect_dist() );
presult->secondrfl_rite_ear_lpfreq = 20000.0;
}
else
{
//bubble-top it is
presult->secondrfl_left_ear_time = time( left_bubble_reflect_dist() );
presult->secondrfl_left_ear_ampl = bubble_top_amplification * sqr( reference_dist_to_dash() / left_bubble_reflect_dist() );
presult->secondrfl_left_ear_lpfreq = 20000.0 / left_ear_misalignment_sqr();
presult->secondrfl_rite_ear_time = time( rite_bubble_reflect_dist() );
presult->secondrfl_rite_ear_ampl = bubble_top_amplification * sqr( reference_dist_to_dash() / rite_bubble_reflect_dist() );
presult->secondrfl_rite_ear_lpfreq = 20000.0 / rite_ear_misalignment_sqr();
}
//now reduce all times by the lowest time:
double smallest_time;
if( presult->direct_left_ear_time < presult->direct_rite_ear_time )
{
smallest_time = presult->direct_left_ear_time;
presult->direct_left_ear_time = 0.0;
presult->direct_rite_ear_time -= smallest_time;
}
else if( presult->direct_rite_ear_time < presult->direct_left_ear_time )
{
smallest_time = presult->direct_rite_ear_time;
presult->direct_rite_ear_time = 0.0;
presult->direct_left_ear_time -= smallest_time;
}
else
{
smallest_time = presult->direct_left_ear_time;
presult->direct_left_ear_time = 0.0;
presult->direct_rite_ear_time = 0.0;
}
presult->hud_refl_left_ear_time -= smallest_time;
presult->hud_refl_rite_ear_time -= smallest_time;
presult->secondrfl_left_ear_time -= smallest_time;
presult->secondrfl_rite_ear_time -= smallest_time;
};
#include <vector>
typedef struct
{
float left;
float rite;
//I know how to spell "right"!...
//I just like them to line-up, ok? Sheesh! ;-)
} sample;
typedef std::vector<sample> sv_t;
typedef std::vector<sample>::iterator svi_t;
sv_t *add_reflections
(
sv_t & vs,
double const & sampling_rate_Hz,
double const & level
);
#endif
cockpit_dash cd_Tarsus(30.0,11.0,0.5,9.0,72.0,0.0);
cockpit_dash cd_Centur(25,0,13.0,1.0,0.0,0.0,22.0);
Latest version of Cinemut Opaque
Latest version of LaGrande noodleworks (scroll down).
An evolving La Grande How-To...
The non-working, but latest, CineMut test_bike
PU (Privateer: Parallel Universe's Home). WC or Privateer Drayman for you?
WCpedia --The Wing Commander Encyclopedia-- From Angel Deveraux through Belisarius to Zachary Banfeld...
WC Nexus forum, the Moonbase Tycho of WC fans.
Latest version of LaGrande noodleworks (scroll down).
An evolving La Grande How-To...
The non-working, but latest, CineMut test_bike
PU (Privateer: Parallel Universe's Home). WC or Privateer Drayman for you?
WCpedia --The Wing Commander Encyclopedia-- From Angel Deveraux through Belisarius to Zachary Banfeld...
WC Nexus forum, the Moonbase Tycho of WC fans.
-
- Elite
- Posts: 7243
- Joined: Mon Apr 18, 2005 2:40 pm
- Location: LS87, Buenos Aires, República Argentina
-
- Elite
- Posts: 8014
- Joined: Fri Sep 05, 2003 4:03 am
- Location: Montreal
- Contact:
At your convenience. All reflections are single, which means, I believe, that all their signs should be negative; but you're the expert.
Latest version of Cinemut Opaque
Latest version of LaGrande noodleworks (scroll down).
An evolving La Grande How-To...
The non-working, but latest, CineMut test_bike
PU (Privateer: Parallel Universe's Home). WC or Privateer Drayman for you?
WCpedia --The Wing Commander Encyclopedia-- From Angel Deveraux through Belisarius to Zachary Banfeld...
WC Nexus forum, the Moonbase Tycho of WC fans.
Latest version of LaGrande noodleworks (scroll down).
An evolving La Grande How-To...
The non-working, but latest, CineMut test_bike
PU (Privateer: Parallel Universe's Home). WC or Privateer Drayman for you?
WCpedia --The Wing Commander Encyclopedia-- From Angel Deveraux through Belisarius to Zachary Banfeld...
WC Nexus forum, the Moonbase Tycho of WC fans.
-
- Elite
- Posts: 7243
- Joined: Mon Apr 18, 2005 2:40 pm
- Location: LS87, Buenos Aires, República Argentina
It so much more complex than that. But that's an acceptable simplification.
Actually, I never studied this propperly, from books, so my terminology may not be right, but I think longitudinal waves are vectored, so it's about directions and not signs. But it's a common simplification, which is not that deviant from reality usually, that single reflections come in opposite directions to that of direct sound.
So, yes... they're negative.
Actually, I never studied this propperly, from books, so my terminology may not be right, but I think longitudinal waves are vectored, so it's about directions and not signs. But it's a common simplification, which is not that deviant from reality usually, that single reflections come in opposite directions to that of direct sound.
So, yes... they're negative.
-
- Elite
- Posts: 7243
- Joined: Mon Apr 18, 2005 2:40 pm
- Location: LS87, Buenos Aires, República Argentina
Good news: I'm uploading the barspeech and commspeech sounds as I type, in the usual place. Actually, it's been uploading for the past two hours. Man, that's taking long. Only for 80Mb.
Oh: the usual place (don't act surprised if I mess the link )
PS: And that's how long it'll take: 2.4 hours, at present speed.
PS2: Yeah, I know. It grew from 40Mb to 80Mb. If you want, I can create more compressed alternatives. For instance, barspeech could easily go 22Khz/mono, IMO, without much degradation. But I like quality, what can I say. Really. I think giving choinces upon download would be a good thing, for those not concerned with quality. Actually, I would try a higher quality version (yes, higher), at around 160MB, so that comm distortion sounds better (call me fanatic, if you like). But all that will have to wait until I come back. For now, 80Mb will have to do.
Chuck: I didn't do the gun sound processing, since in order to use them we'll have to tweak the engine, to be able to specify different environments for guns. (a gun firing in space, outside your cockpit, gets a sound, while a gun firing from your ship, gets another one, and a gun firing from a turret, probably, yet another one).
Oh: the usual place (don't act surprised if I mess the link )
PS: And that's how long it'll take: 2.4 hours, at present speed.
PS2: Yeah, I know. It grew from 40Mb to 80Mb. If you want, I can create more compressed alternatives. For instance, barspeech could easily go 22Khz/mono, IMO, without much degradation. But I like quality, what can I say. Really. I think giving choinces upon download would be a good thing, for those not concerned with quality. Actually, I would try a higher quality version (yes, higher), at around 160MB, so that comm distortion sounds better (call me fanatic, if you like). But all that will have to wait until I come back. For now, 80Mb will have to do.
Chuck: I didn't do the gun sound processing, since in order to use them we'll have to tweak the engine, to be able to specify different environments for guns. (a gun firing in space, outside your cockpit, gets a sound, while a gun firing from your ship, gets another one, and a gun firing from a turret, probably, yet another one).
-
- Elite
- Posts: 8014
- Joined: Fri Sep 05, 2003 4:03 am
- Location: Montreal
- Contact:
Ah, I didn't realize the same sound was used for near and far. Okay, we'll tackle that in due time.
And let it be 80 megs. Why not?
I'm so glad you got around to upload before your trip!
Hope it's a good one, btw. Make sure you carry plenty of fluids and electrolytes. That's a long trip, even on a car. And wear bright clothing. Safety first!
And let it be 80 megs. Why not?
I'm so glad you got around to upload before your trip!
Hope it's a good one, btw. Make sure you carry plenty of fluids and electrolytes. That's a long trip, even on a car. And wear bright clothing. Safety first!
Latest version of Cinemut Opaque
Latest version of LaGrande noodleworks (scroll down).
An evolving La Grande How-To...
The non-working, but latest, CineMut test_bike
PU (Privateer: Parallel Universe's Home). WC or Privateer Drayman for you?
WCpedia --The Wing Commander Encyclopedia-- From Angel Deveraux through Belisarius to Zachary Banfeld...
WC Nexus forum, the Moonbase Tycho of WC fans.
Latest version of LaGrande noodleworks (scroll down).
An evolving La Grande How-To...
The non-working, but latest, CineMut test_bike
PU (Privateer: Parallel Universe's Home). WC or Privateer Drayman for you?
WCpedia --The Wing Commander Encyclopedia-- From Angel Deveraux through Belisarius to Zachary Banfeld...
WC Nexus forum, the Moonbase Tycho of WC fans.
-
- Developer
- Posts: 1831
- Joined: Mon Mar 07, 2005 10:33 pm
- Contact:
-
- Developer
- Posts: 1831
- Joined: Mon Mar 07, 2005 10:33 pm
- Contact:
I found someone who can do a lot of voices and accents who is willing to read lines. If Klauss or anyone else (sound related) want to contact this person (preferrably for WCU but also for PR and VS) the email address is
ianpcorbett]at[hotmail.com
I kinda hired this kitty, so don't worry about taking time, only please start communication quickly ^^;
ianpcorbett]at[hotmail.com
I kinda hired this kitty, so don't worry about taking time, only please start communication quickly ^^;
My Moral Code:
- The only sin is to treat people as if they were things.
- Rules were made for people, not the other way around.
- Don't deceive. Real life is complicated enough.
- If all else fails, smash stuff.
- The only sin is to treat people as if they were things.
- Rules were made for people, not the other way around.
- Don't deceive. Real life is complicated enough.
- If all else fails, smash stuff.
-
- Elite
- Posts: 8014
- Joined: Fri Sep 05, 2003 4:03 am
- Location: Montreal
- Contact:
Thanks! I just sent him an email.
Latest version of Cinemut Opaque
Latest version of LaGrande noodleworks (scroll down).
An evolving La Grande How-To...
The non-working, but latest, CineMut test_bike
PU (Privateer: Parallel Universe's Home). WC or Privateer Drayman for you?
WCpedia --The Wing Commander Encyclopedia-- From Angel Deveraux through Belisarius to Zachary Banfeld...
WC Nexus forum, the Moonbase Tycho of WC fans.
Latest version of LaGrande noodleworks (scroll down).
An evolving La Grande How-To...
The non-working, but latest, CineMut test_bike
PU (Privateer: Parallel Universe's Home). WC or Privateer Drayman for you?
WCpedia --The Wing Commander Encyclopedia-- From Angel Deveraux through Belisarius to Zachary Banfeld...
WC Nexus forum, the Moonbase Tycho of WC fans.