home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Learn 3D Graphics Programming on the PC
/
Learn_3D_Graphics_Programming_on_the_PC_Ferraro.iso
/
rwdos
/
dknight.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-15
|
11KB
|
378 lines
#define INCLUDE_SHELLAPI_H
#include <i86.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h> /* Required for floating point */
#include <string.h>
#include "rwlib.h"
#include "rwdos.h"
#include "danimate.h"
#include "dknight.h"
#include "knight.rwh"
#define CAM_FLY_STEPS 30
int CamFlyStepDelta;
int CamFlyStep;
void SetBackdrop(RwCamera *cam)
{
RwRaster *r;
RwV3d v;
RwV3d xz;
int ox, oy;
RwInt32 vp_h;
RwInt32 dummy;
float theta;
r = RwGetCameraBackdrop(cam);
if (r)
{
RwGetCameraViewport(cam, &dummy, &dummy, &dummy, &vp_h);
RwGetCameraLookAt(cam, &v);
xz.x = v.x;
xz.z = v.z;
xz.y = CREAL(0.0);
RwNormalize(&xz);
if (xz.x > CREAL(1.0))
xz.x = CREAL(1.0);
if (xz.x < CREAL(-1.0))
xz.x = CREAL(-1.0);
theta = acos(REAL2FL(xz.x));
ox = (int)((float)RwGetRasterWidth(r) * theta/6.2832);
if (xz.z < 0.0)
ox = -ox;
oy = -vp_h/2 + (int)((float)RwGetRasterHeight(r)/2.0 * (1.0 - REAL2FL(v.y)));
if (oy > RwGetRasterHeight(r) - vp_h)
oy = RwGetRasterHeight(r) - vp_h;
if (oy < 0)
oy = 0;
RwSetCameraBackdropOffset(cam, ox + RwGetRasterWidth(r)/2, oy);
}
}
void SetCameraState(EnCameraState state)
{
if (state == CAM_MAIN)
{
Camera = MainCamera;
SetBackdrop(MainCamera);
}
else if (((state == CAM_FLY1) || (state == CAM_FLY2)) &&
((CameraState == CAM_MAIN) || (CameraState == CAM_KNIGHT1) || (CameraState == CAM_KNIGHT2)))
{
if (CameraState == CAM_MAIN)
{
Camera = FlyCamera;
CamFlyStepDelta = 1;
CamFlyStep = 1;
}
else
{
CamFlyStepDelta = -1;
CamFlyStep = CAM_FLY_STEPS -1;
}
}
if (CameraState != state)
{
if ((state == CAM_KNIGHT1) || (state == CAM_KNIGHT2))
RwRemoveClumpFromScene((state == CAM_KNIGHT1) ? Knight1 : Knight2);
if ((CameraState == CAM_KNIGHT1) || (CameraState == CAM_KNIGHT2))
RwAddClumpToScene(Scene, (CameraState == CAM_KNIGHT1) ? Knight1 : Knight2);
}
CameraState = state;
/*
CheckMenuItem(MainMenu, M_KNIGHT1, (MF_BYCOMMAND|MF_UNCHECKED));
CheckMenuItem(MainMenu, M_KNIGHT2, (MF_BYCOMMAND|MF_UNCHECKED));
CheckMenuItem(MainMenu, M_OBSERVER, (MF_BYCOMMAND|MF_UNCHECKED));
switch (CameraState)
{
case CAM_MAIN:
CheckMenuItem(MainMenu, M_OBSERVER, (MF_BYCOMMAND|MF_CHECKED));
break;
case CAM_KNIGHT1:
CheckMenuItem(MainMenu, M_KNIGHT1, (MF_BYCOMMAND|MF_CHECKED));
break;
case CAM_KNIGHT2:
CheckMenuItem(MainMenu, M_KNIGHT2, (MF_BYCOMMAND|MF_CHECKED));
break;
}
*/
}
void DoFlyCamera(void)
{
RwClump *clump;
RwV3d dest_at, dest_up, dest_pos;
RwV3d src_at, src_up, src_pos;
RwReal delta;
clump = RwFindTaggedClump((CameraState == CAM_FLY1) ? Knight1 : Knight2, TAG_head);
RwGetClumpLTM(clump, RwScratchMatrix());
delta = FL2REAL((float)CamFlyStep/(float)(CAM_FLY_STEPS));
RwGetCameraPosition(MainCamera, &src_pos);
RwGetCameraLookAt(MainCamera, &src_at);
RwGetCameraLookUp(MainCamera, &src_up);
dest_pos.x = CREAL(0.0);dest_pos.y = CREAL(0.0); dest_pos.z = CREAL(0.0);
dest_up.x = CREAL(0.0); dest_up.y = CREAL(0.0); dest_up.z = CREAL(1.0);
dest_at.x = CREAL(0.0); dest_at.y = CREAL(-1.0); dest_at.z = CREAL(0.0);
RwTransformPoint(&dest_pos, RwScratchMatrix());
RwTransformVector(&dest_up, RwScratchMatrix());
RwTransformVector(&dest_at, RwScratchMatrix());
dest_pos.x = RAdd(dest_pos.x,
RMul((CameraState == CAM_FLY1) ? CREAL(4.0): CREAL(-4.0),
RSub(CREAL(1.0), delta)));
RwSetCameraPosition(FlyCamera,
RAdd(src_pos.x, RMul(delta, RSub(dest_pos.x,src_pos.x))),
RAdd(src_pos.y, RMul(delta, RSub(dest_pos.y,src_pos.y))),
RAdd(src_pos.z, RMul(delta, RSub(dest_pos.z,src_pos.z))));
RwPointCamera(FlyCamera, CREAL(0.0), CREAL(0.0), CREAL(0.0));
RwSetCameraLookUp(FlyCamera, CREAL(0.0), CREAL(1.0), CREAL(0.0));
CamFlyStep += CamFlyStepDelta;
if ((CamFlyStepDelta > 0) && (CamFlyStep == CAM_FLY_STEPS))
{
SetCameraState((CameraState == CAM_FLY1) ? CAM_KNIGHT1 : CAM_KNIGHT2);
}
else if (CamFlyStep == 0)
{
SetCameraState(CAM_MAIN);
}
SetBackdrop(FlyCamera);
}
void KnightCamera(void)
{
RwClump *clump;
if ((CameraState == CAM_KNIGHT1) || (CameraState == CAM_KNIGHT2))
{
RwSetCameraPosition(FlyCamera, CREAL(0.0), CREAL(0.0), CREAL(0.0));
RwSetCameraLookUp(FlyCamera, CREAL(0.0), CREAL(0.0), CREAL(1.0));
RwSetCameraLookAt(FlyCamera, CREAL(0.0), CREAL(-1.0), CREAL(0.0));
clump = RwFindTaggedClump((CameraState == CAM_KNIGHT1) ? Knight1 : Knight2, TAG_head);
RwGetClumpLTM(clump, RwScratchMatrix());
RwTransformCamera(FlyCamera, RwScratchMatrix(),rwPOSTCONCAT);
}
SetBackdrop(FlyCamera);
}
void AnimateCamera(void)
{
static int Frame = 0;
static int Duration = 200;
Frame++;
if (!InterActive)
{
RwVCMoveCamera(MainCamera, CREAL(0.0), CREAL(0.0), -CAMERA_DISTANCE);
RwPanCamera(MainCamera, CREAL(2.0));
RwVCMoveCamera(MainCamera, CREAL(0.0), CREAL(0.0), CAMERA_DISTANCE);
if (CameraState == CAM_MAIN)
SetBackdrop(MainCamera);
if (!(Frame % Duration))
{
switch(CameraState)
{
case CAM_MAIN:
SetCameraState((Duration & 0x01) ? CAM_FLY1: CAM_FLY2);
break;
case CAM_KNIGHT1:
case CAM_KNIGHT2:
SetCameraState((CameraState == CAM_KNIGHT1) ? CAM_FLY1 : CAM_FLY2);
break;
}
Duration = GetRandInt(100, 500);
}
}
switch (CameraState)
{
case CAM_MAIN:
break;
case CAM_KNIGHT1:
case CAM_KNIGHT2:
KnightCamera();
break;
case CAM_FLY1:
case CAM_FLY2:
DoFlyCamera();
break;
}
}
void RenderKnight(void)
{
RwClump *clump;
/* this is a cheat to force quick rendering when viewing from a knights eye point */
if ((CameraState == CAM_KNIGHT1) || (CameraState == CAM_KNIGHT2))
{
RwRemoveLightFromScene(Light); /* put in the default scene */
clump = (CameraState == CAM_KNIGHT1) ? Knight1 : Knight2;
RwRenderClump(RwFindTaggedClump(clump, TAG_Object));
RwRenderClump(RwFindTaggedClump(clump, TAG_SHIELD));
RwRenderClump(RwFindTaggedClump(clump, TAG_lefthand));
RwRenderClump(RwFindTaggedClump(clump, TAG_left4arm));
RwAddLightToScene(Scene, Light); /* put it back in the scene */
}
}
int LoadKnight(RwScene *scene)
{
Knight1 = LoadClump( "knight1.rwx");
if (!Knight1)
return FALSE;
RwAddClumpToScene(scene, Knight1);
RwRotateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(1.0), CREAL(0.0), CREAL(-90.0), rwREPLACE);
RwTransformClumpJoint(Knight1, RwScratchMatrix(), rwREPLACE);
RwTranslateMatrix(RwScratchMatrix(), CREAL(1.3), CREAL(0.4), CREAL(0.0), rwREPLACE);
RwTransformClump(Knight1, RwScratchMatrix(), rwREPLACE);
Knight2 = LoadClump("knight2.rwx");
if (!Knight2)
return FALSE;
RwAddClumpToScene(scene, Knight2);
RwRotateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(1.0), CREAL(0.0), CREAL(90.0), rwREPLACE);
RwTransformClumpJoint(Knight2, RwScratchMatrix(), rwREPLACE);
RwTranslateMatrix(RwScratchMatrix(), CREAL(-1.3), CREAL(0.4), CREAL(0.0), rwREPLACE);
RwTransformClump(Knight2, RwScratchMatrix(), rwREPLACE);
RwForAllClumpsInHierarchyLong(Knight1, RwSetClumpHints, 0L);
RwForAllClumpsInHierarchyLong(Knight2, RwSetClumpHints, 0L);
LoadAnimation(Knight1, ".\\knight.rwv");
LoadAnimation(Knight2, ".\\knight.rwv");
DefineAnimation(Knight1, "BOB1", 0, 10, 5);
DefineAnimation(Knight1, "SLASH", 10, 35, 12);
DefineAnimation(Knight1, "BOB2", 35, 45, 40);
DefineAnimation(Knight1, "PARRY", 45, 60, 48);
DefineAnimation(Knight1, "BOB3", 60, 70, 65);
DefineAnimation(Knight1, "HIT", 70, 85, 85);
DefineAnimation(Knight2, "BOB1", 0, 10, 5);
DefineAnimation(Knight2, "SLASH", 10, 35, 14);
DefineAnimation(Knight2, "BOB2", 35, 45, 40);
DefineAnimation(Knight2, "PARRY", 45, 60, 50);
DefineAnimation(Knight2, "BOB3", 60, 70, 65);
DefineAnimation(Knight2, "HIT", 70, 85, 85);
return TRUE;
}
char *RandomKnight(RwClump *clump)
{
int i;
/* if the other knight isn`t doing anything then don`t attack */
if (((clump == Knight1) && (GetAnimationState(Knight2) != A_ON)) ||
((clump == Knight2) && (GetAnimationState(Knight1) != A_ON)))
return "BOB1";
i = GetRandInt(0, 1);
switch(i)
{
case 0:
return "SLASH";
default:
return "BOB1";
}
}
int CheckKnightAnimation(RwClump *clump)
{
TyAnimationData *ad;
ad = RwGetClumpData(clump);
if (ad)
{
if (ad->current_animation)
{
return (ad->current_animation->end - ad->current_frame);
}
}
return (0);
}
void ReactKnight(RwClump *clump, TyAnimation *a)
{
char *response;
int i;
if (!strcmp(a->name, "HIT"))
{
SetAnimationState(clump, A_DISSOLVE);
return;
}
else if (!strcmp(a->name, "SLASH"))
{
i = GetRandInt(0, 10);
if (i == 7)
response = "HIT";
else
response = "PARRY";
}
else
{
i = GetRandInt(0, 5);
switch (i)
{
case 0:
case 1:
response = "SLASH";
break;
case 2:
response = "BOB1";
break;
case 3:
response = "BOB2";
break;
default:
response = "BOB3";
break;
}
}
if (clump == Knight1)
{
if (CheckKnightAnimation(Knight2) < 15)
StartAnimation(Knight2, response);
}
else
{
if (CheckKnightAnimation(Knight1) < 15)
StartAnimation(Knight1, response);
}
}
void AnimateKnight(int knight, char *name)
{
SetAnimationState(Knight1, A_ON);
SetAnimationState(Knight2, A_ON);
switch (knight)
{
case 1: StartAnimation(Knight1, name); break;
case 2: StartAnimation(Knight2, name); break;
}
}