2017-01-22 2 views
-2

Je suis en train de compiler et d'exécuter un simple programme de physique 2D mais le compilateur dans Code :: Blocks (Windows 10 64 bits) renvoie l'erreur: "Undefined reference to Line (int, int, int, int) J'ai toutes les bibliothèques requises et je ne sais pas ce que je dois faire Quelqu'un peut-il m'aider? J'avoue que je n'ai aucune idée sur les compilateurs C++ mais je veux essayer de modifier et exécuter le code: -)Erreur lors de la compilation d'un simple programme C++ 2D physique

iface.h

/*---------------------------------------------------------------------------- 

2D Physics Test Program - a cheesy test harness for 2D physics 

by Chris Hecker for my Game Developer Magazine articles. See my homepage 
for more information. 

NOTE: This is a hacked test program, not a nice example of Windows programming. 
physics.cpp the only part of this you should look at!!! 

This material is Copyright 1997 Chris Hecker, All Rights Reserved. 
It's for you to read and learn from, not to put in your own articles 
or books or on your website, etc. Thank you. 

Chris Hecker 
[email protected] 
http://www.d6.com/users/checker 

*/ 

/*---------------------------------------------------------------------------- 

Interface functions between physics code and the dumb OS interface. 

*/ 

// physics -> app 

void Line(int X0, int Y0, int X1, int Y1); 
float GetTime(void); 

extern int WorldWidth, WorldHeight; 

// app -> physics 

void Run(void); 

void ToggleWorldSpring(void); 
void ToggleBodySpring(void); 
void ToggleGravity(void); 
void ToggleDamping(void); 

makefile

NAME=physics 

CC = cl -c -W4 -Zi -O2ab1gityp- -G5s -QIfdiv- -DSTRICT -DWIN32 -D_WIN32 
ASM = ml -c -D_WIN32=1 -Zi -Zf -coff 
LINK= link -map -pdb:none -debug:full -debugtype:cv -out:$(NAME).exe -subsystem:windows 
DEF =-DDEBUG -DSTRICT 
RC = rc 

OBJ = $(NAME).obj win32.obj 

LIBS = gdi32.lib user32.lib comdlg32.lib winmm.lib 

.cpp.obj: 
     $(CC) /Fo$*.obj /Fl$*.lst $< 

.asm.obj: 
     $(ASM) /Fo$*.obj /Fl $< 

goal: $(NAME).exe 

$(NAME).exe: $(OBJ) $(NAME).res makefile 
     $(LINK) $(OBJ) $(LIBS) $(NAME).res 

$(NAME).res: $(NAME).rc $(NAME).ico 
     $(RC) -r $(NAME).rc 

clean: 
     del $(NAME).exe 
     del *.lst 
     del *.res 
     del *.err 
     del *.obj 
     del *.map 
     del *.sym 
     del *.cod 
     del *.pdb 

math2d.h

/*---------------------------------------------------------------------------- 

2D Physics Test Program - a cheesy test harness for 2D physics 

by Chris Hecker for my Game Developer Magazine articles. See my homepage 
for more information. 

NOTE: This is a hacked test program, not a nice example of Windows programming. 
physics.cpp the only part of this you should look at!!! 

This material is Copyright 1997 Chris Hecker, All Rights Reserved. 
It's for you to read and learn from, not to put in your own articles 
or books or on your website, etc. Thank you. 

Chris Hecker 
[email protected] 
http://www.d6.com/users/checker 

*/ 

/*---------------------------------------------------------------------------- 

math2d.h - The simple math library for the 2D physics demo. 

10/13/96 - checker 

*/ 

#if !defined(MATH2D_H) 
#define MATH2D_H 

// explicit dependencies 
#include <math.h>  // for sqrt 
#include <float.h> 

/*---------------------------------------------------------------------------- 

Type and constant declarations. 

*/ 

typedef float real; 
typedef real r;   // for constants, ie. r(1), not for declaration use 

real const REAL_MAX = FLT_MAX; 
real const REAL_MIN = FLT_MIN; 

real const PI = r(3.14159265358979323846); 
real const Epsilon = r(0.00001); 

struct vector_2 
{ 
    real X, Y; 

    inline vector_2(void); 
    inline vector_2(real X, real Y); 

    inline vector_2 &operator+=(vector_2 const &A); 
    inline vector_2 &operator-=(vector_2 const &A); 
}; 

struct matrix_2x2 
{ 
    real aElements[2][2]; 

    inline matrix_2x2(void); 
    inline matrix_2x2(real RotateByThisManyRadians); 
}; 



/*---------------------------------------------------------------------------- 

Functions. 

*/ 

inline real RadiansFrom(real Degrees); 
inline real DegreesFrom(real Radians); 

inline vector_2 operator-(vector_2 const &A, vector_2 const &B); 
inline vector_2 operator+(vector_2 const &A, vector_2 const &B); 
inline vector_2 operator*(real A, vector_2 const &B); 
inline vector_2 operator*(vector_2 const &A, real B); 
inline vector_2 operator/(vector_2 const &A, real B); 

inline real DotProduct(vector_2 const &A, vector_2 const &B); 

// A-perp dot B 
inline real PerpDotProduct(vector_2 const &A, vector_2 const &B); 

inline vector_2 GetPerpendicular(vector_2 const &A); 
inline real GetLength(vector_2 const &A); 
inline vector_2 GetNormal(vector_2 const &A); // @todo need this? 

inline vector_2 operator*(matrix_2x2 const &A, vector_2 const &B); 

/*---------------------------------------------------------------------------- 

Inline function definitions. 

*/ 

inline real RadiansFrom(real Degrees) 
{ 
    return (Degrees * PI)/r(180); 
} 

inline real DegreesFrom(real Radians) 
{ 
    return (Radians * r(180))/PI; 
} 

inline vector_2 operator-(vector_2 const &A, vector_2 const &B) 
{ 
    return vector_2(A.X-B.X,A.Y-B.Y); 
} 

inline vector_2 operator+(vector_2 const &A, vector_2 const &B) 
{ 
    return vector_2(A.X+B.X,A.Y+B.Y); 
} 

inline vector_2 operator*(real A, vector_2 const &B) 
{ 
    return vector_2(A*B.X,A*B.Y); 
} 

inline vector_2 operator*(vector_2 const &A, real B) 
{ 
    return vector_2(B*A.X,B*A.Y); 
} 

inline vector_2 operator/(vector_2 const &A, real B) 
{ 
    return vector_2(A.X/B,A.Y/B); 
} 

inline real DotProduct(vector_2 const &A, vector_2 const &B) 
{ 
    return A.X*B.X + A.Y*B.Y; 
} 

inline real PerpDotProduct(vector_2 const &A, vector_2 const &B) 
{ 
    return A.X*B.Y - A.Y*B.X; 
} 

