home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- *
- * File : knight.c
- *
- * Abstract : Handle knight behaviour and animation control
- *
- **********************************************************************
- *
- * This file is a product of Criterion Software Ltd.
- *
- * This file is provided as is with no warranties of any kind and is
- * provided without any obligation on Criterion Software Ltd. or
- * Canon Inc. to assist in its use or modification.
- *
- * Criterion Software Ltd. will not, under any
- * circumstances, be liable for any lost revenue or other damages arising
- * from the use of this file.
- *
- * Copyright (c) 1995 Criterion Software Ltd.
- * All Rights Reserved.
- *
- * RenderWare is a trademark of Canon Inc.
- *
- ************************************************************************/
- #define INCLUDE_SHELLAPI_H
-
- #include <windows.h>
- #include <mmsystem.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
-
- #include "rwlib.h"
- #include "rwwin.h"
-
- #include "common.h"
-
- #include "animate.h"
- #include "knight.h"
- #include "knight.rwh"
-
- #define CAM_FLY_STEPS 30
- int CamFlyStepDelta;
- int CamFlyStep;
-
- void SetBackdrop(RwCamera *cam)
- {
- RwRaster *r;
- RwV3d v;
- RwV3d xz;
- RwInt32 ox, oy;
- RwInt32 vp_h;
- double theta;
-
- r = RwGetCameraBackdrop(cam);
- if (r)
- {
- RwGetCameraViewport(cam,
- (RwInt32 *)NULL, (RwInt32 *)NULL, (RwInt32 *)NULL, &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)((double)RwGetRasterWidth(r) * theta/6.2832);
- if (xz.z < 0.0)
- ox = -ox;
-
- oy = -vp_h/2 + (int)((double)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(HWND window, 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(GetMenu(window), ID_MODE_KNIGHT1, (MF_BYCOMMAND|MF_UNCHECKED));
- CheckMenuItem(GetMenu(window), ID_MODE_KNIGHT2, (MF_BYCOMMAND|MF_UNCHECKED));
- CheckMenuItem(GetMenu(window), ID_MODE_OBSERVER, (MF_BYCOMMAND|MF_UNCHECKED));
- switch (CameraState)
- {
- case CAM_MAIN:
- CheckMenuItem(GetMenu(window), ID_MODE_OBSERVER, (MF_BYCOMMAND|MF_CHECKED));
- break;
- case CAM_KNIGHT1:
- CheckMenuItem(GetMenu(window), ID_MODE_KNIGHT1, (MF_BYCOMMAND|MF_CHECKED));
- break;
- case CAM_KNIGHT2:
- CheckMenuItem(GetMenu(window), ID_MODE_KNIGHT2, (MF_BYCOMMAND|MF_CHECKED));
- break;
- }
- }
-
- void DoFlyCamera(HWND window)
- {
- 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(window, (CameraState == CAM_FLY1) ? CAM_KNIGHT1 : CAM_KNIGHT2);
- }
- else if (CamFlyStep == 0)
- {
- SetCameraState(window, CAM_MAIN);
- }
- SetBackdrop(FlyCamera);
- }
-
- void KnightCamera(void)
- {
- RwClump *clump;
-
- if ((CameraState == CAM_KNIGHT1) || (CameraState == CAM_KNIGHT2))
- {
- clump = RwFindTaggedClump((CameraState == CAM_KNIGHT1) ? Knight1 : Knight2, TAG_head);
- RwGetClumpLTM(clump, RwScratchMatrix());
- RwTransformCamera(FlyCamera, RwScratchMatrix(), rwREPLACE);
- RwTiltCamera(FlyCamera, CREAL(90.0));
- }
- SetBackdrop(FlyCamera);
- }
-
- void AnimateCamera(HWND window)
- {
- static int Frame = 0;
- static long Duration = 200;
-
- Frame++;
- if (!InterActive)
- {
- RwSetCameraPosition(MainCamera, CREAL(0.0), CREAL(0.0), CREAL(0.0));
- #if 0
- RwVCMoveCamera(MainCamera, CREAL(0.0), CREAL(0.0), -CAMERA_DISTANCE);
- #endif
- 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(window, (Duration & 0x01) ? CAM_FLY1: CAM_FLY2);
- break;
- case CAM_KNIGHT1:
- case CAM_KNIGHT2:
- SetCameraState(window, (CameraState == CAM_KNIGHT1) ? CAM_FLY1 : CAM_FLY2);
- break;
-
- }
- Duration = RANDOM_INT(100, 500);
- }
- }
-
- switch (CameraState)
- {
- case CAM_MAIN:
- break;
- case CAM_KNIGHT1:
- case CAM_KNIGHT2:
- KnightCamera();
- break;
-
- case CAM_FLY1:
- case CAM_FLY2:
- DoFlyCamera(window);
- 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 */
- }
- }
-
- RwClump *RemoveTexture(RwClump *c)
- {
- RwForAllPolygonsInClumpPointer(c, (RwPolygon3dFuncPointer)RwSetPolygonTexture, NULL);
- return(c);
- }
-
-
- int LoadKnight(HWND window, HINSTANCE inst, RwScene *scene)
- {
- char buffer[64];
- int i;
-
- GetModuleFileName(inst, buffer, sizeof(buffer));
- i = strlen(buffer);
- while(buffer[i] != '\\')
- i--;
-
- Knight1 = LoadClump(window, "knight.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 = RwDuplicateClump(Knight1);
- if (!Knight2)
- return FALSE;
-
- RwForAllClumpsInHierarchy(Knight2, RemoveTexture);
-
- 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);
-
- buffer[i+1] = 0;
- strcat(buffer, "KNIGHT.RWV");
-
- RwForAllClumpsInHierarchyLong(Knight1, (RwClumpFuncLong)RwSetClumpHints, 0L);
- RwForAllClumpsInHierarchyLong(Knight2, (RwClumpFuncLong)RwSetClumpHints, 0L);
-
- LoadAnimation(Knight1, buffer);
- LoadAnimation(Knight2, buffer);
-
- 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, 12);
- 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)
- {
- long 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 = RANDOM_INT(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);
- }
-
- #ifdef WITH_SOUND
- static char *Sound = NULL;
- static int SoundDelay = 0;
-
- void DelaySound(char *wav, int delay)
- {
- char buffer[128];
- if (!Sound)
- {
- sprintf (buffer, "open %s", wav);
- mciSendString(buffer, NULL, 0, 0);
- Sound = wav;
- SoundDelay = delay;
- }
-
- }
-
- void PlaySound(void)
- {
- char buffer[128];
- if (Sound)
- {
- SoundDelay--;
- if (!SoundDelay)
- {
- sprintf (buffer, "play %s from 0", Sound);
- mciSendString(buffer, NULL, 0, 0);
- Sound = NULL;
- }
- }
- }
- #endif
-
- void ReactKnight(RwClump *clump, TyAnimation *a)
- {
- char *response;
- long i;
-
- if (!strcmp(a->name, "HIT"))
- {
- SetAnimationState(clump, A_DISSOLVE);
- return;
- }
- else if (!strcmp(a->name, "SLASH"))
- {
- i = RANDOM_INT(0, 10);
- if (i == 7)
- {
- response = "HIT";
- #ifdef WITH_SOUND
- DelaySound("scream.wav", 12);
- #endif
- }
- else
- {
- response = "PARRY";
- #ifdef WITH_SOUND
- DelaySound("thunk.wav", 12);
- #endif
- }
- }
- else
- {
- i = RANDOM_INT(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;
- }
- }
-