inline vector_2 GetPerpendicular(vector_2 const &A) 
{ 
    return vector_2(-A.Y,A.X); 
} 

inline real GetLength(vector_2 const &A) 
{ 
    return r(sqrt(A.X*A.X + A.Y*A.Y)); 
} 

inline vector_2 GetNormal(vector_2 const &A) 
{ 
    real OneOverLength = r(1)/GetLength(A); 
    return vector_2(OneOverLength*A.X,OneOverLength*A.Y); 
} 

inline vector_2::vector_2(void) : X(r(0)), Y(r(0)) 
{ 
} 

inline vector_2::vector_2(real X_, real Y_) : X(X_), Y(Y_) 
{ 
} 

inline vector_2 &vector_2::operator+=(vector_2 const &A) 
{ 
    X += A.X; 
    Y += A.Y; 
    return *this; 
} 
inline vector_2 &vector_2::operator-=(vector_2 const &A) 
{ 
    X -= A.X; 
    Y -= A.Y; 
    return *this; 
} 

inline vector_2 operator*(matrix_2x2 const &A, vector_2 const &B) 
{ 
    return vector_2(A.aElements[0][0]*B.X + A.aElements[0][1]*B.Y, 
        A.aElements[1][0]*B.X + A.aElements[1][1]*B.Y); 
} 

inline matrix_2x2::matrix_2x2(void) 
{ 
    aElements[0][0] = aElements[0][1] = aElements[1][0] = aElements[1][1] =r(0); 
} 

inline matrix_2x2::matrix_2x2(real Radians) 
{ 
    real const CosAngle = (real)cos(Radians); 
    real const SinAngle = (real)sin(Radians); 

    aElements[0][0] = CosAngle; aElements[0][1] = -SinAngle; 
    aElements[1][0] = SinAngle; aElements[1][1] = CosAngle; 
} 

#endif 

physics.cpp

/*---------------------------------------------------------------------------- 

2D Physics Test Program - a cheesy test harness for 2D physics 

by Chris Hecker for my Game Developer Magazine articles. See my homepage 
for more information. 

NOTE: This is a hacked test program, not a nice example of Windows programming. 
physics.cpp the only part of this you should look at!!! 

This material is Copyright 1997 Chris Hecker, All Rights Reserved. 
It's for you to read and learn from, not to put in your own articles 
or books or on your website, etc. Thank you. 

Chris Hecker 
[email protected] 
http://www.d6.com/users/checker 

*/ 

/*---------------------------------------------------------------------------- 

physics.cpp - This file implements the 2D physics simulator. 

10/15/96 - checker 

*/ 

#include <assert.h> 

#include "physics.h" 
#include "iface.h" 

/*---------------------------------------------------------------------------- 

Globals 

*/ 

// weird CodeWarrior bug with global initialization forces me to do this 
#define WIDTH 400 
#define HEIGHT 400 

int WorldWidth = WIDTH; 
int WorldHeight = HEIGHT; 

simulation_world World(r(WIDTH),r(HEIGHT)); 

/*---------------------------------------------------------------------------- 

various forces you can add to the system 

@todo need to figure out units here so these numbers mean something 

*/ 

int WorldSpringActive = 0;  // spring goes from body 0: vertex 0 to origin 
real const Kws = r(30);   // Hooke's spring constant 
real const Kwd = r(5);   // damping constant 
vector_2 WorldSpringAnchor(r(0),r(0)); 

int BodySpringActive = 0;  // spring goes from body 0 to body 1 
real const Kbs = r(10);   // Hooke's spring constant 
real const Kbd = r(5);   // damping constant 
int Body0SpringVertexIndex = 2; 
int Body1SpringVertexIndex = 0; 

int GravityActive = 0; 
vector_2 Gravity(r(0),r(-100)); 

int DampingActive = 0; 
real const Kdl = r(2.5);  // linear damping factor 
real const Kda = r(1400);  // angular damping factor 

/*---------------------------------------------------------------------------- 

Run 

*/ 

void Run(void) 
{ 
    static real LastTime = GetTime(); 

    // use a fixed timestep until we implement a better integrator 
    // real Time = GetTime(); 
    real Time = LastTime + r(0.02); 

    World.Simulate(Time - LastTime); 

    World.Render(); 

    LastTime = Time; 
} 

/*---------------------------------------------------------------------------- 

Toggles 

*/ 

void ToggleWorldSpring(void) 
{ 
    WorldSpringActive = WorldSpringActive ? 0 : 1; 
} 

void ToggleBodySpring(void) 
{ 
    BodySpringActive = BodySpringActive ? 0 : 1; 
} 

void ToggleGravity(void) 
{ 
    GravityActive = GravityActive ? 0 : 1; 
} 

void ToggleDamping(void) 
{ 
    DampingActive = DampingActive ? 0 : 1; 
} 

/*---------------------------------------------------------------------------- 

utilities 

*/ 

void InitializeBody(rigid_body &Body, real Density, real Width, real Height, 
        real CoefficientOfRestitution) 
{    
    real const Mass = Density * Width * Height; 

    Body.CoefficientOfRestitution = CoefficientOfRestitution; 

    Body.Width = Width; 
    Body.Height = Height; 

    Body.OneOverMass = r(1)/Mass; 

    // integrate over the body to find the moment of inertia 

    Body.OneOverCMMomentOfInertia = r(1)/((Mass/r(12)) * 
     (Width * Width + Height * Height)); 

    // 0-out non-vector quantities 
    Body.aConfigurations[0].Orientation = r(0); 
    Body.aConfigurations[0].AngularVelocity = r(0); 
    Body.aConfigurations[0].Torque = r(0); 
} 

/*---------------------------------------------------------------------------- 

simulation_world ctor 

*/ 

simulation_world::simulation_world(real WorldWidth_, real WorldHeight_) : 
    WorldWidth(WorldWidth_), WorldHeight(WorldHeight_), 
    SourceConfigurationIndex(0), TargetConfigurationIndex(1) 
{ 
    // initialize bodies 
    real const Density = r(0.01); 
    InitializeBody(aBodies[0],Density,r(40),r(20),r(1)); 
    InitializeBody(aBodies[1],Density,r(50),r(10),r(1)); 

    aBodies[0].aConfigurations[0].CMVelocity = vector_2(r(40),r(10)); 
    aBodies[0].aConfigurations[0].AngularVelocity = r(PI); 

    // initialize walls 
    aWalls[0].Normal = vector_2(r(0),r(-1)); 
    aWalls[0].c = r(WorldHeight/2 - 3); 

    aWalls[1].Normal = vector_2(r(0),r(1)); 
    aWalls[1].c = r(WorldHeight/2 - 3); 

    aWalls[2].Normal = vector_2(r(-1),r(0)); 
    aWalls[2].c = r(WorldWidth/2 - 3); 

    aWalls[3].Normal = vector_2(r(1),r(0)); 
    aWalls[3].c = r(WorldWidth/2 - 3); 

    aWalls[4].Normal = GetNormal(vector_2(r(0.5),r(1))); 
    aWalls[4].c = r(WorldWidth/2); 

    // generate the wall lines 
    for(int Counter = 0;Counter < NumberOfWalls;Counter++) 
    { 
     wall &Wall = aWalls[Counter]; 

     // make a big line in the direction of the wall 

     vector_2 PointOnWall = -Wall.c * Wall.Normal; 
     vector_2 v = GetPerpendicular(Wall.Normal); 
     real t0 = -REAL_MAX; 
     real t1 = REAL_MAX; 

     // now clip the line to the walls 

     for(int WallIndex = 0;WallIndex < NumberOfWalls;WallIndex++) 
     { 
      if(WallIndex != Counter) 
      { 
       wall &ClipWall = aWalls[WallIndex]; 

       real Denominator = DotProduct(v,ClipWall.Normal); 

       if(fabs(Denominator) > Epsilon) 
       { 
        // not coplanar 

        real t = - (ClipWall.c + 
           DotProduct(PointOnWall,ClipWall.Normal))/
            Denominator; 

        if(Denominator > r(0)) 
        { 
         // the clip wall's clipping the t0 side of line 
         if(t > t0) 
         { 
          t0 = t; 
         } 
        } 
        else 
        { 
         // it's clipping the t1 side 
         if(t < t1) 
         { 
          t1 = t; 
         } 
        } 
       } 
      } 
     } 

     // make sure we got clipped 
     assert((t0 != -REAL_MAX) && (t1 != REAL_MAX)); 
     // but not completely clipped 
     assert(t0 < t1); 

     Wall.StartPoint = PointOnWall + t0 * v; 
     Wall.EndPoint = PointOnWall + t1 * v; 
    } 

    // calculate initial box positions 
    CalculateVertices(0); 
} 

/*---------------------------------------------------------------------------- 

simulation_world dtor 

*/ 

simulation_world::~simulation_world(void) 
{ 

} 

/*---------------------------------------------------------------------------- 

Render - render the source configurations 

*/ 

#pragma warning(disable:4244)  // float -> int 
void simulation_world::Render(void) 
{ 
    int Counter; 

    // draw walls 

    for(Counter = 0;Counter < NumberOfWalls;Counter++) 
    { 
     wall &Wall = aWalls[Counter]; 

     Line(Wall.StartPoint.X,Wall.StartPoint.Y, 
      Wall.EndPoint.X,Wall.EndPoint.Y); 
    } 

    // draw bodies 

    for(Counter = 0;Counter < NumberOfBodies;Counter++) 
    { 
     rigid_body::configuration::bounding_box &Box = 
      aBodies[Counter].aConfigurations[SourceConfigurationIndex]. 
      BoundingBox; 

     for(int Edge = 0;Edge < 4;Edge++) 
     { 
      int Start = Edge; 
      int End = (Edge + 1) % 4; 

      Line(Box.aVertices[Start].X,Box.aVertices[Start].Y, 
       Box.aVertices[End].X,Box.aVertices[End].Y); 
     } 
    } 

    // draw springs 

    if(WorldSpringActive) 
    { 
     rigid_body::configuration::bounding_box &Box = 
      aBodies[0].aConfigurations[SourceConfigurationIndex].BoundingBox; 

     Line(Box.aVertices[0].X,Box.aVertices[0].Y, 
      WorldSpringAnchor.X,WorldSpringAnchor.Y); 
    } 

    if(BodySpringActive) 
    { 
     rigid_body::configuration::bounding_box &Box0 = 
      aBodies[0].aConfigurations[SourceConfigurationIndex].BoundingBox; 
     rigid_body::configuration::bounding_box &Box1 = 
      aBodies[1].aConfigurations[SourceConfigurationIndex].BoundingBox; 

     assert(NumberOfBodies >= 2); 
     vector_2 P0 = Box0.aVertices[Body0SpringVertexIndex]; 
     vector_2 P1 = Box1.aVertices[Body1SpringVertexIndex]; 
     Line(P0.X,P0.Y,P1.X,P1.Y); 
    } 

    // draw gravity vector 

    if(GravityActive) 
    { 
     Line(0,0,0,-30); 
     Line(0,-30,5,-25); 
     Line(0,-30,-5,-25); 
    } 

    // draw damping symbol 

    if(DampingActive) 
    { 
     Line(-5,0,5,0); 
     Line(0,-5,0,5); 
    } 
} 
#pragma warning(default:4244)  // float -> int 

/*---------------------------------------------------------------------------- 

Simulate - Integrate forward DeltaTime seconds. 

@todo do I need to store the last simulation time? 

*/ 

void simulation_world::Simulate(real DeltaTime) 
{ 
    real CurrentTime = r(0); 
    real TargetTime = DeltaTime; 

    while(CurrentTime < DeltaTime) 
    { 
     ComputeForces(SourceConfigurationIndex); 

     Integrate(TargetTime-CurrentTime); 

     CalculateVertices(TargetConfigurationIndex); 

     CheckForCollisions(TargetConfigurationIndex); 

     if(CollisionState == Penetrating) 
     { 
      // we simulated too far, so subdivide time and try again 
      TargetTime = (CurrentTime + TargetTime)/r(2); 

      // blow up if we aren't moving forward each step, which is 
      // probably caused by interpenetration at the frame start 

      assert(fabs(TargetTime - CurrentTime) > Epsilon); 
     } 
     else 
     { 
      // either colliding or clear 

      if(CollisionState == Colliding) 
      { 
       // @todo handle multiple simultaneous collisions 

       int Counter = 0; 
       do 
       { 
        ResolveCollisions(TargetConfigurationIndex); 
        Counter++; 
       } while((CheckForCollisions(TargetConfigurationIndex) == 
          Colliding) && (Counter < 100)); 

       assert(Counter < 100); 
      } 

      // we made a successful step, so swap configurations 
      // to "save" the data for the next step 

      CurrentTime = TargetTime; 
      TargetTime = DeltaTime; 

      SourceConfigurationIndex = SourceConfigurationIndex ? 0 : 1; 
      TargetConfigurationIndex = TargetConfigurationIndex ? 0 : 1; 
     } 
    } 
} 

/*---------------------------------------------------------------------------- 

ComputeForces - compute forces for gravity, spring, etc. 

*/ 

void simulation_world::ComputeForces(int ConfigurationIndex) 
{ 
    int Counter; 

    for(Counter = 0;Counter < NumberOfBodies;Counter++) 
    { 
     rigid_body &Body = aBodies[Counter]; 
     rigid_body::configuration &Configuration = 
      Body.aConfigurations[ConfigurationIndex]; 

     // clear forces 

     Configuration.Torque = r(0); 
     Configuration.CMForce = vector_2(r(0),r(0)); 

     if(GravityActive) 
     { 
      Configuration.CMForce += Gravity/Body.OneOverMass; 
     } 

     if(DampingActive) 
     { 
      Configuration.CMForce += -Kdl * Configuration.CMVelocity; 
      Configuration.Torque += -Kda * Configuration.AngularVelocity; 
     } 
    } 

    if(BodySpringActive) 
    { 
     rigid_body &Body0 = aBodies[0]; 
     rigid_body::configuration &Configuration0 = 
       Body0.aConfigurations[ConfigurationIndex]; 
     rigid_body::configuration::bounding_box &Box0 = 
       Configuration0.BoundingBox; 
     vector_2 Position0 = Box0.aVertices[Body0SpringVertexIndex]; 
     vector_2 U0 = Position0 - Configuration0.CMPosition; 
     vector_2 VU0 = Configuration0.CMVelocity + 
         Configuration0.AngularVelocity * GetPerpendicular(U0); 

     rigid_body &Body1 = aBodies[1]; 
     rigid_body::configuration &Configuration1 = 
       Body1.aConfigurations[ConfigurationIndex]; 
     rigid_body::configuration::bounding_box &Box1 = 
       Configuration1.BoundingBox; 
     vector_2 Position1 = Box1.aVertices[Body1SpringVertexIndex]; 
     vector_2 U1 = Position1 - Configuration1.CMPosition; 
     vector_2 VU1 = Configuration1.CMVelocity + 
         Configuration1.AngularVelocity * GetPerpendicular(U1); 

     // spring goes from 0 to 1 

     vector_2 SpringVector = Position1 - Position0; 
     vector_2 Spring = -Kbs * SpringVector; 

     vector_2 RelativeVelocity = VU1 - VU0; 
     // project velocity onto spring to get damping vector 
     // this is basically a Gram-Schmidt projection 
     vector_2 DampingForce = 
      -Kbd * (DotProduct(RelativeVelocity,SpringVector)/ 
        DotProduct(SpringVector,SpringVector)) * SpringVector; 

     Spring += DampingForce; 

     Configuration0.CMForce -= Spring; 
     Configuration0.Torque -= PerpDotProduct(U0,Spring); 

     Configuration1.CMForce += Spring; 
     Configuration1.Torque += PerpDotProduct(U1,Spring); 
    } 

    if(WorldSpringActive) 
    { 
     // apply spring to body 0's vertex 0 to anchor 

     rigid_body &Body = aBodies[0]; 
     rigid_body::configuration &Configuration = 
       Body.aConfigurations[ConfigurationIndex]; 
     rigid_body::configuration::bounding_box &Box = 
       Configuration.BoundingBox; 

     vector_2 Position = Box.aVertices[0]; 

     vector_2 U = Position - Configuration.CMPosition; 
     vector_2 VU = Configuration.CMVelocity + 
         Configuration.AngularVelocity * GetPerpendicular(U); 

     vector_2 Spring = -Kws * (Position - WorldSpringAnchor); 
     // project velocity onto spring to get damping vector 
     // this is basically a Gram-Schmidt projection 
     vector_2 DampingForce = 
      -Kwd * (DotProduct(VU,Spring)/DotProduct(Spring,Spring)) * Spring; 

     Spring += DampingForce; 

     Configuration.CMForce += Spring; 
     Configuration.Torque += PerpDotProduct(U,Spring); 
    } 
} 


/*---------------------------------------------------------------------------- 

CalculateVertices - figure out the body vertices from the configuration 

@todo should't this be in the body? 

*/ 

void simulation_world::CalculateVertices(int ConfigurationIndex) 
{ 
    int Counter; 

    for(Counter = 0;Counter < NumberOfBodies;Counter++) 
    { 
     matrix_2x2 const Rotation(
      aBodies[Counter].aConfigurations[ConfigurationIndex]. 
       Orientation); 

     vector_2 const Position = 
      aBodies[Counter].aConfigurations[ConfigurationIndex]. 
       CMPosition; 

     rigid_body::configuration::bounding_box &Box = 
      aBodies[Counter].aConfigurations[ConfigurationIndex].BoundingBox; 

     real const Width = aBodies[Counter].Width/2.0f; 
     real const Height = aBodies[Counter].Height/2.0f; 

     Box.aVertices[0] = Position + Rotation * vector_2(Width, Height); 
     Box.aVertices[1] = Position + Rotation * vector_2(Width,-Height); 
     Box.aVertices[2] = Position + Rotation * vector_2(-Width,-Height); 
     Box.aVertices[3] = Position + Rotation * vector_2(-Width, Height); 
    } 
} 

/*---------------------------------------------------------------------------- 

Integrate - integrate the rigid body configurations forward in time from 
       source config to target config 

@todo calculate initial derivatives _once_ 
@todo use something better than Euler's method 

*/ 

void simulation_world::Integrate(real DeltaTime) 
{ 
    int Counter; 

    for(Counter = 0;Counter < NumberOfBodies;Counter++) 
    { 
     rigid_body::configuration &Source = 
      aBodies[Counter].aConfigurations[SourceConfigurationIndex]; 
     rigid_body::configuration &Target = 
      aBodies[Counter].aConfigurations[TargetConfigurationIndex]; 

     Target.CMPosition = Source.CMPosition + 
       DeltaTime * Source.CMVelocity; 

     Target.Orientation = Source.Orientation + 
       DeltaTime * Source.AngularVelocity; 

     Target.CMVelocity = Source.CMVelocity + 
       (DeltaTime * aBodies[Counter].OneOverMass) * Source.CMForce; 

     Target.AngularVelocity = Source.AngularVelocity + 
       (DeltaTime * aBodies[Counter].OneOverCMMomentOfInertia) * 
        Source.Torque; 
    } 
} 


/*---------------------------------------------------------------------------- 

CheckForCollisions - test the current configuration for collisions 

@todo handle multiple simultaneous collisions 

*/ 

simulation_world::collision_state 
simulation_world::CheckForCollisions(int ConfigurationIndex) 
{ 
    // be optimistic! 
    CollisionState = Clear; 
    float const DepthEpsilon = 1.0f; 

    real const HalfWidth = WorldWidth/2.0f; 
    real const HalfHeight = WorldHeight/2.0f; 

    for(int Body = 0;(Body < NumberOfBodies) && 
     (CollisionState != Penetrating);Body++) 
    { 
     // @todo active configuration number?!?!? 
     rigid_body::configuration &Configuration = 
       aBodies[Body].aConfigurations[ConfigurationIndex]; 

     rigid_body::configuration::bounding_box &Box = 
       Configuration.BoundingBox; 

     for(int Counter = 0;(Counter < 4) && 
      (CollisionState != Penetrating);Counter++) 
     { 
      vector_2 Position = Box.aVertices[Counter]; 

      vector_2 CMToCornerPerp = 
       GetPerpendicular(Position - Configuration.CMPosition); 

      vector_2 Velocity = Configuration.CMVelocity + 
       Configuration.AngularVelocity * CMToCornerPerp; 

      for(int WallIndex = 0;(WallIndex < NumberOfWalls) && 
       (CollisionState != Penetrating);WallIndex++) 
      { 
       wall &Wall = aWalls[WallIndex]; 

       real axbyc = DotProduct(Position,Wall.Normal) + Wall.c; 

       if(axbyc < -DepthEpsilon) 
       { 
        CollisionState = Penetrating; 
       } 
       else 
       if(axbyc < DepthEpsilon) 
       { 
        real RelativeVelocity = DotProduct(Wall.Normal,Velocity); 

        if(RelativeVelocity < r(0)) 
        { 
         CollisionState = Colliding; 
         CollisionNormal = Wall.Normal; 
         CollidingCornerIndex = Counter; 
         CollidingBodyIndex = Body; 
        } 
       } 
      } 
     } 
    } 

    return CollisionState; 
} 


/*---------------------------------------------------------------------------- 

ResolveCollisions - calculate collision impulses 

@todo handle multiple simultaneous collisions 

*/ 

void simulation_world::ResolveCollisions(int ConfigurationIndex) 
{ 
    rigid_body &Body = aBodies[CollidingBodyIndex]; 
    rigid_body::configuration &Configuration = 
        Body.aConfigurations[ConfigurationIndex]; 

    vector_2 Position = 
        Configuration.BoundingBox.aVertices[CollidingCornerIndex]; 

    vector_2 CMToCornerPerp = GetPerpendicular(Position - 
        Configuration.CMPosition); 

    vector_2 Velocity = Configuration.CMVelocity + 
        Configuration.AngularVelocity * CMToCornerPerp; 

    real ImpulseNumerator = -(r(1) + Body.CoefficientOfRestitution) * 
        DotProduct(Velocity,CollisionNormal); 

    float PerpDot = DotProduct(CMToCornerPerp,CollisionNormal); 

    real ImpulseDenominator = Body.OneOverMass + 
      Body.OneOverCMMomentOfInertia * PerpDot * PerpDot; 

    real Impulse = ImpulseNumerator/ImpulseDenominator; 

    Configuration.CMVelocity += Impulse * Body.OneOverMass * CollisionNormal; 

    Configuration.AngularVelocity += 
          Impulse * Body.OneOverCMMomentOfInertia * PerpDot; 
} 
+2

Salut. Ce n'est pas comme ça que ça fonctionne, malheureusement. S'il vous plaît prenez le temps de lire [demander]. Modifiez votre question et publiez les erreurs et le code pertinent dans la question, pas les liens externes. Personne ici ne va télécharger et regarder un fichier zip aléatoire. Pardon. – OldProgrammer

+0

Aussi, poster du texte pas d'images. Tout le monde n'a pas la résolution d'écran que vous avez et le texte dans les images ne se met pas bien à l'échelle. –

Répondre

0

Première atteint 30000 caractères, donc je dois diviser le contenu physics.h

/*---------------------------------------------------------------------------- 

2D Physics Test Program - a cheesy test harness for 2D physics 

by Chris Hecker for my Game Developer Magazine articles. See my homepage 
for more information. 

NOTE: This is a hacked test program, not a nice example of Windows programming. 
physics.cpp the only part of this you should look at!!! 

This material is Copyright 1997 Chris Hecker, All Rights Reserved. 
It's for you to read and learn from, not to put in your own articles 
or books or on your website, etc. Thank you. 

Chris Hecker 
[email protected] 
http://www.d6.com/users/checker 

*/ 

/*---------------------------------------------------------------------------- 

physics.h - The header for the physics demo. 

10/15/96 - checker 

*/ 

#if !defined(PHYSICS_H) 
#define PHYSICS_H 

// explicit dependencies 
#include "math2d.h" 



/*---------------------------------------------------------------------------- 

Declarations for physics code. 

*/ 

struct rigid_body 
{ 
    real Width, Height; 
    real OneOverMass, OneOverCMMomentOfInertia; 
    real CoefficientOfRestitution; 

    enum { NumberOfConfigurations = 2 }; 

    struct configuration 
    { 
     vector_2 CMPosition; 
     real Orientation; 

     vector_2 CMVelocity; 
     real AngularVelocity; 

     vector_2 CMForce; 
     real Torque; 

     struct bounding_box 
     { 
      vector_2 aVertices[4]; 

     } BoundingBox; 

    } aConfigurations[NumberOfConfigurations]; 
}; 

class simulation_world 
{ 
public: 

    simulation_world(real WorldWidth, real WorldHeight); 

    void Simulate(real DeltaTime); 
    void Render(void); 

    ~simulation_world(void); 

private: 

    enum collision_state 
    { 
     Penetrating, 
     Colliding, 
     Clear 
    } CollisionState; 

    vector_2 CollisionNormal; 
    int CollidingBodyIndex; 
    int CollidingCornerIndex; 

    int SourceConfigurationIndex; 
    int TargetConfigurationIndex; 

    void ComputeForces(int ConfigurationIndex); 
    void Integrate(real DeltaTime); 
    collision_state CheckForCollisions(int ConfigurationIndex); 
    void ResolveCollisions(int ConfigurationIndex); 
    void CalculateVertices(int ConfigurationIndex); 

    real WorldWidth, WorldHeight; 

    enum { NumberOfWalls = 5 }; 
    struct wall 
    { 
     // define wall by plane equation 
     vector_2 Normal;  // inward pointing 
     real c;     // ax + by + c = 0 

     // points for drawing wall 
     vector_2 StartPoint; 
     vector_2 EndPoint; 
    } aWalls[NumberOfWalls]; 

    enum { NumberOfBodies = 2 }; 
    rigid_body aBodies[NumberOfBodies]; 
}; 

#endif 

physics.rc

/*---------------------------------------------------------------------------- 

2D Physics Test Program - a cheesy test harness for 2D physics 

by Chris Hecker for my Game Developer Magazine articles. See my homepage 
for more information. 

NOTE: This is a hacked test program, not a nice example of Windows programming. 
physics.cpp the only part of this you should look at!!! 

This material is Copyright 1997 Chris Hecker, All Rights Reserved. 
It's for you to read and learn from, not to put in your own articles 
or books or on your website, etc. Thank you. 

Chris Hecker 
[email protected] 
http://www.d6.com/users/checker 

*/ 

#include "windows.h" 
#include "win32.h" 

AppIcon ICON physics.ico 

AppAbout DIALOG DISCARDABLE 0, 0, 255, 86 
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU 
CAPTION "About the Cheesy Physics App" 
FONT 8, "MS Sans Serif" 
BEGIN 
    DEFPUSHBUTTON "OK",IDOK,5,65,50,14 
    LTEXT   "Cheesy 2D Physics Test App for my Game Developer Magazine articles", 
        -1,5,5,250,8 
    LTEXT   "by Chris Hecker ([email protected])",-1,5,15,150,8 
    LTEXT   "http://ourworld.compuserve.com/homepages/checker",-1,5,25,250,8 
    ICON   "AppIcon",-1,225,30,0,0 
END 

AppMenu menu 
begin 
    POPUP "&File" 
    BEGIN 
     MENUITEM "&About", MENU_ABOUT 
    END 
    POPUP "&Toggles" 
    BEGIN 
     MENUITEM "&WorldSpring\aW", MENU_WORLDSPRING 
     MENUITEM "&BodySpring\aB", MENU_BODYSPRING 
     MENUITEM "&Damping\aD", MENU_DAMPING 
     MENUITEM "&Gravity\aG", MENU_GRAVITY 
    END 
end 

stream.h

/* strstream.h -- class strstream declarations 

*/ 

/* 
*  C/C++ Run Time Library - Version 6.5 
* 
*  Copyright (c) 1990, 1994 by Borland International 
*  All Rights Reserved. 
* 
*/ 

#ifndef __cplusplus 
#error Must use C++ for the type strstream. 
#endif 

#ifndef __STRSTREAM_H 
#define __STRSTREAM_H 

#if !defined(___DEFS_H) 
#include <_defs.h> 
#endif 

#if !defined(__IOSTREAM_H) 
#include <iostream.h> 
#endif 


#if !defined(RC_INVOKED) 

#pragma option -a- 

#if defined(__BCOPT__) 
#if !defined(_RTL_ALLOW_po) && !defined(__FLAT__) 
#pragma option -po-  // disable Object data calling convention 
#endif 
#endif 

#if !defined(__TINY__) 
#pragma option -RT 
#endif 

#pragma option -Vo- 

#if defined(__STDC__) 
#pragma warn -nak 
#endif 

#endif /* !RC_INVOKED */ 


_CLASSDEF(strstreambuf) 
_CLASSDEF(strstreambase) 
_CLASSDEF(istrstream) 
_CLASSDEF(ostrstream) 
_CLASSDEF(strstream) 

class _EXPCLASS strstreambuf : public streambuf { 
public: 
    _RTLENTRY strstreambuf(); 
    _RTLENTRY strstreambuf(int n); 
    _RTLENTRY strstreambuf(void _FAR * (*a)(long), void (*f)(void _FAR *)); 
    _RTLENTRY strstreambuf(  char _FAR * _s, int, 
            char _FAR * _strt=0); 
    _RTLENTRY strstreambuf(signed char _FAR * _s, int, 
          signed char _FAR * _strt=0); 
    _RTLENTRY strstreambuf(unsigned char _FAR * _s, int, 
          unsigned char _FAR * _strt=0); 
    _RTLENTRY ~strstreambuf(); 

    void _RTLENTRY freeze(int = 1); 
    char _FAR * _RTLENTRY str(); 
virtual int _RTLENTRY doallocate(); 
virtual int _RTLENTRY overflow(int); 
virtual int _RTLENTRY underflow(); 
virtual int _RTLENTRY sync(); 
virtual streambuf _FAR * _RTLENTRY setbuf(char _FAR *, int); 
virtual streampos _RTLENTRY seekoff(streamoff, ios::seek_dir, int); 

private: 
    void _FAR * _RTLENTRY (*allocf)(long); 
    void _RTLENTRY (*freef)(void _FAR *); 
    short ssbflags; 
    enum { dynamic = 1, frozen = 2, unlimited = 4 }; 
    int next_alloc; 

    void _RTLENTRY init(char _FAR *, int, char _FAR *); 
}; 


class _EXPCLASS strstreambase : public virtual ios { 
public: 
    strstreambuf _FAR * _RTLENTRY rdbuf(); 

protected: 
     _RTLENTRY strstreambase(char _FAR *, int, char _FAR *); 
     _RTLENTRY strstreambase(); 
     _RTLENTRY ~strstreambase(); 
private: 
     strstreambuf buf; 
}; 
inline strstreambuf _FAR * _RTLENTRY strstreambase::rdbuf() 
            { return &this->buf; } 


class _EXPCLASS istrstream : public strstreambase, public istream { 
public: 
     _RTLENTRY istrstream(  char _FAR *); 
     _RTLENTRY istrstream(signed char _FAR *); 
     _RTLENTRY istrstream(unsigned char _FAR *); 
     _RTLENTRY istrstream(  char _FAR *, int); 
     _RTLENTRY istrstream(signed char _FAR *, int); 
     _RTLENTRY istrstream(unsigned char _FAR *, int); 
     _RTLENTRY ~istrstream(); 
}; 


class _EXPCLASS ostrstream : public strstreambase, public ostream { 
public: 
     _RTLENTRY ostrstream(  char _FAR *, int, int = ios::out); 
     _RTLENTRY ostrstream(signed char _FAR *, int, int = ios::out); 
     _RTLENTRY ostrstream(unsigned char _FAR *, int, int = ios::out); 
     _RTLENTRY ostrstream(); 
     _RTLENTRY ~ostrstream(); 

    char _FAR * _RTLENTRY str(); 
    int  _RTLENTRY pcount(); 
}; 
inline char _FAR * _RTLENTRY ostrstream::str() 
       { return strstreambase::rdbuf()->str(); } 
inline int _RTLENTRY ostrstream::pcount() 
       { return strstreambase::rdbuf()->out_waiting(); } 


class _EXPCLASS strstream : public strstreambase, public iostream { 
public: 
     _RTLENTRY strstream(); 
     _RTLENTRY strstream(  char _FAR *, int _sz, int _m); 
     _RTLENTRY strstream(signed char _FAR *, int _sz, int _m); 
     _RTLENTRY strstream(unsigned char _FAR *, int _sz, int _m); 
     _RTLENTRY ~strstream(); 

    char _FAR * _RTLENTRY str(); 
}; 
inline char _FAR * _RTLENTRY strstream::str() 
       { return strstreambase::rdbuf()->str(); } 


#if !defined(RC_INVOKED) 

#if defined(__STDC__) 
#pragma warn .nak 
#endif 

#pragma option -Vo. 

#if !defined(__TINY__) 
#pragma option -RT. 
#endif 

#if defined(__BCOPT__) 
#if !defined(_RTL_ALLOW_po) && !defined(__FLAT__) 
#pragma option -po.  // restore Object data calling convention 
#endif 
#endif 

#pragma option -a. /* restore default packing */ 

#endif /* !RC_INVOKED */ 


#endif /* __STRSTREAM_H */ 

win32.cpp

/*---------------------------------------------------------------------------- 

2D Physics Test Program - a cheesy test harness for 2D physics 

by Chris Hecker for my Game Developer Magazine articles. See my homepage 
for more information. 

NOTE: This is a hacked test program, not a nice example of Windows programming. 
physics.cpp the only part of this you should look at!!! 

This material is Copyright 1997 Chris Hecker, All Rights Reserved. 
It's for you to read and learn from, not to put in your own articles 
or books or on your website, etc. Thank you. 

Chris Hecker 
[email protected] 
http://www.d6.com/users/checker 

*/ 

#define WIN32_LEAN_AND_MEAN 
#define WIN32_EXTRA_LEAN 
#include <windows.h> 
#include <windowsx.h> 
#include <mmsystem.h> 
#include <commdlg.h> 
#include <stdlib.h> 
#include <math.h> 
#include <assert.h> 

#include "win32.h" 
#include "iface.h" 

#pragma warning (disable:4244) // conversion from float to int 

/*---------------------------------------------------------------------------- 

Globals and declarations 

*/ 

char szAppName[200] = "Cheesy 2D Physics App"; 

HINSTANCE hInstApp; 
HWND  hwndApp; 
HPALETTE hpalApp; 
BOOL fAppActive; 

LONG FAR PASCAL AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam); 
LONG AppCommand (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam); 
int AppPaint (HWND hwnd, HDC hdc); 

void AppExit(void); 
BOOL AppIdle(void); 

HBITMAP OldBitmap; 
HDC BufferDC; 
HBITMAP BufferBitmap; 

/*----------------------------------------------------------------------------*\ 
| AppAbout(hDlg, uiMessage, wParam, lParam)        | 
|                    | 
| Description:                | 
|  This function handles messages belonging to the "About" dialog box. | 
|  The only message that it looks for is WM_COMMAND, indicating the use | 
|  has pressed the "OK" button. When this happens, it takes down   | 
|  the dialog box.              | 
|                    | 
| Arguments:                 | 
|  hDlg   window handle of about dialog window     | 
|  uiMessage  message number           | 
|  wParam   message-dependent          | 
|  lParam   message-dependent          | 
|                    | 
| Returns:                 | 
|  TRUE if message has been processed, else FALSE       | 
|                    | 
\*----------------------------------------------------------------------------*/ 
BOOL FAR PASCAL AppAbout(HWND hwnd,UINT msg,WPARAM wParam, 
      LPARAM /* lParam */) 
{ 
    switch (msg) 
    { 
     case WM_COMMAND: 
      if (LOWORD(wParam) == IDOK) 
      { 
       EndDialog(hwnd,TRUE); 
      } 
      break; 

     case WM_INITDIALOG: 
      return TRUE; 
    } 
    return FALSE; 
} 

/*----------------------------------------------------------------------------*\ 
| AppInit(hInst, hPrev)              | 
|                    | 
| Description:                | 
|  This is called when the application is first loaded into    | 
|  memory. It performs all initialization that doesn't need to be done | 
|  once per instance.              | 
|                    | 
| Arguments:                 | 
|  hInstance  instance handle of current instance     | 
|  hPrev   instance handle of previous instance     | 
|                    | 
| Returns:                 | 
|  TRUE if successful, FALSE if not          | 
|                    | 
\*----------------------------------------------------------------------------*/ 
BOOL AppInit(HINSTANCE hInst,HINSTANCE hPrev,int sw,LPSTR szCmdLine) 
{ 
    WNDCLASS cls; 

    /* Save instance handle for DialogBoxs */ 
    hInstApp = hInst; 

    if (!hPrev) 
    { 
     /* 
     * Register a class for the main application window 
     */ 
     cls.hCursor  = LoadCursor(NULL,IDC_ARROW); 
     cls.hIcon   = LoadIcon(hInst,"AppIcon"); 
     cls.lpszMenuName = "AppMenu"; 
     cls.lpszClassName = szAppName; 
     cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 
     cls.hInstance  = hInst; 
     cls.style   = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; 
     cls.lpfnWndProc = (WNDPROC)AppWndProc; 
     cls.cbWndExtra  = 0; 
     cls.cbClsExtra  = 0; 

     if (!RegisterClass(&cls)) 
      return FALSE; 
    } 

    DWORD Style = WS_OVERLAPPEDWINDOW; 
    RECT WindowRect = { 0, 0 }; 
    WindowRect.right = WorldWidth; 
    WindowRect.bottom = WorldHeight; 

    AdjustWindowRect(&WindowRect,Style,TRUE); 

    hwndApp = CreateWindow(szAppName,szAppName,Style, 
        CW_USEDEFAULT,0, 
        WindowRect.right-WindowRect.left, 
        WindowRect.bottom-WindowRect.top, 
        0,0,hInst,0); 



    // create buffer bitmap 

    HDC Screen = GetDC(0); 
    BufferDC = CreateCompatibleDC(0); 
    BufferBitmap = CreateCompatibleBitmap(Screen,WorldWidth,WorldHeight); 
    OldBitmap = SelectBitmap(BufferDC,BufferBitmap); 
    ReleaseDC(0,Screen); 

    ShowWindow(hwndApp,sw); 

    return TRUE; 
} 


/*----------------------------------------------------------------------------*\ 
| AppExit()          | 
|                    | 
| Description:                | 
| app is just about to exit, cleanup      | 
|                    | 
\*----------------------------------------------------------------------------*/ 
void AppExit() 
{ 
    SelectObject(BufferDC,OldBitmap); 
    DeleteObject(BufferBitmap); 
    DeleteDC(BufferDC); 
} 

BOOL AppIdle() 
{ 
    if (fAppActive) 
    { 
     HDC WindowDC = GetDC(hwndApp); 
     AppPaint(hwndApp,WindowDC); 
     ReleaseDC(hwndApp,WindowDC); 

     return FALSE; 
    } 
    else 
    { 
    // 
    // we are a background app. 
    // 
    return TRUE;  // nothing to do. 
    } 
} 

/*----------------------------------------------------------------------------*\ 
| WinMain(hInst, hPrev, lpszCmdLine, cmdShow)        | 
|                    | 
| Description:                | 
|  The main procedure for the App. After initializing, it just goes  | 
|  into a message-processing loop until it gets a WM_QUIT message   | 
|  (meaning the app was closed).           | 
|                    | 
| Arguments:                 | 
|  hInst   instance handle of this instance of the app   | 
|  hPrev   instance handle of previous instance, NULL if first | 
|  szCmdLine  ->null-terminated command line       | 
|  cmdShow   specifies how the window is initially displayed  | 
|                    | 
| Returns:                 | 
|  The exit code as specified in the WM_QUIT message.      | 
|                    | 
\*----------------------------------------------------------------------------*/ 
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) 
{ 
    MSG  msg; 

    /* Call initialization procedure */ 
    if (!AppInit(hInst,hPrev,sw,szCmdLine)) 
    return FALSE; 

    /* 
    * Polling messages from event queue 
    */ 
    for (;;) 
    { 
     if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)) 
     { 
      if (msg.message == WM_QUIT) 
       break; 

      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
     else 
     { 
      if (AppIdle()) 
       WaitMessage(); 
     } 
    } 


    AppExit(); 
    return msg.wParam; 
} 

/*----------------------------------------------------------------------------*\ 
| AppPaint(hwnd, hdc)              | 
|                    | 
| Description:                | 
|  The paint function. Right now this does nothing.      | 
|                    | 
| Arguments:                 | 
|  hwnd    window painting into         | 
|  hdc    display context to paint to       | 
|                    | 
| Returns:                 | 
|  nothing                | 
|                    | 
\*----------------------------------------------------------------------------*/ 
int AppPaint (HWND hwnd, HDC hdc) 
{ 
    RECT rc; 
    GetClientRect(hwnd, &rc); 

    PatBlt(BufferDC,0,0,WorldWidth,WorldHeight,WHITENESS); 

    Run();  // run the physics 

    BitBlt(hdc,0,0,rc.right,rc.bottom,BufferDC,0,0,SRCCOPY); 

    return TRUE; 
} 

/*----------------------------------------------------------------------------*\ 
| AppWndProc(hwnd, uiMessage, wParam, lParam)        | 
|                    | 
| Description:                | 
|  The window proc for the app's main (tiled) window. This processes all | 
|  of the parent window's messages.          | 
|                    | 
\*----------------------------------------------------------------------------*/ 
LONG FAR PASCAL AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) 
{ 
    PAINTSTRUCT ps; 
    HDC hdc; 

    switch (msg) 
    { 
     case WM_CREATE: 
     break; 

     case WM_ACTIVATEAPP: 
      fAppActive = (BOOL)wParam; 
      break; 

     case WM_KEYDOWN: 
     { 
      switch(wParam) 
      { 
       case 'W': 
       { 
        SendMessage(hwnd,WM_COMMAND,MENU_WORLDSPRING,0); 
        break; 
       } 
       case 'B': 
       { 
        SendMessage(hwnd,WM_COMMAND,MENU_BODYSPRING,0); 
        break; 
       } 
       case 'D': 
       { 
        SendMessage(hwnd,WM_COMMAND,MENU_DAMPING,0); 
        break; 
       } 
       case 'G': 
       { 
        SendMessage(hwnd,WM_COMMAND,MENU_GRAVITY,0); 
        break; 
       } 
       break; 
      } 
     } 

     case WM_LBUTTONDOWN: 
     { 
      break; 
     } 

     case WM_MOUSEMOVE: 
     { 
      break; 
     } 

     case WM_LBUTTONUP: 
     { 
      break; 
     } 

     case WM_ERASEBKGND: 
      break; 

     case WM_INITMENU: 
      break; 

     case WM_COMMAND: 
      return AppCommand(hwnd,msg,wParam,lParam); 

     case WM_DESTROY: 
      PostQuitMessage(0); 
      break; 

     case WM_CLOSE: 
      break; 

     case WM_PAINT: 
      hdc = BeginPaint(hwnd,&ps); 
      AppPaint (hwnd,hdc); 
      EndPaint(hwnd,&ps); 
      return 0L; 

     case WM_SIZE: 
      break; 
    } 
    return DefWindowProc(hwnd,msg,wParam,lParam); 
} 

/*----------------------------------------------------------------------------*\ 
| AppCommand(hwnd, msg, wParam, lParam)      | 
|                    | 
| Description:                | 
| handles WM_COMMAND messages for the main window (hwndApp)   | 
|  of the parent window's messages.          | 
|                    | 
\*----------------------------------------------------------------------------*/ 
LONG AppCommand (HWND hwnd,UINT /* msg */,WPARAM wParam,LPARAM /* lParam */) 
{ 
    switch(wParam) 
    { 
     case MENU_ABOUT: 
      DialogBox(hInstApp,"AppAbout",hwnd,AppAbout); 
      break; 

     case MENU_WORLDSPRING: 
      ToggleWorldSpring(); 
      break; 
     case MENU_BODYSPRING: 
      ToggleBodySpring(); 
      break; 
     case MENU_DAMPING: 
      ToggleDamping(); 
      break; 
     case MENU_GRAVITY: 
      ToggleGravity(); 
      break; 

     case MENU_EXIT: 
      PostMessage(hwnd,WM_CLOSE,0,0L); 
      break; 
    } 
    return 0L; 
} 

extern "C" void __cdecl _assert(void *pExpression, void *pFile, 
    unsigned LineNumber) 
{ 
    char aBuffer[500]; 
    wsprintf(aBuffer,"Assertion: %s\nFile: %s, Line: %d\n" \ 
        "Hit Abort to exit, Retry to debug, Ignore to continue", 
        pExpression,pFile,LineNumber); 

    int Hit = MessageBox(hwndApp,aBuffer,"Assert!",MB_ABORTRETRYIGNORE | 
        MB_ICONHAND); 

    if(Hit == IDABORT) 
    { 
     exit(0); 
    } 
    else 
    if(Hit == IDRETRY) 
    { 
     DebugBreak(); 
    } 
} 

/*---------------------------------------------------------------------------- 

iface.h functions 

*/ 

void Line(int X0, int Y0, int X1, int Y1) 
{ 
    MoveToEx(BufferDC,(WorldWidth/2)+X0,(WorldHeight/2)-Y0,0); 
    LineTo(BufferDC,(WorldWidth/2)+X1,(WorldHeight/2)-Y1); 
} 

float GetTime(void) 
{ 
    static DWORD StartMilliseconds; 
    if(!StartMilliseconds) 
    { 
     // yes, the first time through will be a 0 timestep 
     StartMilliseconds = timeGetTime(); 
    } 

    DWORD CurrentMilliseconds = timeGetTime(); 
    return float(CurrentMilliseconds - StartMilliseconds)/1000.0f; 
} 

win32.h

/*---------------------------------------------------------------------------- 

2D Physics Test Program - a cheesy test harness for 2D physics 

by Chris Hecker for my Game Developer Magazine articles. See my homepage 
for more information. 

NOTE: This is a hacked test program, not a nice example of Windows programming. 
physics.cpp the only part of this you should look at!!! 

This material is Copyright 1997 Chris Hecker, All Rights Reserved. 
It's for you to read and learn from, not to put in your own articles 
or books or on your website, etc. Thank you. 

Chris Hecker 
[email protected] 
http://www.d6.com/users/checker 

*/ 

/* Menu Items */ 
#define MENU_ABOUT   0 
#define MENU_EXIT   1 
#define MENU_WORLDSPRING 2 
#define MENU_BODYSPRING  3 
#define MENU_DAMPING  4 
#define MENU_GRAVITY  5