diff options
Diffstat (limited to 'src')
50 files changed, 19968 insertions, 0 deletions
diff --git a/src/AGL_DSp.cpp b/src/AGL_DSp.cpp new file mode 100644 index 0000000..eace870 --- /dev/null +++ b/src/AGL_DSp.cpp @@ -0,0 +1,242 @@ +/**> HEADER FILES <**/ +#include "AGL_DSp.h" +#include "Alerts.h" + + +/**> GLOBAL VARIABLES <**/ +DSpContextAttributes gDSpContextAttributes; // Global DrawSprocket context attributes +DSpContextReference gDSpContext; // The global DrawSprocket context +AGLContext gOpenGLContext; // The global OpenGL (AGL) context + + +/********************> ToolboxInit() <*****/ +void ToolboxInit( void ) +{ + + MaxApplZone(); + + InitGraf( &qd.thePort ); + InitFonts(); + InitWindows(); + InitMenus(); + TEInit(); + InitDialogs( 0L ); + InitCursor(); + +} + +/********************> HasAppearance() <*****/ +Boolean HasAppearance( void ) +{ + + OSErr error; + SInt32 response; + Boolean appearancePresent = false; + Boolean appearance101present = false; + Boolean appearance110present = false; + Boolean inCompatibilityMode = false; + + error = Gestalt( gestaltAppearanceAttr, &response ); + + // If Gestalt returns no error and the bit in response represented by the constant + // gestaltAppearanceExists is set, proceed, otherwise exit with an error message. + + if ( error == noErr && ( BitTst( &response, 31 - gestaltAppearanceExists ) ) ) + { + // At least Version 1.0 is present. Set a flag. + appearancePresent = true; + + // If the bit in response represented by the constant gestaltAppearanceCompatMode + // is set, system-wide Appearance is off. The result of this check will be + // relevant only where Versions 1.0 through 1.0.3 are present. + if( BitTst( &response, 31 - gestaltAppearanceCompatMode ) ) + inCompatibilityMode = true; + + // Call Gestalt again with the gestaltAppearanceVersion selector. + Gestalt( gestaltAppearanceVersion, &response ); + + // If the low order word in response is 0x0101, Version 1.0.1, 1.0.2, or 1.0.3 is + // present. If the low order word in response is 0x0110, Version 1.1 is available. + if( response == 0x00000101 ) + appearance101present = true; + else if( response == 0x00000110 ) + appearance110present = true; + } + /*else + { + StopAlert( kNoAppearanceAlert, nil ); + ExitToShell(); + }*/ + + // Register this app as an Appearance Client + //RegisterAppearanceClient(); + + return appearancePresent; + +} + +/********************> SetupScreen() <*****/ +CGrafPtr SetupScreen( int width, int height ) +{ + + OSStatus theError; + CGrafPtr theFrontBuffer; + + // Start DrawSprocket + theError = DSpStartup(); + if( theError ) + FatalErrorAlert( kErr_DSpStartupFailed, theError ); + + // Set the Context Attributes + gDSpContextAttributes.displayWidth = width; + gDSpContextAttributes.displayHeight = height; + gDSpContextAttributes.colorNeeds = kDSpColorNeeds_Require; + gDSpContextAttributes.displayDepthMask = kDSpDepthMask_32; + gDSpContextAttributes.backBufferDepthMask = kDSpDepthMask_32; + gDSpContextAttributes.displayBestDepth = 32; + gDSpContextAttributes.backBufferBestDepth = 32; + gDSpContextAttributes.pageCount = 1; + + // Find the best context for our attributes + theError = DSpFindBestContext( &gDSpContextAttributes, &gDSpContext ); + if( theError != noErr ) + FatalErrorAlert( kErr_DSpFindBestContextFailed, theError ); // This function is in my Alerts.cpp + + // Reserve that context + theError = DSpContext_Reserve( gDSpContext, &gDSpContextAttributes ); + if( theError != noErr ) + FatalErrorAlert( kErr_DSpContext_ReserveFailed, theError ); + + // Fade out + theError = DSpContext_FadeGammaOut( NULL, NULL ); + if( theError != noErr ) + FatalErrorAlert( kErr_DSpFadeFailed, theError ); + + // Activate the context + theError = DSpContext_SetState( gDSpContext, kDSpContextState_Active ); + if( theError != noErr ) + { + // Fade back in the display before dying + theError = DSpContext_FadeGammaIn( NULL, NULL ); + + // Now do the fatal error alert + FatalErrorAlert( kErr_ActivateContextFailed, theError ); + } + + // Fade in + theError = DSpContext_FadeGammaIn( NULL, NULL ); + if( theError != noErr ) + FatalErrorAlert( kErr_DSpFadeFailed, theError ); + + // Create a window to draw in + CreateWindow( theFrontBuffer, width, height ); + + return theFrontBuffer; + +} + +/********************> CreateWindow() <*****/ +void CreateWindow( CGrafPtr &theFrontBuffer, int width, int height ) +{ + + Rect rect; + AuxWinHandle awh; + CTabHandle theColorTable; + OSErr error; + RGBColor backColor = { 0xFFFF, 0xFFFF, 0xFFFF }; + RGBColor foreColor = { 0x0000, 0x0000, 0x0000 }; + + // Set the window rect + rect.top = rect.left = 0; + DSpContext_LocalToGlobal( gDSpContext, ( Point* )&rect ); + rect.right = rect.left + width; + rect.bottom = rect.top + height; + + // Create a new color window + theFrontBuffer = ( CGrafPtr )NewCWindow( NULL, &rect, "\p", 0, plainDBox, kMoveToFront, 0, 0 ); + + // set the content color of the window to black to avoid a white flash when the window appears. + if ( GetAuxWin( ( WindowPtr )theFrontBuffer, &awh ) ) + { + theColorTable = ( **awh ).awCTable; + error = HandToHand( ( Handle* )&theColorTable ); + if ( error ) + DebugStr( "\pOut of memory!" ); + + ( **theColorTable ).ctTable[wContentColor].rgb.red = 0; + ( **theColorTable ).ctTable[wContentColor].rgb.green = 0; + ( **theColorTable ).ctTable[wContentColor].rgb.blue = 0; + + CTabChanged( theColorTable ); + + // the color table will be disposed by the window manager when the window is disposed + SetWinColor( ( WindowPtr )theFrontBuffer, ( WCTabHandle )theColorTable ); + } + + // Show the window + ShowWindow( ( GrafPtr )theFrontBuffer ); + SetPort( ( GrafPtr )theFrontBuffer ); + + // Set current pen colors + RGBForeColor( &foreColor ); + RGBBackColor( &backColor ); + +} + +/********************> ShutdownScreen() <*****/ +void ShutdownScreen( CGrafPtr theFrontBuffer ) +{ + + DSpContext_FadeGammaOut( NULL, NULL ); + DisposeWindow( ( WindowPtr )theFrontBuffer ); + DSpContext_SetState( gDSpContext, kDSpContextState_Inactive ); + DSpContext_FadeGammaIn( NULL, NULL ); + DSpContext_Release( gDSpContext ); + DSpShutdown(); + +} + +/********************> SetupAGL() <*****/ +AGLContext SetupAGL( AGLDrawable window ) +{ + GLint attrib[] = { AGL_RGBA, AGL_DEPTH_SIZE, 24, AGL_DOUBLEBUFFER, AGL_NONE }; + AGLPixelFormat format; + AGLContext context; + GLboolean ok; + + // Choose an rgb pixel format + format = aglChoosePixelFormat( NULL, 0, attrib ); + if ( format == NULL ) + return NULL; + + // Create an AGL context + context = aglCreateContext( format, NULL ); + if ( context == NULL ) + return NULL; + + // Attach the window to the context + ok = aglSetDrawable( context, window ); + if ( !ok ) + return NULL; + + // Make the context the current context + ok = aglSetCurrentContext( context ); + if ( !ok ) + return NULL; + + // The pixel format is no longer needed so get rid of it + aglDestroyPixelFormat( format ); + + return context; + +} + +/********************> CleanupAGL() <*****/ +void CleanupAGL( AGLContext context ) +{ + + aglSetCurrentContext( NULL ); + aglSetDrawable( context, NULL ); + aglDestroyContext( context ); + +} diff --git a/src/AGL_DSp.h b/src/AGL_DSp.h new file mode 100644 index 0000000..4c1d531 --- /dev/null +++ b/src/AGL_DSp.h @@ -0,0 +1,41 @@ +#pragma once + +#ifndef _AGL_DSP_H_ +#define _AGL_DSP_H_ + + +/**> HEADER FILES <**/ +#include <stdlib.h> // ANSI C cross platform headers +#include <stdio.h> +#include <DrawSprocket.h> // DrawSprocket +#include <agl.h> // Apple's OpenGL +#include <glu.h> // Used for setting perspective and making objects +#include <tk.h> // Used for loading images + + +/**> CONSTANT DECLARATIONS <**/ +#define kMoveToFront kFirstWindowOfClass + +// Screen Dimensions +#define SCREEN_WIDTH 640 +#define SCREEN_HEIGHT 480 + + +/**> GLOBAL VARIABLES <**/ +extern DSpContextAttributes gDSpContextAttributes; // Global DrawSprocket context attributes +extern DSpContextReference gDSpContext; // The global DrawSprocket context +extern AGLContext gOpenGLContext; // The global OpenGL (AGL) context + // Note: These are actually defined in AGL_DSp.cpp + + +/**> FUNCTION PROTOTYPES <**/ +void ToolboxInit( void ); +Boolean HasAppearance( void ); +CGrafPtr SetupScreen( int width, int height ); +void CreateWindow( CGrafPtr &theFrontBuffer, int width, int height ); +void ShutdownScreen( CGrafPtr theFrontBuffer ); +AGLContext SetupAGL( AGLDrawable window ); +void CleanupAGL( AGLContext context ); + + +#endif \ No newline at end of file diff --git a/src/Alerts.cpp b/src/Alerts.cpp new file mode 100644 index 0000000..acfefae --- /dev/null +++ b/src/Alerts.cpp @@ -0,0 +1,93 @@ +/**> HEADER FILES <**/ +#include "Alerts.h" + + +/********************> SelectResolution() <*****/ +int SelectResolution( void ) +{ + + DialogPtr dialog; + Boolean dialogDone = false; + short itemHit, itemType; + Handle okItem; + Handle resolutionItem; + Rect itemRect; + int selectionNum; + + // Load the dialog + dialog = GetNewDialog( kResID_DLOG_SelectResolution, nil, kMoveToFront ); + + // Display the dialog + ShowWindow( dialog ); + SetPort( dialog ); + + // Load dialog items + SetDialogDefaultItem( dialog, iOK ); + SetDialogTracksCursor( dialog, true ); + GetDialogItem( dialog, iOK, &itemType, &okItem, &itemRect ); + GetDialogItem( dialog, iResolutionPopUp, &itemType, &resolutionItem, &itemRect ); + + // Set item values + SetControlValue( ( ControlHandle )resolutionItem, i640x480 ); + + + while ( !dialogDone ) + { + + ModalDialog( nil, &itemHit ); + + switch( itemHit ) + { + case iOK: + dialogDone = true; + // Get the item number selected int the popup + selectionNum = GetControlValue( ( ControlHandle )resolutionItem ); + break; + case iResolutionPopUp: + // We don't actually need to do anything here + break; + } + + } + + DisposeDialog( dialog ); + + // Return the item selected in the popup menu + return selectionNum; +} + +/********************> MessageAlert() <*****/ +void MessageAlert( unsigned char *theMessage ) +{ + + // Set parameter ^0 to our message (I could set up to three, but for simplicity's sake I won't) + ParamText( ( unsigned char * )theMessage, NULL, NULL, NULL ); + + // Do the Alert + NoteAlert( kResID_ALRT_MessageAlert, nil ); + +} + +/********************> FatalErrorAlert() <*****/ +void FatalErrorAlert( UInt16 errorNum, OSErr osError ) +{ + + Str15 errNumStr; + Str255 mainMessage; + + // Convert the OSErr to a string + NumToString( osError, errNumStr ); + + // Get the error description (inErrorDesc) from the STR# resource + GetIndString( mainMessage, kResID_STRn_ErrorStrings, errorNum ); + + // Set the parameters (^0 and ^1) in the ALRT to our error messages + ParamText( mainMessage, errNumStr, NULL, NULL ); + + // Do the alert (which now has our messages in it) + StopAlert( kResID_ALRT_ErrorAlert, NULL ); + + // Quit + exit( EXIT_SUCCESS ); + +} diff --git a/src/Alerts.h b/src/Alerts.h new file mode 100644 index 0000000..5db7938 --- /dev/null +++ b/src/Alerts.h @@ -0,0 +1,44 @@ +#ifndef _MYALERTS_H_ +#define _MYALERTS_H_ + + +/**> HEADER FILES <**/ +#include <string.h> +#include <stdlib.h> + + +/**> CONSTANT DECLARATIONS <**/ +#define kMoveToFront kFirstWindowOfClass +// Alerts +#define kResID_ALRT_MessageAlert 128 +#define kResID_ALRT_ErrorAlert 129 +// Dialogs +#define kResID_DLOG_SelectResolution 130 +#define iOK 1 +#define iResolutionPopUp 2 +// Menus +#define mResolution 128 +#define i640x480 1 +#define i800x600 2 +#define i1024x768 3 +// String resources +#define kResID_STRn_ErrorStrings 128 +// Misc +#define kInsignificantConstant7454955 0 + +// Error numbers +#define kErr_DSpFindBestContextFailed 1 +#define kErr_DSpContext_ReserveFailed 2 +#define kErr_ActivateContextFailed 3 +#define kErr_DSpStartupFailed 4 +#define kErr_DSpFadeFailed 5 +#define kErr_AGLContext_CreationFailed 6 + + +/**> FUNCTION PROTOTYPES <**/ +int SelectResolution( void ); +void MessageAlert( unsigned char *theMessage ); +void FatalErrorAlert( UInt16 errorNum, OSErr osError ); + + +#endif \ No newline at end of file diff --git a/src/Camera.cpp b/src/Camera.cpp new file mode 100644 index 0000000..950c12d --- /dev/null +++ b/src/Camera.cpp @@ -0,0 +1,9 @@ +/**> HEADER FILES <**/ +#include "Camera.h" + + +void Camera::Apply() +{ + glTranslatef(-position.x,-position.y,-position.z); +} + diff --git a/src/Camera.h b/src/Camera.h new file mode 100644 index 0000000..a31055f --- /dev/null +++ b/src/Camera.h @@ -0,0 +1,29 @@ +#ifndef _CAMERA_H_ +#define _CAMERA_H_ + + +/**> HEADER FILES <**/ +#ifdef OS9 +#include <gl.h> +#else +#include <GL/gl.h> +#endif + +#include "Quaternions.h" + +class Camera +{ + public: + XYZ position; + XYZ oldposition; + XYZ targetoffset; + + float rotation, rotation2; + float oldrotation, oldrotation2; + float oldoldrotation, oldoldrotation2; + float visrotation, visrotation2; + void Apply(); +}; + +#endif + diff --git a/src/Constants.h b/src/Constants.h new file mode 100644 index 0000000..76c67de --- /dev/null +++ b/src/Constants.h @@ -0,0 +1,136 @@ +#ifndef _CONSTANTS_H_ +#define _CONSTANTS_H_ + +#define max_joints 50 +#define max_frames 50 +#define max_muscles 100 +#define gravity -25 + +#define bullethole 0 +#define crater 1 +#define bloodpool 2 + +#define idleanim 0 +#define joganim 1 +#define pistolaimanim 2 +#define walkanim 3 +#define rifleholdanim 4 +#define rifleaimanim 5 +#define assaultrifleaimanim 6 +#define crouchanim 7 +#define headpainanim 8 +#define chestpainanim 9 +#define stomachpainanim 10 +#define rightarmpainanim 11 +#define leftarmpainanim 12 +#define rightlegpainanim 13 +#define leftlegpainanim 14 +#define riflehitanim 15 +#define grenadeaimanim 16 +#define grenadechargeanim 17 +#define grenadethrowanim 18 +#define zombieeatanim 19 +#define zombiejoganim 20 +#define zombiewalkanim 21 +#define getupfrontanim 22 +#define getupbackanim 23 +#define lyinganim 24 +#define diveanim 25 +#define throwanim 26 +#define thrownanim 27 + +#define nogun 0 +#define sniperrifle 1 +#define assaultrifle 2 +#define handgun1 3 +#define handgun2 4 +#define grenade 5 +#define knife 6 +#define shotgun 7 + +#define sniperriflemodel 0 +#define assaultriflemodel 1 +#define handgunbasemodel 2 +#define handgunslidemodel 3 +#define handgun2basemodel 4 +#define handgun2slidemodel 5 +#define grenadebasemodel 6 +#define grenadepinmodel 7 +#define grenadespoonmodel 8 +#define knifemodel 9 +#define shotgunmodel 10 + +#define visionsound 0 +#define soulinsound 1 +#define souloutsound 2 +#define footstepsound 3 +#define bodylandsound 8 +#define headlandsound 9 +#define riflesound 10 +#define bodyhitsound 11 +#define wallhitsound 12 +#define machinegunsound 13 +#define nearbulletsound 14 +#define headwhacksound 15 +#define headshotsound 16 +#define reloadsound 17 +#define clicksound 18 +#define pistol1sound 19 +#define pistol2sound 20 +#define pinpullsound 21 +#define pinreplacesound 22 +#define grenadethrowsound 23 +#define bouncesound 24 +#define bounce2sound 25 +#define explosionsound 26 +#define bodywhacksound 27 +#define rainsound 28 +#define losesound 29 +#define disguisekillsound 30 +#define knifeslashsound 31 +#define shotgunsound 32 +#define mainmenusong 33 +#define shootsong 34 +#define knifesong 35 +#define zombiesong 36 + +#define sunny_environment 0 +#define foggy_environment 1 +#define snowy_environment 2 +#define rainy_environment 3 +#define firey_environment 4 +#define night_environment 5 + +#define randomshoot_type 0 +#define zombie_type 1 +#define soldiers_type 2 +#define snipers_type 3 +#define stabber_type 4 + +#define shotdelayamount 3 + +#define fleshtone1 240/255 +#define fleshtone2 183/255 +#define fleshtone3 132/255 + +#define headmodel 0 +#define chestmodel 1 +#define abdomenmodel 2 +#define upperarmmodel 3 +#define lowerarmmodel 4 +#define handmodel 5 +#define upperlegmodel 6 +#define lowerlegmodel 7 +#define footmodel 8 + +#define policecostume 0 +#define bodyguardcostume 1 +#define casualcostumes 2 +#define vipcostume 6 + +#define numcasual 4 + +#define soundscalefactordefault 10 + +#endif + diff --git a/src/Decals.cpp b/src/Decals.cpp new file mode 100644 index 0000000..3cebb4c --- /dev/null +++ b/src/Decals.cpp @@ -0,0 +1,375 @@ +#include "Decals.h" +#include "Textures.h" + +extern double multiplier; +extern bool slomo; +extern Fog fog; +extern bool blood; +extern float fogcolorr; +extern float fogcolorg; +extern float fogcolorb; +//Functions +extern float sinefluct; +extern int environment; +extern Model gunmodels[10]; +extern Camera camera; +extern float precipitationhorz; +extern float precipitationvert; +extern float precipitationdensity; +extern float snowdelay; + +int Decals::MakeDecal(int atype, XYZ location, float size, XYZ normal, int poly, Model *model, XYZ move, float rotation){ + int major=0; + float normalv[3]; + XYZ right; + XYZ up; + XYZ nothing; + XYZ axis[3]; + XYZ temp; + + nothing=0; + + axis[0].x=1; + axis[1].y=1; + axis[2].z=1; + + normalv[0]=abs(normal.x); + normalv[1]=abs(normal.y); + normalv[2]=abs(normal.z); + + + if(normalv[1]>normalv[major])major=1; + if(normalv[2]>normalv[major])major=2; + + if (normalv[0] == 1 || normalv[1] == 1 || normalv[2] == 1) + { + if ((major == 0 && normal.x > 0) || major == 1){ + right=0; + right.z=-1;} + else if (major == 0){ + right=0; + right.z=1;} + else { + right=0; + right.x=normal.z;} + } + else + CrossProduct(axis[major], normal, &right); + + CrossProduct(normal, right, &up); + Normalise(&up); + Normalise(&right); + + float count; + float count2; + float countinc=1/size; + if(countinc<.01)countinc=.01; + if(countinc>.2)countinc=.2; + float normaloffset=.02; + int good; + + numpoints[howmanydecals]=0; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right - up) * (size/3) /*+ normal/100*/; + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0; + if((move.x==0&&move.z==0&&rotation==0)|| + LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp) + )numpoints[howmanydecals]++; + else { + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right - up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count - up) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + if(good==-1){ + good=-1; + count2=1-countinc; + while(good==-1&&count2>-1){ + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count2/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count2 - up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + count2-=countinc; + } + if(good!=-1)numpoints[howmanydecals]++; + } + } + + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right - up) * (size/3) /*+ normal/100*/; + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0; + if((move.x==0&&move.y==0&&move.z==0&&rotation==0)|| + LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp) + )numpoints[howmanydecals]++; + else { + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count - up) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right - up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + if(good==-1){ + good=-1; + count2=1-countinc; + while(good==-1&&count2>-1){ + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count2/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count2 - up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + count2-=countinc; + } + if(good!=-1)numpoints[howmanydecals]++; + } + } + + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right + up) * (size/3) /*+ normal/100*/; + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1; + if((move.x==0&&move.y==0&&move.z==0&&rotation==0)|| + LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp) + )numpoints[howmanydecals]++; + else { + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right + up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count + up) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + if(good==-1){ + good=-1; + count2=1-countinc; + while(good==-1&&count2>-1){ + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count2/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count2 + up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + count2-=countinc; + } + if(good!=-1)numpoints[howmanydecals]++; + } + } + + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right + up) * (size/3) /*+ normal/100*/; + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1; + if((move.x==0&&move.y==0&&move.z==0&&rotation==0)|| + LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp) + )numpoints[howmanydecals]++; + else { + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count + up) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right + up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + if(good==-1){ + good=-1; + count2=1-countinc; + while(good==-1&&count2>-1){ + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count2/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count2 + up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + count2-=countinc; + } + if(good!=-1)numpoints[howmanydecals]++; + } + } + for(int i=0;i<numpoints[howmanydecals];i++){ + points[howmanydecals*8+i] += normal*normaloffset; + } + + type[howmanydecals]=atype; + alivetime[howmanydecals]=0; + if(howmanydecals<maxdecals){howmanydecals++;} + + return 0; +} + +int Decals::DeleteDecal(int which){ + if(which>=0){ + numpoints[which]=numpoints[howmanydecals-1]; + alivetime[which]=alivetime[howmanydecals-1]; + type[which]=type[howmanydecals-1]; + for(int i=0;i<numpoints[which];i++){ + points[which*8+i] = points[howmanydecals*8-8+i]; + texcoordsx[which*8+i] = texcoordsx[howmanydecals*8-8+i]; + texcoordsy[which*8+i] = texcoordsy[howmanydecals*8-8+i]; + } + if(howmanydecals>0){howmanydecals--;} + } + + return 0; +} + +void Decals::LoadBulletHoleTexture(char *fileName) +{ + bulletholetextureptr = loadTexture(fileName); +} + +void Decals::LoadBloodTexture(char *fileName, int which) +{ + bloodtextureptr[which] = loadTexture(fileName); +} + +void Decals::LoadCraterTexture(char *fileName) +{ + cratertextureptr = loadTexture(fileName); +} + +void Decals::DoStuff() +{ + for(int i=0;i<howmanydecals;i++){ + alivetime[i]+=multiplier; + if(alivetime[i]>10&&(type[i]==bullethole||type[i]==crater))DeleteDecal(i); + if(alivetime[i]>20&&(type[i]==bloodpool))DeleteDecal(i); + } +} + +void Decals::draw() +{ + glAlphaFunc(GL_GREATER, 0.01); + + float bloodpoolspeed=1; + + glDepthFunc(GL_LEQUAL); + glEnable(GL_BLEND); + glEnable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glDepthMask(0); + glAlphaFunc(GL_GREATER, 0.01); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_POLYGON_OFFSET_FILL); + for(int i=0;i<howmanydecals;i++){ + if(type[i]==bullethole)glBindTexture(GL_TEXTURE_2D, bulletholetextureptr); + if(type[i]==crater)glBindTexture(GL_TEXTURE_2D, cratertextureptr); + if(type[i]!=bloodpool)glColor4f(1,1,1,10-alivetime[i]); + + if(type[i]==bloodpool&&alivetime[i]<bloodpoolspeed*.2)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[0]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.2&&alivetime[i]<bloodpoolspeed*.4)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[1]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.4&&alivetime[i]<bloodpoolspeed*.6)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[2]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.6&&alivetime[i]<bloodpoolspeed*.8)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[3]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.8&&alivetime[i]<bloodpoolspeed*1)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[4]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1&&alivetime[i]<bloodpoolspeed*1.2)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[5]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.2&&alivetime[i]<bloodpoolspeed*1.4)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[6]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.4&&alivetime[i]<bloodpoolspeed*1.6)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[7]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.6&&alivetime[i]<bloodpoolspeed*1.8)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[8]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.8&&alivetime[i]<bloodpoolspeed*2.0)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[9]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*2.0)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[10]); + if(type[i]==bloodpool&&alivetime[i]<bloodpoolspeed*2.0)glColor4f(1,1,1,1.5-(alivetime[i]*5/bloodpoolspeed-(int)(alivetime[i]*5/bloodpoolspeed))); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*2.0)glColor4f(1,1,1,20-alivetime[i]); + + glPushMatrix(); + glBegin(GL_TRIANGLE_FAN); + for(int j=0;j<numpoints[i];j++){ + glTexCoord2f(texcoordsx[i*8+j], texcoordsy[i*8+j]); glVertex3f(points[i*8+j].x,points[i*8+j].y,points[i*8+j].z); + } + glEnd(); + glPopMatrix(); + + if(type[i]==bloodpool&&alivetime[i]<bloodpoolspeed*2.0){ + if(type[i]==bloodpool&&alivetime[i]<bloodpoolspeed*.2)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[1]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.2&&alivetime[i]<bloodpoolspeed*.4)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[2]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.4&&alivetime[i]<bloodpoolspeed*.6)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[3]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.6&&alivetime[i]<bloodpoolspeed*.8)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[4]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.8&&alivetime[i]<bloodpoolspeed*1)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[5]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1&&alivetime[i]<bloodpoolspeed*1.2)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[6]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.2&&alivetime[i]<bloodpoolspeed*1.4)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[7]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.4&&alivetime[i]<bloodpoolspeed*1.6)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[8]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.6&&alivetime[i]<bloodpoolspeed*1.8)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[9]); + if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.8&&alivetime[i]<bloodpoolspeed*2.0)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[10]); + if(type[i]==bloodpool)glColor4f(1,1,1,alivetime[i]*5/bloodpoolspeed-(int)(alivetime[i]*5/bloodpoolspeed)); + + glPushMatrix(); + glBegin(GL_TRIANGLE_FAN); + for(int j=0;j<numpoints[i];j++){ + glTexCoord2f(texcoordsx[i*8+j], texcoordsy[i*8+j]); glVertex3f(points[i*8+j].x,points[i*8+j].y,points[i*8+j].z); + } + glEnd(); + glPopMatrix(); + } + } + glDepthMask(1); + glDisable(GL_TEXTURE_2D); + glColor4f(1,1,1,1); + glEnable(GL_CULL_FACE); + glDisable(GL_POLYGON_OFFSET_FILL); + glDepthFunc(GL_LEQUAL); +} + diff --git a/src/Decals.h b/src/Decals.h new file mode 100644 index 0000000..127a6d2 --- /dev/null +++ b/src/Decals.h @@ -0,0 +1,59 @@ +#ifndef _DECALS_H_ +#define _DECALS_H_ + +#include "Quaternions.h" +#ifdef OS9 +#include <gl.h> +#include <glu.h> +#include "glut.h" +#else +///ZWARNING +///#include <GL/glut.h> +///GLUT REMOVED. +#endif +#include "Files.h" +#include "Quaternions.h" +#include "Camera.h" +#include "Models.h" +#include "Fog.h" +// +// Model Structures +// + +#define maxdecals 120 + +class Decals{ + public: + GLuint bulletholetextureptr; + GLuint cratertextureptr; + GLuint bloodtextureptr[11]; + + int howmanydecals; + + int type[maxdecals]; + + XYZ points[8*maxdecals]; + int numpoints[maxdecals]; + float texcoordsx[8*maxdecals]; + float texcoordsy[8*maxdecals]; + float alivetime[maxdecals]; + + void draw(); + + int DeleteDecal(int which); + int MakeDecal(int atype, XYZ location, float size, XYZ normal, int poly, Model *model, XYZ move, float rotation); + + void DoStuff(); + void LoadBulletHoleTexture(char *fileName); + void LoadCraterTexture(char *fileName); + void LoadBloodTexture(char *fileName, int which); + + ~Decals() { + glDeleteTextures( 1, (const GLuint *)bulletholetextureptr ); + glDeleteTextures( 1, (const GLuint *)cratertextureptr ); + glDeleteTextures( 11, (const GLuint *)bloodtextureptr ); + }; +}; + +#endif + diff --git a/src/Files.cpp b/src/Files.cpp new file mode 100644 index 0000000..dd55c52 --- /dev/null +++ b/src/Files.cpp @@ -0,0 +1,173 @@ +#include "Files.h" + +short Files::OpenFile(Str255 Name) +{ + short volume; + char filename[33]; + short tFile; + tFile=-1; + Point ptOrigin = { 0, 0 }; + volume = 0; + sprintf (filename, "%s", Name); + SetVol( nil, volume ); + CtoPstr( filename ); + FSOpen( (Pstr) filename, volume,&tFile ); + PtoCstr( (Pstr) filename ); + sFile=tFile; + return( tFile ); +} + +short Files::OpenNewFile( SFReply *psfReply, + OSType osTypeCreator, + OSType osTypeType ) +{ + sFile = 0; + OSErr osErr; + + SetVol( nil, psfReply->vRefNum ); + osErr = Create( psfReply->fName, psfReply->vRefNum, osTypeCreator, osTypeType ); + + if ( osErr == dupFNErr ) + { + FSDelete( psfReply->fName, psfReply->vRefNum ); + Create( psfReply->fName, psfReply->vRefNum, osTypeCreator, osTypeType ); + } + + FSOpen( psfReply->fName, psfReply->vRefNum, &sFile ); + + return( sFile ); +} + + +short Files::PromptForSaveAS( short sPromptID, + short sNameID, + Str255 str255NamePrompt, + OSType osTypeCreator, + OSType osTypeType, + SFReply *psfReply ) +{ + Str255 str255Prompt; + Str255 str255Name; + sFile = 0; + Point ptOrigin = { 0, 0 }; + + GetIndString( str255Prompt, FILE_STRINGS, sPromptID ); + + if ( !str255NamePrompt ) + GetIndString( str255Name, FILE_STRINGS, sNameID ); + + else + memcpy( str255Name, str255NamePrompt, *str255NamePrompt + 1 ); + + SFPutFile( ptOrigin, str255Prompt, str255Name, nil, psfReply ); + + if ( psfReply->good ) + { + sFile = OpenNewFile( psfReply, osTypeCreator, osTypeType ); + } + + return( sFile ); +} + +short Files::OpenSavedGame(Str255 Name) +{ + Point ptOrigin = { 0, 0 }; + sSavedGameVolume = 0; + sprintf (szSavedGameName, "%s", Name); + SetVol( nil, sSavedGameVolume ); + CtoPstr( szSavedGameName ); + FSOpen( (Pstr) szSavedGameName, sSavedGameVolume,&sFile ); + PtoCstr( (Pstr) szSavedGameName ); + return( sFile ); +} + +short Files::OpenFileDialog() +{ + Point ptOrigin = { 0, 0 }; + sFile = 0; + SFReply sfReply; + SFTypeList sfTypeList = { 'DMAP', '\p', '\p', '\p' }; + SFGetFile( ptOrigin, "\p", nil, 1, sfTypeList, nil, &sfReply ); + + if ( sfReply.good ) + { + PtoCstr( sfReply.fName ); + strcpy( szSavedGameName, (Cstr) sfReply.fName ); + } + + if ( sfReply.good ) + { + sSavedGameVolume = sfReply.vRefNum; + SetVol( nil, sSavedGameVolume ); + + CtoPstr( szSavedGameName ); + + FSOpen( (Pstr) szSavedGameName, sSavedGameVolume,&sFile ); + + PtoCstr( (Pstr) szSavedGameName ); + } + + return( sFile ); +} + +void Files::StartSave() +{ + int x,y; + SFReply sfReply; + sFile = 0; + long lSize; + long lLongSize = sizeof( long ); + + CtoPstr( szSavedGameName ); + + sFile = PromptForSaveAS( SAVE_GAME_STRING, 0, (Pstr)szSavedGameName,'DAVD', 'DMAP', &sfReply ); + + PtoCstr((Pstr) szSavedGameName ); + + if ( sFile ) + { + sSavedGameVolume = sfReply.vRefNum; + PtoCstr( sfReply.fName ); + strcpy( szSavedGameName, (Cstr)sfReply.fName ); + } + + else + { + sfReply.vRefNum = sSavedGameVolume; + strcpy( (Cstr) sfReply.fName, szSavedGameName ); + CtoPstr( (Cstr)sfReply.fName ); + + sFile = OpenNewFile( &sfReply, 'GLF2', 'SKLT' ); + } + +} + +void Files::EndSave() +{ + int x,y; + SFReply sfReply; + long lSize; + long lLongSize = sizeof( long ); + + if ( sFile ) + FSClose( sFile ); + +} + +void Files::StartLoad() +{ + Boolean bLoaded = false; + long lSize; + long lLongSize = sizeof( long ); + + int x,y,kl; + sFile=OpenFileDialog(); + +} + +void Files::EndLoad() +{ + + if (sFile) + FSClose( sFile ); +} \ No newline at end of file diff --git a/src/Files.h b/src/Files.h new file mode 100644 index 0000000..35f4b6e --- /dev/null +++ b/src/Files.h @@ -0,0 +1,113 @@ +#ifndef _FILES_H_ +#define _FILES_H_ + +#include <stdio.h> +#include <stdlib.h> // Header File For Standard functions +#include <stdio.h> // Header File For Standard Input/Output +#include <string.h> +#include <ctype.h> +#include <cstdarg> +#include <cmath> +#include <iostream> +#include <fstream> +#ifdef OS9 +#include "gl.h" // Header File For The OpenGL32 Library +#include "glu.h" // Header File For The GLu32 Library +#include "tk.h" // Header File For The Glaux Library +#else +#include <GL/gl.h> +#include <GL/glu.h> +#endif +#ifdef OS9 +#include <Sound.h> +#include <Resources.h> +#include "AGL_DSp.h" // Header for OpenGL and DrawSprocket Functions +#include "Alerts.h" // Header for Dialogs and alerts for this application +#endif +#include "MacInput.h" // Header for Special Mac Input functions +#ifdef OS9 +#include "glm.h" +#include <TextUtils.h> +#endif + +#include "Support.h" + +#define FILE_STRINGS 130 +#define Pstr unsigned char * +#define Cstr char * + +#define FILE_ERROR_ALERT 138 +#define OLD_SAVE_VERSION 139 +#define UNREADABLE_SCORES_ALERT 140 + +#define SAVE_WARNING_ID 132 +#define PB_SAVE 1 +#define PB_CANCEL 2 +#define PB_DONT_SAVE 3 + +#define FILE_ERROR_STRINGS 129 +#define FILE_ERROR_PREFIX 1 +#define FILE_ERROR_SUFFIX 2 + +#define SAVE_WARNING_STRINGS 132 + +#define FILE_STRINGS 130 +#define SAVE_GAME_STRING 1 +#define SAVE_SCORES_STRING 2 +#define SCORES_NAME_STRING 3 +#define SAVE_JOURNAL_STRING 4 +#define JOURNAL_NAME_STRING 5 +#define UNTITLED_STRING 6 +#define SAVE_FORM_STRING 7 +#define FORM_NAME_STRING 8 + +#define REGISTRATION_FORM 136 + +#define FILE_NAME_SIZE 32 +#define ERROR_LENGTH 80 + +/**> Files Opening <**/ +class Files +{ + public: + char szSavedGameName[FILE_NAME_SIZE + 1]; + short sSavedGameVolume; +#ifdef OS9 + SFReply sfReply; + Boolean bGameSaved; +#endif +#ifdef OS9 + short sFile; +#else + int sFile; +#endif + +#ifdef OS9 + short OpenFile(Str255 Name); +#else + int OpenFile(Str255 Name); + Files() : sFile(-1) { } +#endif + +#ifdef OS9 + short PromptForSaveAS( short sPromptID, + short sNameID, + Str255 str255NamePrompt, + OSType osTypeCreator, + OSType osTypeType, + SFReply *psfReply ); + short OpenNewFile( SFReply *psfReply, OSType osTypeCreator, OSType osTypeType ); +#endif + short OpenSavedGame(Str255 Name); + short OpenFileDialog(); + void LoadNamedMap(Str255 Name); + void LoadGame(Str255 Name, int animnum); + + void LoadMap(); + void StartSave(); + void EndSave(); + void StartLoad(); + void EndLoad(); +}; + +#endif diff --git a/src/Fog.cpp b/src/Fog.cpp new file mode 100644 index 0000000..21ca229 --- /dev/null +++ b/src/Fog.cpp @@ -0,0 +1,54 @@ +/**> HEADER FILES <**/ +#include "Fog.h" + +void Fog::SetFog(float colorR, float colorG, float colorB, float fStart, float fEnd, float Density) +{ + fogColor[0]=colorR; + fogColor[1]=colorG; + fogColor[2]=colorB; + fogColor[3]=1; + fogStart=fStart; + fogEnd=fEnd; + fogDensity=Density; + fogMode=GL_LINEAR; + + glFogi(GL_FOG_MODE,fogMode); + glFogfv(GL_FOG_COLOR,fogColor); + glFogf(GL_FOG_DENSITY,fogDensity); + glFogi(GL_FOG_HINT,GL_DONT_CARE); + glFogi(GL_FOG_START,fogStart); + glFogi(GL_FOG_END,fogEnd); + + glEnable(GL_FOG); +} + +void Fog::TempFog(float colorR, float colorG, float colorB) +{ + GLfloat tempfogColor[4]; + tempfogColor[0]=colorR; + tempfogColor[1]=colorG; + tempfogColor[2]=colorB; + tempfogColor[3]=1; + + glFogi(GL_FOG_MODE,fogMode); + glFogfv(GL_FOG_COLOR,tempfogColor); + glFogf(GL_FOG_DENSITY,fogDensity); + glFogi(GL_FOG_HINT,GL_DONT_CARE); + glFogi(GL_FOG_START,fogStart); + glFogi(GL_FOG_END,fogEnd); + + glEnable(GL_FOG); +} + +void Fog::ResetFog() +{ + glFogi(GL_FOG_MODE,fogMode); + glFogfv(GL_FOG_COLOR,fogColor); + glFogf(GL_FOG_DENSITY,fogDensity); + glFogi(GL_FOG_HINT,GL_DONT_CARE); + glFogi(GL_FOG_START,fogStart); + glFogi(GL_FOG_END,fogEnd); + + glEnable(GL_FOG); +} + diff --git a/src/Fog.h b/src/Fog.h new file mode 100644 index 0000000..a7e0c25 --- /dev/null +++ b/src/Fog.h @@ -0,0 +1,28 @@ +#ifndef _FOG_H_ +#define _FOG_H_ + + +/**> HEADER FILES <**/ +#ifdef OS9 +#include <gl.h> +#else +#include <GL/gl.h> +#endif +#include "Quaternions.h" + + +class Fog{ + public: + GLfloat fogColor[4]; + GLint fogMode; + GLfloat fogDensity; + GLfloat fogStart; + GLfloat fogEnd; + + void SetFog(float colorR, float colorG, float colorB, float fStart, float fEnd, float fogDensity); + void TempFog(float colorR, float colorG, float colorB); + void ResetFog(); +}; + +#endif + diff --git a/src/Frustum.cpp b/src/Frustum.cpp new file mode 100644 index 0000000..0e617b8 --- /dev/null +++ b/src/Frustum.cpp @@ -0,0 +1,246 @@ +#include <cmath> +#ifdef OS9 +#include "gl.h" +#else +#include <GL/gl.h> +#endif + +#include "Frustum.h" + +void FRUSTUM:: + GetFrustum() { + float projmatrix[16]; + float mvmatrix[16]; + float clip[16]; + float t; + + glGetFloatv(GL_PROJECTION_MATRIX, projmatrix); + glGetFloatv(GL_MODELVIEW_MATRIX, mvmatrix); + + // Combine the matrices + clip[0] = mvmatrix[0] * projmatrix[0] + mvmatrix[1] * projmatrix[4] + mvmatrix[2] * projmatrix[8] + mvmatrix[3] * projmatrix[12]; + clip[1] = mvmatrix[0] * projmatrix[1] + mvmatrix[1] * projmatrix[5] + mvmatrix[2] * projmatrix[9] + mvmatrix[3] * projmatrix[13]; + clip[2] = mvmatrix[0] * projmatrix[2] + mvmatrix[1] * projmatrix[6] + mvmatrix[2] * projmatrix[10] + mvmatrix[3] * projmatrix[14]; + clip[3] = mvmatrix[0] * projmatrix[3] + mvmatrix[1] * projmatrix[7] + mvmatrix[2] * projmatrix[11] + mvmatrix[3] * projmatrix[15]; + + clip[4] = mvmatrix[4] * projmatrix[0] + mvmatrix[5] * projmatrix[4] + mvmatrix[6] * projmatrix[8] + mvmatrix[7] * projmatrix[12]; + clip[5] = mvmatrix[4] * projmatrix[1] + mvmatrix[5] * projmatrix[5] + mvmatrix[6] * projmatrix[9] + mvmatrix[7] * projmatrix[13]; + clip[6] = mvmatrix[4] * projmatrix[2] + mvmatrix[5] * projmatrix[6] + mvmatrix[6] * projmatrix[10] + mvmatrix[7] * projmatrix[14]; + clip[7] = mvmatrix[4] * projmatrix[3] + mvmatrix[5] * projmatrix[7] + mvmatrix[6] * projmatrix[11] + mvmatrix[7] * projmatrix[15]; + + clip[8] = mvmatrix[8] * projmatrix[0] + mvmatrix[9] * projmatrix[4] + mvmatrix[10] * projmatrix[8] + mvmatrix[11] * projmatrix[12]; + clip[9] = mvmatrix[8] * projmatrix[1] + mvmatrix[9] * projmatrix[5] + mvmatrix[10] * projmatrix[9] + mvmatrix[11] * projmatrix[13]; + clip[10] = mvmatrix[8] * projmatrix[2] + mvmatrix[9] * projmatrix[6] + mvmatrix[10] * projmatrix[10] + mvmatrix[11] * projmatrix[14]; + clip[11] = mvmatrix[8] * projmatrix[3] + mvmatrix[9] * projmatrix[7] + mvmatrix[10] * projmatrix[11] + mvmatrix[11] * projmatrix[15]; + + clip[12] = mvmatrix[12] * projmatrix[0] + mvmatrix[13] * projmatrix[4] + mvmatrix[14] * projmatrix[8] + mvmatrix[15] * projmatrix[12]; + clip[13] = mvmatrix[12] * projmatrix[1] + mvmatrix[13] * projmatrix[5] + mvmatrix[14] * projmatrix[9] + mvmatrix[15] * projmatrix[13]; + clip[14] = mvmatrix[12] * projmatrix[2] + mvmatrix[13] * projmatrix[6] + mvmatrix[14] * projmatrix[10] + mvmatrix[15] * projmatrix[14]; + clip[15] = mvmatrix[12] * projmatrix[3] + mvmatrix[13] * projmatrix[7] + mvmatrix[14] * projmatrix[11] + mvmatrix[15] * projmatrix[15]; + + // Right plane + frustum[0][0] = clip[3] - clip[0]; + frustum[0][1] = clip[7] - clip[4]; + frustum[0][2] = clip[11] - clip[8]; + frustum[0][3] = clip[15] - clip[12]; + + // Left plane + frustum[1][0] = clip[3] + clip[0]; + frustum[1][1] = clip[7] + clip[4]; + frustum[1][2] = clip[11] + clip[8]; + frustum[1][3] = clip[15] + clip[12]; + + // Bottom plane + frustum[2][0] = clip[3] + clip[1]; + frustum[2][1] = clip[7] + clip[5]; + frustum[2][2] = clip[11] + clip[9]; + frustum[2][3] = clip[15] + clip[13]; + + // Top plane + frustum[3][0] = clip[3] - clip[1]; + frustum[3][1] = clip[7] - clip[5]; + frustum[3][2] = clip[11] - clip[9]; + frustum[3][3] = clip[15] - clip[13]; + + // Far plane + frustum[4][0] = clip[3] - clip[2]; + frustum[4][1] = clip[7] - clip[6]; + frustum[4][2] = clip[11] - clip[10]; + frustum[4][3] = clip[15] - clip[14]; + + // Near plane + frustum[5][0] = clip[3] + clip[2]; + frustum[5][1] = clip[7] + clip[6]; + frustum[5][2] = clip[11] + clip[10]; + frustum[5][3] = clip[15] + clip[14]; + + /* normalize the right plane */ + t = sqrt(frustum[0][0]*frustum[0][0] + + frustum[0][1]*frustum[0][1] + + frustum[0][2]*frustum[0][2]); + frustum[0][0] /= t; + frustum[0][1] /= t; + frustum[0][2] /= t; + frustum[0][3] /= t; + + /* calculate left plane */ + frustum[1][0] = clip[ 3] + clip[ 0]; + frustum[1][1] = clip[ 7] + clip[ 4]; + frustum[1][2] = clip[11] + clip[ 8]; + frustum[1][3] = clip[15] + clip[12]; + + /* normalize the left plane */ + t = sqrt(frustum[1][0]*frustum[1][0] + + frustum[1][1]*frustum[1][1] + + frustum[1][2]*frustum[1][2]); + frustum[1][0] /= t; + frustum[1][1] /= t; + frustum[1][2] /= t; + frustum[1][3] /= t; + + /* calculate the bottom plane */ + frustum[2][0] = clip[ 3] + clip[ 1]; + frustum[2][1] = clip[ 7] + clip[ 5]; + frustum[2][2] = clip[11] + clip[ 9]; + frustum[2][3] = clip[15] + clip[13]; + + /* normalize the bottom plane */ + t = sqrt(frustum[2][0]*frustum[2][0] + + frustum[2][1]*frustum[2][1] + + frustum[2][2]*frustum[2][2]); + frustum[2][0] /= t; + frustum[2][1] /= t; + frustum[2][2] /= t; + frustum[2][3] /= t; + + /* calculate the top plane */ + frustum[3][0] = clip[ 3] - clip[ 1]; + frustum[3][1] = clip[ 7] - clip[ 5]; + frustum[3][2] = clip[11] - clip[ 9]; + frustum[3][3] = clip[15] - clip[13]; + + /* normalize the top plane */ + t = sqrt(frustum[3][0]*frustum[3][0] + + frustum[3][1]*frustum[3][1] + + frustum[3][2]*frustum[3][2]); + frustum[3][0] /= t; + frustum[3][1] /= t; + frustum[3][2] /= t; + frustum[3][3] /= t; + + /* calculate the far plane */ + frustum[4][0] = clip[ 3] - clip[ 2]; + frustum[4][1] = clip[ 7] - clip[ 6]; + frustum[4][2] = clip[11] - clip[10]; + frustum[4][3] = clip[15] - clip[14]; + + /* normalize the far plane */ + t = sqrt(frustum[4][0]*frustum[4][0] + + frustum[4][1]*frustum[4][1] + + frustum[4][2]*frustum[4][2]); + frustum[4][0] /= t; + frustum[4][1] /= t; + frustum[4][2] /= t; + frustum[4][3] /= t; + + /* calculate the near plane */ + frustum[5][0] = clip[ 3] + clip[ 2]; + frustum[5][1] = clip[ 7] + clip[ 6]; + frustum[5][2] = clip[11] + clip[10]; + frustum[5][3] = clip[15] + clip[14]; + + /* normalize the near plane */ + t = sqrt(frustum[5][0]*frustum[5][0] + + frustum[5][1]*frustum[5][1] + + frustum[5][2]*frustum[5][2]); + frustum[5][0] /= t; + frustum[5][1] /= t; + frustum[5][2] /= t; + frustum[5][3] /= t; + +} + +int FRUSTUM:: + CubeInFrustum(float x, float y, float z, float size) { + int c, c2; + + c2 = 0; + for(int i=0; i<6; i++) { + c=0; + if(frustum[i][0] * (x-size) + frustum[i][1] * (y-size) + frustum[i][2] * (z-size) + frustum[i][3] > 0) + c++; + if(frustum[i][0] * (x+size) + frustum[i][1] * (y-size) + frustum[i][2] * (z-size) + frustum[i][3] > 0) + c++; + if(frustum[i][0] * (x-size) + frustum[i][1] * (y+size) + frustum[i][2] * (z-size) + frustum[i][3] > 0) + c++; + if(frustum[i][0] * (x+size) + frustum[i][1] * (y+size) + frustum[i][2] * (z-size) + frustum[i][3] > 0) + c++; + if(frustum[i][0] * (x-size) + frustum[i][1] * (y-size) + frustum[i][2] * (z+size) + frustum[i][3] > 0) + c++; + if(frustum[i][0] * (x+size) + frustum[i][1] * (y-size) + frustum[i][2] * (z+size) + frustum[i][3] > 0) + c++; + if(frustum[i][0] * (x-size) + frustum[i][1] * (y+size) + frustum[i][2] * (z+size) + frustum[i][3] > 0) + c++; + if(frustum[i][0] * (x+size) + frustum[i][1] * (y+size) + frustum[i][2] * (z+size) + frustum[i][3] > 0) + c++; + if(c==0) + return 0; + if(c==8) + c2++; + } + if(c2>=6) + return 2; + else + return 1; +} + +int FRUSTUM:: + CubeInFrustum(float x, float y, float z, float size, float height) { + int c, c2; + + c2 = 0; + for(int i=0; i<6; i++) { + c=0; + if(frustum[i][0] * (x-size) + frustum[i][1] * (y-height) + frustum[i][2] * (z-size) + frustum[i][3] > 0) + c++; + if(frustum[i][0] * (x+size) + frustum[i][1] * (y-height) + frustum[i][2] * (z-size) + frustum[i][3] > 0) + c++; + if(frustum[i][0] * (x-size) + frustum[i][1] * (y+height) + frustum[i][2] * (z-size) + frustum[i][3] > 0) + c++; + if(frustum[i][0] * (x+size) + frustum[i][1] * (y+height) + frustum[i][2] * (z-size) + frustum[i][3] > 0) + c++; + if(frustum[i][0] * (x-size) + frustum[i][1] * (y-height) + frustum[i][2] * (z+size) + frustum[i][3] > 0) + c++; + if(frustum[i][0] * (x+size) + frustum[i][1] * (y-height) + frustum[i][2] * (z+size) + frustum[i][3] > 0) + c++; + if(frustum[i][0] * (x-size) + frustum[i][1] * (y+height) + frustum[i][2] * (z+size) + frustum[i][3] > 0) + c++; + if(frustum[i][0] * (x+size) + frustum[i][1] * (y+height) + frustum[i][2] * (z+size) + frustum[i][3] > 0) + c++; + if(c==0) + return 0; + if(c==8) + c2++; + } + if(c2>=6) + return 2; + else + return 1; +} + +int FRUSTUM:: + SphereInFrustum(float x, float y, float z, float radius) { + int c2; + + c2 = 0; + for(int i=0; i<6; i++) { + if(frustum[i][0] * x + frustum[i][1] * y + frustum[i][2] * z + frustum[i][3] > -1*radius) + c2++; + else + return 0; + } + if(c2>=6) + return 2; + else + return 1; +} diff --git a/src/Frustum.h b/src/Frustum.h new file mode 100644 index 0000000..1680226 --- /dev/null +++ b/src/Frustum.h @@ -0,0 +1,14 @@ +#ifndef FRUSTUM_H +#define FRUSTUM_H + +class FRUSTUM { + public: + float frustum[6][4]; + void GetFrustum(); + int CubeInFrustum(float, float, float, float); + int CubeInFrustum(float, float, float, float, float); + int SphereInFrustum(float, float, float, float); +}; + +#endif + diff --git a/src/Game.h b/src/Game.h new file mode 100644 index 0000000..e7d5b53 --- /dev/null +++ b/src/Game.h @@ -0,0 +1,230 @@ +#ifndef _GAME_H_ +#define _GAME_H_ + +#ifdef OS9 +#include <gl.h> +#include <glu.h> +#include <tk.h> +#else +#include <GL/gl.h> +#include <GL/glu.h> +#endif +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#ifdef OS9 +#include <Sound.h> +#include <Resources.h> +#endif +#include <cstdarg> +#ifdef OS9 +#include <glm.h> +#include <TextUtils.h> +#endif +#ifndef OS9 +#include <SDL/SDL.h> +#endif +#ifdef OS9 +#include "alut.h" +#else +#include <AL/al.h> +#include <AL/alut.h> +#endif +#include "Timer.h" +#ifdef OS9 +#include "AGL_DSp.h" +#endif +#include "MacInput.h" +#include "Quaternions.h" +#include "Camera.h" +#include "Skeleton.h" +#include "Files.h" +#include "Models.h" +#include "Text.h" +#include "Fog.h" +#include "Frustum.h" +#include "Sprites.h" +#include "Person.h" +#include "Decals.h" + +#define num_blocks 100 +#define block_spacing 360 +#define max_people 90 +#define max_people_block 20 + + +class Game +{ + public: + //Eventloop + Boolean gQuit; + float gamespeed; + double multiplier2,multiplier3,multiplier4,multiplier5,end,start,timetaken,framespersecond; + timer theTimer; + float sps; + int maxfps; +#ifdef OS9 + AGLContext gOpenGLContext; + CGrafPtr theScreen; +#endif + //Graphics + int screenwidth,screenheight; + float viewdistance; + + //GL functions + GLvoid ReSizeGLScene(float fov, float near); + int DrawGLScene(void); + int InitGL(void); + void LoadingScreen(float percent); + + //Game Functions + void HandleKeyDown( char theChar ); +#ifdef OS9 + void DoEvent( EventRecord *event ); +#endif + void EventLoop( void ); + void Tick(); + void Splat(int k); + void InitGame(); + void Dispose(); + + //Mouse + Point mouseloc; + Point oldmouseloc; + + float mouserotation,mouserotation2; + float oldmouserotation,oldmouserotation2; + float mousesensitivity; + float usermousesensitivity; + + //keyboard + + bool tabkeydown; + + //Project Specific + int cityrotation[num_blocks][num_blocks]; + int citytype[num_blocks][num_blocks]; + int citypeoplenum[num_blocks][num_blocks]; + bool drawn[num_blocks][num_blocks]; + int onblockx,onblocky; + bool cubetest; + bool disttest; + bool oldbutton; + + bool initialized; + + float flashamount; + float flashr,flashg,flashb; + + int enemystate; + + int cycle; + + bool whacked; + + float losedelay; + + XYZ bodycoords; + + FRUSTUM frustum; + Model blocks[4]; + Model blockwalls[4]; + Model blockcollide[4]; + Model blocksimplecollide[4]; + Model blockroofs[4]; + Model blockocclude; + Model sidewalkcollide; + Model street; + Model Bigstreet; + Model path; + Model blocksimple; + XYZ boundingpoints[8]; + Files files; + Text text; + int goodkills; + int badkills; + int civkills; + int machinegunsoundloop; + + bool lasersight; + bool debug; + bool vblsync; + + bool blur; + bool blurness; + + bool paused; + + int mainmenu; + + bool reloadtoggle; + + bool aimtoggle; + + Point olddrawmouse; + + XYZ vipgoal; + + XYZ aimer[2]; + + double eqn[4]; + + float oldrot,oldrot2; + + XYZ lastshot[2]; + bool zoom; + bool oldzoom; + + int numpeople; + float spawndelay; + + bool customlevels; + + bool musictoggle; + + float psychicpower; + + int type; + + bool slomokeydown; + + int mouseoverbutton; + int oldmouseoverbutton; + + Person person[max_people]; + + GLuint personspritetextureptr; + GLuint deadpersonspritetextureptr; + GLuint scopetextureptr; + GLuint flaretextureptr; + + bool killedinnocent; + bool gameinprogress; + bool beatgame; + bool mainmenuness; + int murderer; + float timeremaining; + int whichsong; + int oldscore; + int highscore; + int score; + int mission; + int nummissions; + int numpossibleguns; + int possiblegun[6]; + int evilprobability; + float difficulty; + bool azertykeyboard; + bool oldvisionkey; + + ~Game() { + glDeleteTextures( 1, (const GLuint *)personspritetextureptr ); + glDeleteTextures( 1, (const GLuint *)deadpersonspritetextureptr ); + glDeleteTextures( 1, (const GLuint *)scopetextureptr ); + glDeleteTextures( 1, (const GLuint *)flaretextureptr ); + } + +}; + +#endif diff --git a/src/GameDraw.cpp b/src/GameDraw.cpp new file mode 100644 index 0000000..c79d87e --- /dev/null +++ b/src/GameDraw.cpp @@ -0,0 +1,1770 @@ +#include "Game.h" + +extern int thirdperson; + +extern double multiplier; + +extern int nocolors; + +extern int visions; + +extern unsigned int gSourceID[100]; + +extern unsigned int gSampleSet[100]; + +extern Camera camera; + +extern Sprites sprites; + +extern float camerashake; + +extern Fog fog; + +extern float fogcolorr; + +extern float fogcolorg; + +extern float fogcolorb; + +extern float sinefluct; + +extern float sinefluctprog; + +extern int environment; + +extern Decals decals; + +/*********************> DrawGLScene() <*****/ + +int Game::DrawGLScene(void) + +{ + + //Main menu + + if(mainmenu==1){ + + //Setup fast sine fluctuation + + sinefluct=sin(sinefluctprog); + + sinefluctprog+=multiplier*1.5; + + + + glLoadIdentity(); + + glClearColor(0,0,0,1); + + glDisable(GL_CLIP_PLANE0); + + glDisable(GL_FOG); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + + //"Black Shades" + + glDisable(GL_TEXTURE_2D); + + glDisable(GL_DEPTH_TEST); // Disables Depth Testing + + glDisable(GL_CULL_FACE); + + glDisable(GL_LIGHTING); + + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + + glDepthMask(0); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPushMatrix(); // Store The Projection Matrix + + glLoadIdentity(); // Reset The Projection Matrix + + glOrtho(0,640,0,480,-100,100); // Set Up An Ortho Screen + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + //Draw smoke + + glPushMatrix(); // Store The Modelview Matrix + + glLoadIdentity(); // Reset The Modelview Matrix + + glTranslatef(60+sinefluct*40,335-sinefluct*9,0); + + glScalef(500-sinefluct*80,70+sinefluct*18,1); + + glTranslatef(.5,.5,0); + + glScalef(.5,.5,1); + + glRotatef(sinefluctprog*50,0,0,1); + + glEnable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, sprites.smoketextureptr); + + glEnable(GL_BLEND); + + glColor4f(1,1,1,.4+sinefluct/8); + + glBegin(GL_TRIANGLES); + + glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f); + + glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f); + + glEnd(); + + glPopMatrix(); + + glPushMatrix(); // Store The Modelview Matrix + + glLoadIdentity(); // Reset The Modelview Matrix + + glTranslatef(60+sinefluct*40,335-sinefluct*9,0); + + glScalef(530-sinefluct*80,50+sinefluct*18,1); + + glTranslatef(.5,.5,0); + + glScalef(.5,.5,1); + + glRotatef(-sinefluctprog*50,0,0,1); + + glEnable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, sprites.smoketextureptr); + + glEnable(GL_BLEND); + + glColor4f(1,1,1,.4-sinefluct/8); + + glBegin(GL_TRIANGLES); + + glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f); + + glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f); + + glEnd(); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glDepthMask(1); + + + + //Text + + + + glEnable(GL_TEXTURE_2D); + + glColor4f(0,0,0,1); + + static char string[256]=""; + + sprintf (string, "Black Shades"); + + text.glPrint(100,175,string,1,2,640,480); + + + + //"New Game" + + glDisable(GL_TEXTURE_2D); + + glDisable(GL_DEPTH_TEST); // Disables Depth Testing + + glDisable(GL_CULL_FACE); + + glDisable(GL_LIGHTING); + + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + + glDepthMask(0); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPushMatrix(); // Store The Projection Matrix + + glLoadIdentity(); // Reset The Projection Matrix + + glOrtho(0,640,0,480,-100,100); // Set Up An Ortho Screen + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + //Draw smoke + + glPushMatrix(); // Store The Modelview Matrix + + glLoadIdentity(); // Reset The Modelview Matrix + + glTranslatef(120-sinefluct*40,235+sinefluct*9,0); + + glScalef(440+sinefluct*80,70-sinefluct*18,1); + + glTranslatef(.5,.5,0); + + glScalef(.5,.5,1); + + glRotatef(sinefluctprog*50,0,0,1); + + glEnable(GL_TEXTURE_2D); + + if(mouseoverbutton!=1)glBindTexture(GL_TEXTURE_2D, sprites.smoketextureptr); + + if(mouseoverbutton==1)glBindTexture(GL_TEXTURE_2D, flaretextureptr); + + glEnable(GL_BLEND); + + glColor4f(1,0,0,.5+sinefluct/6); + + glBegin(GL_TRIANGLES); + + glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f); + + glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f); + + glEnd(); + + glPopMatrix(); + + glPushMatrix(); // Store The Modelview Matrix + + glLoadIdentity(); // Reset The Modelview Matrix + + glTranslatef(120-sinefluct*40,235+sinefluct*9,0); + + glScalef(460+sinefluct*80,50-sinefluct*18,1); + + glTranslatef(.5,.5,0); + + glScalef(.5,.5,1); + + glRotatef(-sinefluctprog*50,0,0,1); + + glEnable(GL_TEXTURE_2D); + + if(mouseoverbutton!=1)glBindTexture(GL_TEXTURE_2D, sprites.smoketextureptr); + + if(mouseoverbutton==1)glBindTexture(GL_TEXTURE_2D, flaretextureptr); + + glEnable(GL_BLEND); + + glColor4f(1,0,0,.5-sinefluct/6); + + glBegin(GL_TRIANGLES); + + glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f); + + glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f); + + glEnd(); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glDepthMask(1); + + + + //Text + + + + glEnable(GL_TEXTURE_2D); + + glColor4f(0,0,0,1); + + if(!gameinprogress)sprintf (string, "New Game"); + + if(gameinprogress)sprintf (string, "Resume Game"); + + text.glPrint(190-gameinprogress*10,170,string,1,1.5,640,480); + + + + //"Quit" + + glDisable(GL_TEXTURE_2D); + + glDisable(GL_DEPTH_TEST); // Disables Depth Testing + + glDisable(GL_CULL_FACE); + + glDisable(GL_LIGHTING); + + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + + glDepthMask(0); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPushMatrix(); // Store The Projection Matrix + + glLoadIdentity(); // Reset The Projection Matrix + + glOrtho(0,640,0,480,-100,100); // Set Up An Ortho Screen + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + //Draw smoke + + glPushMatrix(); // Store The Modelview Matrix + + glLoadIdentity(); // Reset The Modelview Matrix + + glTranslatef(120-sinefluct*40,112+sinefluct*9,0); + + glScalef(440+sinefluct*80,70-sinefluct*18,1); + + glTranslatef(.5,.5,0); + + glScalef(.5,.5,1); + + glRotatef(sinefluctprog*50,0,0,1); + + glEnable(GL_TEXTURE_2D); + + if(mouseoverbutton!=2)glBindTexture(GL_TEXTURE_2D, sprites.smoketextureptr); + + if(mouseoverbutton==2)glBindTexture(GL_TEXTURE_2D, flaretextureptr); + + glEnable(GL_BLEND); + + glColor4f(1,0,0,.5+sinefluct/6); + + glBegin(GL_TRIANGLES); + + glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f); + + glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f); + + glEnd(); + + glPopMatrix(); + + glPushMatrix(); // Store The Modelview Matrix + + glLoadIdentity(); // Reset The Modelview Matrix + + glTranslatef(120-sinefluct*40,112+sinefluct*9,0); + + glScalef(460+sinefluct*80,50-sinefluct*18,1); + + glTranslatef(.5,.5,0); + + glScalef(.5,.5,1); + + glRotatef(-sinefluctprog*50,0,0,1); + + glEnable(GL_TEXTURE_2D); + + if(mouseoverbutton!=2)glBindTexture(GL_TEXTURE_2D, sprites.smoketextureptr); + + if(mouseoverbutton==2)glBindTexture(GL_TEXTURE_2D, flaretextureptr); + + glEnable(GL_BLEND); + + glColor4f(1,0,0,.5-sinefluct/6); + + glBegin(GL_TRIANGLES); + + glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f); + + glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f); + + glEnd(); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glDepthMask(1); + + + + //Text + + + + glEnable(GL_TEXTURE_2D); + + glColor4f(0,0,0,1); + + if(!gameinprogress)sprintf (string, "Quit"); + + if(gameinprogress)sprintf (string, "End Game"); + + text.glPrint(197-gameinprogress*15,87,string,1,1.5,640,480); + + + + //High score + + glColor4f(.5+sinefluct/5,0,0,1); + + if(!beatgame)sprintf (string, "High Score: %d", highscore); + + if(beatgame)sprintf (string, "High Score: %d *COMPLETED* Please vote for Black Shades at iDevGames.com!", highscore); + + text.glPrint(0,0,string,1,.8,640,480); + + + + //Mandatory udg text + + glColor4f(.3-sinefluct/20,.3-sinefluct/20,.3-sinefluct/20,1); + + sprintf (string, "uDevGame 2002 Entry - Visit iDevGames.com for more games!"); + + text.glPrint(500,750,string,1,.6,640,480); + + + + + //Mouse (draw) + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPushMatrix(); // Store The Projection Matrix + + glLoadIdentity(); // Reset The Projection Matrix + + glOrtho(0,screenwidth,0,screenheight,-100,100); // Set Up An Ortho Screen + + glMatrixMode(GL_MODELVIEW); + + glDisable(GL_TEXTURE_2D); + + + Point mouseloc; + + GetMouse(&mouseloc); + + mouseloc.v=screenheight-mouseloc.v; + + + glColor4f(.1,0,0,1); + + + + float size=5; + + + + glBegin(GL_TRIANGLES); + + glVertex3f(mouseloc.h,mouseloc.v,0); + + glVertex3f(mouseloc.h+2*size,mouseloc.v-2*size,0); + + glVertex3f(mouseloc.h+.5*size,mouseloc.v-2*size,0); + + glEnd(); + + + + glColor4f(1,0,0,1); + + + + glBegin(GL_QUADS); + + glVertex3f(olddrawmouse.h,olddrawmouse.v,0); + + glVertex3f(mouseloc.h,mouseloc.v,0); + + glVertex3f(mouseloc.h+2*size,mouseloc.v-2*size,0); + + glVertex3f(olddrawmouse.h+2*size,olddrawmouse.v-2*size,0); + + + + glVertex3f(olddrawmouse.h,olddrawmouse.v,0); + + glVertex3f(mouseloc.h,mouseloc.v,0); + + glVertex3f(mouseloc.h+.5*size,mouseloc.v-2*size,0); + + glVertex3f(olddrawmouse.h+.5*size,olddrawmouse.v-2*size,0); + + + + glVertex3f(olddrawmouse.h+2*size,olddrawmouse.v-2*size,0); + + glVertex3f(mouseloc.h+2*size,mouseloc.v-2*size,0); + + glVertex3f(mouseloc.h+.5*size,mouseloc.v-2*size,0); + + glVertex3f(olddrawmouse.h+.5*size,olddrawmouse.v-2*size,0); + + glEnd(); + + glPopMatrix(); + + + olddrawmouse=mouseloc; + + + //Flash + + if(flashamount>0){ + + if(flashamount>1)flashamount=1; + + flashamount-=multiplier; + + if(flashamount<0)flashamount=0; + + glDisable(GL_DEPTH_TEST); // Disables Depth Testing + + glDisable(GL_CULL_FACE); + + glDisable(GL_LIGHTING); + + glDepthMask(0); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPushMatrix(); // Store The Projection Matrix + + glLoadIdentity(); // Reset The Projection Matrix + + glOrtho(0,screenwidth,0,screenheight,-100,100); // Set Up An Ortho Screen + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPushMatrix(); // Store The Modelview Matrix + + glLoadIdentity(); // Reset The Modelview Matrix + + glScalef(screenwidth,screenheight,1); + + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_BLEND); + + glColor4f(flashr,flashg,flashb,flashamount); + + glBegin(GL_QUADS); + + glVertex3f(0, 0, 0.0f); + + glVertex3f(256, 0, 0.0f); + + glVertex3f(256, 256, 0.0f); + + glVertex3f(0, 256, 0.0f); + + glEnd(); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glEnable(GL_DEPTH_TEST); // Enables Depth Testing + + glEnable(GL_CULL_FACE); + + glDisable(GL_BLEND); + + glDepthMask(1); + + } + + } + + //If in-game + + if(mainmenu!=1){ + + //If flashing to fix menu bug, go back to menu after a frame + + if(mainmenu==2)mainmenu=1; + + glLoadIdentity(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); + + glDisable(GL_CLIP_PLANE0); + + //Visions + + sinefluct=sin(sinefluctprog); + + sinefluctprog+=multiplier*3; + + if(visions==0){ + + //environment light + + if(environment==sunny_environment){ + + viewdistance=2000; + + fogcolorr=.5; + + fogcolorg=.5; + + fogcolorb=.8; + + fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.1); + + } + + if(environment==foggy_environment){ + + viewdistance=500; + + fogcolorr=.5; + + fogcolorg=.5; + + fogcolorb=.5; + + fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.2); + + } + + if(environment==night_environment){ + + viewdistance=500; + + fogcolorr=.15; + + fogcolorg=.15; + + fogcolorb=.3; + + fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.2); + + } + + if(environment==snowy_environment){ + + viewdistance=800; + + fogcolorr=.5; + + fogcolorg=.5; + + fogcolorb=.5; + + fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.2); + + } + + if(environment==rainy_environment){ + + viewdistance=700; + + fogcolorr=.3; + + fogcolorg=.3; + + fogcolorb=.3; + + fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.2); + + } + + if(environment==firey_environment){ + + viewdistance=600; + + fogcolorr=.3; + + fogcolorg=.1; + + fogcolorb=0; + + fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.2); + + } + + glClearColor(fogcolorr,fogcolorg,fogcolorb,1); + + + + if(environment==sunny_environment){ + + GLfloat LightAmbient[]= { fogcolorr/4, fogcolorg/4, fogcolorb/4, 1.0f}; + + GLfloat LightDiffuse[]= { fogcolorr*1.6, fogcolorg*1.6, fogcolorr*1.6, 1.0f }; + + glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient); + + glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse); + + } + + if(environment!=sunny_environment){ + + GLfloat LightAmbient[]= { fogcolorr*.8, fogcolorg*.8, fogcolorb*.8, 1.0f}; + + GLfloat LightDiffuse[]= { fogcolorr*.8, fogcolorg*.8, fogcolorr*.8, 1.0f }; + + glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient); + + glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse); + + } + + + + glEnable(GL_LIGHT0); + + + + //Change fov if zooming with scope + + if(!zoom)ReSizeGLScene(90,.1); + + if(zoom)ReSizeGLScene(10,.6); + + nocolors=0; + + } + + + + if(visions==1){ + + //light + + GLfloat LightAmbient[]= { 0, 0, 0, 1.0f}; + + GLfloat LightDiffuse[]= { .1+sinefluct/5, 0, 0, 1.0f }; + + + + glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient); + + glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse); + + glEnable(GL_LIGHT0); + + + + fogcolorr=(sinefluct/4+.5); + + fogcolorg=0; + + fogcolorb=0; + + fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8*.5*(sinefluct/4+.3),sinefluct/3+.7); + + glClearColor(fogcolorr,fogcolorg,fogcolorb,1); + + ReSizeGLScene(120-sinefluct*20,.3); + + glRotatef(sinefluct*10,0,0,.1); + + nocolors=1; + + //Pitch higher if moving for effect + + if(person[0].currentanimation==idleanim)alSourcef(gSourceID[visionsound], AL_PITCH, 1); + + if(person[0].currentanimation!=idleanim)alSourcef(gSourceID[visionsound], AL_PITCH, 2); + + } + + + + //Camera + + float bluramount=.1*blurness; + + blur=1-blur; + + //Set rotation/position + + if(thirdperson)glTranslatef(camera.targetoffset.x,camera.targetoffset.y,camera.targetoffset.z); + + if(thirdperson!=2&&(person[0].skeleton.free!=1||thirdperson!=0)){ + + glRotatef(camera.visrotation2+-bluramount/2+(float)blur*bluramount,1,0,0); + + glRotatef(camera.visrotation+-bluramount/2+(float)blur*bluramount,0,1,0); + + } + + if(thirdperson==0&&person[0].skeleton.free==1){ + + glRotatef(person[0].skeleton.joints[(person[0].skeleton.jointlabels[head])].rotate3,0,1,0); + + glRotatef(180-(person[0].skeleton.joints[(person[0].skeleton.jointlabels[head])].rotate2+90),0,0,1); + + glRotatef(person[0].skeleton.joints[(person[0].skeleton.jointlabels[head])].rotate1+90,0,1,0); + + } + + if(thirdperson==2){ + + glRotatef(oldrot2+-bluramount/2+(float)blur*bluramount,1,0,0); + + glRotatef(oldrot+-bluramount/2+(float)blur*bluramount,0,1,0); + + } + + //Shake camera if grenade explosion + + if(camerashake>0){ + + if(!(person[0].aiming<1||person[0].whichgun==grenade||thirdperson)){ + + camerashake=0; + + } + + glTranslatef((float)(Random()%100)/100*camerashake,(float)(Random()%100)/100*camerashake,(float)(Random()%100)/100*camerashake); + + } + + camera.Apply(); + + + + glPushMatrix(); + + glClipPlane(GL_CLIP_PLANE0, eqn); + + glDisable(GL_CLIP_PLANE0); + + glPopMatrix(); + + + + frustum.GetFrustum(); + + + + GLfloat LightPosition[]= { -.5, 1, -.8, 0.0f }; + + glLightfv(GL_LIGHT0, GL_POSITION, LightPosition); + + + + glDisable(GL_TEXTURE_2D); + + glEnable(GL_FOG); + + glEnable(GL_COLOR_MATERIAL); + + glEnable(GL_CULL_FACE); + + glDepthMask(1); + + + + //Draw street + + glPushMatrix(); + + glDepthMask(0); + + glDisable(GL_DEPTH_TEST); + + glEnable(GL_LIGHTING); + + glTranslatef(camera.position.x,0,camera.position.z); + + glScalef(viewdistance*5/100,1,viewdistance*5/100); + + if(visions==0)street.draw(.22,.22,.22); + + if(visions==1)street.draw(0,0,0); + + glEnable(GL_DEPTH_TEST); + + glDepthMask(1); + + glPopMatrix(); + + + + if(visions==0)glEnable(GL_LIGHTING); + + if(visions==1)glDisable(GL_LIGHTING); + + + + //Draw blocks + + glEnable(GL_BLEND); + + XYZ move2; + + XYZ move; + + int beginx,endx; + + int beginz,endz; + + int beginoccludex,endoccludex; + + int beginoccludez,endoccludez; + + int distsquared; + + + + //Only nearby blocks + + beginx=(camera.position.x-viewdistance+block_spacing/2)/block_spacing-2; + + if(beginx<0)beginx=0; + + beginz=(camera.position.z-viewdistance+block_spacing/2)/block_spacing-2; + + if(beginz<0)beginz=0; + + + + endx=(camera.position.x+viewdistance+block_spacing/2)/block_spacing+2; + + if(endx>num_blocks-1)endx=num_blocks-1; + + endz=(camera.position.z+viewdistance+block_spacing/2)/block_spacing+2; + + if(endz>num_blocks-1)endz=num_blocks-1; + + + + bool draw; + + int numfail; + + int whichtri; + + XYZ collpoint; + + + + for(int i=beginx;i<=endx;i++){ + + for(int j=beginz;j<=endz;j++){ + + drawn[i][j]=1; + + } + + } + + + + if(beginx<endx&&beginz<endz) + + for(int i=beginx;i<=endx;i++){ + + for(int j=beginz;j<=endz;j++){ + + draw=1; + + //Only draw if visible + + distsquared=((i)*block_spacing-camera.position.x)*((i)*block_spacing-camera.position.x)+((j)*block_spacing-camera.position.z)*((j)*block_spacing-camera.position.z); + + if(distsquared>(viewdistance*viewdistance+block_spacing*block_spacing ))draw=0; + + if(draw&&citytype[i][j]!=3&&!frustum.CubeInFrustum((i)*block_spacing,0,(j)*block_spacing,block_spacing))draw=0; + + if(draw&&citytype[i][j]!=3&&!frustum.SphereInFrustum(blocks[citytype[i][j]].boundingspherecenter.x+(i)*block_spacing,blocks[citytype[i][j]].boundingspherecenter.y,blocks[citytype[i][j]].boundingspherecenter.z+(j)*block_spacing,blocks[citytype[i][j]].boundingsphereradius))draw=0; + + if(draw){ + + glPushMatrix(); + + glTranslatef(i*block_spacing,0,j*block_spacing); + + glRotatef(cityrotation[i][j]*90,0,1,0); + + blocks[citytype[i][j]].draw(); + + glPopMatrix(); + + } + + if(!draw){ + + move.y=0; + + move.x=i*block_spacing; + + move.z=j*block_spacing; + + if(findDistancefast(move,camera.position)<300000)drawn[i][j]=0; + + } + + } + + } + + + + //Decals + + decals.draw(); + + + + //Occluding blocks + + beginx=(camera.position.x+block_spacing/2)/block_spacing-2; + + if(beginx<0)beginx=0; + + beginz=(camera.position.z+block_spacing/2)/block_spacing-2; + + if(beginz<0)beginz=0; + + + + endx=(camera.position.x+block_spacing/2)/block_spacing+2; + + if(endx>num_blocks-1)endx=num_blocks-1; + + endz=(camera.position.z+block_spacing/2)/block_spacing+2; + + if(endz>num_blocks-1)endz=num_blocks-1; + + + + float M[16]; + + XYZ drawpoint; + + float size=20; + + + + //Draw people + + if(visions==1)fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8*.5*(-sinefluct/4+.3),-sinefluct/3+.7); + + glColor4f(1,1,1,1); + + glEnable(GL_COLOR_MATERIAL); + + glEnable(GL_BLEND); + + for(int i=0;i<numpeople;i++){ + + + + draw=1; + + if(person[i].skeleton.free<1){ + + if(person[i].whichblockx>=0&&person[i].whichblockx<num_blocks&&person[i].whichblocky>=0&&person[i].whichblocky<num_blocks){ + + if(!drawn[person[i].whichblockx][person[i].whichblocky])draw=0; + + }else draw=0; + + if(draw) + + if(!frustum.CubeInFrustum(person[i].playercoords.x,person[i].playercoords.y,person[i].playercoords.z,5))draw=0; + + if(draw) + + if(findDistancefast(person[i].playercoords,camera.position)>1000000)draw=0; + + if(draw) + + for(int j=beginx;j<=endx;j++){ + + for(int k=beginz;k<=endz;k++){ + + if(draw){ + + move.y=0; + + move.x=j*block_spacing; + + move.z=k*block_spacing; + + if(findDistancefast(move,camera.position)<100000){ + + whichtri=blockocclude.LineCheck2(camera.position,person[i].playercoords,&collpoint,move,0); + + if(whichtri!=-1)draw=0; + + } + + } + + } + + } + + if(draw){ + + move.y=0; + + move.x=person[i].whichblockx*block_spacing; + + move.z=person[i].whichblocky*block_spacing; + + whichtri=blockocclude.LineCheck2(camera.position,person[i].playercoords,&collpoint,move,0); + + if(whichtri!=-1)draw=0; + + } + + if(i==0)draw=1; + + } + + if(person[i].skeleton.free==1){ + + if(draw) + + if(!person[i].skeleton.broken&&!frustum.CubeInFrustum(person[i].averageloc.x,person[i].averageloc.y,person[i].averageloc.z,5))draw=0; + + if(draw) + + if(findDistancefast(person[i].averageloc,camera.position)>1000000)draw=0; + + if(draw) + + if(person[i].skeleton.joints[0].position.y<-2)draw=0; + + for(int j=beginx;j<=endx;j++){ + + for(int k=beginz;k<=endz;k++){ + + if(draw){ + + move.y=0; + + move.x=j*block_spacing; + + move.z=k*block_spacing; + + if(findDistancefast(move,camera.position)<100000){ + + whichtri=blockocclude.LineCheck2(camera.position,person[i].averageloc,&collpoint,move,0); + + if(whichtri!=-1)draw=0; + + } + + } + + } + + } + + if(draw){ + + move.y=0; + + move.x=person[i].whichblockx*block_spacing; + + move.z=person[i].whichblocky*block_spacing; + + whichtri=blockocclude.LineCheck2(camera.position,person[i].averageloc,&collpoint,move,0); + + if(whichtri!=-1)draw=0; + + } + + if(i==0)draw=1; + + } + + if(draw&&person[i].existing==1){ + + if((findDistancefast(person[i].playercoords,camera.position)<100000+zoom*3000000&&person[i].skeleton.free<1)||(findDistancefast(person[i].averageloc,camera.position)<100000+zoom*3000000&&person[i].skeleton.free>=1)){ + + glPushMatrix(); + + if(person[i].skeleton.free==0){ + + glTranslatef(person[i].playercoords.x,person[i].playercoords.y,person[i].playercoords.z); + + glRotatef(person[i].playerrotation,0,1,0); + + if(i!=0||visions==0)person[i].DoAnimations(i); + + if(i==0&&visions==1)person[i].DoAnimationslite(i); + + } + + if(visions==1)nocolors=1; + + if(visions==1&&person[i].type==eviltype)nocolors=2; + + if(visions==1&&person[i].type==viptype)nocolors=3; + + if(!(visions==1&&i==0)&&!(zoom==1&&i==0))person[i].DrawSkeleton(i); + + glPopMatrix(); + + } + + else{ + + glPushMatrix(); + + if(person[i].skeleton.free<1)person[i].DoAnimationslite(i); + + glColor4f(1,1,1,1); + + glEnable(GL_BLEND); + + glDisable(GL_CULL_FACE); + + glEnable(GL_TEXTURE_2D); + + glDisable(GL_LIGHTING); + + glDepthMask(0); + + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + if(person[i].skeleton.free<1){ + + glBindTexture(GL_TEXTURE_2D, personspritetextureptr); + + glTranslatef(person[i].playercoords.x,person[i].playercoords.y+size/2*.3,person[i].playercoords.z); + + } + + if(person[i].skeleton.free==1){ + + glBindTexture(GL_TEXTURE_2D, deadpersonspritetextureptr); + + glTranslatef(person[i].averageloc.x,person[i].averageloc.y+size/2*.3,person[i].averageloc.z); + + } + + glGetFloatv(GL_MODELVIEW_MATRIX,M); + + drawpoint.x=M[12]; + + drawpoint.y=M[13]; + + drawpoint.z=M[14]; + + glLoadIdentity(); + + glTranslatef(drawpoint.x, drawpoint.y, drawpoint.z); + + glBegin(GL_TRIANGLES); + + glTexCoord2f(1.0f, 1.0f); glVertex3f( .3f*size, .3f*size, 0.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-.3f*size, .3f*size, 0.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( .3f*size,-.3f*size, 0.0f); + + glTexCoord2f(0.0f, 0.0f); glVertex3f(-.3f*size,-.3f*size, 0.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( .3f*size, -.3f*size, 0.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-.3f*size, .3f*size, 0.0f); + + glEnd(); + + glPopMatrix(); + + glDepthMask(1); + + glDisable(GL_TEXTURE_2D); + + glEnable(GL_CULL_FACE); + + if(visions!=1)glEnable(GL_LIGHTING); + + } + + } + + if(person[i].skeleton.free<1&&!draw)person[i].DoAnimationslite(i); + + + + if(!person[i].existing) + + if(!draw||findDistancefast(person[i].playercoords,camera.position)>10000){person[i].existing=1;} + + } + + glDisable(GL_COLOR_MATERIAL); + + glDisable(GL_BLEND); + + + + //Attacker psychicness + + for(int i=0;i<numpeople;i++){ + + if(person[i].killtarget>-1&&person[i].killtargetvisible&&person[i].skeleton.free==0&&person[person[i].killtarget].skeleton.free==0){ + + sprites.MakeSprite(bulletinstant, (shotdelayamount/difficulty-person[i].shotdelay)/shotdelayamount/difficulty/2, 1, person[i].shotdelay/shotdelayamount/difficulty, person[i].shotdelay/shotdelayamount/difficulty, DoRotation(person[i].skeleton.joints[person[i].skeleton.jointlabels[lefthand]].position,0,person[i].playerrotation,0)+person[i].playercoords, person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[abdomen]].position+person[person[i].killtarget].playercoords, person[i].shotdelay*2); + + } + + if(person[i].killtarget>-1&&person[i].killtargetvisible&&person[i].skeleton.free==0&&person[person[i].killtarget].skeleton.free!=0){ + + sprites.MakeSprite(bulletinstant, (shotdelayamount/difficulty-person[i].shotdelay)/shotdelayamount/difficulty/2, 1, person[i].shotdelay/shotdelayamount/difficulty, person[i].shotdelay/shotdelayamount/difficulty, DoRotation(person[i].skeleton.joints[person[i].skeleton.jointlabels[lefthand]].position,0,person[i].playerrotation,0)+person[i].playercoords, person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[abdomen]].position, person[i].shotdelay*2); + + } + + } + + + + //Sprites + + glEnable(GL_CLIP_PLANE0); + + sprites.draw(); + + + + glDisable(GL_CLIP_PLANE0); + + + + glDisable(GL_FOG); + + //Zoom + + glAlphaFunc(GL_GREATER, 0.01); + + + + if(zoom){ + + glDisable(GL_DEPTH_TEST); // Disables Depth Testing + + glDisable(GL_CULL_FACE); + + glDisable(GL_LIGHTING); + + glDepthMask(0); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPushMatrix(); // Store The Projection Matrix + + glLoadIdentity(); // Reset The Projection Matrix + + glOrtho(0,screenwidth,0,screenheight,-100,100); // Set Up An Ortho Screen + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPushMatrix(); // Store The Modelview Matrix + + glLoadIdentity(); // Reset The Modelview Matrix + + glScalef(screenwidth,screenheight,1); + + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_BLEND); + + glEnable(GL_TEXTURE_2D); + + glColor4f(.5,.5,.5,1); + + glBindTexture(GL_TEXTURE_2D, scopetextureptr); + + glBegin(GL_QUADS); + + glTexCoord2f(0,0); + + glVertex3f(0, 0, 0.0f); + + glTexCoord2f(1,0); + + glVertex3f(1, 0, 0.0f); + + glTexCoord2f(1,1); + + glVertex3f(1, 1, 0.0f); + + glTexCoord2f(0,1); + + glVertex3f(0, 1, 0.0f); + + glEnd(); + + glDisable(GL_TEXTURE_2D); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glEnable(GL_DEPTH_TEST); // Enables Depth Testing + + glEnable(GL_CULL_FACE); + + glDisable(GL_BLEND); + + glDepthMask(1); + + } + + + + //Flash + + if(flashamount>0){ + + if(flashamount>1)flashamount=1; + + flashamount-=multiplier; + + if(flashamount<0)flashamount=0; + + glDisable(GL_DEPTH_TEST); // Disables Depth Testing + + glDisable(GL_CULL_FACE); + + glDisable(GL_LIGHTING); + + glDepthMask(0); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPushMatrix(); // Store The Projection Matrix + + glLoadIdentity(); // Reset The Projection Matrix + + glOrtho(0,screenwidth,0,screenheight,-100,100); // Set Up An Ortho Screen + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPushMatrix(); // Store The Modelview Matrix + + glLoadIdentity(); // Reset The Modelview Matrix + + glScalef(screenwidth,screenheight,1); + + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_BLEND); + + glColor4f(flashr,flashg,flashb,flashamount); + + glBegin(GL_QUADS); + + glVertex3f(0, 0, 0.0f); + + glVertex3f(256, 0, 0.0f); + + glVertex3f(256, 256, 0.0f); + + glVertex3f(0, 256, 0.0f); + + glEnd(); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glEnable(GL_DEPTH_TEST); // Enables Depth Testing + + glEnable(GL_CULL_FACE); + + glDisable(GL_BLEND); + + glDepthMask(1); + + } + + if(person[0].skeleton.free>0&&thirdperson!=2){ + + glDisable(GL_DEPTH_TEST); // Disables Depth Testing + + glDisable(GL_CULL_FACE); + + glDisable(GL_LIGHTING); + + glDepthMask(0); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPushMatrix(); // Store The Projection Matrix + + glLoadIdentity(); // Reset The Projection Matrix + + glOrtho(0,screenwidth,0,screenheight,-100,100); // Set Up An Ortho Screen + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPushMatrix(); // Store The Modelview Matrix + + glLoadIdentity(); // Reset The Modelview Matrix + + glScalef(screenwidth,screenheight,1); + + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_BLEND); + + glColor4f(0,0,0,1-person[0].longdead); + + glBegin(GL_QUADS); + + glVertex3f(0, 0, 0.0f); + + glVertex3f(256, 0, 0.0f); + + glVertex3f(256, 256, 0.0f); + + glVertex3f(0, 256, 0.0f); + + glEnd(); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glEnable(GL_DEPTH_TEST); // Enables Depth Testing + + glEnable(GL_CULL_FACE); + + glDisable(GL_BLEND); + + glDepthMask(1); + + } + + + + //Text + + glEnable(GL_TEXTURE_2D); + + glColor4f(1,1,1,1); + + static char string[256]=""; + + if(!debug){ + + if(person[0].whichgun==nogun)sprintf (string, "UNARMED"); + + if(person[0].whichgun==knife)sprintf (string, "KNIFE"); + + if(person[0].whichgun==assaultrifle)sprintf (string, "ASSAULT RIFLE"); + + if(person[0].whichgun==shotgun)sprintf (string, "SHOTGUN"); + + if(person[0].whichgun==sniperrifle)sprintf (string, "SNIPER RIFLE"); + + if(person[0].whichgun==grenade)sprintf (string, "HAND GRENADE"); + + if(person[0].whichgun==handgun1)sprintf (string, "MAGNUM"); + + if(person[0].whichgun==handgun2)sprintf (string, "HANDGUN"); + + text.glPrint(10,90,string,1,.8,640,480); + + if(person[0].whichgun!=nogun&&person[0].whichgun!=knife&&person[0].whichgun!=grenade){ + + glColor4f(0,1,0,1); + + sprintf (string, "Magazines"); + + text.glPrint(10,30,string,0,.8,640,480); + + glColor4f(1,1,1,1); + + sprintf (string, "0%d",(int)person[0].reloads[person[0].whichgun]); + + text.glPrint(10,10,string,1,1,640,480); + + if(person[0].ammo>=0){ + + glColor4f(0,1,0,1); + + sprintf (string, "Ammo"); + + text.glPrint(10,65,string,0,.8,640,480); + + glColor4f(1,1,1,1); + + if(person[0].ammo>=10)sprintf (string, "%d",(int)person[0].ammo); + + if(person[0].ammo<10)sprintf (string, "0%d",(int)person[0].ammo); + + text.glPrint(10,40,string,1,1,640,480); + + } + + } + + if(person[0].whichgun==grenade){ + + sprintf (string, "Grenades Left: %d",(int)person[0].reloads[person[0].whichgun]+1); + + text.glPrint(10,20,string,0,.8,640,480); + + } + + glColor4f(1,1,0,1); + + sprintf (string, "Score"); + + text.glPrint(725,575,string,0,.8,640,480); + + glColor4f(1,1,1,1); + + sprintf (string, "%d", score); + + text.glPrint(580,440,string,1,1,640,480); + + + + glColor4f(1,1,0,1); + + sprintf (string, "Time Remaining"); + + text.glPrint(50,575,string,0,.8,640,480); + + glColor4f(1,1,1,1); + + if((int)timeremaining%60>=10)sprintf (string, "%d:%d", (int)(timeremaining/60),(int)timeremaining%60); + + if((int)timeremaining%60<10)sprintf (string, "%d:0%d", (int)(timeremaining/60),(int)timeremaining%60); + + text.glPrint(72.5,440,string,1,1,640,480); + + } + + + + if(debug){ + + sprintf (string, "The framespersecond is %d out of maximum %d.",(int)framespersecond+1,maxfps); + + text.glPrint(10,30,string,0,.8,screenwidth,screenheight); + + if(enemystate==0)sprintf (string, "Enemies are in random assassination mode."); + + if(enemystate==1)sprintf (string, "Enemies are in passive mode."); + + if(enemystate==2)sprintf (string, "Enemies are in DIE!!!! mode."); + + text.glPrint(10,20,string,0,.8,screenwidth,screenheight); + + sprintf (string, "You have pointlessly shot or beaten %d unarmed civilians.",civkills); + + text.glPrint(10,60,string,0,.8,screenwidth,screenheight); + + sprintf (string, "You have incapacitated %d assassins.",goodkills); + + text.glPrint(10,70,string,0,.8,screenwidth,screenheight); + + sprintf (string, "You have allowed %d successful murders.",badkills); + + text.glPrint(10,80,string,0,.8,screenwidth,screenheight); + + } + + /* + sprintf (string, ""); + + text.glPrint(10,80,string,0,.8,screenwidth,screenheight); + */ + + } + + return 1; +} + diff --git a/src/GameInitDispose.cpp b/src/GameInitDispose.cpp new file mode 100644 index 0000000..7f22344 --- /dev/null +++ b/src/GameInitDispose.cpp @@ -0,0 +1,4235 @@ +#include <ctype.h> +#include "Textures.h" + +#ifndef OS9 +#include <time.h> +#endif + +#include "Game.h" + + +extern unsigned int gSourceID[100]; + +extern unsigned int gSampleSet[100]; + +extern Camera camera; + +extern Skeleton testskeleton; + +extern Sprites sprites; + +extern Decals decals; + +/*********************> InitGame()<*****/ + +extern Model skeletonmodels[10]; + +extern Model gunmodels[10]; + +extern Costume costume[10]; + +extern Animation animation[30]; + +extern int visions; + +extern float rad2deg; + +extern Fog fog; + +extern bool blood; + +extern float fogcolorr; + +extern float fogcolorg; + +extern float fogcolorb; + +extern int environment; + +extern float precipitationhorz; + +extern float precipitationvert; + +extern float precipitationdensity; + +extern float soundscalefactor; + +extern int slomo; + + + +extern int forwardskey; + +extern int backwardskey; + +extern int leftkey; + +extern int rightkey; + +extern int aimkey; + +extern int psychicaimkey; + +extern int psychickey; + + + +void LoadSounds(bool musictoggle); + +void LoadSounds(bool musictoggle) + +{ + char *pBuffer1; + + long lBuffer1Len; + + ALenum formatBuffer1; + + ALsizei freqBuffer1; + + Str255 sFileName; + + short fRefNum; + + SInt16 iNumSources, iNumSampleSets; + + // EAX test + + unsigned long ulEAXVal; + + long lGlobalReverb; + + + + // initialize OpenAL + + alutInit(NULL, 0); + + + + + + // load up some audio data... + + // generate ten OpenAL sample sets and two sources + + iNumSources = 37; + + iNumSampleSets = 37; + + alGenSources(iNumSources, &gSourceID[0]); + + alGenBuffers(iNumSampleSets, &gSampleSet[0]); + +#ifdef NOOGG + alutLoadWAVFile((char *)":Data:Sounds:underwater.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[visionsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[visionsound], AL_BUFFER, gSampleSet[visionsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:soulin.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[soulinsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[soulinsound], AL_BUFFER, gSampleSet[soulinsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:soulout.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[souloutsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[souloutsound], AL_BUFFER, gSampleSet[souloutsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:footstep1.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[footstepsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[footstepsound], AL_BUFFER, gSampleSet[footstepsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:footstep2.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[footstepsound+1], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[footstepsound+1], AL_BUFFER, gSampleSet[footstepsound+1]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:footstep3.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[footstepsound+2], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[footstepsound+2], AL_BUFFER, gSampleSet[footstepsound+2]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:footstep4.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[footstepsound+3], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[footstepsound+3], AL_BUFFER, gSampleSet[footstepsound+3]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:footstep5.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[footstepsound+4], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[footstepsound+4], AL_BUFFER, gSampleSet[footstepsound+4]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:bodyland.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[bodylandsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[bodylandsound], AL_BUFFER, gSampleSet[bodylandsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:headland.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[headlandsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[headlandsound], AL_BUFFER, gSampleSet[headlandsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:sniperrifle.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[riflesound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[riflesound], AL_BUFFER, gSampleSet[riflesound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:BodyHit.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[bodyhitsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[bodyhitsound], AL_BUFFER, gSampleSet[bodyhitsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:WallHit.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[wallhitsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[wallhitsound], AL_BUFFER, gSampleSet[wallhitsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:machinegun.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[machinegunsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[machinegunsound], AL_BUFFER, gSampleSet[machinegunsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:Nearbullet.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[nearbulletsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[nearbulletsound], AL_BUFFER, gSampleSet[nearbulletsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:riflewhack.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[headwhacksound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[headwhacksound], AL_BUFFER, gSampleSet[headwhacksound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:headshot.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[headshotsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[headshotsound], AL_BUFFER, gSampleSet[headshotsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:reload.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[reloadsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[reloadsound], AL_BUFFER, gSampleSet[reloadsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:click.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[clicksound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[clicksound], AL_BUFFER, gSampleSet[clicksound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:SW.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[pistol1sound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[pistol1sound], AL_BUFFER, gSampleSet[pistol1sound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:glock.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[pistol2sound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[pistol2sound], AL_BUFFER, gSampleSet[pistol2sound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:pinpull.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[pinpullsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[pinpullsound], AL_BUFFER, gSampleSet[pinpullsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:pinreplace.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[pinreplacesound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[pinreplacesound], AL_BUFFER, gSampleSet[pinreplacesound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:handlerelease.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[grenadethrowsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[grenadethrowsound], AL_BUFFER, gSampleSet[grenadethrowsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:bounce.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[bouncesound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[bouncesound], AL_BUFFER, gSampleSet[bouncesound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:bounce2.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[bounce2sound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[bounce2sound], AL_BUFFER, gSampleSet[bounce2sound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:explosion.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[explosionsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[explosionsound], AL_BUFFER, gSampleSet[explosionsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:headland.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[bodywhacksound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[bodywhacksound], AL_BUFFER, gSampleSet[bodywhacksound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:rain.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[rainsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[rainsound], AL_BUFFER, gSampleSet[rainsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:Lose.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[losesound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[losesound], AL_BUFFER, gSampleSet[losesound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:Disguisekill.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[disguisekillsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[disguisekillsound], AL_BUFFER, gSampleSet[disguisekillsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:knifeslash.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[knifeslashsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[knifeslashsound], AL_BUFFER, gSampleSet[knifeslashsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:shotgun.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[shotgunsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[shotgunsound], AL_BUFFER, gSampleSet[shotgunsound]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + if(musictoggle){ + + alutLoadWAVFile((char *)":Data:Sounds:mainmenusong.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[mainmenusong], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[mainmenusong], AL_BUFFER, gSampleSet[mainmenusong]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:shootsong.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[shootsong], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[shootsong], AL_BUFFER, gSampleSet[shootsong]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:zombiesong.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[zombiesong], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[zombiesong], AL_BUFFER, gSampleSet[zombiesong]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + alutLoadWAVFile((char *)":Data:Sounds:knifesong.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[knifesong], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[knifesong], AL_BUFFER, gSampleSet[knifesong]); + + alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + } +#else + LoadOGG_CFH((char *)":Data:Sounds:underwater.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[visionsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[visionsound], AL_BUFFER, gSampleSet[visionsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:soulin.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[soulinsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[soulinsound], AL_BUFFER, gSampleSet[soulinsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:soulout.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[souloutsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[souloutsound], AL_BUFFER, gSampleSet[souloutsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:footstep1.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[footstepsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[footstepsound], AL_BUFFER, gSampleSet[footstepsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:footstep2.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[footstepsound+1], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[footstepsound+1], AL_BUFFER, gSampleSet[footstepsound+1]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:footstep3.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[footstepsound+2], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[footstepsound+2], AL_BUFFER, gSampleSet[footstepsound+2]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:footstep4.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[footstepsound+3], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[footstepsound+3], AL_BUFFER, gSampleSet[footstepsound+3]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:footstep5.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[footstepsound+4], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[footstepsound+4], AL_BUFFER, gSampleSet[footstepsound+4]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:bodyland.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[bodylandsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[bodylandsound], AL_BUFFER, gSampleSet[bodylandsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:headland.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[headlandsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[headlandsound], AL_BUFFER, gSampleSet[headlandsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:sniperrifle.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[riflesound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[riflesound], AL_BUFFER, gSampleSet[riflesound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:BodyHit.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[bodyhitsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[bodyhitsound], AL_BUFFER, gSampleSet[bodyhitsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:WallHit.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[wallhitsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[wallhitsound], AL_BUFFER, gSampleSet[wallhitsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:machinegun.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[machinegunsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[machinegunsound], AL_BUFFER, gSampleSet[machinegunsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:Nearbullet.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[nearbulletsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[nearbulletsound], AL_BUFFER, gSampleSet[nearbulletsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:riflewhack.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[headwhacksound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[headwhacksound], AL_BUFFER, gSampleSet[headwhacksound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:headshot.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[headshotsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[headshotsound], AL_BUFFER, gSampleSet[headshotsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:reload.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[reloadsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[reloadsound], AL_BUFFER, gSampleSet[reloadsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:click.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[clicksound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[clicksound], AL_BUFFER, gSampleSet[clicksound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:SW.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[pistol1sound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[pistol1sound], AL_BUFFER, gSampleSet[pistol1sound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:glock.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[pistol2sound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[pistol2sound], AL_BUFFER, gSampleSet[pistol2sound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:pinpull.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[pinpullsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[pinpullsound], AL_BUFFER, gSampleSet[pinpullsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:pinreplace.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[pinreplacesound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[pinreplacesound], AL_BUFFER, gSampleSet[pinreplacesound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:handlerelease.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[grenadethrowsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[grenadethrowsound], AL_BUFFER, gSampleSet[grenadethrowsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:bounce.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[bouncesound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[bouncesound], AL_BUFFER, gSampleSet[bouncesound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:bounce2.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[bounce2sound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[bounce2sound], AL_BUFFER, gSampleSet[bounce2sound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:explosion.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[explosionsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[explosionsound], AL_BUFFER, gSampleSet[explosionsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:headland.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[bodywhacksound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[bodywhacksound], AL_BUFFER, gSampleSet[bodywhacksound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:rain.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[rainsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[rainsound], AL_BUFFER, gSampleSet[rainsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:Lose.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[losesound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[losesound], AL_BUFFER, gSampleSet[losesound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:Disguisekill.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[disguisekillsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[disguisekillsound], AL_BUFFER, gSampleSet[disguisekillsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:knifeslash.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[knifeslashsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[knifeslashsound], AL_BUFFER, gSampleSet[knifeslashsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:shotgun.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[shotgunsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[shotgunsound], AL_BUFFER, gSampleSet[shotgunsound]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + if(musictoggle){ + + LoadOGG_CFH((char *)":Data:Sounds:mainmenusong.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[mainmenusong], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[mainmenusong], AL_BUFFER, gSampleSet[mainmenusong]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:shootsong.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[shootsong], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[shootsong], AL_BUFFER, gSampleSet[shootsong]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:zombiesong.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[zombiesong], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[zombiesong], AL_BUFFER, gSampleSet[zombiesong]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + + + LoadOGG_CFH((char *)":Data:Sounds:knifesong.ogg",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1); + + alBufferData(gSampleSet[knifesong], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + alSourcei(gSourceID[knifesong], AL_BUFFER, gSampleSet[knifesong]); + + FreeOGG(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1); + + } + + +#endif + + + float gLoc[3]; + + + + gLoc[0]=0; + + gLoc[1]=0; + + gLoc[2]=0; + + + + alSourcefv(gSourceID[visionsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[visionsound], AL_LOOPING, 1); + + alSourcef(gSourceID[visionsound], AL_MIN_GAIN, 1); + + + + alSourcefv(gSourceID[soulinsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[soulinsound], AL_LOOPING, 0); + + alSourcef(gSourceID[soulinsound], AL_MIN_GAIN, 1); + + + + alSourcefv(gSourceID[souloutsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[souloutsound], AL_LOOPING, 0); + + alSourcef(gSourceID[souloutsound], AL_MIN_GAIN, 1); + + + + for(int i=0;i<5;i++){ + + alSourcefv(gSourceID[footstepsound+i], AL_POSITION, gLoc); + + alSourcei(gSourceID[footstepsound+i], AL_LOOPING, 0); + + alSourcef(gSourceID[footstepsound+i], AL_MIN_GAIN, 0); + + } + + + + alSourcefv(gSourceID[bodylandsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[bodylandsound], AL_LOOPING, 0); + + alSourcef(gSourceID[bodylandsound], AL_MIN_GAIN, 0); + + + + alSourcefv(gSourceID[headlandsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[headlandsound], AL_LOOPING, 0); + + alSourcef(gSourceID[headlandsound], AL_MIN_GAIN, 0); + + + + alSourcefv(gSourceID[riflesound], AL_POSITION, gLoc); + + alSourcei(gSourceID[riflesound], AL_LOOPING, 0); + + alSourcef(gSourceID[riflesound], AL_MIN_GAIN, 0); + + + + alSourcefv(gSourceID[bodyhitsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[bodyhitsound], AL_LOOPING, 0); + + alSourcef(gSourceID[bodyhitsound], AL_MIN_GAIN, .1); + + + + alSourcefv(gSourceID[wallhitsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[wallhitsound], AL_LOOPING, 0); + + alSourcef(gSourceID[wallhitsound], AL_MIN_GAIN, 0); + + alSourcef(gSourceID[wallhitsound], AL_MAX_GAIN, .6); + + + + alSourcefv(gSourceID[machinegunsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[machinegunsound], AL_LOOPING, 0); + + alSourcef(gSourceID[machinegunsound], AL_MIN_GAIN,0); + + + + alSourcefv(gSourceID[nearbulletsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[nearbulletsound], AL_LOOPING, 0); + + alSourcef(gSourceID[nearbulletsound], AL_MIN_GAIN,0); + + + + alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc); + + alSourcei(gSourceID[headwhacksound], AL_LOOPING, 0); + + alSourcef(gSourceID[headwhacksound], AL_MIN_GAIN,0); + + + + alSourcefv(gSourceID[headshotsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[headshotsound], AL_LOOPING, 0); + + alSourcef(gSourceID[headshotsound], AL_MIN_GAIN, 0); + + + + alSourcefv(gSourceID[reloadsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[reloadsound], AL_LOOPING, 0); + + alSourcef(gSourceID[reloadsound], AL_MIN_GAIN, 0); + + + + alSourcefv(gSourceID[clicksound], AL_POSITION, gLoc); + + alSourcei(gSourceID[clicksound], AL_LOOPING, 0); + + alSourcef(gSourceID[clicksound], AL_MIN_GAIN, 0); + + + + alSourcefv(gSourceID[pistol1sound], AL_POSITION, gLoc); + + alSourcei(gSourceID[pistol1sound], AL_LOOPING, 0); + + alSourcef(gSourceID[pistol1sound], AL_MIN_GAIN, 0); + + + + alSourcefv(gSourceID[pistol2sound], AL_POSITION, gLoc); + + alSourcei(gSourceID[pistol2sound], AL_LOOPING, 0); + + alSourcef(gSourceID[pistol2sound], AL_MIN_GAIN, 0); + + + + alSourcefv(gSourceID[pinpullsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[pinpullsound], AL_LOOPING, 0); + + alSourcef(gSourceID[pinpullsound], AL_MIN_GAIN,0); + + + + alSourcefv(gSourceID[pinreplacesound], AL_POSITION, gLoc); + + alSourcei(gSourceID[pinreplacesound], AL_LOOPING, 0); + + alSourcef(gSourceID[pinreplacesound], AL_MIN_GAIN,0); + + + + alSourcefv(gSourceID[grenadethrowsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[grenadethrowsound], AL_LOOPING, 0); + + alSourcef(gSourceID[grenadethrowsound], AL_MIN_GAIN,0); + + + + alSourcefv(gSourceID[bouncesound], AL_POSITION, gLoc); + + alSourcei(gSourceID[bouncesound], AL_LOOPING, 0); + + alSourcef(gSourceID[bouncesound], AL_MIN_GAIN,0); + + + + alSourcefv(gSourceID[bounce2sound], AL_POSITION, gLoc); + + alSourcei(gSourceID[bounce2sound], AL_LOOPING, 0); + + alSourcef(gSourceID[bounce2sound], AL_MIN_GAIN,0); + + + + alSourcefv(gSourceID[explosionsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[explosionsound], AL_LOOPING, 0); + + alSourcef(gSourceID[explosionsound], AL_MIN_GAIN,0); + + + + alSourcefv(gSourceID[bodywhacksound], AL_POSITION, gLoc); + + alSourcei(gSourceID[bodywhacksound], AL_LOOPING, 0); + + alSourcef(gSourceID[bodywhacksound], AL_MIN_GAIN, 0); + + + + alSourcefv(gSourceID[rainsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[rainsound], AL_LOOPING, 1); + + alSourcef(gSourceID[rainsound], AL_MIN_GAIN, .3); + + + + alSourcefv(gSourceID[losesound], AL_POSITION, gLoc); + + alSourcei(gSourceID[losesound], AL_LOOPING, 0); + + alSourcef(gSourceID[losesound], AL_MIN_GAIN, 1); + + + + alSourcefv(gSourceID[disguisekillsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[disguisekillsound], AL_LOOPING, 0); + + alSourcef(gSourceID[disguisekillsound], AL_MIN_GAIN, 1); + + + + alSourcefv(gSourceID[knifeslashsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[knifeslashsound], AL_LOOPING, 0); + + alSourcef(gSourceID[knifeslashsound], AL_MIN_GAIN,0); + + + + alSourcefv(gSourceID[shotgunsound], AL_POSITION, gLoc); + + alSourcei(gSourceID[shotgunsound], AL_LOOPING, 0); + + alSourcef(gSourceID[shotgunsound], AL_MIN_GAIN, 0); + + + + alSourcefv(gSourceID[knifesong], AL_POSITION, gLoc); + + alSourcei(gSourceID[knifesong], AL_LOOPING, 1); + + alSourcef(gSourceID[knifesong], AL_MIN_GAIN, 1); + + + + alSourcefv(gSourceID[mainmenusong], AL_POSITION, gLoc); + + alSourcei(gSourceID[mainmenusong], AL_LOOPING, 1); + + alSourcef(gSourceID[mainmenusong], AL_MIN_GAIN, 1); + + + + alSourcefv(gSourceID[zombiesong], AL_POSITION, gLoc); + + alSourcei(gSourceID[zombiesong], AL_LOOPING, 1); + + alSourcef(gSourceID[zombiesong], AL_MIN_GAIN, 1); + + + + alSourcefv(gSourceID[shootsong], AL_POSITION, gLoc); + + alSourcei(gSourceID[shootsong], AL_LOOPING, 1); + + alSourcef(gSourceID[shootsong], AL_MIN_GAIN, 1); + + + + + +} + + + +void Game::LoadingScreen(float percent) + +{ + + float size=1; + + glLoadIdentity(); + + //Clear to black + + glClearColor(0,0,0,1); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + + //Background + + + + glDisable(GL_TEXTURE_2D); + + glDisable(GL_DEPTH_TEST); // Disables Depth Testing + + glDisable(GL_CULL_FACE); + + glDisable(GL_LIGHTING); + + glDepthMask(0); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPushMatrix(); // Store The Projection Matrix + + glLoadIdentity(); // Reset The Projection Matrix + + glOrtho(0,640,0,480,-100,100); // Set Up An Ortho Screen + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPushMatrix(); // Store The Modelview Matrix + + for(int i=19;i>=0;i--){ + + glLoadIdentity(); // Reset The Modelview Matrix + + glTranslatef(120-i*1,190-i*1,0); + + glScalef(400+i*2,30+i*2,1); + + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_BLEND); + + if(i)glColor4f(1-(float)i/20-percent/100,1-(float)i/20-percent/100,1-(float)i/20-percent/100,1); + + if(!i)glColor4f(0,0,0,1); + + glBegin(GL_QUADS); + + glVertex3f(0, 0, 0.0f); + + glVertex3f(1, 0, 0.0f); + + glVertex3f(1, 1, 0.0f); + + glVertex3f(0, 1, 0.0f); + + glEnd(); + + } + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glDisable(GL_BLEND); + + glDepthMask(1); + + + + //Progress + + + + glDisable(GL_DEPTH_TEST); // Disables Depth Testing + + glDisable(GL_CULL_FACE); + + glDisable(GL_LIGHTING); + + glDisable(GL_TEXTURE_2D); + + glDepthMask(0); + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPushMatrix(); // Store The Projection Matrix + + glLoadIdentity(); // Reset The Projection Matrix + + glOrtho(0,640,0,480,-100,100); // Set Up An Ortho Screen + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPushMatrix(); // Store The Modelview Matrix + + for(int i=19;i>=0;i--){ + + glLoadIdentity(); // Reset The Modelview Matrix + + glTranslatef(120,190,0); + + if(4*percent+i*2<400)glScalef(4*percent+i*2,30,1); + + if(4*percent+i*2>=400)glScalef(400,30,1); + + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_BLEND); + + glColor4f(1,0,0,.1); + + glBegin(GL_QUADS); + + glVertex3f(0, 0, 0.0f); + + glVertex3f(1, 0, 0.0f); + + glVertex3f(1, 1, 0.0f); + + glVertex3f(0, 1, 0.0f); + + glEnd(); + + } + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + glPopMatrix(); // Restore The Old Projection Matrix + + glDisable(GL_BLEND); + + glDepthMask(1); + + + + //Text + + + + glEnable(GL_TEXTURE_2D); + + glColor4f(.6-.6*percent/100,0,0,1); + + static char string[256]=""; + + sprintf (string, "LOADING..."); + + text.glPrint(280,195,string,1,1,640,480); + + + + +#ifdef OS9 + aglSwapBuffers( gOpenGLContext ); +#else + SDL_GL_SwapBuffers( ); +#endif + +} + + + +void LoadPersonSpriteTexture(char *fileName, GLuint *textureid); + +void LoadPersonSpriteTexture(char *fileName, GLuint *textureid) + +{ + *textureid = loadTexture(fileName); + glBindTexture(GL_TEXTURE_2D, *textureid); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +} + + + +void Game::InitGame() + +{ + + //Setup loading screen + + float loadingscreenamount=0; + + float loadingscreenamounttotal=200; + + if(initialized)loadingscreenamounttotal=20; + + + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + //Set up rain and snow + + precipitationhorz=60; + + precipitationvert=40; + + precipitationdensity=25; + + + + //Bodyguard stats + + person[0].playercoords=camera.position; + + person[0].oldplayercoords=person[0].playercoords; + + person[0].type=playertype; + + person[0].existing=1; + + for(int i=0;i<10;i++){ + + person[0].reloads[i]=0; + + } + + + + //Level setup + + killedinnocent=0; //Haven't shot any civilians yet... + + + + if(customlevels){ //Load custom levels + + nummissions=1; //Default level in case of load failure + + type=randomshoot_type; + + possiblegun[0]=handgun1; + + possiblegun[1]=handgun2; + + possiblegun[2]=shotgun; + + numpossibleguns=3; + + evilprobability=6; + + person[0].whichgun=knife; + + person[0].reloads[person[0].whichgun]=6; + + if(!gameinprogress)score=0; + + timeremaining=50; + + difficulty=.8; + + ifstream ipstream("Data/customlevels.txt"); + + if(!ipstream) { + + customlevels=0; + + } + + if(ipstream){ + + ipstream.ignore(256,'\n');//ignore descriptive text + + ipstream >> nummissions; + + for(int j=0;j<mission+1;j++){ + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> type; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> environment; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> numpossibleguns; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + for(int i=0;i<numpossibleguns;i++){ + + ipstream >> possiblegun[i]; + + } + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> evilprobability; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> person[0].whichgun; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> person[0].reloads[person[0].whichgun]; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> timeremaining; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> difficulty; + + ipstream.ignore(256,'\n'); + + } + + ipstream.close(); + + } + + } + + + + if(!customlevels){ //Setup hardcoded default levels + + if(mission==0){ + + environment=sunny_environment; + + type=randomshoot_type; + + possiblegun[0]=handgun1; + + possiblegun[1]=handgun2; + + possiblegun[2]=shotgun; + + numpossibleguns=3; + + evilprobability=6; + + person[0].whichgun=assaultrifle; + + person[0].reloads[person[0].whichgun]=6; + + if(!gameinprogress)score=0; + + timeremaining=50; + + difficulty=.6; + + } + + if(mission==1){ + + environment=snowy_environment; + + type=randomshoot_type; + + possiblegun[0]=knife; + + possiblegun[1]=assaultrifle; + + numpossibleguns=2; + + evilprobability=5; + + person[0].whichgun=handgun2; + + person[0].reloads[person[0].whichgun]=3; + + if(!gameinprogress)score=0; + + timeremaining=40; + + difficulty=.6; + + } + + if(mission==2){ + + environment=foggy_environment; + + type=randomshoot_type; + + possiblegun[0]=sniperrifle; + + numpossibleguns=1; + + evilprobability=5; + + person[0].whichgun=sniperrifle; + + person[0].reloads[person[0].whichgun]=4; + + if(!gameinprogress)score=0; + + timeremaining=50; + + difficulty=0.9; + + } + + if(mission==3){ + + environment=firey_environment; + + type=zombie_type; + + numpossibleguns=0; + + evilprobability=5; + + person[0].whichgun=shotgun; + + person[0].reloads[person[0].whichgun]=5; + + if(!gameinprogress)score=0; + + timeremaining=35; + + difficulty=.7; + + } + + if(mission==4){ + + environment=snowy_environment; + + type=randomshoot_type; + + possiblegun[0]=sniperrifle; + + possiblegun[1]=assaultrifle; + + numpossibleguns=2; + + evilprobability=5; + + person[0].whichgun=grenade; + + person[0].reloads[person[0].whichgun]=20; + + if(!gameinprogress)score=0; + + timeremaining=30; + + difficulty=.5; + + } + + if(mission==5){ + + environment=rainy_environment; + + type=randomshoot_type; + + possiblegun[0]=handgun1; + + possiblegun[1]=shotgun; + + possiblegun[2]=assaultrifle; + + numpossibleguns=3; + + evilprobability=6; + + person[0].whichgun=knife; + + person[0].reloads[person[0].whichgun]=3; + + if(!gameinprogress)score=0; + + timeremaining=40; + + difficulty=.8; + + } + + if(mission==6){ + + environment=night_environment; + + type=randomshoot_type; + + possiblegun[1]=handgun1; + + possiblegun[2]=handgun2; + + possiblegun[3]=shotgun; + + numpossibleguns=3; + + evilprobability=5; + + person[0].whichgun=handgun1; + + person[0].reloads[person[0].whichgun]=4; + + if(!gameinprogress)score=0; + + timeremaining=30; + + difficulty=1; + + } + + if(mission==7){ + + environment=firey_environment; + + type=zombie_type; + + person[0].whichgun=assaultrifle; + + person[0].reloads[person[0].whichgun]=5; + + if(!gameinprogress)score=0; + + timeremaining=30; + + difficulty=1; + + } + + if(mission==8){ + + environment=rainy_environment; + + type=randomshoot_type; + + possiblegun[0]=handgun1; + + possiblegun[1]=handgun2; + + possiblegun[2]=shotgun; + + possiblegun[3]=sniperrifle; + + possiblegun[4]=assaultrifle; + + numpossibleguns=5; + + evilprobability=5; + + person[0].whichgun=nogun; + + person[0].reloads[person[0].whichgun]=3; + + if(!gameinprogress)score=0; + + timeremaining=40; + + difficulty=.8; + + } + + if(mission==9){ + + environment=snowy_environment; + + type=randomshoot_type; + + possiblegun[0]=knife; + + possiblegun[1]=handgun1; + + possiblegun[2]=handgun2; + + possiblegun[3]=shotgun; + + possiblegun[4]=sniperrifle; + + possiblegun[5]=assaultrifle; + + numpossibleguns=6; + + evilprobability=4; + + person[0].whichgun=handgun1; + + person[0].reloads[person[0].whichgun]=3; + + if(!gameinprogress)score=0; + + timeremaining=90; + + difficulty=1; + + } + + if(mission==10){ + + environment=night_environment; + + type=randomshoot_type; + + possiblegun[0]=sniperrifle; + + numpossibleguns=1; + + evilprobability=5; + + person[0].whichgun=sniperrifle; + + person[0].reloads[person[0].whichgun]=4; + + if(!gameinprogress)score=0; + + timeremaining=30; + + difficulty=1.3; + + } + + if(mission==11){ + + environment=sunny_environment; + + type=randomshoot_type; + + possiblegun[0]=knife; + + possiblegun[1]=sniperrifle; + + numpossibleguns=2; + + evilprobability=4; + + person[0].whichgun=knife; + + if(!gameinprogress)score=0; + + timeremaining=30; + + difficulty=1.5; + + } + + if(mission==12){ + + environment=firey_environment; + + type=zombie_type; + + possiblegun[0]=knife; + + possiblegun[1]=sniperrifle; + + person[0].whichgun=handgun2; + + person[0].reloads[person[0].whichgun]=10; + + if(!gameinprogress)score=0; + + timeremaining=60; + + difficulty=1.5; + + } + + + + nummissions=13; + + } + + + + //Setup fast radian to degree conversion + + rad2deg= 56.54866776; + + visions=0; + + + + //Setup bounding cylinder model + + float boundingscale=3; + + + + if(!initialized){ + + boundingpoints[0]=0; + + boundingpoints[0].z=boundingscale; + + boundingpoints[0].y=0; + + for(int i=1;i<8;i++){ + + boundingpoints[i]=DoRotation(boundingpoints[0],0,i*360/7,0); + + } + + } + + civkills=0; + + badkills=0; + + goodkills=0; + + enemystate=2; + + + + if(!initialized){ + + if(!azertykeyboard){ + + forwardskey=MAC_W_KEY; + + backwardskey=MAC_S_KEY; + + leftkey=MAC_A_KEY; + + rightkey=MAC_D_KEY; + + aimkey=MAC_Q_KEY; + + psychicaimkey=MAC_E_KEY; + + psychickey=MAC_Z_KEY; + + } + + + + if(azertykeyboard){ + + forwardskey=MAC_Z_KEY; + + backwardskey=MAC_S_KEY; + + leftkey=MAC_Q_KEY; + + rightkey=MAC_D_KEY; + + aimkey=MAC_A_KEY; + + psychicaimkey=MAC_E_KEY; + + psychickey=MAC_W_KEY; + + } + + + + soundscalefactor=soundscalefactordefault; //Setup sound falloff + + + + gQuit=false; + + + + //Sounds + + LoadSounds(musictoggle); + + //Play correct song + + if(environment==rainy_environment)alSourcePlay(gSourceID[rainsound]); + + if(environment!=rainy_environment)alSourcePause(gSourceID[rainsound]); + + alSourceStop(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0); + + alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0); + + whichsong=mainmenusong; + + alSourceStop(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_PITCH, 1); + + alSourcePlay(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1); + + alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1); + + } + + + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + //Setup random seed + +#ifdef OS9 + qd.randSeed = TickCount(); +#else + srand(time(NULL)); +#endif + + gamespeed=1; + + + + //Setup camera + + camera.position=0; + + camera.position.x=num_blocks/2*block_spacing+block_spacing/2; + + camera.position.z=num_blocks/2*block_spacing+block_spacing/2; + + camera.position.y=30; + + camera.oldposition=camera.position; + + numpeople=1; + + + + //Setup path to walk around blocks + + path.load((unsigned char *)":Data:Models:path.solid"); + + path.Rotate(90,0,0); + + path.Scale(.8,.8,.8); + + path.CalculateNormals(); + + + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + person[0].speedmult=1.3; + + + + //Add vip + + person[numpeople].playerrotation=0; + + + + person[numpeople].whichcostume=vipcostume; + + + + person[numpeople].whichblockx=((person[0].playercoords.x+block_spacing/2)/block_spacing); + + person[numpeople].whichblocky=((person[0].playercoords.x+block_spacing/2)/block_spacing); + + + + person[numpeople].pathnum=-1; + + person[numpeople].oldpathnum=-1; + + person[numpeople].oldoldpathnum=-1; + + person[numpeople].oldoldoldpathnum=-1; + + while(person[numpeople].pathnum<0||person[numpeople].pathnum>=path.vertexNum||person[numpeople].pathnum==1){ + + person[numpeople].pathnum=Random()%path.vertexNum; + + } + + person[numpeople].pathtarget.x=path.vertex[person[numpeople].pathnum].x; + + person[numpeople].pathtarget.z=path.vertex[person[numpeople].pathnum].z; + + person[numpeople].pathsize=.98+float(abs(Random()%20))/400; + + person[numpeople].pathtarget*=person[numpeople].pathsize; + + person[numpeople].pathtarget.x+=person[numpeople].whichblockx*block_spacing; + + person[numpeople].pathtarget.z+=person[numpeople].whichblocky*block_spacing; + + + + + + person[numpeople].playercoords=person[numpeople].pathtarget; + + person[numpeople].oldplayercoords=person[numpeople].playercoords; + + + + person[0].playercoords=person[numpeople].playercoords; + + person[0].playercoords.x+=1; + + person[0].playercoords.z+=1; + + person[0].oldplayercoords=person[0].playercoords; + + + + person[numpeople].skeleton.free=0; + + + + person[numpeople].targetanimation=walkanim; + + person[numpeople].speed=1; + + person[numpeople].existing=0; + + person[numpeople].speedmult=1; + + if(type==zombie_type)person[numpeople].speedmult=.8; + + person[numpeople].health=100; + + person[numpeople].playerrotation2=0;//20; + + + + person[numpeople].lastdistancevictim=200000; + + + + if(person[numpeople].skeleton.broken)person[numpeople].skeleton.Load((char *)":Data:Skeleton:Basic Figure"); + + + + person[numpeople].type=viptype; + + person[numpeople].whichgun=nogun; person[numpeople].aiming=0; person[numpeople].killtarget=-1; + + person[numpeople].existing=1; + + + + citypeoplenum[person[numpeople].whichblockx][person[numpeople].whichblocky]++; + + numpeople++; + + spawndelay=.1; + + + + XYZ vipdistance; + + vipdistance=0; + + vipdistance.x=10000000; + + vipgoal=person[1].playercoords+DoRotation(vipdistance,0,Random()%360,0); + + + + //Setup block models + + if(!initialized){ + + blocks[0].load((unsigned char *)":Data:Models:Block1.solid"); + + blocks[0].Rotate(90,0,0); + + blocks[0].Scale(.8,.8,.8); + + blocks[0].CalculateNormals(); + + + + blocks[1].load((unsigned char *)":Data:Models:Block2.solid"); + + blocks[1].Rotate(90,0,0); + + blocks[1].Scale(.8,.8,.8); + + blocks[1].CalculateNormals(); + + + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + blocks[2].load((unsigned char *)":Data:Models:Block3.solid"); + + blocks[2].Rotate(90,0,0); + + blocks[2].Scale(.8,.8,.8); + + blocks[2].CalculateNormals(); + + + + blocks[3].load((unsigned char *)":Data:Models:Block4.solid"); + + blocks[3].Rotate(90,0,0); + + blocks[3].Scale(.8,.8,.8); + + blocks[3].CalculateNormals(); + + + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + sidewalkcollide.load((unsigned char *)":Data:Models:Lowheightcollide.solid"); + + sidewalkcollide.Rotate(90,0,0); + + sidewalkcollide.Scale(.8,.8,.8); + + sidewalkcollide.CalculateNormals(); + + + + blockwalls[0].load((unsigned char *)":Data:Models:Block1collide.solid"); + + blockwalls[0].Rotate(90,0,0); + + blockwalls[0].Scale(.8,.75,.8); + + blockwalls[0].CalculateNormals(); + + + + blockwalls[1].load((unsigned char *)":Data:Models:Block2collide.solid"); + + blockwalls[1].Rotate(90,0,0); + + blockwalls[1].Scale(.8,.75,.8); + + blockwalls[1].CalculateNormals(); + + + + blockwalls[2].load((unsigned char *)":Data:Models:Block3collide.solid"); + + blockwalls[2].Rotate(90,0,0); + + blockwalls[2].Scale(.8,.75,.8); + + blockwalls[2].CalculateNormals(); + + + + blockwalls[3].load((unsigned char *)":Data:Models:Block4collide.solid"); + + blockwalls[3].Rotate(90,0,0); + + blockwalls[3].Scale(.8,.75,.8); + + blockwalls[3].CalculateNormals(); + + + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + blockroofs[0].load((unsigned char *)":Data:Models:Highblock1collide.solid"); + + blockroofs[0].Rotate(90,0,0); + + blockroofs[0].Scale(.8,.8,.8); + + blockroofs[0].CalculateNormals(); + + + + blockroofs[1].load((unsigned char *)":Data:Models:Highblock2collide.solid"); + + blockroofs[1].Rotate(90,0,0); + + blockroofs[1].Scale(.8,.8,.8); + + blockroofs[1].CalculateNormals(); + + + + blockroofs[2].load((unsigned char *)":Data:Models:Highblock3collide.solid"); + + blockroofs[2].Rotate(90,0,0); + + blockroofs[2].Scale(.8,.8,.8); + + blockroofs[2].CalculateNormals(); + + + + blockroofs[3].load((unsigned char *)":Data:Models:Highblock4collide.solid"); + + blockroofs[3].Rotate(90,0,0); + + blockroofs[3].Scale(.8,.8,.8); + + blockroofs[3].CalculateNormals(); + + + + blockcollide[0].load((unsigned char *)":Data:Models:block1complete.solid"); + + blockcollide[0].Rotate(90,0,0); + + blockcollide[0].Scale(.8,.8,.8); + + blockcollide[0].CalculateNormals(); + + + + blockcollide[1].load((unsigned char *)":Data:Models:block2complete.solid"); + + blockcollide[1].Rotate(90,0,0); + + blockcollide[1].Scale(.8,.8,.8); + + blockcollide[1].CalculateNormals(); + + + + blockcollide[2].load((unsigned char *)":Data:Models:block3complete.solid"); + + blockcollide[2].Rotate(90,0,0); + + blockcollide[2].Scale(.8,.8,.8); + + blockcollide[2].CalculateNormals(); + + + + blockcollide[3].load((unsigned char *)":Data:Models:block4complete.solid"); + + blockcollide[3].Rotate(90,0,0); + + blockcollide[3].Scale(.8,.8,.8); + + blockcollide[3].CalculateNormals(); + + + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + + + blocksimplecollide[0].load((unsigned char *)":Data:Models:lowsimplecollide1.solid"); + + blocksimplecollide[0].Rotate(90,0,0); + + blocksimplecollide[0].Scale(.8,.8,.8); + + blocksimplecollide[0].CalculateNormals(); + + + + blocksimplecollide[1].load((unsigned char *)":Data:Models:lowsimplecollide2.solid"); + + blocksimplecollide[1].Rotate(90,0,0); + + blocksimplecollide[1].Scale(.8,.8,.8); + + blocksimplecollide[1].CalculateNormals(); + + + + blocksimplecollide[2].load((unsigned char *)":Data:Models:lowsimplecollide3.solid"); + + blocksimplecollide[2].Rotate(90,0,0); + + blocksimplecollide[2].Scale(.8,.8,.8); + + blocksimplecollide[2].CalculateNormals(); + + + + blocksimplecollide[3].load((unsigned char *)":Data:Models:lowsimplecollide4.solid"); + + blocksimplecollide[3].Rotate(90,0,0); + + blocksimplecollide[3].Scale(.8,.8,.8); + + blocksimplecollide[3].CalculateNormals(); + + + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + blockocclude.load((unsigned char *)":Data:Models:blockocclude.solid"); + + blockocclude.Rotate(90,0,0); + + blockocclude.Scale(.8,.8,.8); + + blockocclude.CalculateNormals(); + + + + blocksimple.load((unsigned char *)":Data:Models:blocksimple.solid"); + + blocksimple.Rotate(90,0,0); + + blocksimple.Scale(.8,2,.8); + + blocksimple.CalculateNormals(); + + + + street.load((unsigned char *)":Data:Models:streetsubdivided2.solid"); + + street.Rotate(90,0,0); + + street.Scale(.01,.01,.01); + + street.CalculateNormals(); + + + + Bigstreet=street; + + Bigstreet.Scale(10000,10000,10000); + + + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + path.load((unsigned char *)":Data:Models:path.solid"); + + path.Rotate(90,0,0); + + path.Scale(.8,.8,.8); + + path.CalculateNormals(); + + + + //Fix block radius + + for(int i=0;i<4;i++){ + + blocks[i].boundingspherecenter.x=0; + + blocks[i].boundingspherecenter.z=0; + + blocks[i].boundingsphereradius=0; + + for(int x=0;i<blocks[x].vertexNum;x++){ + + if(findDistancefast(blocks[i].boundingspherecenter,blocks[i].vertex[x])>blocks[i].boundingsphereradius)blocks[i].boundingsphereradius=findDistancefast(blocks[i].boundingspherecenter,blocks[i].vertex[x]); + + } + + blocks[i].boundingsphereradius=sqrt(blocks[i].boundingsphereradius); + + } + + } + + mousesensitivity=1; + + + + //init city block rotations + + for(int i=0;i<num_blocks;i++){ + + for(int j=0;j<num_blocks;j++){ + + cityrotation[i][j]=Random()%4; + + citytype[i][j]=Random()%4; + + citypeoplenum[i][j]=0; + + if(citytype[i][j]<0)citytype[i][j]=0; + + if(citytype[i][j]>3)citytype[i][j]=3; + + } + + } + + + + if(!initialized){ + + //Load player model + + skeletonmodels[0].load((unsigned char *)":Data:Models:Head.solid"); + + skeletonmodels[0].Rotate(90,0,0); + + skeletonmodels[0].Scale(.02,.02,.02); + + skeletonmodels[0].CalculateNormals(); + + + + skeletonmodels[1].load((unsigned char *)":Data:Models:Chest.solid"); + + skeletonmodels[1].Rotate(90,0,0); + + skeletonmodels[1].Scale(.02,.02,.02); + + skeletonmodels[1].CalculateNormals(); + + + + skeletonmodels[2].load((unsigned char *)":Data:Models:Abdomen.solid"); + + skeletonmodels[2].Rotate(90,0,0); + + skeletonmodels[2].Scale(.02,.02,.02); + + skeletonmodels[2].CalculateNormals(); + + + + skeletonmodels[3].load((unsigned char *)":Data:Models:Upper arm.solid"); + + skeletonmodels[3].Rotate(90,0,0); + + skeletonmodels[3].Scale(.02,.02,.02); + + skeletonmodels[3].CalculateNormals(); + + + + skeletonmodels[4].load((unsigned char *)":Data:Models:Lower arm.solid"); + + skeletonmodels[4].Rotate(90,0,0); + + skeletonmodels[4].Scale(.02,.02,.02); + + skeletonmodels[4].CalculateNormals(); + + + + skeletonmodels[5].load((unsigned char *)":Data:Models:Hand.solid"); + + skeletonmodels[5].Rotate(90,0,0); + + skeletonmodels[5].Scale(.02,.02,.02); + + skeletonmodels[5].CalculateNormals(); + + + + skeletonmodels[6].load((unsigned char *)":Data:Models:Upper leg.solid"); + + skeletonmodels[6].Rotate(90,0,0); + + skeletonmodels[6].Scale(.02,.02,.02); + + skeletonmodels[6].CalculateNormals(); + + + + skeletonmodels[7].load((unsigned char *)":Data:Models:Lower leg.solid"); + + skeletonmodels[7].Rotate(90,0,0); + + skeletonmodels[7].Scale(.02,.02,.02); + + skeletonmodels[7].CalculateNormals(); + + + + skeletonmodels[8].load((unsigned char *)":Data:Models:Foot.solid"); + + skeletonmodels[8].Rotate(90,0,0); + + skeletonmodels[8].Scale(.02,.02,.02); + + skeletonmodels[8].CalculateNormals(); + + + + skeletonmodels[9].load((unsigned char *)":Data:Models:Shades.solid"); + + skeletonmodels[9].Rotate(90,0,0); + + skeletonmodels[9].Scale(.02,.02,.02); + + skeletonmodels[9].CalculateNormals(); + + + + //Load gun models + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + gunmodels[sniperriflemodel].load((unsigned char *)":Data:Models:sniperrifle.solid"); + + gunmodels[sniperriflemodel].Rotate(0,0,90); + + gunmodels[sniperriflemodel].Scale(.001,.001,.001); + + gunmodels[sniperriflemodel].CalculateNormals(); + + + + gunmodels[assaultriflemodel].load((unsigned char *)":Data:Models:assaultrifle.solid"); + + gunmodels[assaultriflemodel].Rotate(0,0,90); + + gunmodels[assaultriflemodel].Scale(.01,.01,.01); + + gunmodels[assaultriflemodel].CalculateNormals(); + + + + gunmodels[handgunbasemodel].load((unsigned char *)":Data:Models:Handgunbase.solid"); + + gunmodels[handgunbasemodel].Rotate(0,0,90); + + gunmodels[handgunbasemodel].Rotate(180,0,0); + + gunmodels[handgunbasemodel].Scale(.014,.014,.014); + + gunmodels[handgunbasemodel].CalculateNormals(); + + gunmodels[handgunbasemodel].MultColor(.6); + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + gunmodels[handgunslidemodel].load((unsigned char *)":Data:Models:Handgunslide.solid"); + + gunmodels[handgunslidemodel].Rotate(0,0,90); + + gunmodels[handgunslidemodel].Rotate(180,0,0); + + gunmodels[handgunslidemodel].Scale(.014,.014,.014); + + gunmodels[handgunslidemodel].CalculateNormals(); + + gunmodels[handgunslidemodel].MultColor(.6); + + + + gunmodels[handgun2basemodel].load((unsigned char *)":Data:Models:glockbase.solid"); + + gunmodels[handgun2basemodel].Rotate(0,0,90); + + gunmodels[handgun2basemodel].Rotate(180,0,0); + + gunmodels[handgun2basemodel].Scale(.014,.014,.014); + + gunmodels[handgun2basemodel].CalculateNormals(); + + gunmodels[handgun2basemodel].MultColor(.6); + + + + gunmodels[handgun2slidemodel].load((unsigned char *)":Data:Models:glockslide.solid"); + + gunmodels[handgun2slidemodel].Rotate(0,0,90); + + gunmodels[handgun2slidemodel].Rotate(180,0,0); + + gunmodels[handgun2slidemodel].Scale(.014,.014,.014); + + gunmodels[handgun2slidemodel].CalculateNormals(); + + gunmodels[handgun2slidemodel].MultColor(.6); + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + gunmodels[grenadebasemodel].load((unsigned char *)":Data:Models:grenadebase.solid"); + + gunmodels[grenadebasemodel].Rotate(0,0,90); + + gunmodels[grenadebasemodel].Rotate(180,0,0); + + gunmodels[grenadebasemodel].Scale(.014,.014,.014); + + gunmodels[grenadebasemodel].CalculateNormals(); + + + + gunmodels[grenadepinmodel].load((unsigned char *)":Data:Models:grenadepin.solid"); + + gunmodels[grenadepinmodel].Rotate(0,0,90); + + gunmodels[grenadepinmodel].Rotate(180,0,0); + + gunmodels[grenadepinmodel].Scale(.014,.014,.014); + + gunmodels[grenadepinmodel].CalculateNormals(); + + + + gunmodels[grenadespoonmodel].load((unsigned char *)":Data:Models:grenadespoon.solid"); + + gunmodels[grenadespoonmodel].Rotate(0,0,90); + + gunmodels[grenadespoonmodel].Rotate(180,0,0); + + gunmodels[grenadespoonmodel].Scale(.014,.014,.014); + + gunmodels[grenadespoonmodel].CalculateNormals(); + + + + gunmodels[knifemodel].load((unsigned char *)":Data:Models:Knife.solid"); + + gunmodels[knifemodel].Rotate(0,0,90); + + gunmodels[knifemodel].Rotate(180,0,0); + + gunmodels[knifemodel].Scale(.014,.014,.014); + + gunmodels[knifemodel].CalculateNormals(); + + + + gunmodels[shotgunmodel].load((unsigned char *)":Data:Models:shotgun.solid"); + + gunmodels[shotgunmodel].Rotate(0,0,90); + + gunmodels[shotgunmodel].Scale(.001,.001,.001); + + gunmodels[shotgunmodel].CalculateNormals(); + + gunmodels[shotgunmodel].MultColor(.6); + + } + + + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + //Setup costumes + + float headcolor[3]; + + float footcolor[3]; + + float handcolor[3]; + + float topcolor[3]; + + float bottomcolor[3]; + + //Police + + headcolor[0]=(float)240/255; + + headcolor[1]=(float)183/255; + + headcolor[2]=(float)132/255; + + + + footcolor[0]=(float)119/255; + + footcolor[1]=(float)68/255; + + footcolor[2]=(float)18/255; + + + + handcolor[0]=(float)240/255; + + handcolor[1]=(float)183/255; + + handcolor[2]=(float)132/255; + + + + topcolor[0]=(float)14/255; + + topcolor[1]=(float)18/255; + + topcolor[2]=(float)195/255; + + + + bottomcolor[0]=(float)14/255; + + bottomcolor[1]=(float)18/255; + + bottomcolor[2]=(float)195/255; + + + + //Greenish skin if zombies + + if(type==zombie_type){ + + headcolor[0]=(float)223/255; + + headcolor[1]=(float)243/255; + + headcolor[2]=(float)197/255; + + + + handcolor[0]=(float)223/255; + + handcolor[1]=(float)243/255; + + handcolor[2]=(float)197/255; + + } + + + + costume[policecostume].headcolor[0]=headcolor[0]; + + costume[policecostume].headcolor[1]=headcolor[1]; + + costume[policecostume].headcolor[2]=headcolor[2]; + + + + costume[policecostume].handcolor[0]=handcolor[0]; + + costume[policecostume].handcolor[1]=handcolor[1]; + + costume[policecostume].handcolor[2]=handcolor[2]; + + + + costume[policecostume].chestcolor[0]=topcolor[0]; + + costume[policecostume].chestcolor[1]=topcolor[1]; + + costume[policecostume].chestcolor[2]=topcolor[2]; + + + + costume[policecostume].abdomencolor[0]=topcolor[0]; + + costume[policecostume].abdomencolor[1]=topcolor[1]; + + costume[policecostume].abdomencolor[2]=topcolor[2]; + + + + costume[policecostume].upperarmcolor[0]=topcolor[0]; + + costume[policecostume].upperarmcolor[1]=topcolor[1]; + + costume[policecostume].upperarmcolor[2]=topcolor[2]; + + + + costume[policecostume].lowerarmcolor[0]=topcolor[0]; + + costume[policecostume].lowerarmcolor[1]=topcolor[1]; + + costume[policecostume].lowerarmcolor[2]=topcolor[2]; + + + + costume[policecostume].upperlegcolor[0]=bottomcolor[0]; + + costume[policecostume].upperlegcolor[1]=bottomcolor[1]; + + costume[policecostume].upperlegcolor[2]=bottomcolor[2]; + + + + costume[policecostume].lowerlegcolor[0]=bottomcolor[0]; + + costume[policecostume].lowerlegcolor[1]=bottomcolor[1]; + + costume[policecostume].lowerlegcolor[2]=bottomcolor[2]; + + + + costume[policecostume].footcolor[0]=footcolor[0]; + + costume[policecostume].footcolor[1]=footcolor[1]; + + costume[policecostume].footcolor[2]=footcolor[2]; + + + + //casual + + topcolor[0]=(float)14/255; + + topcolor[1]=(float)200/255; + + topcolor[2]=(float)30/255; + + + + bottomcolor[0]=(float)14/255; + + bottomcolor[1]=(float)18/255; + + bottomcolor[2]=(float)195/255; + + + + costume[casualcostumes].headcolor[0]=headcolor[0]; + + costume[casualcostumes].headcolor[1]=headcolor[1]; + + costume[casualcostumes].headcolor[2]=headcolor[2]; + + + + costume[casualcostumes].handcolor[0]=handcolor[0]; + + costume[casualcostumes].handcolor[1]=handcolor[1]; + + costume[casualcostumes].handcolor[2]=handcolor[2]; + + + + costume[casualcostumes].chestcolor[0]=topcolor[0]; + + costume[casualcostumes].chestcolor[1]=topcolor[1]; + + costume[casualcostumes].chestcolor[2]=topcolor[2]; + + + + costume[casualcostumes].abdomencolor[0]=topcolor[0]; + + costume[casualcostumes].abdomencolor[1]=topcolor[1]; + + costume[casualcostumes].abdomencolor[2]=topcolor[2]; + + + + costume[casualcostumes].upperarmcolor[0]=topcolor[0]; + + costume[casualcostumes].upperarmcolor[1]=topcolor[1]; + + costume[casualcostumes].upperarmcolor[2]=topcolor[2]; + + + + costume[casualcostumes].lowerarmcolor[0]=handcolor[0]; + + costume[casualcostumes].lowerarmcolor[1]=handcolor[1]; + + costume[casualcostumes].lowerarmcolor[2]=handcolor[2]; + + + + costume[casualcostumes].upperlegcolor[0]=bottomcolor[0]; + + costume[casualcostumes].upperlegcolor[1]=bottomcolor[1]; + + costume[casualcostumes].upperlegcolor[2]=bottomcolor[2]; + + + + costume[casualcostumes].lowerlegcolor[0]=bottomcolor[0]; + + costume[casualcostumes].lowerlegcolor[1]=bottomcolor[1]; + + costume[casualcostumes].lowerlegcolor[2]=bottomcolor[2]; + + + + costume[casualcostumes].footcolor[0]=footcolor[0]; + + costume[casualcostumes].footcolor[1]=footcolor[1]; + + costume[casualcostumes].footcolor[2]=footcolor[2]; + + + + //casual 2 + + topcolor[0]=(float)140/255; + + topcolor[1]=(float)55/255; + + topcolor[2]=(float)4/255; + + + + bottomcolor[0]=(float)14/255; + + bottomcolor[1]=(float)18/255; + + bottomcolor[2]=(float)135/255; + + + + costume[casualcostumes+1].headcolor[0]=headcolor[0]; + + costume[casualcostumes+1].headcolor[1]=headcolor[1]; + + costume[casualcostumes+1].headcolor[2]=headcolor[2]; + + + + costume[casualcostumes+1].handcolor[0]=handcolor[0]; + + costume[casualcostumes+1].handcolor[1]=handcolor[1]; + + costume[casualcostumes+1].handcolor[2]=handcolor[2]; + + + + costume[casualcostumes+1].chestcolor[0]=topcolor[0]; + + costume[casualcostumes+1].chestcolor[1]=topcolor[1]; + + costume[casualcostumes+1].chestcolor[2]=topcolor[2]; + + + + costume[casualcostumes+1].abdomencolor[0]=topcolor[0]; + + costume[casualcostumes+1].abdomencolor[1]=topcolor[1]; + + costume[casualcostumes+1].abdomencolor[2]=topcolor[2]; + + + + costume[casualcostumes+1].upperarmcolor[0]=topcolor[0]; + + costume[casualcostumes+1].upperarmcolor[1]=topcolor[1]; + + costume[casualcostumes+1].upperarmcolor[2]=topcolor[2]; + + + + costume[casualcostumes+1].lowerarmcolor[0]=topcolor[0]; + + costume[casualcostumes+1].lowerarmcolor[1]=topcolor[1]; + + costume[casualcostumes+1].lowerarmcolor[2]=topcolor[2]; + + + + costume[casualcostumes+1].upperlegcolor[0]=bottomcolor[0]; + + costume[casualcostumes+1].upperlegcolor[1]=bottomcolor[1]; + + costume[casualcostumes+1].upperlegcolor[2]=bottomcolor[2]; + + + + costume[casualcostumes+1].lowerlegcolor[0]=bottomcolor[0]; + + costume[casualcostumes+1].lowerlegcolor[1]=bottomcolor[1]; + + costume[casualcostumes+1].lowerlegcolor[2]=bottomcolor[2]; + + + + costume[casualcostumes+1].footcolor[0]=footcolor[0]; + + costume[casualcostumes+1].footcolor[1]=footcolor[1]; + + costume[casualcostumes+1].footcolor[2]=footcolor[2]; + + + + //casual 3 + + topcolor[0]=(float)134/255; + + topcolor[1]=(float)80/255; + + topcolor[2]=(float)3/255; + + + + bottomcolor[0]=(float)30/255; + + bottomcolor[1]=(float)30/255; + + bottomcolor[2]=(float)30/255; + + + + footcolor[0]=(float)20/255; + + footcolor[1]=(float)20/255; + + footcolor[2]=(float)20/255; + + + + + + costume[casualcostumes+2].headcolor[0]=headcolor[0]; + + costume[casualcostumes+2].headcolor[1]=headcolor[1]; + + costume[casualcostumes+2].headcolor[2]=headcolor[2]; + + + + costume[casualcostumes+2].handcolor[0]=handcolor[0]; + + costume[casualcostumes+2].handcolor[1]=handcolor[1]; + + costume[casualcostumes+2].handcolor[2]=handcolor[2]; + + + + costume[casualcostumes+2].chestcolor[0]=topcolor[0]; + + costume[casualcostumes+2].chestcolor[1]=topcolor[1]; + + costume[casualcostumes+2].chestcolor[2]=topcolor[2]; + + + + costume[casualcostumes+2].abdomencolor[0]=topcolor[0]; + + costume[casualcostumes+2].abdomencolor[1]=topcolor[1]; + + costume[casualcostumes+2].abdomencolor[2]=topcolor[2]; + + + + costume[casualcostumes+2].upperarmcolor[0]=topcolor[0]; + + costume[casualcostumes+2].upperarmcolor[1]=topcolor[1]; + + costume[casualcostumes+2].upperarmcolor[2]=topcolor[2]; + + + + costume[casualcostumes+2].lowerarmcolor[0]=topcolor[0]; + + costume[casualcostumes+2].lowerarmcolor[1]=topcolor[1]; + + costume[casualcostumes+2].lowerarmcolor[2]=topcolor[2]; + + + + costume[casualcostumes+2].upperlegcolor[0]=bottomcolor[0]; + + costume[casualcostumes+2].upperlegcolor[1]=bottomcolor[1]; + + costume[casualcostumes+2].upperlegcolor[2]=bottomcolor[2]; + + + + costume[casualcostumes+2].lowerlegcolor[0]=bottomcolor[0]; + + costume[casualcostumes+2].lowerlegcolor[1]=bottomcolor[1]; + + costume[casualcostumes+2].lowerlegcolor[2]=bottomcolor[2]; + + + + costume[casualcostumes+2].footcolor[0]=footcolor[0]; + + costume[casualcostumes+2].footcolor[1]=footcolor[1]; + + costume[casualcostumes+2].footcolor[2]=footcolor[2]; + + + + //casual 4 + + topcolor[0]=(float)228/255; + + topcolor[1]=(float)220/255; + + topcolor[2]=(float)0/255; + + + + bottomcolor[0]=(float)20/255; + + bottomcolor[1]=(float)20/255; + + bottomcolor[2]=(float)20/255; + + + + footcolor[0]=(float)119/255; + + footcolor[1]=(float)68/255; + + footcolor[2]=(float)18/255; + + + + costume[casualcostumes+3].headcolor[0]=headcolor[0]; + + costume[casualcostumes+3].headcolor[1]=headcolor[1]; + + costume[casualcostumes+3].headcolor[2]=headcolor[2]; + + + + costume[casualcostumes+3].handcolor[0]=handcolor[0]; + + costume[casualcostumes+3].handcolor[1]=handcolor[1]; + + costume[casualcostumes+3].handcolor[2]=handcolor[2]; + + + + costume[casualcostumes+3].chestcolor[0]=topcolor[0]; + + costume[casualcostumes+3].chestcolor[1]=topcolor[1]; + + costume[casualcostumes+3].chestcolor[2]=topcolor[2]; + + + + costume[casualcostumes+3].abdomencolor[0]=topcolor[0]; + + costume[casualcostumes+3].abdomencolor[1]=topcolor[1]; + + costume[casualcostumes+3].abdomencolor[2]=topcolor[2]; + + + + costume[casualcostumes+3].upperarmcolor[0]=topcolor[0]; + + costume[casualcostumes+3].upperarmcolor[1]=topcolor[1]; + + costume[casualcostumes+3].upperarmcolor[2]=topcolor[2]; + + + + costume[casualcostumes+3].lowerarmcolor[0]=handcolor[0]; + + costume[casualcostumes+3].lowerarmcolor[1]=handcolor[1]; + + costume[casualcostumes+3].lowerarmcolor[2]=handcolor[2]; + + + + costume[casualcostumes+3].upperlegcolor[0]=bottomcolor[0]; + + costume[casualcostumes+3].upperlegcolor[1]=bottomcolor[1]; + + costume[casualcostumes+3].upperlegcolor[2]=bottomcolor[2]; + + + + costume[casualcostumes+3].lowerlegcolor[0]=bottomcolor[0]; + + costume[casualcostumes+3].lowerlegcolor[1]=bottomcolor[1]; + + costume[casualcostumes+3].lowerlegcolor[2]=bottomcolor[2]; + + + + costume[casualcostumes+3].footcolor[0]=footcolor[0]; + + costume[casualcostumes+3].footcolor[1]=footcolor[1]; + + costume[casualcostumes+3].footcolor[2]=footcolor[2]; + + + + if(!initialized){ + + //vip + + topcolor[0]=(float)235/255; + + topcolor[1]=(float)235/255; + + topcolor[2]=(float)235/255; + + + + bottomcolor[0]=(float)200/255; + + bottomcolor[1]=(float)200/255; + + bottomcolor[2]=(float)200/255; + + + + footcolor[0]=(float)119/255; + + footcolor[1]=(float)68/255; + + footcolor[2]=(float)18/255; + + + + headcolor[0]=(float)240/255; + + headcolor[1]=(float)183/255; + + headcolor[2]=(float)132/255; + + + + footcolor[0]=(float)119/255; + + footcolor[1]=(float)68/255; + + footcolor[2]=(float)18/255; + + + + handcolor[0]=(float)240/255; + + handcolor[1]=(float)183/255; + + handcolor[2]=(float)132/255; + + + + costume[vipcostume].headcolor[0]=headcolor[0]; + + costume[vipcostume].headcolor[1]=headcolor[1]; + + costume[vipcostume].headcolor[2]=headcolor[2]; + + + + costume[vipcostume].handcolor[0]=handcolor[0]; + + costume[vipcostume].handcolor[1]=handcolor[1]; + + costume[vipcostume].handcolor[2]=handcolor[2]; + + + + costume[vipcostume].chestcolor[0]=topcolor[0]; + + costume[vipcostume].chestcolor[1]=topcolor[1]; + + costume[vipcostume].chestcolor[2]=topcolor[2]; + + + + costume[vipcostume].abdomencolor[0]=topcolor[0]; + + costume[vipcostume].abdomencolor[1]=topcolor[1]; + + costume[vipcostume].abdomencolor[2]=topcolor[2]; + + + + costume[vipcostume].upperarmcolor[0]=topcolor[0]; + + costume[vipcostume].upperarmcolor[1]=topcolor[1]; + + costume[vipcostume].upperarmcolor[2]=topcolor[2]; + + + + costume[vipcostume].lowerarmcolor[0]=topcolor[0]; + + costume[vipcostume].lowerarmcolor[1]=topcolor[1]; + + costume[vipcostume].lowerarmcolor[2]=topcolor[2]; + + + + costume[vipcostume].upperlegcolor[0]=bottomcolor[0]; + + costume[vipcostume].upperlegcolor[1]=bottomcolor[1]; + + costume[vipcostume].upperlegcolor[2]=bottomcolor[2]; + + + + costume[vipcostume].lowerlegcolor[0]=bottomcolor[0]; + + costume[vipcostume].lowerlegcolor[1]=bottomcolor[1]; + + costume[vipcostume].lowerlegcolor[2]=bottomcolor[2]; + + + + costume[vipcostume].footcolor[0]=footcolor[0]; + + costume[vipcostume].footcolor[1]=footcolor[1]; + + costume[vipcostume].footcolor[2]=footcolor[2]; + + + + //Bodyguard + + topcolor[0]=(float)50/255; + + topcolor[1]=(float)50/255; + + topcolor[2]=(float)50/255; + + + + bottomcolor[0]=(float)30/255; + + bottomcolor[1]=(float)30/255; + + bottomcolor[2]=(float)30/255; + + + + footcolor[0]=(float)20/255; + + footcolor[1]=(float)20/255; + + footcolor[2]=(float)20/255; + + + + costume[bodyguardcostume].headcolor[0]=headcolor[0]; + + costume[bodyguardcostume].headcolor[1]=headcolor[1]; + + costume[bodyguardcostume].headcolor[2]=headcolor[2]; + + + + costume[bodyguardcostume].handcolor[0]=handcolor[0]; + + costume[bodyguardcostume].handcolor[1]=handcolor[1]; + + costume[bodyguardcostume].handcolor[2]=handcolor[2]; + + + + costume[bodyguardcostume].chestcolor[0]=topcolor[0]; + + costume[bodyguardcostume].chestcolor[1]=topcolor[1]; + + costume[bodyguardcostume].chestcolor[2]=topcolor[2]; + + + + costume[bodyguardcostume].abdomencolor[0]=topcolor[0]; + + costume[bodyguardcostume].abdomencolor[1]=topcolor[1]; + + costume[bodyguardcostume].abdomencolor[2]=topcolor[2]; + + + + costume[bodyguardcostume].upperarmcolor[0]=topcolor[0]; + + costume[bodyguardcostume].upperarmcolor[1]=topcolor[1]; + + costume[bodyguardcostume].upperarmcolor[2]=topcolor[2]; + + + + costume[bodyguardcostume].lowerarmcolor[0]=topcolor[0]; + + costume[bodyguardcostume].lowerarmcolor[1]=topcolor[1]; + + costume[bodyguardcostume].lowerarmcolor[2]=topcolor[2]; + + + + costume[bodyguardcostume].upperlegcolor[0]=bottomcolor[0]; + + costume[bodyguardcostume].upperlegcolor[1]=bottomcolor[1]; + + costume[bodyguardcostume].upperlegcolor[2]=bottomcolor[2]; + + + + costume[bodyguardcostume].lowerlegcolor[0]=bottomcolor[0]; + + costume[bodyguardcostume].lowerlegcolor[1]=bottomcolor[1]; + + costume[bodyguardcostume].lowerlegcolor[2]=bottomcolor[2]; + + + + costume[bodyguardcostume].footcolor[0]=footcolor[0]; + + costume[bodyguardcostume].footcolor[1]=footcolor[1]; + + costume[bodyguardcostume].footcolor[2]=footcolor[2]; + + + + //Load animations + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + testskeleton.Load((char *)":Data:Skeleton:Basic Figure"); + + animation[idleanim].Load((char *)":Data:Animations:Breathe"); + + animation[joganim].Load((char *)":Data:Animations:Run"); + + animation[pistolaimanim].Load((char *)":Data:Animations:PistolAim"); + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + animation[walkanim].Load((char *)":Data:Animations:Walk"); + + animation[rifleholdanim].Load((char *)":Data:Animations:Riflehold"); + + animation[rifleaimanim].Load((char *)":Data:Animations:Rifleaim"); + + animation[assaultrifleaimanim].Load((char *)":Data:Animations:AssaultRifleaim"); + + animation[crouchanim].Load((char *)":Data:Animations:Crouch"); + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + animation[headpainanim].Load((char *)":Data:Animations:Headshot"); + + animation[chestpainanim].Load((char *)":Data:Animations:Chestshot"); + + animation[stomachpainanim].Load((char *)":Data:Animations:Stomachshot"); + + animation[rightarmpainanim].Load((char *)":Data:Animations:Rightarmshot"); + + animation[leftarmpainanim].Load((char *)":Data:Animations:Leftarmshot"); + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + animation[rightlegpainanim].Load((char *)":Data:Animations:Rightlegshot"); + + animation[leftlegpainanim].Load((char *)":Data:Animations:Leftlegshot"); + + animation[riflehitanim].Load((char *)":Data:Animations:Riflehit"); + + animation[grenadeaimanim].Load((char *)":Data:Animations:grenadeaim"); + + animation[grenadechargeanim].Load((char *)":Data:Animations:grenadecharge"); + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + animation[grenadethrowanim].Load((char *)":Data:Animations:grenadethrow"); + + animation[zombieeatanim].Load((char *)":Data:Animations:Zombiemunch"); + + animation[zombiejoganim].Load((char *)":Data:Animations:ZombieRun"); + + animation[zombiewalkanim].Load((char *)":Data:Animations:Zombiewalk"); + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + animation[getupfrontanim].Load((char *)":Data:Animations:Getupfromfront"); + + animation[getupbackanim].Load((char *)":Data:Animations:Getupfromback",180); + + animation[diveanim].Load((char *)":Data:Animations:Dive"); + + animation[throwanim].Load((char *)":Data:Animations:Aikidothrow"); + + animation[thrownanim].Load((char *)":Data:Animations:Aikidothrown"); + + } + + + + //Setup people + + for(int i=0;i<max_people;i++){ + + if(i==0){ + + person[i].whichcostume=bodyguardcostume; + + } + + + + if(i>1){ + + person[i].whichcostume=casualcostumes+abs(Random())%numcasual; + + } + + //person[i].firstlongdead=0; + + person[i].dead=0; + + person[i].health=100; + + person[i].skeleton.free=0; + + person[i].ammo=0; + + person[i].velocity=0; + + //Load skeleton structure + + if(!initialized)person[i].skeleton.Load((char *)":Data:Skeleton:Basic Figure"); + + + + if(i%5==0){ + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + } + + } + + + + loadingscreenamount+=5; + + if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + if(initialized)person[0].skeleton.Load((char *)":Data:Skeleton:Basic Figure"); + + + + person[0].attackframe=-1; + + + + spawndelay=0; + + + + fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.1); + + + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + + + + //light + + GLfloat LightAmbient[]= { .3, .3, .3, 1.0f}; + + GLfloat LightDiffuse[]= { 1, 1, 1, 1.0f }; + + + + glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient); + + glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse); + + glEnable(GL_LIGHT0); + + + + loadingscreenamount+=5; + + + + //Load some textures + + if(!initialized){ + + LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + + + + + LoadPersonSpriteTexture(":Data:Textures:Personsprite.png",&personspritetextureptr); + + LoadPersonSpriteTexture(":Data:Textures:DeadPersonsprite.png",&deadpersonspritetextureptr); + + LoadPersonSpriteTexture(":Data:Textures:Scope.png",&scopetextureptr); + + LoadPersonSpriteTexture(":Data:Textures:Flare.png",&flaretextureptr); + + + + sprites.LoadFlareTexture(":Data:Textures:HitFlash.png"); + + sprites.LoadMuzzleFlareTexture(":Data:Textures:MuzzleFlash.png"); + + sprites.LoadSmokeTexture(":Data:Textures:Smoke.png"); + + sprites.LoadBloodTexture(":Data:Textures:Blood.png"); + + sprites.LoadRainTexture(":Data:Textures:rain.png"); + + sprites.LoadSnowTexture(":Data:Textures:snow.png"); + + decals.LoadBulletHoleTexture(":Data:Textures:BulletHole.png"); + + decals.LoadCraterTexture(":Data:Textures:Crater.png"); + + decals.LoadBloodTexture(":Data:Textures:Blood:Blood1.png",0); + + decals.LoadBloodTexture(":Data:Textures:Blood:Blood2.png",1); + + decals.LoadBloodTexture(":Data:Textures:Blood:Blood3.png",2); + + decals.LoadBloodTexture(":Data:Textures:Blood:Blood4.png",3); + + decals.LoadBloodTexture(":Data:Textures:Blood:Blood5.png",4); + + decals.LoadBloodTexture(":Data:Textures:Blood:Blood6.png",5); + + decals.LoadBloodTexture(":Data:Textures:Blood:Blood7.png",6); + + decals.LoadBloodTexture(":Data:Textures:Blood:Blood8.png",7); + + decals.LoadBloodTexture(":Data:Textures:Blood:Blood9.png",8); + + decals.LoadBloodTexture(":Data:Textures:Blood:Blood10.png",9); + + decals.LoadBloodTexture(":Data:Textures:Blood:Blood11.png",10); + + } + + + + //Setup clip plane equation + + eqn[0]=0; + + eqn[1]=1; + + eqn[2]=0; + + eqn[3]=0; + + + + glClearColor(fogcolorr,fogcolorg,fogcolorb,1); + + + + if(!initialized)InitMouse(); + + + + //Draw city one frame to fix evil menu bug + + if(!initialized)mainmenu=2; + + + + if(!initialized){ + + LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100); + + flashamount=1; + + flashr=1;flashg=1;flashb=1; + + alSourcePlay(gSourceID[soulinsound]); + + } + + + + initialized=1; + + + + loadingscreenamount+=5; + + + + //Sync to refresh rate + + if(vblsync){ + + GLint swapInt = 1; + +#ifdef OS9 + aglSetInteger(gOpenGLContext, AGL_SWAP_INTERVAL, &swapInt); +#else + +#endif + + + + + } + + /* + + for(int i=0;i<sprites.howmanysprites;i++){ + + sprites.DeleteSprite(0); + + } + + + + for(int i=0;i<decals.howmanydecals;i++){ + + decals.DeleteDecal(0); + + }*/ + + decals.howmanydecals=0; + + sprites.howmanysprites=0; + + + + losedelay=1; + + + + oldscore=score; + +} + + + +/*********************> InitGL() <*****/ + + + + + +int Game::InitGL(void) + +{ + + //Config + + if(!initialized){ + + //Default config in case config is not found +#ifdef OS9 + HideCursor(); +#else + STUB_FUNCTION; +#endif + + screenwidth = 640; + + screenheight = 480; + + usermousesensitivity=.7; + + debug=0; + + vblsync=1; + + blood = 1; + + blurness = 0; + + mainmenuness=1; + + customlevels=0; + + musictoggle=1; + + + + //If no config, write one + + ifstream ipstream("config.txt"); + + if(!ipstream) { + + ofstream opstream("config.txt"); + + opstream << "Screenwidth:\n"; + + opstream << screenwidth; + + opstream << "\nScreenheight:\n"; + + opstream << screenheight; + + opstream << "\nMouse sensitivity:\n"; + + opstream << usermousesensitivity; + + opstream << "\nShow fps and other info:\n"; + + opstream << debug; + + opstream << "\nVBL sync:\n"; + + opstream << vblsync; + + opstream << "\nBlood:\n"; + + opstream << blood; + + opstream << "\nBlur:\n"; + + opstream << blurness; + + opstream << "\nMain Menu:\n"; + + opstream << mainmenuness; + + opstream << "\nCustom levels:\n"; + + opstream << customlevels; + + opstream << "\nMusic:\n"; + + opstream << musictoggle; + + opstream << "\azerty keyboard:\n"; + + opstream << azertykeyboard; + + opstream.close(); + + } + + //Read config + + if(ipstream){ + + ipstream.ignore(256,'\n'); + + ipstream >> screenwidth; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> screenheight; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> usermousesensitivity; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> debug; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> vblsync; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> blood; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> blurness; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> mainmenuness; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> customlevels; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> musictoggle; + + ipstream.ignore(256,'\n'); + + ipstream.ignore(256,'\n'); + + ipstream >> azertykeyboard; + + ipstream.close(); + + } + + + + //Read high score +#ifdef OS9 + ifstream ipstream2(":Data:Highscore"); +#else + /* TODO */ + ifstream ipstream2("Data/Highscore"); +#endif + if(!ipstream2) { + + highscore=0; + + beatgame=0; + +#ifdef OS9 + ofstream opstream(":Data:Highscore"); +#else + /* TODO */ + ofstream opstream("Data/Highscore"); +#endif + opstream << highscore; + + opstream << "\n"; + + opstream << beatgame; + + opstream.close(); + + } + + if(ipstream2){ + + ipstream2 >> highscore; + + ipstream.ignore(256,'\n'); + + ipstream2 >> beatgame; + + ipstream2.close(); + + } + + + + sps=40; + + maxfps=90; + + + + disttest=1; + + cubetest=1; + + } + + + + //Setup screen +#ifdef OS9 + if(screenwidth<640||screenheight<480) + + theScreen = SetupScreen( 640, 480 ); + + else + + theScreen = SetupScreen( screenwidth, screenheight ); + + + + gOpenGLContext = SetupAGL( ( AGLDrawable )theScreen ); + + if ( !gOpenGLContext ) + + return; +#else + if (SDL_Init(SDL_INIT_VIDEO) == -1) { + fprintf(stderr, "SDL Init Video failed: %s\n", SDL_GetError()); + exit(EXIT_FAILURE); + } + + atexit(SDL_Quit); + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + if(screenwidth<640||screenheight<480) { +#ifdef FULLSCREEN + if (SDL_SetVideoMode(640, 480, 0, SDL_OPENGL | SDL_FULLSCREEN) == NULL) { +#else + if (SDL_SetVideoMode(640, 480, 0, SDL_OPENGL) == NULL) { +#endif + fprintf(stderr, "(OpenGL) SDL SetVideoMode failed: %s\n", SDL_GetError()); + exit(EXIT_FAILURE); + } + } else { +#ifdef FULLSCREEN + if (SDL_SetVideoMode(screenwidth, screenheight, 0, SDL_OPENGL | SDL_FULLSCREEN) == NULL) { +#else + if (SDL_SetVideoMode(screenwidth, screenheight, 0, SDL_OPENGL) == NULL) { +#endif + fprintf(stderr, "(OpenGL) SDL SetVideoMode failed: %s\n", SDL_GetError()); + exit(EXIT_FAILURE); + } + } + + SDL_WM_SetCaption("Black Shades", "Black Shades"); + + SDL_EnableUNICODE(1); /* toggle it to ON */ + +#ifdef FULLSCREEN + SDL_WM_GrabInput(SDL_GRAB_ON); + SDL_ShowCursor(0); +#endif + +#endif + + + text.LoadFontTexture(":Data:Textures:Font.png"); + + text.BuildFont(); + + glAlphaFunc(GL_GREATER, 0.01); + + glDepthFunc(GL_LESS); + + + + glPolygonOffset(-8,0); + + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + + + + return TRUE; + +} + + + +//***************> Dispose() <******/ + +void Game::Dispose() + +{ +#ifdef OS9 + CleanupAGL( gOpenGLContext ); + + ShutdownScreen( theScreen ); + + ShowCursor(); +#endif + + + //Delete sound sources + + alDeleteSources(100, gSourceID); + + + +} + + + +//***************> ResizeGLScene() <******/ + +GLvoid Game::ReSizeGLScene(float fov, float near) + +{ + + if (screenheight==0) + + { + + screenheight=1; + + } + + + + glViewport(0,0,screenwidth,screenheight); + + + + glMatrixMode(GL_PROJECTION); + + glLoadIdentity(); + + + + gluPerspective(fov,(GLfloat)screenwidth/(GLfloat)screenheight,near,viewdistance); + + + + glMatrixMode(GL_MODELVIEW); + + glLoadIdentity(); + +} + diff --git a/src/GameLoop.cpp b/src/GameLoop.cpp new file mode 100644 index 0000000..8a72b4b --- /dev/null +++ b/src/GameLoop.cpp @@ -0,0 +1,573 @@ +#include "Game.h" + + + +extern double multiplier; + +extern int visions; + +extern unsigned int gSourceID[100]; + +extern unsigned int gSampleSet[100]; + +extern Camera camera; + +extern float rad2deg; + +extern Fog fog; + +extern int environment; + +extern int slomo; + +/********************> HandleKeyDown() <*****/ + +void Game::HandleKeyDown( char theChar ) + +{ + + XYZ facing; + + + + if(!mainmenu){ + + switch( theChar ) + + { + + case 'l': + if(!lasersight==1){lasersight=1;}else{lasersight=0;} + + break; + + case 'k': + + if(debug)timeremaining=0; + + break; + + + + case 'b': + + if(debug){ + + alSourcePlay(gSourceID[soulinsound]); + + if(!slomo)slomo=1; + + else slomo=0;} + + if(slomo){ + + alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat)(.5)); + + alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat)(.5)); + + alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat)(.5)); + + } + + if(!slomo){ + + alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat)(1)); + + alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat)(1)); + + alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat)(1)); + + } + + break; + + case 'B': + + if(debug){ + + alSourcePlay(gSourceID[soulinsound]); + + paused=1-paused;} + + break; + + case 'f': + + if(debug){ + + alSourcePlay(gSourceID[souloutsound]); + + //Facing + + facing=0; + + facing.z=-1; + + + + facing=DoRotation(facing,-camera.rotation2,0,0); + + facing=DoRotation(facing,0,0-camera.rotation,0); + + for(int i=1;i<numpeople;i++){ + + if(person[i].skeleton.free!=1){ + + if(findDistancefast(person[i].playercoords,person[0].playercoords)<1000){ + + person[i].skeleton.free=1; + + person[i].longdead=1; + + for(int j=0;j<person[i].skeleton.num_joints;j++){ + + person[i].skeleton.joints[j].position=DoRotation(person[i].skeleton.joints[j].position,0,person[i].playerrotation,0); + + person[i].skeleton.joints[j].position+=person[i].playercoords; + + person[i].skeleton.joints[j].realoldposition=person[i].skeleton.joints[j].position; + + person[i].skeleton.joints[j].velocity=DoRotation(person[i].skeleton.joints[j].velocity,0,person[i].playerrotation,0); + + person[i].skeleton.joints[j].velocity+=person[i].velocity; + + person[i].skeleton.joints[j].velocity+=facing*50; + + person[i].skeleton.joints[j].velocity.x+=abs(Random()%20)-10; + + person[i].skeleton.joints[j].velocity.y+=abs(Random()%20)-10; + + person[i].skeleton.joints[j].velocity.z+=abs(Random()%20)-10; + + }}} + + }} + + break; + + case 'X': + + if(debug){ + + if(person[0].grenphase==0){ + + person[0].ammo=-1; + + person[0].whichgun++; + + person[0].grenphase=0; + + person[0].reloads[person[0].whichgun]=3; + + if(person[0].whichgun>7)person[0].whichgun=0; + + }} + + break; + + } + + } + +} + + + +/********************> DoEvent() <*****/ + +#ifdef OS9 +void Game::DoEvent( EventRecord *event ) + +{ + + + + char theChar; + + + + switch ( event->what ) + + { + + case keyDown: + + case autoKey: + + theChar = event->message & charCodeMask; // Get the letter of the key pressed from the event message + + HandleKeyDown( theChar ); // Only some key presses are handled here because it is slower and less responsive + + break; + + } + + + + + +} +#endif + +#ifndef OS9 +static int mapinit = 0; +static int sdlkeymap[SDLK_LAST]; + +static unsigned char ourkeys[16]; + +static void init_sdlkeymap() +{ + int i; + + for (i = 0; i < SDLK_LAST; i++) { + sdlkeymap[i] = -1; + } + + sdlkeymap[SDLK_1] = MAC_1_KEY; + sdlkeymap[SDLK_2] = MAC_2_KEY; + sdlkeymap[SDLK_3] = MAC_3_KEY; + sdlkeymap[SDLK_4] = MAC_4_KEY; + sdlkeymap[SDLK_5] = MAC_5_KEY; + sdlkeymap[SDLK_6] = MAC_6_KEY; + sdlkeymap[SDLK_7] = MAC_7_KEY; + sdlkeymap[SDLK_8] = MAC_8_KEY; + sdlkeymap[SDLK_9] = MAC_9_KEY; + sdlkeymap[SDLK_0] = MAC_0_KEY; + sdlkeymap[SDLK_KP1] = MAC_NUMPAD_1_KEY; + sdlkeymap[SDLK_KP2] = MAC_NUMPAD_2_KEY; + sdlkeymap[SDLK_KP3] = MAC_NUMPAD_3_KEY; + sdlkeymap[SDLK_KP4] = MAC_NUMPAD_4_KEY; + sdlkeymap[SDLK_KP5] = MAC_NUMPAD_5_KEY; + sdlkeymap[SDLK_KP6] = MAC_NUMPAD_6_KEY; + sdlkeymap[SDLK_KP7] = MAC_NUMPAD_7_KEY; + sdlkeymap[SDLK_KP8] = MAC_NUMPAD_8_KEY; + sdlkeymap[SDLK_KP9] = MAC_NUMPAD_9_KEY; + sdlkeymap[SDLK_KP0] = MAC_NUMPAD_0_KEY; + sdlkeymap[SDLK_a] = MAC_A_KEY; + sdlkeymap[SDLK_b] = MAC_B_KEY; + sdlkeymap[SDLK_c] = MAC_C_KEY; + sdlkeymap[SDLK_d] = MAC_D_KEY; + sdlkeymap[SDLK_e] = MAC_E_KEY; + sdlkeymap[SDLK_f] = MAC_F_KEY; + sdlkeymap[SDLK_g] = MAC_G_KEY; + sdlkeymap[SDLK_h] = MAC_H_KEY; + sdlkeymap[SDLK_i] = MAC_I_KEY; + sdlkeymap[SDLK_j] = MAC_J_KEY; + sdlkeymap[SDLK_k] = MAC_K_KEY; + sdlkeymap[SDLK_l] = MAC_L_KEY; + sdlkeymap[SDLK_m] = MAC_M_KEY; + sdlkeymap[SDLK_n] = MAC_N_KEY; + sdlkeymap[SDLK_o] = MAC_O_KEY; + sdlkeymap[SDLK_p] = MAC_P_KEY; + sdlkeymap[SDLK_q] = MAC_Q_KEY; + sdlkeymap[SDLK_r] = MAC_R_KEY; + sdlkeymap[SDLK_s] = MAC_S_KEY; + sdlkeymap[SDLK_t] = MAC_T_KEY; + sdlkeymap[SDLK_u] = MAC_U_KEY; + sdlkeymap[SDLK_v] = MAC_V_KEY; + sdlkeymap[SDLK_w] = MAC_W_KEY; + sdlkeymap[SDLK_x] = MAC_X_KEY; + sdlkeymap[SDLK_y] = MAC_Y_KEY; + sdlkeymap[SDLK_z] = MAC_Z_KEY; + sdlkeymap[SDLK_F1] = MAC_F1_KEY; + sdlkeymap[SDLK_F2] = MAC_F2_KEY; + sdlkeymap[SDLK_F3] = MAC_F3_KEY; + sdlkeymap[SDLK_F4] = MAC_F4_KEY; + sdlkeymap[SDLK_F5] = MAC_F5_KEY; + sdlkeymap[SDLK_F6] = MAC_F6_KEY; + sdlkeymap[SDLK_F7] = MAC_F7_KEY; + sdlkeymap[SDLK_F8] = MAC_F8_KEY; + sdlkeymap[SDLK_F9] = MAC_F9_KEY; + sdlkeymap[SDLK_F10] = MAC_F10_KEY; + sdlkeymap[SDLK_F11] = MAC_F11_KEY; + sdlkeymap[SDLK_F12] = MAC_F12_KEY; + sdlkeymap[SDLK_RETURN] = MAC_RETURN_KEY; + sdlkeymap[SDLK_KP_ENTER] = MAC_ENTER_KEY; + sdlkeymap[SDLK_TAB] = MAC_TAB_KEY; + sdlkeymap[SDLK_SPACE] = MAC_SPACE_KEY; + sdlkeymap[SDLK_BACKSPACE] = MAC_DELETE_KEY; + sdlkeymap[SDLK_ESCAPE] = MAC_ESCAPE_KEY; + sdlkeymap[SDLK_LCTRL] = MAC_CONTROL_KEY; + sdlkeymap[SDLK_RCTRL] = MAC_CONTROL_KEY; + sdlkeymap[SDLK_LSHIFT] = MAC_SHIFT_KEY; + sdlkeymap[SDLK_RSHIFT] = MAC_SHIFT_KEY; + sdlkeymap[SDLK_CAPSLOCK] = MAC_CAPS_LOCK_KEY; + sdlkeymap[SDLK_LALT] = MAC_OPTION_KEY; + sdlkeymap[SDLK_RALT] = MAC_OPTION_KEY; + sdlkeymap[SDLK_PAGEUP] = MAC_PAGE_UP_KEY; + sdlkeymap[SDLK_PAGEDOWN] = MAC_PAGE_DOWN_KEY; + sdlkeymap[SDLK_INSERT] = MAC_INSERT_KEY; + sdlkeymap[SDLK_DELETE] = MAC_DEL_KEY; + sdlkeymap[SDLK_HOME] = MAC_HOME_KEY; + sdlkeymap[SDLK_END] = MAC_END_KEY; + sdlkeymap[SDLK_LEFTBRACKET] = MAC_LEFT_BRACKET_KEY; + sdlkeymap[SDLK_RIGHTBRACKET] = MAC_RIGHT_BRACKET_KEY; + sdlkeymap[SDLK_UP] = MAC_ARROW_UP_KEY; + sdlkeymap[SDLK_DOWN] = MAC_ARROW_DOWN_KEY; + sdlkeymap[SDLK_LEFT] = MAC_ARROW_LEFT_KEY; + sdlkeymap[SDLK_RIGHT] = MAC_ARROW_RIGHT_KEY; + + mapinit = 1; +} + +void GetKeys(unsigned long *keys) +{ + /* this is just weird */ + memcpy(keys, ourkeys, sizeof(ourkeys)); +} + +static void DoSDLKey(Game *g, SDL_Event *event) +{ + int press = (event->type == SDL_KEYDOWN) ? 1 : 0; + int mackey; + int index; + int mask; + + + if (mapinit == 0) { + init_sdlkeymap(); + } + + mackey = sdlkeymap[event->key.keysym.sym]; + + if (mackey != -1) { + index = mackey / 8; + mask = 1 << (mackey % 8); + + if (press) { + ourkeys[index] |= mask; + } else { + ourkeys[index] &= ~mask; + } + } + + if (event->key.keysym.unicode && + !(event->key.keysym.unicode & 0xFF80)) { + + /* hey, at least it was aleady public */ + g->HandleKeyDown(event->key.keysym.unicode); + } + + +} + +static void ProcessSDLEvents(Game *g) +{ + SDL_Event event; + + if (SDL_PollEvent(&event)) { + do { + switch(event.type) { + case SDL_KEYDOWN: + if (event.key.keysym.sym == SDLK_RETURN && + event.key.keysym.mod & KMOD_ALT) + { + SDL_WM_ToggleFullScreen (SDL_GetVideoSurface ()); + break; + } + if (event.key.keysym.sym == SDLK_g && + event.key.keysym.mod & KMOD_CTRL) + { + if (SDL_WM_GrabInput (SDL_GRAB_QUERY) == SDL_GRAB_OFF) + { + SDL_WM_GrabInput (SDL_GRAB_ON); + SDL_ShowCursor (SDL_DISABLE); + } + else + { + SDL_WM_GrabInput (SDL_GRAB_OFF); + SDL_ShowCursor (SDL_ENABLE); + } + break; + } + case SDL_KEYUP: + DoSDLKey(g, &event); + break; + case SDL_QUIT: + exit(0); + } + } while (SDL_PollEvent(&event)); + } +} + +#endif + +/********************> EventLoop() <*****/ + +void Game::EventLoop( void ) + +{ + +#ifdef OS9 + EventRecord event; +#endif + + unsigned char theKeyMap[16]; + + int colaccuracy,i; + + GLfloat oldmult; + + gQuit = false; + + while ( gQuit == false ) + + { + +#ifdef OS9 + if ( GetNextEvent( everyEvent, &event ) ) + + DoEvent( &event ); +#else + ProcessSDLEvents(this); +#endif + + + start=TimerGetTime(&theTimer); + + + + colaccuracy=sps/framespersecond+1; + + if(colaccuracy>sps){colaccuracy=sps;} + + + + oldmult=multiplier; + + multiplier/=colaccuracy; + + for(i=0;i<(int)(colaccuracy+.5);i++){ + + Tick(); + + } + + multiplier=oldmult; + + + + if ( DrawGLScene()) + +#ifdef OS9 + aglSwapBuffers( gOpenGLContext ); +#else + SDL_GL_SwapBuffers(); +#endif + + else + + gQuit = true; + + oldmult=multiplier; + + + + end=TimerGetTime(&theTimer); + + timetaken=end-start; + + framespersecond=600000000/timetaken; + + while(framespersecond>maxfps){ + + end=TimerGetTime(&theTimer); + + timetaken=end-start; + + framespersecond=600000000/timetaken; + + } + + multiplier5=multiplier4; + + multiplier4=multiplier3; + + multiplier3=multiplier2; + + multiplier2=1/framespersecond; + + multiplier=(multiplier2+multiplier3+multiplier4+multiplier5)/4; + + if(multiplier>1)multiplier=1; + + if(multiplier<.00001)multiplier=.00001; + + if(visions==1&&mainmenu==0)multiplier/=3; + + if(slomo)multiplier*=.2; + + if(paused)multiplier=0; + + GetKeys( ( unsigned long * )theKeyMap ); + + if ( IsKeyDown( theKeyMap, MAC_COMMAND_KEY )&&IsKeyDown( theKeyMap, MAC_Q_KEY )){ + + gQuit = true; + + if(score>highscore){ + + highscore=score; + +#ifdef OS9 + ofstream opstream(":Data:Highscore"); +#else + /* TODO */ + ofstream opstream("Data/Highscore"); +#endif + + opstream << highscore; + + opstream << "\n"; + + opstream << beatgame; + + opstream.close(); + + } + + } + + if ( IsKeyDown( theKeyMap, MAC_ESCAPE_KEY )){ + + alSourcePause(gSourceID[rainsound]); + + + + mainmenu=1; + + alSourcePlay(gSourceID[souloutsound]); + + flashamount=1; + + flashr=1;flashg=1;flashb=1; + + alSourceStop(gSourceID[visionsound]); + + whichsong=mainmenusong; + + alSourceStop(gSourceID[knifesong]); + + alSourceStop(gSourceID[shootsong]); + + alSourceStop(gSourceID[zombiesong]); + + alSourceStop(gSourceID[mainmenusong]); + + alSourcef(gSourceID[knifesong], AL_MIN_GAIN, 0); + + alSourcef(gSourceID[shootsong], AL_MIN_GAIN, 0); + + alSourcef(gSourceID[zombiesong], AL_MIN_GAIN, 0); + + alSourcef(gSourceID[mainmenusong], AL_MIN_GAIN, 0); + + alSourcePlay(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1); + + } + + } + +} diff --git a/src/GameTick.cpp b/src/GameTick.cpp new file mode 100644 index 0000000..ce597df --- /dev/null +++ b/src/GameTick.cpp @@ -0,0 +1,4957 @@ +#include "Game.h" + + + +extern double multiplier; + +extern int thirdperson; + +extern int visions; + +extern Sprites sprites; + + + +extern unsigned int gSourceID[100]; + +extern unsigned int gSampleSet[100]; + +extern Camera camera; + +extern float camerashake; + +extern Fog fog; + +extern int environment; + +extern float precipitationhorz; + +extern float precipitationvert; + +extern float snowdelay; + +extern float precipitationdensity; + +extern float soundscalefactor; + +extern int slomo; + + + +extern int forwardskey; + +extern int backwardskey; + +extern int leftkey; + +extern int rightkey; + +extern int aimkey; + +extern int psychicaimkey; + +extern int psychickey; + + + +extern Decals decals; + +/********************> Tick() <*****/ + +#define maxfallvel 40 + + + +void Game::Splat(int k){ + + if(k!=0||visions==0){ + + person[k].health=0; + + person[k].DoAnimations(k); + + person[k].skeleton.offset=0; + + person[k].skeleton.free=1; + + person[k].longdead=1; + + + + person[k].bleeding=1; + + person[k].bleeddelay=1; + + person[k].bjoint1=&person[k].skeleton.joints[person[k].skeleton.jointlabels[head]]; + + person[k].bjoint2=&person[k].skeleton.joints[person[k].skeleton.jointlabels[neck]]; + + + + for(int j=0;j<person[k].skeleton.num_joints;j++){ + + person[k].skeleton.joints[j].position+=person[k].skeleton.joints[j].offset; + + person[k].skeleton.joints[j].position=DoRotation(person[k].skeleton.joints[j].position,0,person[k].playerrotation,0); + + person[k].skeleton.joints[j].position+=person[k].playercoords; + + person[k].skeleton.joints[j].realoldposition=person[k].skeleton.joints[j].position; + + person[k].skeleton.joints[j].velocity=0; + + person[k].skeleton.joints[j].velocity.y+=person[k].velocity.y; + + } + + + + float gLoc[3]; + + gLoc[0]=person[k].skeleton.joints[person[k].skeleton.jointlabels[head]].position.x/soundscalefactor; + + gLoc[1]=person[k].skeleton.joints[person[k].skeleton.jointlabels[head]].position.y/soundscalefactor; + + gLoc[2]=person[k].skeleton.joints[person[k].skeleton.jointlabels[head]].position.z/soundscalefactor; + + alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[headwhacksound]); + + } + +} + + + +void Game::Tick(){ + + if(mainmenu){ + + + + unsigned char theKeyMap[16]; + + GetKeys( ( unsigned long * )theKeyMap ); + + + + if(IsKeyDown(theKeyMap, MAC_SPACE_KEY)){ + + mainmenu=0; + + } + + + + GetMouse(&mouseloc); + + float mousex=mouseloc.h; + + float mousey=mouseloc.v; + + mousex=(float)mouseloc.h*640/screenwidth; + + mousey=480-(float)mouseloc.v*480/screenheight; + + + oldmouseoverbutton=mouseoverbutton; + + mouseoverbutton=0; + + if(mousex>120&&mousex<560&&mousey>235&&mousey<305){ + + mouseoverbutton=1; + + } + + if(mousex>120&&mousex<560&&mousey>112&&mousey<182){ + + mouseoverbutton=2; + + } + + if((Button()&&mouseoverbutton==1&&!gameinprogress&&!oldbutton)||!mainmenuness){ + + if(environment==rainy_environment)alSourcePlay(gSourceID[rainsound]); + + if(environment!=rainy_environment)alSourcePause(gSourceID[rainsound]); + + alSourceStop(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0); + + alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0); + + if(person[0].whichgun==knife)whichsong=knifesong; + + if(person[0].whichgun!=knife)whichsong=shootsong; + + if(type==zombie_type)whichsong=zombiesong; + + alSourcef(gSourceID[whichsong], AL_PITCH, 1); + + alSourcePlay(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1); + + alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1); + + flashamount=1; + + flashr=1;flashg=1;flashb=1; + + mainmenu=0; + + alSourcePlay(gSourceID[soulinsound]); + + mission=0; + + InitGame(); + + gameinprogress=1; + + } + + if((Button()&&mouseoverbutton==1&&gameinprogress&&!oldbutton)||!mainmenuness){ + + flashamount=1; + + flashr=1;flashg=1;flashb=1; + + mainmenu=0; + + MoveMouse(oldmouseloc.h,oldmouseloc.v,&mouseloc); + + //if(!visions){ + + if(environment==rainy_environment)alSourcePlay(gSourceID[rainsound]); + + if(environment!=rainy_environment)alSourcePause(gSourceID[rainsound]); + + alSourceStop(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0); + + alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0); + + if(person[0].whichgun==knife)whichsong=knifesong; + + if(person[0].whichgun!=knife)whichsong=shootsong; + + if(type==zombie_type)whichsong=zombiesong; + + alSourcePlay(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1); + + alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1); + + //} + + alSourcePlay(gSourceID[soulinsound]); + + if(visions)alSourcePlay(gSourceID[visionsound]); + + } + + if(Button()&&mouseoverbutton==2&&!gameinprogress&&!oldbutton){ + + flashamount=1; + + flashr=1;flashg=0;flashb=0; + + alSourcePlay(gSourceID[losesound]); + + gQuit = true; + + if(score>highscore){ + + highscore=score; + +#ifdef OS9 + ofstream opstream(":Data:Highscore"); +#else + /* TODO */ + ofstream opstream("Data/Highscore"); +#endif + opstream << highscore; + + opstream << "\n"; + + opstream << beatgame; + + opstream.close(); + + } + + } + + if(Button()&&mouseoverbutton==2&&gameinprogress&&!oldbutton){ + + flashamount=1; + + flashr=1;flashg=1;flashb=1; + + alSourcePlay(gSourceID[losesound]); + + gameinprogress=0; + + if(score>highscore){ + + highscore=score; + +#ifdef OS9 + ofstream opstream(":Data:Highscore"); +#else + /* TODO */ + ofstream opstream("Data/Highscore"); +#endif + opstream << highscore; + + opstream << "\n"; + + opstream << beatgame; + + opstream.close(); + + } + + } + + + + if(Button())oldbutton=1; + + if(!Button())oldbutton=0; + + } + + if(!mainmenu){ + + + + + + XYZ facing; + + XYZ flatfacing; + + float speed=10; + + + + if(person[1].health<=0||person[0].health<=0||killedinnocent){ + + losedelay-=multiplier/6; + + } + + + + if(person[1].health>0&&person[0].health>0&&!killedinnocent)timeremaining-=multiplier*25/40; + + if(timeremaining<=0){ + + flashamount=1; + + flashr=0;flashg=1;flashb=0; + + mission++; + + alSourcePlay(gSourceID[souloutsound]); + + score+=100+(mission*50); + + if(mission>=nummissions){ + + beatgame=1; + + mainmenu=1; + + gameinprogress=0; + + alSourcePause(gSourceID[rainsound]); + + + + alSourceStop(gSourceID[visionsound]); + + alSourceStop(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0); + + alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0); + + whichsong=mainmenusong; + + alSourceStop(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_PITCH, 1); + + alSourcePlay(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1); + + alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1); + + if(score>highscore){ + + highscore=score; + +#ifdef OS9 + ofstream opstream(":Data:Highscore"); +#else + /* TODO */ + ofstream opstream("Data/Highscore"); +#endif + opstream << highscore; + + opstream << "\n"; + + opstream << beatgame; + + opstream.close(); + + } + + } + + if(!mainmenu){ + + InitGame(); + + if(environment==rainy_environment)alSourcePlay(gSourceID[rainsound]); + + if(environment!=rainy_environment)alSourcePause(gSourceID[rainsound]); + + alSourceStop(gSourceID[visionsound]); + + alSourceStop(gSourceID[whichsong]); + + if(person[0].whichgun==knife)whichsong=knifesong; + + if(person[0].whichgun!=knife)whichsong=shootsong; + + if(type==zombie_type)whichsong=zombiesong; + + alSourcef(gSourceID[whichsong], AL_PITCH, 1); + + alSourcePlay(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1); + + alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1); + + } + + } + + if(losedelay<=0){ + + flashamount=1; + + flashr=0;flashg=0;flashb=0; + + if(person[murderer].health>0)score=oldscore-200; + + if(person[murderer].health<=0)score=oldscore-100; + + InitGame(); + + alSourceStop(gSourceID[whichsong]); + + if(person[0].whichgun==knife)whichsong=knifesong; + + if(person[0].whichgun!=knife)whichsong=shootsong; + + if(type==zombie_type)whichsong=zombiesong; + + alSourcef(gSourceID[whichsong], AL_PITCH, 1); + + alSourcePlay(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1); + + alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1); + + alSourcePlay(gSourceID[soulinsound]); + + } + + + + unsigned char theKeyMap[16]; + + GetKeys( ( unsigned long * )theKeyMap ); + + + + //Sprites + + sprites.DoStuff(); + + + + //Decals + + decals.DoStuff(); + + + + //Facing + + facing=0; + + facing.z=-1; + + + + facing=DoRotation(facing,-camera.rotation2,0,0); + + facing=DoRotation(facing,0,0-camera.rotation,0); + + + + flatfacing=facing; + + flatfacing.y=0; + + Normalise(&flatfacing); + + + + if(IsKeyDown(theKeyMap, psychickey)&&!oldvisionkey){ + + oldvisionkey=1; + + visions++; + + if(visions==2)visions=0; + + if(visions==0){ + + float rad2deg=56.54866776; + + flashamount=1; + + flashr=1;flashg=1;flashb=1; + + + + if(person[0].playercoords.x!=bodycoords.x||person[0].playercoords.z!=bodycoords.z){ + + XYZ towards; + + towards=person[0].playercoords-bodycoords; + + Normalise(&towards); + + camera.rotation=-asin(0-towards.x); + + camera.rotation*=360/6.28; + + if(towards.z>0)camera.rotation=180-camera.rotation; + + camera.visrotation=camera.rotation; + + camera.oldrotation=camera.rotation; + + camera.oldoldrotation=camera.rotation; + + } + + + + person[0].playercoords=bodycoords; + + person[0].oldplayercoords=bodycoords; + + person[0].velocity=0; + + alSourcePlay(gSourceID[soulinsound]); + + alSourceStop(gSourceID[visionsound]); + + alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat)(1)); + + alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat)(1)); + + alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat)(1)); + + } + + if(visions==1){ + + alSourceStop(gSourceID[visionsound]); + + flashamount=1; + + flashr=1;flashg=0;flashb=0; + + bodycoords=person[0].oldplayercoords; + + alSourcePlay(gSourceID[souloutsound]); + + alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat)(.5)); + + alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat)(.5)); + + alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat)(.5)); + + alSourcePlay(gSourceID[visionsound]); + + } + + } + + if(!IsKeyDown(theKeyMap, psychickey)){ + + oldvisionkey=0; + + } + + + + if(IsKeyDown(theKeyMap, MAC_TAB_KEY)&&!tabkeydown&&debug){ + + thirdperson++; + + if(thirdperson>2)thirdperson=0; + + tabkeydown=1; + + } + + + + if(!IsKeyDown(theKeyMap, MAC_TAB_KEY)) + + tabkeydown=0; + + + + if(IsKeyDown(theKeyMap, aimkey)&&!aimtoggle){ + + person[0].aiming=1-person[0].aiming; + + aimtoggle=1; + + } + + + + if(!IsKeyDown(theKeyMap, aimkey)) + + aimtoggle=0; + + + + if(IsKeyDown(theKeyMap, MAC_R_KEY)&&!reloadtoggle){ + + if(person[0].reloads[person[0].whichgun]>0&&person[0].reloading<=0)person[0].ammo=-1; + + reloadtoggle=1; + + } + + + + if(!IsKeyDown(theKeyMap, MAC_R_KEY)) + + reloadtoggle=0; + + + + if(IsKeyDown(theKeyMap, psychicaimkey)&&!slomokeydown&&slomo==0){ + + alSourcePlay(gSourceID[souloutsound]); + + slomo=2; + + flashamount=.5; + + flashr=1;flashg=0;flashb=0; + + slomokeydown=1; + + score-=20; + + alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat)(.5)); + + alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat)(.5)); + + alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat)(.5)); + + } + + + + if(!IsKeyDown(theKeyMap, psychicaimkey)) + + slomokeydown=0; + + + + //Mouse look + + + + if((person[0].aimamount<=0&&person[0].targetanimation!=crouchanim)){ + + camera.rotation=camera.visrotation; + + camera.rotation2=camera.visrotation2; + + mousesensitivity=usermousesensitivity; + + } + + if(person[0].aimamount>=1&&zoom==0){ + + mousesensitivity=usermousesensitivity*.8; + + } + + if(slomo==2){ + + mousesensitivity*=.6; + + } + +#if 0 // DDOI + GetMouse(&mouseloc); + + if (mouseloc.h>600){MoveMouse(mouseloc.h-500,mouseloc.v,&mouseloc);} + + if (mouseloc.h<100){MoveMouse(mouseloc.h+500,mouseloc.v,&mouseloc);} + + GetMouse(&mouseloc); + + if (mouseloc.v>400){MoveMouse(mouseloc.h,mouseloc.v-300,&mouseloc);} + + if (mouseloc.v<100){MoveMouse(mouseloc.h,mouseloc.v+300,&mouseloc);} + + GetMouse(&mouseloc); + +#else + GetMouseRel(&mouseloc); +#endif + + + +#if 0 // DDOI + oldmouserotation=(oldmouseloc.h/1.3888)*mousesensitivity; + + oldmouserotation2=(oldmouseloc.v/1.3888)*mousesensitivity; +#endif + + mouserotation=(mouseloc.h/1.3888)*mousesensitivity; + + mouserotation2=(mouseloc.v/1.3888)*mousesensitivity; + + + +#if 0 // DDOI + if(abs(oldmouseloc.h-mouseloc.h)<400)camera.rotation+=mouserotation-oldmouserotation; + + if(abs(oldmouseloc.v-mouseloc.v)<200)camera.rotation2+=mouserotation2-oldmouserotation2; + + if(mouseloc.h-oldmouseloc.h>400)camera.rotation+=mouserotation-oldmouserotation-(500/1.3888*mousesensitivity); + + if(mouseloc.h-oldmouseloc.h<-400)camera.rotation+=mouserotation-oldmouserotation+(500/1.3888*mousesensitivity); + + if(mouseloc.v-oldmouseloc.v>200)camera.rotation2+=mouserotation2-oldmouserotation2-(300/1.3888*mousesensitivity); + + if(mouseloc.v-oldmouseloc.v<-200)camera.rotation2+=mouserotation2-oldmouserotation2+(300/1.3888*mousesensitivity); +#else + if(abs(mouseloc.h)<400)camera.rotation+=mouserotation; + if(abs(mouseloc.v)<200)camera.rotation2+=mouserotation2; + if(mouseloc.h>400)camera.rotation+=mouserotation-(500/1.3888*mousesensitivity); + if(mouseloc.h<-400)camera.rotation+=mouserotation+(500/1.3888*mousesensitivity); + + if(mouseloc.v>200)camera.rotation2+=mouserotation2-(300/1.3888*mousesensitivity); + + if(mouseloc.v<-200)camera.rotation2+=mouserotation2+(300/1.3888*mousesensitivity); +#endif + + + + if(camera.rotation2>89){camera.rotation2=89;} + + if(camera.rotation2<-89){camera.rotation2=-89;} + + + + //Smooth + + camera.rotation=(camera.oldoldrotation+((camera.rotation-camera.oldoldrotation)*.7+(camera.oldrotation-camera.oldoldrotation)*.3)); + + camera.rotation2=(camera.oldoldrotation2+((camera.rotation2-camera.oldoldrotation2)*.7+(camera.oldrotation2-camera.oldoldrotation2)*.3)); + + + + if(camera.visrotation<camera.rotation-7)camera.visrotation=camera.rotation-7; + + if(camera.visrotation>camera.rotation+7)camera.visrotation=camera.rotation+7; + + if(camera.visrotation2<camera.rotation2-15)camera.visrotation2=camera.rotation2-15; + + if(camera.visrotation2>camera.rotation2+15)camera.visrotation2=camera.rotation2+15; + + + + if(zoom||person[0].aimamount<=0||person[0].whichgun==nogun||visions||person[0].whichgun==grenade||person[0].whichgun==knife){ + + camera.visrotation=camera.rotation; + + camera.visrotation2=camera.rotation2; + + } + + oldzoom=zoom; + + + + camera.oldoldrotation=camera.oldrotation; + + camera.oldoldrotation2=camera.oldrotation2; + + camera.oldrotation=camera.rotation; + + camera.oldrotation2=camera.rotation2; + + + + //Check collision with buildings + + + + int beginx,endx; + + int beginz,endz; + + int distsquared; + + XYZ collpoint; + + XYZ move; + + float howmuchintersect; + + int whichtri; + + float olddist; + + XYZ nothing; + + XYZ underpoint; + + XYZ overpoint; + + int pointnum; + + float depth; + + XYZ normalrotated; + + XYZ pointrotated; + + bool inblock; + + + + + + person[0].playerrotation=180-camera.rotation; + + + + //Check people collisions + + for(int k=0;k<numpeople;k++){ + // SBF - backing up the old coordinates makes + // the most sense here. + person[k].oldplayercoords=person[k].playercoords; + + person[k].DoStuff(k); + + if(person[k].skeleton.free<1){ + + if(1==1){ + + person[k].onground=0; + + overpoint=person[k].playercoords; + + overpoint.y+=3000; + + underpoint=person[k].playercoords; + + underpoint.y-=3000; + + + + beginx=(person[k].playercoords.x+block_spacing/2)/block_spacing; + + if(beginx<0)beginx=0; + + beginz=(person[k].playercoords.z+block_spacing/2)/block_spacing; + + if(beginz<0)beginz=0; + + + + endx=(person[k].playercoords.x+block_spacing/2)/block_spacing+1; + + if(endx>num_blocks-1)endx=num_blocks-1; + + endz=(person[k].playercoords.z+block_spacing/2)/block_spacing+1; + + if(endz>num_blocks-1)endz=num_blocks-1; + + + + if(k!=0){ + /* TODO: huh? */ + beginx==person[k].whichblockx; + + beginz==person[k].whichblocky; + + endx==person[k].whichblockx; + + endz==person[k].whichblocky; + + } + + + + if(beginx<=endx&&beginz<=endz) + + for(int i=beginx;i<=endx;i++) + + for(int j=beginz;j<=endz;j++){ + + inblock=0; + + //Ground collision + + move=0; + + move.x=i*block_spacing; + + move.z=j*block_spacing; + + whichtri=sidewalkcollide.LineCheck2(overpoint,underpoint,&collpoint,move,cityrotation[i][j]*90); + + if(whichtri!=-1&&person[k].playercoords.y<=collpoint.y&&person[k].velocity.y<=0){ + + person[k].playercoords.y=collpoint.y; + + person[k].onground=1; + + if(person[k].velocity.y<-maxfallvel)Splat(k); + + else person[k].velocity.y=0; + + } + + if(whichtri!=-1){ + + inblock=1; + + if(k==0){onblockx=i;onblocky=j;} + + } + + //Wall collision + + if(k==0){ + + if(inblock){ + + for(int l=0;l<8;l++){ + + move=0; + + move.x=i*block_spacing; + + move.z=j*block_spacing; + + whichtri=blockwalls[citytype[i][j]].LineCheck3(person[k].oldplayercoords+boundingpoints[l],person[k].playercoords+boundingpoints[l],&collpoint,move,cityrotation[i][j]*90,&depth); + + if(whichtri!=-1){ + + normalrotated=DoRotation(blockwalls[citytype[i][j]].normals[whichtri],0,cityrotation[i][j]*90,0); + + person[k].playercoords+=normalrotated*(-(dotproduct(normalrotated,person[k].playercoords-person[k].oldplayercoords))-depth); + + } + + } + + for(int l=0;l<8;l++){ + + pointnum=k+1; + + if(pointnum>3)pointnum=0; + + move=0; + + move.x=i*block_spacing; + + move.z=j*block_spacing; + + whichtri=blockwalls[citytype[i][j]].LineCheck3(person[k].playercoords+boundingpoints[l],person[k].playercoords+boundingpoints[pointnum],&collpoint,move,cityrotation[i][j]*90,&depth); + + if(whichtri!=-1){ + + normalrotated=DoRotation(blockwalls[citytype[i][j]].normals[whichtri],0,cityrotation[i][j]*90,0); + + person[k].playercoords+=normalrotated; + + } + + } + + } + + //Roof collision + + if(inblock&&person[k].playercoords.y>30){ + + if(!person[k].onground){ + + move=0; + + move.x=i*block_spacing; + + move.z=j*block_spacing; + + whichtri=blockroofs[citytype[i][j]].LineCheck2(overpoint,underpoint,&collpoint,move,cityrotation[i][j]*90); + + if(whichtri!=-1&&person[k].playercoords.y<=collpoint.y&&person[k].velocity.y<=0){ + + person[k].playercoords.y=collpoint.y; + + person[k].onground=1; + + if(person[k].velocity.y<-maxfallvel)Splat(k); + + else person[k].velocity.y=0; + + } + + if(whichtri!=-1)inblock=1; + + } + + } + + } + + } + + if(person[k].playercoords.y<=0){ + + person[k].onground=1; + + person[k].playercoords.y=0; + + if(person[k].velocity.y<-maxfallvel)Splat(k); + + else person[k].velocity.y=0; + + if(k==0)onblockx=-1;onblocky=-1; + + } + + // SBF - this is definately in the wrong spot! + //person[k].oldplayercoords=person[k].playercoords; + + } + + } + + } + + + + if(IsKeyDown( theKeyMap, MAC_SPACE_KEY )){ + + if(visions==0&&person[0].targetanimation==joganim&&person[0].currentanimation==joganim&&person[0].backwardsanim==0&&person[0].playerrotation==person[0].playerlowrotation){ + + person[0].targetanimation=diveanim; + + person[0].targetframe=0; + + person[0].target=0; + + person[0].aimamount=0; + + } + + } + + + + //Camera + + camera.oldposition=camera.position; + + camera.targetoffset=0; + + camera.targetoffset.z=-5; + + + + + + //Spawn people + + spawndelay-=multiplier; + + int blockspawnx,blockspawny; + + blockspawnx=0; + + blockspawny=0; + + int cyclenum; + + cyclenum=0; + + while((citypeoplenum[blockspawnx][blockspawny]>=max_people_block&&cyclenum<10)||blockspawnx==0){ + + blockspawnx=((person[0].playercoords.x+block_spacing/2)/block_spacing)+Random()%2; + + blockspawny=((person[0].playercoords.z+block_spacing/2)/block_spacing)+Random()%2; + + cyclenum++; + + } + + if(cyclenum<10){ + + if(spawndelay<0&&numpeople<max_people){ + + if(type==randomshoot_type){ + + if(abs(Random()%evilprobability)==0)person[numpeople].type=eviltype; + + else person[numpeople].type=civiliantype; + + } + + if(type==zombie_type){ + + person[numpeople].type=zombietype; + + } + + + + if(person[numpeople].type!=civiliantype&&blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky){ + + while((citypeoplenum[blockspawnx][blockspawny]>=max_people_block&&cyclenum<10)||blockspawnx==0||(blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky)){ + + blockspawnx=((person[0].playercoords.x+block_spacing/2)/block_spacing)+Random()%2; + + blockspawny=((person[0].playercoords.z+block_spacing/2)/block_spacing)+Random()%2; + + cyclenum++; + + } + + } + + + + person[numpeople].playerrotation=0; + + + + person[numpeople].whichcostume=casualcostumes+abs(Random())%numcasual; + + + + person[numpeople].whichblockx=blockspawnx; + + person[numpeople].whichblocky=blockspawny; + + + + person[numpeople].pathnum=-1; + + person[numpeople].oldpathnum=-1; + + person[numpeople].oldoldpathnum=-1; + + person[numpeople].oldoldoldpathnum=-1; + + while(person[numpeople].pathnum<0||person[numpeople].pathnum>=path.vertexNum||person[numpeople].pathnum==1){ + + person[numpeople].pathnum=Random()%path.vertexNum; + + } + + person[numpeople].pathtarget.x=path.vertex[person[numpeople].pathnum].x; + + person[numpeople].pathtarget.z=path.vertex[person[numpeople].pathnum].z; + + person[numpeople].pathsize=.98+float(abs(Random()%20))/400; + + person[numpeople].pathtarget*=person[numpeople].pathsize; + + person[numpeople].pathtarget.x+=person[numpeople].whichblockx*block_spacing; + + person[numpeople].pathtarget.z+=person[numpeople].whichblocky*block_spacing; + + + + + + person[numpeople].playercoords=person[numpeople].pathtarget; + + person[numpeople].oldplayercoords=person[numpeople].playercoords; + + person[numpeople].skeleton.free=0; + + + + person[numpeople].targetanimation=walkanim; + + if(person[numpeople].type==zombietype)person[numpeople].targetanimation=zombiewalkanim; + + person[numpeople].speed=1; + + person[numpeople].existing=0; + + person[numpeople].speedmult=.8+float(abs(Random()%20))/50; + + person[numpeople].health=100; + + person[numpeople].maxhealth=100; + + person[numpeople].playerrotation2=0; + + + + person[numpeople].lastdistancevictim=200000; + + + + if(person[numpeople].skeleton.broken)person[numpeople].skeleton.Load((char *)":Data:Skeleton:Basic Figure"); + + + + if(numpeople==1)person[numpeople].type=viptype; + + + + person[numpeople].killtarget=-1; + + + + if(person[numpeople].type==eviltype){person[numpeople].existing=1; person[numpeople].pathsize=1.04; person[numpeople].whichgun=nogun; person[numpeople].aiming=1; person[numpeople].killtarget=-1; person[numpeople].speedmult=1+.3*difficulty;} + + if(person[numpeople].type==zombietype){person[numpeople].existing=1; person[numpeople].pathsize=1.04; person[numpeople].whichgun=nogun; person[numpeople].aiming=0; person[numpeople].killtarget=-1; person[numpeople].speedmult=0.7+.2*difficulty;} + + else {person[numpeople].whichgun=nogun; person[numpeople].aiming=0; person[numpeople].killtarget=-1;} + + + + if(person[numpeople].type==viptype){person[numpeople].existing=1;} + + + + + + if(enemystate==2)person[numpeople].killtarget=1; + + + + numpeople++; + + citypeoplenum[blockspawnx][blockspawny]++; + + spawndelay=.1; + + } + + if(spawndelay<0&&numpeople>=max_people){ + + if(cycle>=max_people)cycle=0; + + cyclenum=0; + + while(cyclenum<max_people&&(person[cycle].type==playertype||person[cycle].type==viptype||(abs(person[cycle].whichblockx-((person[0].playercoords.x+block_spacing/2)/block_spacing))<2&&abs(person[cycle].whichblocky-((person[0].playercoords.z+block_spacing/2)/block_spacing))<2))){ + + cycle++; + + cyclenum++; + + if(cycle>=max_people)cycle=0; + + } + + if(cycle<max_people&&cyclenum<max_people){ + + if(type==randomshoot_type){ + + if(abs(Random()%evilprobability)==0)person[cycle].type=eviltype; + + else person[cycle].type=civiliantype; + + } + + if(type==zombie_type){ + + person[cycle].type=zombietype; + + } + + if(person[cycle].type!=civiliantype&&blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky){ + + while((citypeoplenum[blockspawnx][blockspawny]>=max_people_block&&cyclenum<10)||blockspawnx==0||(blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky)){ + + blockspawnx=((person[0].playercoords.x+block_spacing/2)/block_spacing)+Random()%2; + + blockspawny=((person[0].playercoords.z+block_spacing/2)/block_spacing)+Random()%2; + + cyclenum++; + + } + + } + + person[cycle].playerrotation=0; + + + + person[cycle].whichcostume=casualcostumes+abs(Random())%numcasual; + + + + citypeoplenum[person[cycle].whichblockx][person[cycle].whichblocky]--; + + person[cycle].whichblockx=blockspawnx; + + person[cycle].whichblocky=blockspawny; + + + + person[cycle].pathnum=-1; + + person[cycle].oldpathnum=-1; + + person[cycle].oldoldpathnum=-1; + + person[cycle].oldoldoldpathnum=-1; + + while(person[cycle].pathnum<0||person[cycle].pathnum>=path.vertexNum||person[cycle].pathnum==1){ + + person[cycle].pathnum=Random()%path.vertexNum; + + } + + person[cycle].pathtarget.x=path.vertex[person[cycle].pathnum].x; + + person[cycle].pathtarget.z=path.vertex[person[cycle].pathnum].z; + + person[cycle].pathsize=.98+float(abs(Random()%20))/400; + + person[cycle].pathtarget*=person[cycle].pathsize; + + person[cycle].pathtarget.x+=person[cycle].whichblockx*block_spacing; + + person[cycle].pathtarget.z+=person[cycle].whichblocky*block_spacing; + + + + person[cycle].playercoords=person[cycle].pathtarget; + + person[cycle].oldplayercoords=person[cycle].playercoords; + + person[cycle].skeleton.free=0; + + + + person[cycle].targetanimation=walkanim; + + if(person[cycle].type==zombietype)person[cycle].targetanimation=zombiewalkanim; + + person[cycle].speed=1; + + person[cycle].existing=0; + + person[cycle].speedmult=.8+float(abs(Random()%20))/50; + + person[cycle].health=100; + + person[cycle].maxhealth=100; + + person[cycle].playerrotation2=0; + + + + if(person[cycle].skeleton.broken)person[cycle].skeleton.Load((char *)":Data:Skeleton:Basic Figure"); + + + + if(enemystate==1)person[cycle].killtarget=-1; + + + + if(person[cycle].type==eviltype){person[cycle].existing=1; person[cycle].pathsize=1.04; person[cycle].whichgun=nogun; person[cycle].aiming=1; person[cycle].killtarget=-1; person[cycle].speedmult=1+.3*difficulty;} + + if(person[cycle].type==zombietype){person[cycle].existing=1; person[cycle].pathsize=1.04; person[cycle].whichgun=nogun; person[cycle].aiming=0; person[cycle].killtarget=-1; person[cycle].speedmult=.7+.2*difficulty;} + + else {person[cycle].whichgun=nogun; person[cycle].aiming=0; person[cycle].killtarget=-1;} + + + + person[cycle].lastdistancevictim=200000; + + + + if(enemystate==2)person[cycle].killtarget=1; + + + + if(numpeople<max_people)numpeople++; + + citypeoplenum[blockspawnx][blockspawny]++; + + cycle++; + + + + spawndelay=.1; + + } + + }} + + + + XYZ towards; + + XYZ finaltarget; + + XYZ blah; + + int closesttarget = 0; + + float leastdistance = 0.0; + + + + + + XYZ bleedloc; + + XYZ vel; + + + + float tooclose; + + float toofar; + + + + //People + + for(int i=0;i<numpeople;i++){ + + if(person[i].health<0&&person[i].longdead<0&&person[i].firstlongdead==0){ + + if(person[i].type!=zombietype){ + + overpoint=person[i].skeleton.joints[person[i].skeleton.jointlabels[abdomen]].position; + + overpoint.y+=3000; + + underpoint=person[i].skeleton.joints[person[i].skeleton.jointlabels[abdomen]].position; + + underpoint.y-=3000; + + move=0; + + move.x=person[i].whichblockx*block_spacing; + + move.z=person[i].whichblocky*block_spacing; + + XYZ temp; + + whichtri=sidewalkcollide.LineCheck2(overpoint,underpoint,&temp,move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90); + + XYZ normish; + + normish=0; + + normish.y=1; + + if(whichtri>=0){ + + decals.MakeDecal(bloodpool,temp,12,normish, whichtri, &sidewalkcollide, move, cityrotation[person[i].whichblockx][person[i].whichblocky]*90); + + } + + if(whichtri==-1){ + + temp=person[i].skeleton.joints[person[i].skeleton.jointlabels[abdomen]].position; + + temp.y=-.5; + + move=0; + + decals.MakeDecal(bloodpool,temp,12,normish, 0, &sidewalkcollide, move, 0); + + } + + person[i].firstlongdead=1; + + } + + } + + if(person[i].health<100&&person[i].type!=zombietype){ + + person[i].health-=multiplier*120; + + } + + if(person[i].health<100&&person[i].type==zombietype){ + + person[i].health+=multiplier*10; + + if(person[i].health>person[i].maxhealth)person[i].health=person[i].maxhealth; + + } + + if(person[i].health<100&&person[i].type==zombietype&&person[i].skeleton.free==1){ + + person[i].health+=multiplier*10; + + if(person[i].health>person[i].maxhealth)person[i].health=person[i].maxhealth; + + } + + if(person[i].health<40&&person[i].type==zombietype){ + + person[i].speedmult-=multiplier/20; + + if(person[i].speedmult<.6){ + + person[i].speedmult=.6; + + person[i].killtarget=-1; + + } + + } + + if(person[i].health>=40&&person[i].type==zombietype){ + + person[i].speedmult+=multiplier/40; + + if(person[i].speedmult>.7+difficulty*.2){ + + person[i].speedmult=.7+difficulty*.2; + + person[i].killtarget=1; + + } + + } + + + + if(person[i].maxhealth<100&&person[i].type==zombietype){ + + person[i].maxhealth+=multiplier*2; + + if(person[i].maxhealth>100)person[i].maxhealth=100; + + } + + if(person[i].bleeding>0){ + + person[i].bleeding-=multiplier; + + person[i].bleeddelay-=multiplier*10; + + if(person[i].bleeddelay<=0){ + + person[i].bleeddelay=1; + + if(person[i].skeleton.free==0){ + + bleedloc=DoRotation((person[i].bjoint1->position+person[i].bjoint2->position)/2,0,person[i].playerrotation,0)+person[i].playercoords; + + } + + if(person[i].skeleton.free>0){ + + bleedloc=(person[i].bjoint1->position+person[i].bjoint2->position)/2; + + } + + vel=0; + + sprites.MakeSprite(bloodspritedown, .6, 1, .2, .2,bleedloc, vel, 3*person[i].bleeding); + + } + + } + + if(person[i].skeleton.free==0){ + + //Gun + + if(person[i].type==playertype||person[i].type==eviltype){ + + if(i==0){ + + if(person[i].whichgun==shotgun)person[i].recoil-=multiplier*4; + + if(person[i].whichgun==sniperrifle)person[i].recoil-=multiplier*2; + + if(person[i].whichgun==handgun1)person[i].recoil-=multiplier*5; + + if(person[i].whichgun==handgun2)person[i].recoil-=multiplier*5; + + if(person[i].whichgun==assaultrifle)person[i].recoil-=multiplier*10; + + } + + if(i!=0){ + + if(person[i].whichgun==shotgun)person[i].recoil-=multiplier*1; + + if(person[i].whichgun==sniperrifle)person[i].recoil-=multiplier*1; + + if(person[i].whichgun==handgun1)person[i].recoil-=multiplier*2; + + if(person[i].whichgun==handgun2)person[i].recoil-=multiplier*2; + + if(person[i].whichgun==assaultrifle)person[i].recoil-=multiplier*10; + + } + + if(person[i].recoil<0)person[i].recoil=0; + + if(i==0){ + + if(zoom){ + + mousesensitivity=.05*usermousesensitivity; + + if(person[i].targetanimation!=crouchanim||person[i].currentanimation!=crouchanim||person[i].aiming<1){ + + zoom=0; + + } + + if(visions==1)zoom=0; + + } + + if(person[i].currentanimation==crouchanim&&person[i].targetanimation==crouchanim&&person[i].aiming>=1&&person[i].whichgun==sniperrifle){ + + zoom=1; + + if(zoom&&!oldzoom)camera.rotation2-=6; + + } + + if(!zoom)mousesensitivity=1*usermousesensitivity; + + if(person[i].whichgun!=sniperrifle)zoom=0; + + } + + } + + //Zombie eat + + if(i>0&&person[person[i].killtarget].eaten==i&&person[i].targetanimation==zombieeatanim){ + + person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[head]].locked=1; + + person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[rightshoulder]].locked=1; + + for(int k=0;k<2;k++){ + + person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[head]].position=DoRotation(person[i].skeleton.joints[person[i].skeleton.jointlabels[righthand]].position,0,person[i].playerrotation,0)+person[i].playercoords; + + person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[head]].velocity=0; + + person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[rightshoulder]].position=DoRotation(person[i].skeleton.joints[person[i].skeleton.jointlabels[lefthand]].position,0,person[i].playerrotation,0)+person[i].playercoords; + + person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[rightshoulder]].velocity=0; + + person[person[i].killtarget].skeleton.DoConstraints(); + + person[person[i].killtarget].skeleton.DoConstraints(&blocksimplecollide[citytype[person[i].whichblockx][person[i].whichblocky]],&move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90); + + } + + person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[head]].locked=0; + + person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[rightshoulder]].locked=0; + + + + person[person[i].killtarget].longdead=1; + + } + + + + if(i>0&&enemystate!=1&&person[i].type==zombietype&&person[i].speedmult>.7){ + + if(findDistancefast(person[i].playercoords,person[1].playercoords)<20000)person[i].killtarget=1; + + else person[i].killtarget=-1; + + } + + if(i>0&&enemystate!=1&&person[i].type==zombietype&&person[i].speedmult<.7){ + + person[i].killtarget=-1; + + } + + + + bool realcheck = false; + + //Pathfinding + if(i>0&&person[i].targetanimation!=getupfrontanim&&person[i].targetanimation!=thrownanim&&person[i].targetanimation!=getupbackanim&&person[i].currentanimation!=getupfrontanim&&person[i].currentanimation!=getupbackanim){ + + person[i].pathcheckdelay-=multiplier; + + // Realcheck tells us + // a) we've got close to the end of our path or + // b) we're moving away from our target + realcheck=(abs(person[i].playercoords.x-person[i].pathtarget.x)<1&&abs(person[i].playercoords.z-person[i].pathtarget.z)<1) + ||findDistancefast(person[i].playercoords,person[i].pathtarget)>findDistancefast(person[i].oldplayercoords,person[i].pathtarget); + + if(person[i].targetanimation==idleanim&&person[i].killtargetvisible==0){ + + person[i].targetanimation=walkanim; + + if(person[i].type==zombietype)person[i].targetanimation=zombiewalkanim; + + realcheck=1; + + } + + if((realcheck||((person[i].killtarget>-1&&person[i].type!=civiliantype)&&person[i].pathcheckdelay<=0)||person[i].killtargetvisible)){ + + person[i].pathcheckdelay=1.2; + + if((person[i].killtarget==-1||person[i].type==civiliantype)&&!person[i].running){ + + person[i].killtargetvisible=0; + + leastdistance=2000000; + + for(int j=0;j<path.vertexNum;j++){ + + person[i].pathtarget.x=path.vertex[j].x; + + person[i].pathtarget.z=path.vertex[j].z; + + person[i].pathtarget.y=path.vertex[j].y; + + person[i].pathtarget*=person[i].pathsize; + + person[i].pathtarget.x+=person[i].whichblockx*block_spacing; + + person[i].pathtarget.z+=person[i].whichblocky*block_spacing; + + if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&j!=1&&j!=person[i].oldpathnum&&j!=person[i].oldoldpathnum&&j!=person[i].oldoldoldpathnum){ + + leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget); + + closesttarget=j; + + } + + } + + if(closesttarget>=0&&closesttarget<path.vertexNum){ + + person[i].oldoldoldpathnum=person[i].oldoldpathnum; + + person[i].oldoldpathnum=person[i].oldpathnum; + + person[i].oldpathnum=person[i].pathnum; + + person[i].pathnum=closesttarget; + + person[i].pathtarget.x=path.vertex[person[i].pathnum].x; + + person[i].pathtarget.z=path.vertex[person[i].pathnum].z; + + person[i].pathtarget*=person[i].pathsize; + + person[i].pathtarget.x+=person[i].whichblockx*block_spacing; + + person[i].pathtarget.z+=person[i].whichblocky*block_spacing; + + } + + } + + if(person[i].running&&realcheck){ + + person[i].killtargetvisible=0; + + person[i].targetanimation=joganim; + + //Dead target? + + if(person[person[i].killtarget].health<=0){ + + person[i].running=0; + + } + + person[i].killtarget=1; + + + + //If pathfind + + if(realcheck){ + + leastdistance=2000000; + + person[i].lastdistancevictim=0; + + closesttarget=-1; + + //Check best path + + closesttarget=person[i].pathnum; + + //Check other blocks? + + if ((closesttarget==person[i].pathnum)){ + + beginx=person[i].whichblockx-2; + + if(beginx<0)beginx=0; + + beginz=person[i].whichblocky-2; + + if(beginz<0)beginz=0; + + + + endx=person[i].whichblockx+2; + + if(endx>num_blocks-1)endx=num_blocks-1; + + endz=person[i].whichblocky+2; + + if(endz>num_blocks-1)endz=num_blocks-1; + + + + leastdistance=2000000; + + for(int l=beginx;l<=endx;l++){ + + for(int m=beginx;m<=endx;m++){ + + for(int j=0;j<path.vertexNum;j++){ + + person[i].pathtarget.x=path.vertex[j].x; + + person[i].pathtarget.y=path.vertex[j].y; + + person[i].pathtarget.z=path.vertex[j].z; + + person[i].pathtarget*=person[i].pathsize; + + person[i].pathtarget.x+=l*block_spacing; + + person[i].pathtarget.z+=m*block_spacing; + + if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)>findDistancefast(person[i].playercoords,person[person[i].killtarget].playercoords)&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[l][m])==-1){ + + person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords); + + leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget); + + closesttarget=j; + + finaltarget=person[i].pathtarget; + + person[i].whichblockx=l; + + person[i].whichblocky=m; + + } + + } + + } + + } + + } + + if(closesttarget!=-1){ + + person[i].pathnum=closesttarget; + + person[i].pathtarget=finaltarget; + + } + + } + + } + + //Assassin + + if((person[i].killtarget>-1&&person[i].type!=civiliantype)&&!person[i].running){ + + //Dead target? + + if(person[person[i].killtarget].health<=0&&person[i].type==eviltype){ + + person[i].playerrotation2=0; + + person[i].whichgun=nogun; + + person[i].targetanimation=walkanim; + + person[i].lastdistancevictim=200000; + + person[i].pathnum=-1; + + enemystate=1; + + person[i].killtarget=-1; + + realcheck=1; + + } + + if(person[i].type==zombietype&&person[person[i].killtarget].health<=0){ + + if(person[person[i].killtarget].eaten!=i){ + + person[i].playerrotation2=0; + + person[i].targetanimation=zombiewalkanim; + + person[i].lastdistancevictim=200000; + + person[i].pathnum=-1; + + realcheck=1; + + person[i].killtarget=-1; + + } + + if(person[person[i].killtarget].eaten==i&&person[i].targetanimation!=zombieeatanim){ + + person[i].targetanimation=zombieeatanim; + + person[i].targetframe=0; + + person[i].target=0; + + } + + enemystate=1; + + } + + if(person[person[i].killtarget].health>0){ + + if(person[person[i].killtarget].skeleton.free){ + + person[person[i].killtarget].playercoords=person[person[i].killtarget].averageloc; + + } + + + + //If pathfind + + if(realcheck){ + + leastdistance=2000000; + + person[i].lastdistancevictim=2000000; + + closesttarget=-1; + + //Check best path + + for(int j=0;j<path.vertexNum;j++){ + + person[i].pathtarget.x=path.vertex[j].x; + + person[i].pathtarget.z=path.vertex[j].z; + + person[i].pathtarget.y=path.vertex[j].y; + + person[i].pathtarget*=person[i].pathsize; + + person[i].pathtarget.x+=person[i].whichblockx*block_spacing; + + person[i].pathtarget.z+=person[i].whichblocky*block_spacing; + + if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)<person[i].lastdistancevictim&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1){ + + leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget); + + person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords); + + closesttarget=j; + + finaltarget=person[i].pathtarget; + + } + + } + + leastdistance=2000000; + + for(int j=0;j<path.vertexNum;j++){ + + person[i].pathtarget.x=path.vertex[j].x; + + person[i].pathtarget.z=path.vertex[j].z; + + person[i].pathtarget.y=path.vertex[j].y; + + person[i].pathtarget*=person[i].pathsize; + + person[i].pathtarget.x+=person[i].whichblockx*block_spacing; + + person[i].pathtarget.z+=person[i].whichblocky*block_spacing; + + if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)<person[i].lastdistancevictim&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1){ + + leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget); + + person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords); + + closesttarget=j; + + finaltarget=person[i].pathtarget; + + } + + } + + //Check other blocks? + + if((closesttarget==person[i].pathnum)||closesttarget==-1){ + + beginx=person[i].whichblockx-2; + + if(beginx<0)beginx=0; + + beginz=person[i].whichblocky-2; + + if(beginz<0)beginz=0; + + + + endx=person[i].whichblockx+2; + + if(endx>num_blocks-1)endx=num_blocks-1; + + endz=person[i].whichblocky+2; + + if(endz>num_blocks-1)endz=num_blocks-1; + + + + leastdistance=2000000; + + for(int l=beginx;l<=endx;l++){ + + for(int m=beginx;m<=endx;m++){ + + if(l!=person[i].whichblockx||m!=person[i].whichblocky){ + + for(int j=0;j<path.vertexNum;j++){ + + person[i].pathtarget.x=path.vertex[j].x; + + person[i].pathtarget.y=path.vertex[j].y; + + person[i].pathtarget.z=path.vertex[j].z; + + person[i].pathtarget*=person[i].pathsize; + + person[i].pathtarget.x+=l*block_spacing; + + person[i].pathtarget.z+=m*block_spacing; + + if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)<findDistancefast(person[i].playercoords,person[person[i].killtarget].playercoords)&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[l][m])==-1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1){ + + leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget); + + closesttarget=j; + + finaltarget=person[i].pathtarget; + + person[i].whichblockx=l; + + person[i].whichblocky=m; + + } + + } + + } + + } + + } + + } + + if(closesttarget!=-1){ + + person[i].onpath=1; + + person[i].pathnum=closesttarget; + + person[i].pathtarget=finaltarget; + + } + + } + + //Check killtargetvisible + + person[i].killtargetvisible=1; + + if(person[person[i].killtarget].health<=0)person[i].killtargetvisible=0; + + if(closesttarget!=-1&&findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)>30000)person[i].killtargetvisible=0; + + if(person[i].killtarget==0&&visions==1)person[i].killtargetvisible=0; + + if(person[i].killtargetvisible){ + + beginx=person[i].whichblockx-2; + + if(beginx<0)beginx=0; + + beginz=person[i].whichblocky-2; + + if(beginz<0)beginz=0; + + + + endx=person[i].whichblockx+2; + + if(endx>num_blocks-1)endx=num_blocks-1; + + endz=person[i].whichblocky+2; + + if(endz>num_blocks-1)endz=num_blocks-1; + + + + for(int l=beginx;l<=endx;l++){ + + for(int m=beginx;m<=endx;m++){ + + move.x=l*block_spacing; + + move.z=m*block_spacing; + + move.y=-3; + + if(person[i].killtargetvisible){ + + if(blocksimple.LineCheck2(person[i].playercoords,person[person[i].killtarget].playercoords,&blah,move,cityrotation[l][m])!=-1) + + { + + person[i].killtargetvisible=0; + + } + + } + + } + + } + + } + + if(person[i].type==eviltype){ + + if(!person[i].killtargetvisible&&person[i].targetanimation==idleanim){ + + person[i].targetanimation=joganim; + + } + + if(!person[i].killtargetvisible){ + + person[i].aiming=0; + + } + + if(person[i].killtargetvisible){ + + person[i].onpath=0; + + person[i].lastdistancevictim=200000; + + person[i].pathnum=-1; + + if(person[i].whichgun==nogun){ + + person[i].whichgun=possiblegun[abs(Random()%numpossibleguns)]; + + person[i].reloads[person[i].whichgun]=1; + + if(person[i].whichgun==knife)person[i].speedmult=.8+.5*difficulty; + + } + + if(person[i].aiming==0)person[i].shotdelay=shotdelayamount/difficulty; + + person[i].aiming=1; + + if(person[i].reloading>0)person[i].aiming=0; + + if(person[i].whichgun==handgun1||person[i].whichgun==handgun2)person[i].playerrotation2=-10; + + if(person[i].whichgun==assaultrifle||person[i].whichgun==sniperrifle||person[i].whichgun==shotgun)person[i].playerrotation2=20; + + tooclose=1300; + + toofar=3000; + + if(person[i].whichgun==shotgun){ + + tooclose=1400; + + toofar=5000; + + } + + if(person[i].whichgun==assaultrifle){ + + tooclose=5000; + + toofar=9000; + + } + + if(person[i].whichgun==sniperrifle){ + + tooclose=10000; + + toofar=20000; + + } + + if(person[i].whichgun==knife){ + + tooclose=20; + + toofar=20000; + + } + + if(findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)>toofar) + + person[i].targetanimation=joganim; + + if((findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<=tooclose&&person[person[i].killtarget].skeleton.free==0)||(tooclose>200&&findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<=200)||(tooclose<=200&&findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<tooclose)){ + + if(person[i].targetanimation!=idleanim){ + + person[i].targetanimation=idleanim; + + person[i].targetframe=0; + + person[i].target=0; + + } + + if(person[i].whichgun==knife&&person[person[i].killtarget].health==100){ + + murderer=i; + + person[i].attacktarget=0; + + person[i].attackframe=0; + + float gLoc[3]; + + gLoc[0]=(camera.position.x+((person[i].playercoords.x+flatfacing.x)-camera.position.x)/2)/soundscalefactor; + + gLoc[1]=(camera.position.y+((person[i].playercoords.y+flatfacing.y)-camera.position.y)/2)/soundscalefactor; + + gLoc[2]=(camera.position.z+((person[i].playercoords.z+flatfacing.z)-camera.position.z)/2)/soundscalefactor; + + if(person[person[i].killtarget].type!=zombietype) + + { + + alSourcefv(gSourceID[knifeslashsound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[knifeslashsound]); + + person[person[i].killtarget].bjoint1=&person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[neck]]; + + person[person[i].killtarget].bjoint2=&person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[neck]]; + + person[person[i].killtarget].bleeding=1; + + person[person[i].killtarget].bleeddelay=1; + + person[person[i].killtarget].health-=20; + + person[person[i].killtarget].targetanimation=chestpainanim; + + person[person[i].killtarget].targetframe=0; + + person[person[i].killtarget].target=0; + + person[person[i].killtarget].longdead=1; + + } + + } + + } + + finaltarget=person[person[i].killtarget].playercoords; + + } + + } + + if(person[i].type==zombietype&&person[person[i].killtarget].health>0){ + + if(!person[i].killtargetvisible&&person[i].targetanimation==idleanim){ + + person[i].targetanimation=zombiejoganim; + + } + + if(!person[i].killtargetvisible){ + + person[i].aiming=0; + + } + + if(person[i].killtargetvisible){ + + person[i].onpath=0; + + person[i].lastdistancevictim=200000; + + person[i].pathnum=-1; + + if(person[i].aiming==0)person[i].shotdelay=shotdelayamount/difficulty; + + if(findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)>20||person[i].targetanimation!=idleanim) + + person[i].targetanimation=zombiejoganim; + + if(findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<=20){ + + murderer=i; + + person[person[i].killtarget].health=0; + + person[person[i].killtarget].eaten=i; + + } + + finaltarget=person[person[i].killtarget].playercoords; + + } + + } + + if(person[i].killtargetvisible||realcheck)person[i].pathtarget=finaltarget; + + if(realcheck)person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords); + + } + + } + + + + if(person[i].targetanimation!=zombieeatanim||person[i].type!=zombietype){ + + towards=person[i].playercoords-person[i].pathtarget; + + Normalise(&towards); + + person[i].playerrotation=asin(0-towards.x)*360/6.28; + + if(towards.z>0)person[i].playerrotation=180-person[i].playerrotation; + + } + + } + + } + + person[i].whichblockx=((person[i].playercoords.x+block_spacing/2)/block_spacing); + + person[i].whichblocky=((person[i].playercoords.z+block_spacing/2)/block_spacing); + + + + if(!person[i].onground)person[i].velocity.y+=multiplier*gravity; + + if(!person[i].onground&&(i!=0||visions!=1))person[i].playercoords+=person[i].velocity*multiplier; + + //Death by bleeding/shock + + if(person[i].health<=0){ + + person[i].skeleton.offset=0; + + person[i].skeleton.free=1; + + person[i].longdead=1; + + for(int j=0;j<person[i].skeleton.num_joints;j++){ + + person[i].skeleton.joints[j].position+=person[i].skeleton.joints[j].offset; + + person[i].skeleton.joints[j].position=DoRotation(person[i].skeleton.joints[j].position,0,person[i].playerrotation,0); + + person[i].skeleton.joints[j].position+=person[i].playercoords; + + person[i].skeleton.joints[j].realoldposition=person[i].skeleton.joints[j].position; + + person[i].skeleton.joints[j].velocity=DoRotation(person[i].skeleton.joints[j].velocity,0,person[i].playerrotation,0); + + person[i].skeleton.joints[j].velocity+=person[i].velocity; + + person[i].skeleton.joints[j].velocity+=person[i].facing*4; + + } + + } + + } + + //Rag doll + + if(person[i].skeleton.free==1&&person[i].longdead>0){ + + person[i].whichblockx=((person[i].skeleton.joints[0].position.x+block_spacing/2)/block_spacing); + + person[i].whichblocky=((person[i].skeleton.joints[0].position.z+block_spacing/2)/block_spacing); + + move=0; + + move.x=person[i].whichblockx*block_spacing; + + move.z=person[i].whichblocky*block_spacing; + + person[i].skeleton.DoGravity(); + + if(person[i].averageloc.y<=50)person[i].skeleton.DoConstraints(&blocksimplecollide[citytype[person[i].whichblockx][person[i].whichblocky]],&move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90); + + if(person[i].averageloc.y>50)person[i].skeleton.DoConstraints(&blockcollide[citytype[person[i].whichblockx][person[i].whichblocky]],&move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90); + + person[i].oldaverageloc=person[i].averageloc; + + person[i].averageloc=0; + + for(int j=0;j<person[i].skeleton.num_joints;j++){ + + person[i].averageloc+=person[i].skeleton.joints[j].position; + + } + + person[i].averageloc/=person[i].skeleton.num_joints; + + person[i].playercoords=person[i].averageloc; + + if(person[i].longdead<multiplier/2&&person[i].longdead>0)person[i].DrawSkeleton(i); + + if(findDistancefast(person[i].averageloc,person[i].oldaverageloc)<.2*multiplier)person[i].longdead-=multiplier/2; + + } + + if(person[i].skeleton.free==1&&person[i].longdead<=0&&person[i].health>0&&person[i].longdead!=-1){ + + person[i].longdead=1; + + person[i].skeleton.free=0; + + person[i].currentanimation=lyinganim; + + person[i].target=0; + + person[i].targetframe=0; + + //Get up from front or back? + + if(person[i].skeleton.forward.y>0) + + person[i].targetanimation=getupfrontanim; + + else + + person[i].targetanimation=getupbackanim; + + //Find playercoords + + person[i].playercoords=person[i].averageloc; + + for(int j=0;j<person[i].skeleton.num_joints;j++){ + + if(person[i].skeleton.joints[j].position.y>person[i].playercoords.y)person[i].playercoords.y=person[i].skeleton.joints[j].position.y; + + } + + //Find orientation + + XYZ firsttop=person[i].skeleton.joints[person[i].skeleton.jointlabels[neck]].position-person[i].skeleton.joints[person[i].skeleton.jointlabels[groin]].position; + + Normalise(&firsttop); + + person[i].playerrotation=acos(0-firsttop.z); + + person[i].playerrotation*=360/6.28; + + if(0>firsttop.x)person[i].playerrotation=360-person[i].playerrotation; + + person[i].playerrotation*=-1; + + person[i].playervelocity=0; + + if(person[i].targetanimation==getupfrontanim)person[i].playerrotation+=180; + + for(int j=0;j<person[i].skeleton.num_joints;j++){ + + person[i].tempanimation.position[j][0]=person[i].skeleton.joints[j].position-person[i].playercoords; + + person[i].tempanimation.position[j][0]=DoRotation(person[i].tempanimation.position[j][0],0,-person[i].playerrotation,0); + + } + + } + + } + + + + //Grenade + + if(Button()&&person[0].whichgun==grenade&&person[0].ammo>0&&person[0].reloading<=0&&person[0].attackframe<0&&person[0].targetanimation!=crouchanim){ + + if(person[0].grenphase==0){ + + XYZ soundsource=DoRotation(person[0].skeleton.joints[person[0].skeleton.jointlabels[righthand]].position,0,person[0].playerrotation,0)+person[0].playercoords; + + float gLoc[3]; + + gLoc[0]=soundsource.x/soundscalefactor; + + gLoc[1]=soundsource.y/soundscalefactor; + + gLoc[2]=soundsource.z/soundscalefactor; + + alSourcefv(gSourceID[pinpullsound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[pinpullsound]); + + person[0].grenphase=1; + + } + + } + + if((!Button())&&person[0].whichgun==grenade){ + + if(person[0].grenphase==1){ + + person[0].grenphase=0; + + person[0].attackframe=0; + + person[0].attacktarget=0; + + person[0].killtarget=0; + + } + + } + + if(person[0].targetanimation==crouchanim){ + + if(person[0].grenphase==1){ + + person[0].grenphase=0; + + XYZ soundsource=DoRotation(person[0].skeleton.joints[person[0].skeleton.jointlabels[righthand]].position,0,person[0].playerrotation,0)+person[0].playercoords; + + float gLoc[3]; + + gLoc[0]=soundsource.x/soundscalefactor; + + gLoc[1]=soundsource.y/soundscalefactor; + + gLoc[2]=soundsource.z/soundscalefactor; + + alSourcefv(gSourceID[pinreplacesound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[pinreplacesound]); + + } + + } + + + + //Get gun + + int temp; + + int temp2; + + bool switched=0; + + if(Button()&&!oldbutton&&(person[0].aiming==0||person[0].whichgun==grenade||person[0].whichgun==nogun||person[0].whichgun==knife)&&person[0].currentanimation==crouchanim){ + + for(int i=0;i<max_people;i++){ + + if(!switched&&person[i].skeleton.free==1&&findDistancefast(person[0].playercoords,person[i].averageloc)<200){ + + float gLoc[3]; + + gLoc[0]=person[0].playercoords.x/soundscalefactor; + + gLoc[1]=person[0].playercoords.y/soundscalefactor; + + gLoc[2]=person[0].playercoords.z/soundscalefactor; + + + + alSourcefv(gSourceID[clicksound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[clicksound]); + + + + temp=person[0].whichgun; + + temp2=person[0].ammo; + + person[0].whichgun=person[i].whichgun; + + person[0].ammo=person[i].ammo; + + person[i].whichgun=temp; + + person[i].ammo=temp2; + + person[0].aiming=1; + + person[0].aimamount=0; + + + + switched=1; + + } + + } + + } + + + + //Throw + + if(Button()&&person[0].attackframe<0&&((person[0].whichgun==nogun||person[0].aiming==0)&&person[0].whichgun!=knife)&&person[0].currentanimation!=crouchanim&&person[0].targetanimation!=crouchanim&&person[0].targetanimation!=throwanim&&visions==0){ + + if(person[0].targetanimation==idleanim||person[0].targetanimation==walkanim){ + + bool attacking=0; + + person[0].killtarget=-1; + + float closedistance=-1; + + for(int i=1;i<numpeople;i++){ + + if(person[i].skeleton.free<1&&(person[i].whichgun!=nogun)&&findDistancefast(person[i].playercoords,person[0].playercoords+flatfacing)<12){ + + attacking=1; + + if(person[0].killtarget==-1||findDistancefast(person[i].playercoords,person[0].playercoords)<closedistance){ + + person[0].killtarget=i; + + closedistance=findDistancefast(person[i].playercoords,person[0].playercoords); + + } + + } + + } + + if(attacking){ + + score+=150; + + person[0].aiming=1; + + person[0].whichgun=person[person[0].killtarget].whichgun; + + person[0].ammo=person[person[0].killtarget].ammo; + + person[person[0].killtarget].whichgun=nogun; + + person[person[0].killtarget].killtarget=-1; + + person[0].targetframe=0; + + person[0].targetanimation=throwanim; + + person[0].target=1; + + person[0].speed=1; + + person[person[0].killtarget].targetframe=0; + + person[person[0].killtarget].targetanimation=thrownanim; + + person[person[0].killtarget].target=1; + + person[person[0].killtarget].playercoords=person[0].playercoords; + + person[person[0].killtarget].playerrotation=person[0].playerrotation; + + person[person[0].killtarget].speed=person[0].speed; + + person[person[0].killtarget].speedmult=1; + + } + + } + + } + + + + //Gun whacking + + if(Button()&&(person[0].aiming==0||person[0].ammo<=0||person[0].whichgun==nogun||person[0].whichgun==knife||person[0].targetanimation==joganim)&&person[0].currentanimation!=crouchanim&&person[0].targetanimation!=throwanim&&person[0].whichgun!=grenade&&person[0].targetanimation!=crouchanim&&visions==0){ + + if(person[0].attackframe==-1||person[person[0].killtarget].skeleton.free==1){ + + bool attacking=0; + + person[0].killtarget=-1; + + float closedistance=-1; + + for(int i=1;i<numpeople;i++){ + + if(person[i].existing&&person[i].type!=viptype&&person[i].skeleton.free<1&&findDistancefast(person[i].playercoords,person[0].playercoords+flatfacing)<12+(person[0].whichgun==knife)*10){ + + if(person[0].killtarget==-1||findDistancefast(person[i].playercoords,person[0].playercoords)<closedistance){ + + attacking=1; + + person[0].killtarget=i; + + closedistance=findDistancefast(person[i].playercoords,person[0].playercoords); + + } + + } + + } + + if(attacking){ + + person[0].attacktarget=0; + + person[0].attackframe=0; + + } + + whacked=0; + + } + + } + + + + XYZ velocity; + + + + if(person[0].attackframe>1||(person[0].attackframe>=0&&person[0].currentanimation==joganim)){ + + if(person[person[0].killtarget].skeleton.free<1&&person[0].killtarget!=0&&(person[0].aiming<1||person[0].whichgun==nogun||person[0].whichgun==knife||person[0].targetanimation==joganim)){ + + float gLoc[3]; + + gLoc[0]=(camera.position.x+((person[0].playercoords.x+flatfacing.x)-camera.position.x)/2)/soundscalefactor; + + gLoc[1]=(camera.position.y+((person[0].playercoords.y+flatfacing.y)-camera.position.y)/2)/soundscalefactor; + + gLoc[2]=(camera.position.z+((person[0].playercoords.z+flatfacing.z)-camera.position.z)/2)/soundscalefactor; + + if(person[person[0].killtarget].type!=zombietype) + + { + + if(person[0].whichgun!=knife){ + + alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[headwhacksound]); + + } + + if(person[0].whichgun==knife){ + + alSourcefv(gSourceID[knifeslashsound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[knifeslashsound]); + + person[person[0].killtarget].bjoint1=&person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]]; + + person[person[0].killtarget].bjoint2=&person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]]; + + person[person[0].killtarget].bleeding=1; + + person[person[0].killtarget].bleeddelay=1; + + person[0].bjoint1=&person[0].skeleton.joints[person[0].skeleton.jointlabels[righthand]]; + + person[0].bjoint2=&person[0].skeleton.joints[person[0].skeleton.jointlabels[righthand]]; + + person[0].bleeding=1; + + person[0].bleeddelay=1; + + velocity=DoRotation(flatfacing,0,70,0)*50+person[0].velocity*2; + + velocity.y+=30; + + sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.3, 2); + + sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.2, 3); + + sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.1, 4); + + } + + person[person[0].killtarget].health-=100; + + person[person[0].killtarget].skeleton.free=1; + + person[person[0].killtarget].longdead=1; + + for(int j=0;j<person[person[0].killtarget].skeleton.num_joints;j++){ + + person[person[0].killtarget].skeleton.joints[j].position=DoRotation(person[person[0].killtarget].skeleton.joints[j].position,0,person[person[0].killtarget].playerrotation,0); + + person[person[0].killtarget].skeleton.joints[j].position+=person[person[0].killtarget].playercoords; + + person[person[0].killtarget].skeleton.joints[j].realoldposition=person[person[0].killtarget].skeleton.joints[j].position; + + person[person[0].killtarget].skeleton.joints[j].velocity=person[person[0].killtarget].velocity; + + person[person[0].killtarget].skeleton.joints[j].velocity.x+=abs(Random()%10)-5; + + person[person[0].killtarget].skeleton.joints[j].velocity.y+=abs(Random()%10)-5; + + person[person[0].killtarget].skeleton.joints[j].velocity.z+=abs(Random()%10)-5; + + } + + if(person[0].whichgun!=knife){ + + person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[head]].velocity+=DoRotation(flatfacing,0,40,0)*50; + + person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[head]].velocity+=person[0].velocity*2; + + } + + } + + else + + { + + if(whacked==0){ + + whacked=1; + + if(person[0].whichgun!=knife){ + + alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[headwhacksound]); + + } + + if(person[0].whichgun==knife){ + + alSourcefv(gSourceID[knifeslashsound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[knifeslashsound]); + + person[person[0].killtarget].bjoint1=&person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]]; + + person[person[0].killtarget].bjoint2=&person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]]; + + person[person[0].killtarget].bleeding=1; + + person[person[0].killtarget].bleeddelay=1; + + person[0].bjoint1=&person[0].skeleton.joints[person[0].skeleton.jointlabels[righthand]]; + + person[0].bjoint2=&person[0].skeleton.joints[person[0].skeleton.jointlabels[righthand]]; + + person[0].bleeding=1; + + person[0].bleeddelay=1; + + velocity=DoRotation(flatfacing,0,70,0)*50+person[0].velocity*2; + + velocity.y+=30; + + sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.3, 2); + + sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.2, 3); + + sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.1, 4); + + } + + person[person[0].killtarget].health-=200; + + person[person[0].killtarget].maxhealth-=20; + + person[person[0].killtarget].skeleton.free=1; + + person[person[0].killtarget].longdead=1; + + for(int j=0;j<person[person[0].killtarget].skeleton.num_joints;j++){ + + person[person[0].killtarget].skeleton.joints[j].position=DoRotation(person[person[0].killtarget].skeleton.joints[j].position,0,person[person[0].killtarget].playerrotation,0); + + person[person[0].killtarget].skeleton.joints[j].position+=person[person[0].killtarget].playercoords; + + person[person[0].killtarget].skeleton.joints[j].realoldposition=person[person[0].killtarget].skeleton.joints[j].position; + + person[person[0].killtarget].skeleton.joints[j].velocity=person[person[0].killtarget].velocity; + + person[person[0].killtarget].skeleton.joints[j].velocity.x+=abs(Random()%10)-5; + + person[person[0].killtarget].skeleton.joints[j].velocity.y+=abs(Random()%10)-5; + + person[person[0].killtarget].skeleton.joints[j].velocity.z+=abs(Random()%10)-5; + + } + + if(person[0].whichgun!=knife){ + + person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[head]].velocity+=DoRotation(flatfacing,0,40,0)*50; + + person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[head]].velocity+=person[0].velocity*2; + + } + + } + + } + + } + + } + + + + //Tackle + + if(person[0].currentanimation==diveanim&&visions==0){ + + for(int i=1;i<numpeople;i++){ + + if(person[i].skeleton.free<1&&findDistancefast(person[i].playercoords,person[0].playercoords+flatfacing)<22){ + + float gLoc[3]; + + gLoc[0]=(camera.position.x+((person[0].playercoords.x+flatfacing.x)-camera.position.x)/2)/soundscalefactor; + + gLoc[1]=(camera.position.y+((person[0].playercoords.y+flatfacing.y)-camera.position.y)/2)/soundscalefactor; + + gLoc[2]=(camera.position.z+((person[0].playercoords.z+flatfacing.z)-camera.position.z)/2)/soundscalefactor; + + alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[headwhacksound]); + + person[i].skeleton.free=1; + + person[i].longdead=1; + + for(int j=0;j<person[i].skeleton.num_joints;j++){ + + person[i].skeleton.joints[j].position=DoRotation(person[i].skeleton.joints[j].position,0,person[i].playerrotation,0); + + person[i].skeleton.joints[j].position+=person[i].playercoords; + + person[i].skeleton.joints[j].realoldposition=person[i].skeleton.joints[j].position; + + person[i].skeleton.joints[j].velocity=person[0].velocity; + + person[i].skeleton.joints[j].velocity.y=-10; + + person[i].skeleton.joints[j].velocity.x+=abs(Random()%10)-5; + + person[i].skeleton.joints[j].velocity.y+=abs(Random()%10)-5; + + person[i].skeleton.joints[j].velocity.z+=abs(Random()%10)-5; + + } + + } + + } + + } + + + + //Fire/wing + + XYZ wallhit; + + XYZ start; + + XYZ finalwallhit; + + bool firing; + + float inaccuracy = 0.0; + + int numshots; + + XYZ hitnorm; + + XYZ hitmove; + + int hitpoly=0; + + float hitrotation = 0.0f; + + Model *model = NULL; + + for(int j=0;j<numpeople;j++){ + + if(person[j].type==playertype||person[j].type==eviltype){ + + firing=0; + + if(person[j].ammo>0&&person[j].reloading<=0&&person[j].targetanimation!=joganim){ + + if(Button()&&!oldbutton&&j==0)firing=1; + + if(j!=0)firing=0; + + if(j!=0&&person[j].whichgun!=nogun&&person[j].whichgun!=knife&&person[j].killtargetvisible&&person[j].shotdelay<0)firing=1; + + if(j!=0&&person[j].whichgun!=nogun&&person[j].whichgun!=knife&&person[j].killtargetvisible&&person[j].shotdelay>0)person[j].shotdelay-=multiplier*.9; + + if(person[j].skeleton.free==1||person[j].targetanimation==getupfrontanim||person[j].targetanimation==getupbackanim)person[j].shotdelay=shotdelayamount/difficulty; + + if(j!=0&&person[j].whichgun!=nogun&&person[j].whichgun!=knife&&person[j].killtargetvisible)person[j].aiming=1; + + if(person[0].whichgun!=assaultrifle)oldbutton=1; + + } + + if(person[j].ammo==0&&person[j].reloads[person[j].whichgun]>0){ + + person[j].ammo=-1; + + person[j].aiming=0; + + firing=0; + + } + + if(person[0].ammo<=0&&Button()&&!oldbutton&&person[0].targetanimation!=joganim&&person[0].whichgun!=nogun&&person[0].whichgun!=knife&&person[0].whichgun!=grenade&&person[0].aiming){ + + oldbutton=1; + + float gLoc[3]; + + gLoc[0]=person[0].playercoords.x/soundscalefactor; + + gLoc[1]=person[0].playercoords.y/soundscalefactor; + + gLoc[2]=person[0].playercoords.z/soundscalefactor; + + + + alSourcefv(gSourceID[clicksound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[clicksound]); + + } + + if(j==0&&visions==1&&firing){ + + firing=0; + + alSourcePlay(gSourceID[soulinsound]); + + } + + if(person[j].aimamount<1)firing=0; + + if(firing){ + + if(person[j].whichgun==handgun1||person[j].whichgun==handgun2)inaccuracy=8; + + if(person[j].whichgun==assaultrifle)inaccuracy=6; + + if(person[j].whichgun==sniperrifle)inaccuracy=2; + + if(person[j].whichgun==shotgun)inaccuracy=6; + + if(person[person[j].killtarget].skeleton.free==1)inaccuracy*=3; + + + + person[j].shotdelay=shotdelayamount/difficulty; + + if(person[j].aiming>=1&&person[j].recoil<=0){ + + //Firing + + person[j].litup=1; + + person[j].recoil=1; + + XYZ end, aim, oldend; + + HitStruct hitstruct,temphitstruct; + + float olddistance = 0.0f; + + float distance = 0.0f; + + float totalarea = 0.0f; + + int whichhit=-1; + + if(person[j].whichgun==shotgun)numshots=7; + + if(person[j].whichgun!=shotgun)numshots=1; + + if(person[j].whichgun!=grenade)person[j].ammo--; + + for(int p=0;p<numshots;p++){ + + if(!zoom||j!=0){ + + if(person[j].whichgun==assaultrifle)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position-person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position,0,person[j].playerrotation-2.5,0); + + if(person[j].whichgun==sniperrifle)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position-person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position,0,person[j].playerrotation+4,0); + + if(person[j].whichgun==shotgun)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position-person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position,2+(float)(Random()%1000)/500,0,0); + + if(person[j].whichgun==shotgun)aim=DoRotation(aim,0,person[j].playerrotation-1+(float)(Random()%1000)/500,0); + + if(person[j].whichgun==handgun1&&!thirdperson&&j==0)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.65+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.35),0,person[j].playerrotation-.9,0); + + if(person[j].whichgun==handgun1&&(thirdperson||j!=0))aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.35+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.65),0,person[j].playerrotation-.9,0); + + if(person[j].whichgun==handgun2&&!thirdperson&&j==0)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.65+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.35),0,person[j].playerrotation-.9,0); + + if(person[j].whichgun==handgun2&&(thirdperson||j!=0))aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.35+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.65),0,person[j].playerrotation-.9,0); + + if(j!=0&&person[person[j].killtarget].skeleton.free==0)aim=(DoRotation(person[person[j].killtarget].skeleton.joints[person[person[j].killtarget].skeleton.jointlabels[abdomen]].position,0,person[person[j].killtarget].playerrotation,0)+person[person[j].killtarget].playercoords)-(DoRotation(person[j].skeleton.joints[person[j].skeleton.jointlabels[lefthand]].position,0,person[j].playerrotation,0)+person[j].playercoords); + + if(j!=0&&person[person[j].killtarget].skeleton.free!=0)aim=person[person[j].killtarget].skeleton.joints[person[person[j].killtarget].skeleton.jointlabels[abdomen]].position-(DoRotation(person[j].skeleton.joints[person[j].skeleton.jointlabels[lefthand]].position,0,person[j].playerrotation,0)+person[j].playercoords); + + if(j!=0)aim=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),(float)(abs(Random()%2000))/2000*inaccuracy-inaccuracy/2,(float)(abs(Random()%2000))/2000*inaccuracy-inaccuracy/2,0),0,person[j].playerrotation,0); + + } + + if(zoom&&j==0){ + + start=camera.position; + + aim=facing; + + } + + Normalise(&aim); + + if(person[j].whichgun==sniperrifle){ + + start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position,0,person[j].playerrotation,0); + + float gLoc[3]; + + + + start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*.35; + + + + gLoc[0]=(camera.position.x+(start.x-camera.position.x)/4)/soundscalefactor; + + gLoc[1]=(camera.position.y+(start.y-camera.position.y)/4)/soundscalefactor; + + gLoc[2]=(camera.position.z+(start.z-camera.position.z)/4)/soundscalefactor; + + alSourcefv(gSourceID[riflesound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[riflesound]); + + if(j==0){ + + if(person[j].currentanimation!=crouchanim)camera.rotation2-=7; + + if(person[j].currentanimation==crouchanim)camera.rotation2-=3; + + } + + } + + if(person[j].whichgun==shotgun){ + + start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position,0,person[j].playerrotation,0); + + float gLoc[3]; + + + + start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*.35; + + + + if(p==numshots-1){ + + gLoc[0]=(camera.position.x+(start.x-camera.position.x)/4)/soundscalefactor; + + gLoc[1]=(camera.position.y+(start.y-camera.position.y)/4)/soundscalefactor; + + gLoc[2]=(camera.position.z+(start.z-camera.position.z)/4)/soundscalefactor; + + alSourcefv(gSourceID[shotgunsound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[shotgunsound]); + + if(j==0){ + + if(person[j].currentanimation!=crouchanim)camera.rotation2-=7; + + if(person[j].currentanimation==crouchanim)camera.rotation2-=3; + + } + + } + + } + + if(person[j].whichgun==handgun1){ + + start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[rightwrist])].position,0,person[j].playerrotation,0); + + start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*.55; + + + + float gLoc[3]; + + + + gLoc[0]=(camera.position.x+(start.x-camera.position.x)/4)/soundscalefactor; + + gLoc[1]=(camera.position.y+(start.y-camera.position.y)/4)/soundscalefactor; + + gLoc[2]=(camera.position.z+(start.z-camera.position.z)/4)/soundscalefactor; + + alSourcefv(gSourceID[pistol1sound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[pistol1sound]); + + if(j==0){ + + if(person[j].currentanimation!=crouchanim)camera.rotation2-=6; + + if(person[j].currentanimation==crouchanim)camera.rotation2-=4; + + } + + } + + if(person[j].whichgun==handgun2){ + + start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[rightwrist])].position,0,person[j].playerrotation,0); + + start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*.55; + + + + float gLoc[3]; + + + + gLoc[0]=(camera.position.x+(start.x-camera.position.x)/4)/soundscalefactor; + + gLoc[1]=(camera.position.y+(start.y-camera.position.y)/4)/soundscalefactor; + + gLoc[2]=(camera.position.z+(start.z-camera.position.z)/4)/soundscalefactor; + + alSourcefv(gSourceID[pistol2sound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[pistol2sound]); + + if(j==0){ + + if(person[j].currentanimation!=crouchanim)camera.rotation2-=5; + + if(person[j].currentanimation==crouchanim)camera.rotation2-=3; + + } + + } + + if(person[j].whichgun==assaultrifle){ + + start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position,0,person[j].playerrotation,0); + + start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*.25; + + + + float gLoc[3]; + + gLoc[0]=(camera.position.x+(start.x-camera.position.x)/4)/soundscalefactor; + + gLoc[1]=(camera.position.y+(start.y-camera.position.y)/4)/soundscalefactor; + + gLoc[2]=(camera.position.z+(start.z-camera.position.z)/4)/soundscalefactor; + + alSourcefv(gSourceID[machinegunsound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[machinegunsound]); + + if(j==0){ + + if(person[j].currentanimation!=crouchanim){ + + camera.rotation2-=2.3; + + camera.rotation+=(float)(Random()%100)/50; + + } + + if(person[j].currentanimation==crouchanim){ + + camera.rotation2-=1.5; + + camera.rotation+=(float)(Random()%100)/60; + + } + + } + + } + + end=start+aim*1000; + + if(debug){ + + if(IsKeyDown(theKeyMap, MAC_G_KEY)&&j==0){ + + sprites.MakeSprite(grenadesprite, 1, 1, 1, 1, start, aim*200, 1.01); + + } + + } + + if(!IsKeyDown(theKeyMap, MAC_G_KEY)||j!=0||!debug){ + + int bulletstrength=1; + + int firstpass=-1; + + bool penetrate; + + for(int m=0;m<bulletstrength;m++){ + + //People + + whichhit=-1; + + for(int i=0;i<numpeople;i++){ + + if(i!=j&&i!=firstpass&&person[i].existing){ + + temphitstruct=person[i].BulletCollideWithPlayer(i, start, end); + + if(temphitstruct.collision){ + + distance=findDistancefast(start,temphitstruct.hitlocation); + + if(distance<olddistance||whichhit==-1){ + + end=temphitstruct.hitlocation; + + olddistance=distance; + + hitstruct=temphitstruct; + + whichhit=i; + + } + + } + + } + + } + + //Blocks + + wallhit=0; + + beginx=(person[j].playercoords.x+block_spacing/2)/block_spacing-3; + + if(beginx<0)beginx=0; + + beginz=(person[j].playercoords.z+block_spacing/2)/block_spacing-3; + + if(beginz<0)beginz=0; + + + + endx=(person[j].playercoords.x+block_spacing/2)/block_spacing+3; + + if(endx>num_blocks-1)endx=num_blocks-1; + + endz=(person[j].playercoords.z+block_spacing/2)/block_spacing+3; + + if(endz>num_blocks-1)endz=num_blocks-1; + + + + if(beginx<endx&&beginz<endz) + + finalwallhit=0; + + for(int i=beginx;i<=endx;i++) + + for(int j=beginz;j<=endz;j++){ + + move=0; + + move.x=i*block_spacing; + + move.z=j*block_spacing; + + whichtri=blocks[citytype[i][j]].LineCheck2(start,end,&wallhit,move,cityrotation[i][j]*90); + + if(whichtri!=-1){ + + whichhit=-1; + + end=wallhit; + + finalwallhit=wallhit; + + hitnorm=DoRotation(blocks[citytype[i][j]].normals[whichtri],0,cityrotation[i][j]*90,0); + + hitmove=move; + + hitrotation=cityrotation[i][j]*90; + + hitpoly=whichtri; + + model=&blocks[citytype[i][j]]; + + if(j==0&&blocks[citytype[i][j]].normals[whichtri].y>.9)bulletstrength=2; + + } + + } + + wallhit=0; + + wallhit.x=camera.position.x; + + wallhit.z=camera.position.z; + + whichtri=Bigstreet.LineCheck2(start,end,&wallhit,wallhit,0); + + if(whichtri!=-1){ + + end.y-=.5; + + end=wallhit; + + finalwallhit=wallhit; + + bulletstrength=2; + + hitnorm=0; + + hitnorm.y=1; + + hitmove=0; + + hitrotation=0; + + } + + if(m==0){ + + if(j==0&&slomo==2){ + + soundscalefactor=soundscalefactordefault; + + alSourceStop(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0); + + alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0); + + if(person[0].whichgun==knife)whichsong=knifesong; + + if(person[0].whichgun!=knife)whichsong=shootsong; + + if(type==zombie_type)whichsong=zombiesong; + + alSourcef(gSourceID[whichsong], AL_PITCH, 1); + + alSourcePlay(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1); + + alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1); + + slomo=0; + + if(whichhit==-1)alSourcePlay(gSourceID[disguisekillsound]); + + flashamount=.5; + + flashr=1;flashg=1;flashb=1; + + } + + } + + //Impact + + oldend=end; + + //with person + + if(whichhit!=-1&&whichhit!=firstpass){ + + if(j==0)person[whichhit].dead=1; + + if(whichhit==1){ + + murderer=j; + + } + + if(person[whichhit].health==100&&j==0){ + + if(person[whichhit].type==civiliantype)civkills++; + + if(person[whichhit].type==eviltype)goodkills++; + + } + + if(person[whichhit].health==100&&j!=0){ + + badkills++; + + } + + //penetrate + + penetrate=abs(Random()%2)==1; + + if(numshots>1)penetrate=0; + + if(penetrate){bulletstrength=2; + + firstpass=whichhit; + + end=start+aim*1000;} + + if(person[j].whichgun==assaultrifle)person[whichhit].health-=20; + + if(person[j].whichgun==assaultrifle&&person[whichhit].type==zombietype)person[whichhit].health-=60; + + if(person[j].whichgun==handgun1){ + + if(person[whichhit].type!=zombietype)person[whichhit].health-=100; + + if(person[whichhit].type==zombietype)person[whichhit].health-=100; + + person[whichhit].DoAnimations(whichhit); + + } + + if(person[j].whichgun==handgun2)person[whichhit].health-=20; + + if(person[j].whichgun==handgun2&&person[whichhit].type==zombietype)person[whichhit].health-=60; + + if(person[j].whichgun==sniperrifle&&m!=0)person[whichhit].health-=30; + + if(person[j].whichgun==shotgun)person[whichhit].health-=60; + + if(person[j].whichgun==sniperrifle&&m==0){ + + if(person[whichhit].type!=zombietype)person[whichhit].health-=100; + + if(person[whichhit].type==zombietype)person[whichhit].health-=120; + + person[whichhit].DoAnimations(whichhit); + + } + + if(hitstruct.joint1->modelnum==headmodel&&person[whichhit].type!=zombietype){ + + person[whichhit].health-=60; + + } + + if(person[whichhit].type==zombietype)person[whichhit].speedmult-=.05; + + if(person[whichhit].type==zombietype)person[whichhit].maxhealth-=10; + + if(whichhit==0){ + + bulletstrength=1; + + person[0].health=100; + + flashr=0; + + flashg=0; + + flashb=0; + + flashamount=1; + + float gLoc[3]; + + gLoc[0]=hitstruct.hitlocation.x/soundscalefactor; + + gLoc[1]=hitstruct.hitlocation.y/soundscalefactor; + + gLoc[2]=hitstruct.hitlocation.z/soundscalefactor; + + alSourcefv(gSourceID[bodywhacksound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[bodywhacksound]); + + } + + person[whichhit].longdead=1; + + + + if(person[whichhit].health<=0){ + + person[whichhit].skeleton.offset=0; + + if(person[whichhit].skeleton.free!=1){ + + person[whichhit].skeleton.free=1; + + totalarea=0; + + for(int j=0;j<person[whichhit].skeleton.num_joints;j++){ + + person[whichhit].skeleton.joints[j].position=DoRotation(person[whichhit].skeleton.joints[j].position,0,person[whichhit].playerrotation,0); + + person[whichhit].skeleton.joints[j].position+=person[whichhit].playercoords; + + person[whichhit].skeleton.joints[j].realoldposition=person[whichhit].skeleton.joints[j].position; + + person[whichhit].skeleton.joints[j].velocity=person[whichhit].velocity; + + person[whichhit].skeleton.joints[j].velocity.x+=(float)(abs(Random()%20)-10)/2; + + person[whichhit].skeleton.joints[j].velocity.y+=(float)(abs(Random()%20)-10)/2; + + person[whichhit].skeleton.joints[j].velocity.z+=(float)(abs(Random()%20)-10)/2; + + } + + } + + for(int j=0;j<person[whichhit].skeleton.num_joints;j++){ + + if(findDistancefast(person[whichhit].skeleton.joints[j].position,hitstruct.hitlocation)<200){ + + totalarea+=(200/findDistancefast(person[whichhit].skeleton.joints[j].position,hitstruct.hitlocation)); + + } + + } + + for(int j=0;j<person[whichhit].skeleton.num_joints;j++){ + + if(findDistancefast(person[whichhit].skeleton.joints[j].position,hitstruct.hitlocation)<200){ + + person[whichhit].skeleton.joints[j].velocity+=aim*((200/findDistancefast(person[whichhit].skeleton.joints[j].position,hitstruct.hitlocation))/totalarea*200); + + } + + } + + } + + if(person[whichhit].health>0){ + + if(person[whichhit].killtargetvisible==0&&person[whichhit].type!=zombietype&&person[whichhit].currentanimation!=getupfrontanim&person[whichhit].currentanimation!=getupbackanim){ + + if(hitstruct.joint1->modelnum==headmodel)person[whichhit].targetanimation=headpainanim; + + if(hitstruct.joint1->modelnum==chestmodel)person[whichhit].targetanimation=chestpainanim; + + if(hitstruct.joint1->modelnum==abdomenmodel)person[whichhit].targetanimation=stomachpainanim; + + if(hitstruct.joint1->label==rightelbow||hitstruct.joint1->label==rightshoulder||hitstruct.joint1->label==rightwrist||hitstruct.joint1->label==righthand)person[whichhit].targetanimation=rightarmpainanim; + + if(hitstruct.joint1->label==leftelbow||hitstruct.joint1->label==leftshoulder||hitstruct.joint1->label==leftwrist||hitstruct.joint1->label==lefthand)person[whichhit].targetanimation=leftarmpainanim; + + if(hitstruct.joint1->label==rightknee||hitstruct.joint1->label==righthip||hitstruct.joint1->label==rightankle||hitstruct.joint1->label==rightfoot)person[whichhit].targetanimation=rightlegpainanim; + + if(hitstruct.joint1->label==leftknee||hitstruct.joint1->label==lefthip||hitstruct.joint1->label==leftankle||hitstruct.joint1->label==leftfoot)person[whichhit].targetanimation=leftlegpainanim; + + person[whichhit].targetframe=0; + + person[whichhit].target=0; + + } + + person[whichhit].skeleton.offset=1; + + for(int j=0;j<person[whichhit].skeleton.num_joints;j++){ + + if(findDistancefast(DoRotation(person[whichhit].skeleton.joints[j].position,0,person[whichhit].playerrotation,0)+person[whichhit].playercoords,hitstruct.hitlocation)<200){ + + totalarea+=(200/findDistancefast(DoRotation(person[whichhit].skeleton.joints[j].position,0,person[whichhit].playerrotation,0)+person[whichhit].playercoords,hitstruct.hitlocation)); + + } + + } + + float offsetlength; + + for(int j=0;j<person[whichhit].skeleton.num_joints;j++){ + + if(findDistancefast(DoRotation(person[whichhit].skeleton.joints[j].position,0,person[whichhit].playerrotation,0)+person[whichhit].playercoords,hitstruct.hitlocation)<200){ + + person[whichhit].skeleton.joints[j].offset+=DoRotation(aim*((200/findDistancefast(DoRotation(person[whichhit].skeleton.joints[j].position,0,person[whichhit].playerrotation,0)+person[whichhit].playercoords,hitstruct.hitlocation))/totalarea*10),0,-person[whichhit].playerrotation,0); + + } + + offsetlength=findLengthfast(person[whichhit].skeleton.joints[j].offset); + + if(offsetlength>36){ + + Normalise(&person[whichhit].skeleton.joints[j].offset); + + person[whichhit].skeleton.joints[j].offset*=6; + + } + + } + + } + + if(hitstruct.joint1->modelnum==headmodel&&person[whichhit].health<=0){ + + for(int j=0;j<person[whichhit].skeleton.num_joints;j++){ + + if(&person[whichhit].skeleton.joints[j]==hitstruct.joint1||&person[whichhit].skeleton.joints[j]==hitstruct.joint2){ + + if(j!=person[whichhit].skeleton.jointlabels[abdomen]&&j!=person[whichhit].skeleton.jointlabels[groin]&&j!=person[whichhit].skeleton.jointlabels[neck]){ + + sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, person[whichhit].skeleton.joints[j].velocity/3, 9); + + sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, DoRotation(person[whichhit].skeleton.joints[j].velocity/3,Random()%360,Random()%360,0)/5, 5); + + sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, DoRotation(person[whichhit].skeleton.joints[j].velocity/3,Random()%360,Random()%360,0)/5, 5); + + sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, DoRotation(person[whichhit].skeleton.joints[j].velocity/3,Random()%360,Random()%360,0)/5, 5); + + sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, DoRotation(person[whichhit].skeleton.joints[j].velocity/3,Random()%360,Random()%360,0)/5, 5); + + person[whichhit].skeleton.DeleteJoint(j); + + person[whichhit].skeleton.broken=1; + + person[whichhit].health=-10000; + + person[whichhit].skeleton.joints[j].existing=0; + + if(person[whichhit].type==zombietype)score+=300; + + } + + } + + } + + } + + + + XYZ velocity; + + velocity=aim*-8; + + //blood + + if(!hitstruct.joint1->modelnum==headmodel){ + + if(person[j].whichgun==sniperrifle)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 5); + + if(person[j].whichgun==sniperrifle&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 7); + + if(person[j].whichgun==shotgun)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 5); + + if(person[j].whichgun==shotgun&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 7); + + if(person[j].whichgun==assaultrifle)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 3); + + if(person[j].whichgun==assaultrifle&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 7); + + if(person[j].whichgun==handgun1)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 3); + + if(person[j].whichgun==handgun1&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 4); + + if(person[j].whichgun==handgun2)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 3); + + if(person[j].whichgun==handgun2&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 4); + + }else{ + + sprites.MakeSprite(bloodspritenoup, 1, 1, .2, .2, hitstruct.hitlocation, velocity*0, 6); + + sprites.MakeSprite(bloodspritenoup, 1, 1, .5, .5, hitstruct.hitlocation, velocity*-2, 7); + + sprites.MakeSprite(bloodspritenoup, 1, 1, .2, .2, hitstruct.hitlocation, velocity*-3, 10); + + } + + + + person[whichhit].bjoint1=hitstruct.joint1; + + person[whichhit].bjoint2=hitstruct.joint2; + + person[whichhit].bleeding=1; + + person[whichhit].bleeddelay=1; + + float gLoc[3]; + + gLoc[0]=(camera.position.x+(hitstruct.hitlocation.x-camera.position.x)/4)/soundscalefactor; + + gLoc[1]=(camera.position.y+(hitstruct.hitlocation.y-camera.position.y)/4)/soundscalefactor; + + gLoc[2]=(camera.position.z+(hitstruct.hitlocation.z-camera.position.z)/4)/soundscalefactor; + + if(!hitstruct.joint1->modelnum==headmodel){ + + if(!thirdperson)alSourcef(gSourceID[bodyhitsound], AL_MIN_GAIN, 1); + + if(thirdperson)alSourcef(gSourceID[bodyhitsound], AL_MIN_GAIN, .1); + + alSourcefv(gSourceID[bodyhitsound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[bodyhitsound]); + + } + + if(hitstruct.joint1->modelnum==headmodel){ + + if(!thirdperson)alSourcef(gSourceID[headshotsound], AL_MIN_GAIN, 1); + + if(thirdperson)alSourcef(gSourceID[headshotsound], AL_MIN_GAIN, .1); + + alSourcefv(gSourceID[headshotsound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[headshotsound]); + + } + + }//with wall + + if(oldend==finalwallhit){ + + decals.MakeDecal(bullethole, finalwallhit,.7,hitnorm, hitpoly, model, hitmove, hitrotation); + + XYZ velocity; + + velocity=aim*-4; + + velocity=hitnorm*3; + + if(person[j].whichgun==sniperrifle){ + + sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 10); + + sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 2); + + } + + if(person[j].whichgun==shotgun){ + + sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 5); + + sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, .8); + + } + + if(person[j].whichgun==assaultrifle){ + + sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 6); + + sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 1); + + } + + if(person[j].whichgun==handgun1){ + + sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 6); + + sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 1); + + } + + if(person[j].whichgun==handgun2){ + + sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 6); + + sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 1); + + } + + float gLoc[3]; + + gLoc[0]=finalwallhit.x/soundscalefactor; + + gLoc[1]=finalwallhit.y/soundscalefactor; + + gLoc[2]=finalwallhit.z/soundscalefactor; + + alSourcefv(gSourceID[wallhitsound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[wallhitsound]); + + } + + lastshot[0]=start; + + lastshot[1]=oldend; + + velocity=aim*8; + + if(person[j].whichgun!=sniperrifle&&person[j].whichgun!=shotgun&&p==numshots-1)sprites.MakeSprite(smokesprite, .3, 1, 1, 1, start+aim*1.5, velocity, 3); + + if(person[j].whichgun==shotgun&&p==numshots-1)sprites.MakeSprite(smokesprite, .4, 1, 1, 1, start+aim*1.5, velocity, 5); + + if(person[j].whichgun==sniperrifle&&!zoom)sprites.MakeSprite(smokesprite, .3, 1, 1, 1, start+aim*2.2, velocity, 4); + + if(j!=0||zoom==0)sprites.MakeSprite(bullet, .07, 1, 1, .7, lastshot[0]+aim*1, lastshot[1], .2); + + //Nearby bullet whoosh + + long dot_ta,dot_tb; + + XYZ *a,*b,*c,nearest; + + a=&lastshot[0]; + + *a+=aim*1; + + b=&lastshot[1]; + + c=&camera.position; + + nearest=0; + + dot_ta = (c->x - a->x)*(b->x - a->x) + (c->y - a->y)*(b->y - a->y) + (c->z - a->z)*(b->z - a->z); + + dot_tb = (c->x - b->x)*(a->x - b->x) + (c->y - b->y)*(a->y - b->y) + (c->z - b->z)*(a->z - b->z); + + if (!dot_ta <= 0&&!dot_tb <= 0){ + + + + nearest.x = a->x + ((b->x - a->x) * dot_ta)/(dot_ta + dot_tb); + + nearest.y = a->y + ((b->y - a->y) * dot_ta)/(dot_ta +dot_tb); + + nearest.z = a->z + ((b->z - a->z) * dot_ta)/(dot_ta +dot_tb); + + } + + + + if(nearest.x){ + + if(findDistancefast(nearest,camera.position)<10&&(thirdperson==2||j!=0)){ + + float gLoc[3]; + + + + gLoc[0]=(camera.position.x+(nearest.x-camera.position.x))/soundscalefactor; + + gLoc[1]=(camera.position.y+(nearest.y-camera.position.y))/soundscalefactor; + + gLoc[2]=(camera.position.z+(nearest.z-camera.position.z))/soundscalefactor; + + alSourcefv(gSourceID[nearbulletsound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[nearbulletsound]); + + } + + } + + } + + } + + } + + } + + } + + } + + } + + + + if(!Button())oldbutton=0; + + + + if(lasersight&&person[0].whichgun!=grenade){ + + for(int j=0;j<numpeople;j++){ + + if(person[j].type==playertype){ + + if(person[j].aiming>=1){ + + //Firing + + XYZ end, aim, oldend; + + HitStruct hitstruct,temphitstruct; + + float olddistance; + + float distance; + + int whichhit=-1; + + if(!zoom||j!=0){ + + if(person[j].whichgun==assaultrifle)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position-person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position,0,person[j].playerrotation-2.5,0); + + if(person[j].whichgun==sniperrifle)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position-person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position,0,person[j].playerrotation+4,0); + + if(person[j].whichgun==shotgun)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position-person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position,0,person[j].playerrotation+4,0); + + if(person[j].whichgun==handgun1&&!thirdperson&&j==0)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.65+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.35),0,person[j].playerrotation-.9,0); + + if(person[j].whichgun==handgun1&&(thirdperson||j!=0))aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.35+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.65),0,person[j].playerrotation-.9,0); + + if(person[j].whichgun==handgun2&&!thirdperson&&j==0)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.65+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.35),0,person[j].playerrotation-.9,0); + + if(person[j].whichgun==handgun2&&(thirdperson||j!=0))aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.35+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.65),0,person[j].playerrotation-.9,0); + + } + + if(zoom&&j==0){ + + start=camera.position; + + aim=facing; + + } + + Normalise(&aim); + + if(person[j].whichgun==sniperrifle){ + + start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position,0,person[j].playerrotation,0); + + start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(0-.4); + + } + + if(person[j].whichgun==shotgun){ + + start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position,0,person[j].playerrotation,0); + + start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(0-.4); + + } + + if(person[j].whichgun==handgun1){ + + start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[rightwrist])].position,0,person[j].playerrotation,0); + + start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(.55-.4); + + } + + if(person[j].whichgun==handgun2){ + + start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[rightwrist])].position,0,person[j].playerrotation,0); + + start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(.55-.4); + + } + + if(person[j].whichgun==assaultrifle){ + + start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position,0,person[j].playerrotation,0); + + start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(.25-.4); + + } + + end=start+aim*1000; + + //Blocks + + wallhit=0; + + beginx=(person[j].playercoords.x+block_spacing/2)/block_spacing-2; + + if(beginx<0)beginx=0; + + beginz=(person[j].playercoords.z+block_spacing/2)/block_spacing-2; + + if(beginz<0)beginz=0; + + + + endx=(person[j].playercoords.x+block_spacing/2)/block_spacing+2; + + if(endx>num_blocks-1)endx=num_blocks-1; + + endz=(person[j].playercoords.z+block_spacing/2)/block_spacing+2; + + if(endz>num_blocks-1)endz=num_blocks-1; + + + + if(beginx<endx&&beginz<endz) + + finalwallhit=0; + + for(int i=beginx;i<=endx;i++) + + for(int j=beginz;j<=endz;j++){ + + move=0; + + move.x=i*block_spacing; + + move.z=j*block_spacing; + + whichtri=blocks[citytype[i][j]].LineCheck2(start,end,&wallhit,move,cityrotation[i][j]*90); + + if(whichtri!=-1){ + + end=wallhit; + + finalwallhit=wallhit; + + } + + } + + wallhit=0; + + wallhit.x=camera.position.x; + + wallhit.z=camera.position.z; + + whichtri=Bigstreet.LineCheck2(start,end,&wallhit,wallhit,0); + + if(whichtri!=-1){ + + end=wallhit; + + finalwallhit=wallhit; + + } + + //People + + whichhit=-1; + + for(int i=0;i<numpeople;i++){ + + if(i!=j&&findDistancefast(person[j].playercoords,person[i].playercoords)<20000){ + + temphitstruct=person[i].BulletCollideWithPlayer(i, start, end); + + if(temphitstruct.collision){ + + distance=findDistancefast(start,temphitstruct.hitlocation); + + if(distance<olddistance||whichhit==-1){ + + end=temphitstruct.hitlocation; + + olddistance=distance; + + hitstruct=temphitstruct; + + whichhit=i; + + } + + } + + } + + } + + aimer[0]=start; + + aimer[1]=end; + + sprites.MakeSprite(bulletinstant, .4, 1, 0, 0, aimer[0], aimer[1], .2); + + + + } + + } + + } + + } + + + + //Snow + + snowdelay-=multiplier; + + while(snowdelay<0&&environment==snowy_environment){ + + snowdelay+=1/precipitationdensity*2; + + velocity=0; + + velocity.y=-5; + + start=camera.position; + + start.y+=precipitationvert; + + start.x+=Random()%(int)precipitationhorz; + + start.z+=Random()%(int)precipitationhorz; + + sprites.MakeSprite(snowsprite, 1, 1, 1, 1, start, velocity, 1.01); + + } + + while(snowdelay<0&&environment==rainy_environment){ + + snowdelay+=1/precipitationdensity/4; + + velocity=0; + + velocity.y=-100; + + start=camera.position; + + start.y+=precipitationvert; + + start.x+=Random()%(int)precipitationhorz*.5; + + start.z+=Random()%(int)precipitationhorz*.5; + + sprites.MakeSprite(rainsprite, .5, 1, 1, 1, start, velocity, 2.00); + + } + + + + //Grenade collision + + int wherex,wherey,whichsound,severwhat; + + bool impact; + + for(int i=0;i<sprites.howmanysprites;i++){ + + if(sprites.type[i]==grenadesprite||sprites.type[i]==spoonsprite||sprites.type[i]==pinsprite){ + + impact=0; + + if(sprites.type[i]!=grenadesprite){ + + sprites.brightness[i]-=multiplier*.2; + + } + + + + if(findLengthfast(sprites.velocity[i])>0){ + + wherex=(sprites.location[i].x+block_spacing/2)/block_spacing; + + wherey=(sprites.location[i].z+block_spacing/2)/block_spacing; + + move=0; + + move.x=wherex*block_spacing; + + move.z=wherey*block_spacing; + + whichtri=blocks[citytype[wherex][wherey]].LineCheck2(sprites.oldlocation[i],sprites.location[i],&wallhit,move,cityrotation[wherex][wherey]*90); + + if(whichtri!=-1){ + + impact=1; + + normalrotated=DoRotation(blocks[citytype[wherex][wherey]].normals[whichtri],0,cityrotation[wherex][wherey]*90,0); + + if(sprites.size[i]>1)decals.MakeDecal(crater, wallhit,9,normalrotated, whichtri, &blocks[citytype[wherex][wherey]], move, cityrotation[wherex][wherey]*90); + + sprites.location[i]=wallhit+normalrotated*.02; + + ReflectVector(&sprites.velocity[i],&normalrotated); + + sprites.velocity[i]*=.3; + + if(sprites.type[i]==grenadesprite){ + + float gLoc[3]; + + gLoc[0]=(((sprites.location[i].x)-camera.position.x)/findLengthfast(sprites.velocity[i])*5+camera.position.x)/soundscalefactor; + + gLoc[1]=(((sprites.location[i].y)-camera.position.y)/findLengthfast(sprites.velocity[i])*5+camera.position.y)/soundscalefactor; + + gLoc[2]=(((sprites.location[i].z)-camera.position.z)/findLengthfast(sprites.velocity[i])*5+camera.position.z)/soundscalefactor; + + whichsound=abs(Random()%2); + + alSourcefv(gSourceID[bouncesound+whichsound], AL_POSITION, gLoc); + + if(sprites.size[i]<=1)alSourcePlay(gSourceID[bouncesound+whichsound]); + + } + + if(findLengthfast(sprites.velocity[i])<=10)sprites.velocity[i]=0; + + } + + if(sprites.location[i].y<0){ + + impact=1; + + sprites.velocity[i].y*=-1; + + sprites.velocity[i]*=.3; + + sprites.location[i].y=0; + + if(sprites.type[i]==grenadesprite){ + + if(sprites.size[i]>1){ + + move=0; + + sprites.location[i].y=-.5; + + XYZ normish; + + normish=0; + + normish.y=1; + + decals.MakeDecal(crater, sprites.location[i],9,normish, 0, &blocks[citytype[wherex][wherey]], move, 0); + + } + + float gLoc[3]; + + gLoc[0]=(((sprites.location[i].x)-camera.position.x)/findLengthfast(sprites.velocity[i])*5+camera.position.x)/soundscalefactor; + + gLoc[1]=(((sprites.location[i].y)-camera.position.y)/findLengthfast(sprites.velocity[i])*5+camera.position.y)/soundscalefactor; + + gLoc[2]=(((sprites.location[i].z)-camera.position.z)/findLengthfast(sprites.velocity[i])*5+camera.position.z)/soundscalefactor; + + whichsound=abs(Random()%2); + + alSourcefv(gSourceID[bouncesound+whichsound], AL_POSITION, gLoc); + + if(sprites.size[i]<=1)alSourcePlay(gSourceID[bouncesound+whichsound]); + + } + + if(findLengthfast(sprites.velocity[i])<=10)sprites.velocity[i]=0; + + } + + if(sprites.type[i]==grenadesprite&&findLengthfast(sprites.velocity[i])>20){ + + HitStruct hitstruct; + + for(int j=0;j<numpeople;j++){ + + if((j!=0||sprites.brightness[i]<.9)&&person[j].existing){ + + hitstruct=person[j].BulletCollideWithPlayer(j, sprites.oldlocation[i], sprites.location[i]); + + if(hitstruct.collision){ + + impact=1; + + sprites.location[i]=hitstruct.hitlocation; + + float gLoc[3]; + + gLoc[0]=(((sprites.location[i].x)-camera.position.x)/findLengthfast(sprites.velocity[i])*5+camera.position.x)/soundscalefactor; + + gLoc[1]=(((sprites.location[i].y)-camera.position.y)/findLengthfast(sprites.velocity[i])*5+camera.position.y)/soundscalefactor; + + gLoc[2]=(((sprites.location[i].z)-camera.position.z)/findLengthfast(sprites.velocity[i])*5+camera.position.z)/soundscalefactor; + + if(person[j].skeleton.free<1){ + + if((hitstruct.joint1->label==head||hitstruct.joint2->label==head)&&person[j].type!=zombietype){ + + alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc); + + if(sprites.size[i]<=1)alSourcePlay(gSourceID[headwhacksound]); + + person[j].skeleton.free=1; + + person[j].longdead=1; + + for(int k=0;k<person[j].skeleton.num_joints;k++){ + + person[j].skeleton.joints[k].position=DoRotation(person[j].skeleton.joints[k].position,0,person[j].playerrotation,0); + + person[j].skeleton.joints[k].position+=person[j].playercoords; + + person[j].skeleton.joints[k].realoldposition=person[j].skeleton.joints[k].position; + + person[j].skeleton.joints[k].velocity=person[j].velocity; + + person[j].skeleton.joints[k].velocity.x+=abs(Random()%10)-5; + + person[j].skeleton.joints[k].velocity.y+=abs(Random()%10)-5; + + person[j].skeleton.joints[k].velocity.z+=abs(Random()%10)-5; + + } + + hitstruct.joint1->velocity+=sprites.velocity[i]; + + hitstruct.joint2->velocity+=sprites.velocity[i]; + + if(person[j].type==civiliantype)civkills++; + + if(person[j].type==eviltype)goodkills++; + + }else{ + + float totalarea; + + alSourcefv(gSourceID[bodywhacksound], AL_POSITION, gLoc); + + if(sprites.size[i]<=1)alSourcePlay(gSourceID[bodywhacksound]); + + person[j].skeleton.offset=1; + + for(int k=0;k<person[j].skeleton.num_joints;k++){ + + if(findDistancefast(DoRotation(person[j].skeleton.joints[k].position,0,person[j].playerrotation,0)+person[j].playercoords,hitstruct.hitlocation)<200){ + + totalarea+=(200/findDistancefast(DoRotation(person[j].skeleton.joints[k].position,0,person[j].playerrotation,0)+person[j].playercoords,hitstruct.hitlocation)); + + } + + } + + float offsetlength; + + for(int k=0;k<person[j].skeleton.num_joints;k++){ + + if(findDistancefast(DoRotation(person[j].skeleton.joints[k].position,0,person[j].playerrotation,0)+person[j].playercoords,hitstruct.hitlocation)<200){ + + person[j].skeleton.joints[k].offset+=DoRotation(sprites.velocity[i]*.1*((200/findDistancefast(DoRotation(person[j].skeleton.joints[k].position,0,person[j].playerrotation,0)+person[j].playercoords,hitstruct.hitlocation))/totalarea*10),0,-person[j].playerrotation,0); + + } + + offsetlength=findLengthfast(person[j].skeleton.joints[k].offset); + + if(offsetlength>9){ + + Normalise(&person[j].skeleton.joints[k].offset); + + person[j].skeleton.joints[k].offset*=3; + + } + + } + + }} + + sprites.velocity[i]*=-.3; + + } + + } + + } + + } + + sprites.oldlocation[i]=sprites.location[i]; + + } + + //Explode + + if(sprites.type[i]==grenadesprite){ + + sprites.brightness[i]-=multiplier*.3; + + if(sprites.brightness[i]<=0||(impact&&sprites.size[i]>1)){ + + sprites.brightness[i]=0; + + sprites.MakeSprite(smokesprite, 1, 1, 1, 1, sprites.location[i], facing*0, 60); + + sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, sprites.location[i], facing*0, 9); + + float gLoc[3]; + + gLoc[0]=(((sprites.location[i].x)-camera.position.x)/3+camera.position.x)/soundscalefactor; + + gLoc[1]=(((sprites.location[i].y)-camera.position.y)/3+camera.position.y)/soundscalefactor; + + gLoc[2]=(((sprites.location[i].z)-camera.position.z)/3+camera.position.z)/soundscalefactor; + + alSourcefv(gSourceID[explosionsound], AL_POSITION, gLoc); + + alSourcePlay(gSourceID[explosionsound]); + + XYZ relation; + + camerashake=1-findDistance(person[0].playercoords,sprites.location[i])/200; + + //if(!sprites.size[i]>1){ + + overpoint=sprites.location[i]; + + overpoint.y+=3000; + + underpoint=sprites.location[i]; + + underpoint.y-=3000; + + move=0; + + wherex=(sprites.location[i].x+block_spacing/2)/block_spacing; + + wherey=(sprites.location[i].z+block_spacing/2)/block_spacing; + + move.x=wherex*block_spacing; + + move.z=wherey*block_spacing; + + XYZ temp; + + whichtri=sidewalkcollide.LineCheck2(overpoint,underpoint,&temp,move,cityrotation[wherex][wherey]*90); + + XYZ normish; + + normish=0; + + normish.y=1; + + if(whichtri>=0){ + + decals.MakeDecal(crater, sprites.location[i],9,normish, 0, &sidewalkcollide, move, cityrotation[wherex][wherey]*90); + + } + + if(whichtri==-1){ + + temp=sprites.location[i]; + + temp.y=-.5; + + move=0; + + decals.MakeDecal(crater, sprites.location[i],9,normish, 0, &sidewalkcollide, move, 0); + + } + + //} + + for(int k=0;k<numpeople;k++){ + + if(person[k].existing&&(person[k].longdead!=-1||person[k].skeleton.free<1)){ + + if((findDistancefast(person[k].playercoords,sprites.location[i])<700&&person[k].skeleton.free<1)||(findDistancefast(person[k].averageloc,sprites.location[i])<700&&person[k].skeleton.free>=1)){ + + if(person[k].skeleton.free!=1){ + + if(person[k].type==civiliantype)civkills++; + + if(person[k].type==eviltype)goodkills++; + + person[k].skeleton.free=1; + + person[k].killtargetvisible=0; + + if((findDistancefast(person[k].playercoords,sprites.location[i])<600&&person[k].skeleton.free<1)||(findDistancefast(person[k].averageloc,sprites.location[i])<600&&person[k].skeleton.free>=1)||person[k].type==playertype){ + + person[k].health-=100; + + person[k].bleeding=1; + + } + + person[k].DoAnimations(k); + + person[k].longdead=1; + + + + person[k].bleeddelay=1; + + person[k].bjoint1=&person[k].skeleton.joints[person[k].skeleton.jointlabels[head]]; + + person[k].bjoint2=&person[k].skeleton.joints[person[k].skeleton.jointlabels[neck]]; + + + + + + for(int j=0;j<person[k].skeleton.num_joints;j++){ + + person[k].skeleton.joints[j].position=DoRotation(person[k].skeleton.joints[j].position,0,person[k].playerrotation,0); + + person[k].skeleton.joints[j].position+=person[k].playercoords; + + person[k].skeleton.joints[j].realoldposition=person[k].skeleton.joints[j].position; + + person[k].skeleton.joints[j].velocity=DoRotation(person[k].skeleton.joints[j].velocity,0,person[k].playerrotation,0); + + person[k].skeleton.joints[j].velocity+=person[k].velocity; + + person[k].skeleton.joints[j].velocity.x+=abs(Random()%20)-10; + + person[k].skeleton.joints[j].velocity.y+=abs(Random()%20)-10; + + person[k].skeleton.joints[j].velocity.z+=abs(Random()%20)-10; + + }} + + for(int j=0;j<person[k].skeleton.num_joints;j++){ + + relation=person[k].skeleton.joints[j].position-sprites.location[i]; + + Normalise(&relation); + + if(findDistance(person[k].skeleton.joints[j].position,sprites.location[i])>1)person[k].skeleton.joints[j].velocity+=relation/findDistance(person[k].skeleton.joints[j].position,sprites.location[i])*300; + + else person[k].skeleton.joints[j].velocity+=relation*300; + + } + + person[k].longdead=1; + + for(int j=0;j<person[k].skeleton.num_joints;j++){ + + //Sever stuff + + if(findLengthfast(person[k].skeleton.joints[j].velocity)>1500&&person[k].skeleton.joints[j].existing==1&&abs(Random()%3)!=1){ + + sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[k].skeleton.joints[j].position, person[k].skeleton.joints[j].velocity/3, 9); + + person[k].skeleton.DeleteJoint(j); + + person[k].skeleton.broken=2; + + person[k].health=-10000; + + person[k].skeleton.joints[j].existing=0; + + } + + } + + } + + } + + } + + + + } + + } + + } + + } + + + + //camera shake + + camerashake-=multiplier; + + if(camerashake<0)camerashake=0; + + + + //camera position + + XYZ average; + + if(!zoom)average=person[0].skeleton.joints[(person[0].skeleton.jointlabels[head])].position*(person[0].aimamount/2+.5)+person[0].skeleton.joints[(person[0].skeleton.jointlabels[neck])].position*((1-person[0].aimamount)/2); + + if(zoom)average=person[0].skeleton.joints[(person[0].skeleton.jointlabels[righthand])].position; + + + + if(person[0].skeleton.free==0&&thirdperson!=2)camera.position=person[0].playercoords+DoRotation(average,0,person[0].playerrotation,0); + + if(person[0].skeleton.free==1&&thirdperson!=2)camera.position=average; + + + + //Restraints + + if(camera.position.y<.1)camera.position.y=.1; + + + + if(thirdperson!=2){ + + oldrot=camera.visrotation; + + oldrot2=camera.visrotation2; + + } + + + + //Kill count + + for(int i=0;i<numpeople;i++){ + + if(person[i].oldhealth>0&&person[i].health<=0){ + + if(i==1)alSourcePlay(gSourceID[losesound]); + + if(person[i].type==civiliantype){ + + alSourcePlay(gSourceID[disguisekillsound]); + + score-=300; + + } + + if(person[i].type==eviltype){ + + alSourcePlay(gSourceID[soulinsound]); + + score+=75; + + if(person[i].whichgun==knife)score+=50; + + } + + person[i].firstlongdead=0; + + } + + person[i].oldhealth=person[i].health; + + } + + + + if(slomo==2){ + + psychicpower-=multiplier*15; + + if(psychicpower<0){ + + soundscalefactor=soundscalefactordefault; + + alSourceStop(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0); + + alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0); + + if(person[0].whichgun==knife)whichsong=knifesong; + + if(person[0].whichgun!=knife)whichsong=shootsong; + + if(type==zombie_type)whichsong=zombiesong; + + alSourcef(gSourceID[whichsong], AL_PITCH, 1); + + alSourcePlay(gSourceID[whichsong]); + + alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1); + + alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1); + + slomo=0; + + alSourcePlay(gSourceID[soulinsound]); + + psychicpower=0; + + flashamount=.5; + + flashr=1;flashg=1;flashb=1; + + } + + } + + psychicpower+=multiplier*5; + + if(psychicpower>10)psychicpower=10; + + + + //3d sound + + ALint tempInt; + + float gLoc[3]; + + gLoc[0]=camera.position.x/soundscalefactor; + + gLoc[1]=camera.position.y/soundscalefactor; + + gLoc[2]=camera.position.z/soundscalefactor; + + //Set listener position + + alListenerfv(AL_POSITION, gLoc); + + + + //Set orientation with forward and up vectors + + XYZ upvector; + + upvector=0; + + upvector.z=-1; + + + + upvector=DoRotation(upvector,-camera.rotation2+90,0,0); + + upvector=DoRotation(upvector,0,0-camera.rotation,0); + + + + float ori[6]; + + ori[0] = -facing.x; + + ori[1] = facing.y; + + ori[2] = facing.z; + + ori[3] = -upvector.x; + + ori[4] = upvector.y; + + ori[5] = upvector.z; + + alListenerfv(AL_ORIENTATION, ori); + + + + if(person[0].currentanimation==throwanim||person[0].currentanimation==diveanim||paused){ + + MoveMouse(oldmouseloc.h,oldmouseloc.v,&mouseloc); + + GetMouse(&mouseloc); + + } + + oldmouseloc=mouseloc; + + + + if(score<0)score=0; + + } + +} diff --git a/src/Globals.cpp b/src/Globals.cpp new file mode 100644 index 0000000..fa18cfe --- /dev/null +++ b/src/Globals.cpp @@ -0,0 +1,89 @@ +#include "Quaternions.h" +#include "Constants.h" +#include "Models.h" +#include "Person.h" +#include "Game.h" + +float sinefluct; +float sinefluctprog; + +double multiplier=0; + +unsigned int gSourceID[100]; // hundred source IDs +unsigned int gSampleSet[100]; // hundred sample set ID numbers + +float precipitationhorz; +float precipitationvert; +float precipitationdensity; + +int environment; + +float soundscalefactor; +int slomo; + +Animation animation[30]; +Model skeletonmodels[10]; +Model gunmodels[11]; +Costume costume[10]; +Sprites sprites; +Decals decals; +int thirdperson; +int nocolors; +int visions; +Camera camera; +float rad2deg; +Skeleton testskeleton; + +float snowdelay; + +float camerashake; + +Fog fog; + +int forwardskey; +int backwardskey; +int leftkey; +int rightkey; +int aimkey; +int psychicaimkey; +int psychickey; + +bool blood; + +float fogcolorr; +float fogcolorg; +float fogcolorb; + +float d; +float a1,a2,a3; +float total,denom,mu; +XYZ n,pa1,pa2,pa3; + +float u0, u1, u2; +float v0, v1, v2; +float a, b; +int i, j; +bool bInter; +float pointv[3]; +float p1v[3]; +float p2v[3]; +float p3v[3]; +float normalv[3]; + +XYZ vel; +XYZ midp; +XYZ newpoint1,newpoint2; + +float oldlength; +float relaxlength; + +float friction; +int numrepeats; +float groundlevel; +float offset; +XYZ impact; +XYZ overpoint; +XYZ underpoint; +int whichtri; +XYZ normalrotated; +bool groundish; diff --git a/src/MacInput.cpp b/src/MacInput.cpp new file mode 100644 index 0000000..512200d --- /dev/null +++ b/src/MacInput.cpp @@ -0,0 +1,46 @@ +/**> HEADER FILES <**/ +#include "MacInput.h" + +/**> Mouse Stuff <**/ +#ifdef OS9 +CursorDevicePtr theCursor; +#endif + +/********************> IsKeyDown() <*****/ +Boolean IsKeyDown( unsigned char *keyMap, unsigned short theKey ) +{ + long keyMapIndex; + Boolean isKeyDown; + short bitToCheck; + + // Calculate the key map index + keyMapIndex = keyMap[theKey/8]; + + // Calculate the individual bit to check + bitToCheck = theKey%8; + + // Check the status of the key + isKeyDown = ( keyMapIndex >> bitToCheck ) & 0x01; + + // Return the status of the key + return isKeyDown; + +} + +#ifdef OS9 +void InitMouse() +{ + CursorDeviceNewDevice( &theCursor ); //Mouse +} + +void MoveMouse(int xcoord, int ycoord, Point *mouseloc) +{ + CursorDeviceMoveTo( theCursor, xcoord, ycoord); + GetMouse(mouseloc); +} + +void DisposeMouse() +{ + CursorDeviceDisposeDevice( theCursor );//Mouse +} +#endif diff --git a/src/MacInput.h b/src/MacInput.h new file mode 100644 index 0000000..0c741aa --- /dev/null +++ b/src/MacInput.h @@ -0,0 +1,105 @@ +#ifndef _MACINPUT_H_ +#define _MACINPUT_H_ + +/**> HEADER FILES <**/ +#include <stdlib.h> +#include <stdio.h> +#ifdef OS9 +#include <CursorDevices.h> //Mouse +#endif + +#include "Support.h" + +/**> CONSTANT DECLARATIONS <**/ +// Mac Keyboard Codes +#define MAC_1_KEY 0x12 +#define MAC_2_KEY 0x13 +#define MAC_3_KEY 0x14 +#define MAC_4_KEY 0x15 +#define MAC_5_KEY 0x17 +#define MAC_6_KEY 0x16 +#define MAC_7_KEY 0x1A +#define MAC_8_KEY 0x1C +#define MAC_9_KEY 0x19 +#define MAC_0_KEY 0x1D +#define MAC_NUMPAD_1_KEY 0x53 +#define MAC_NUMPAD_2_KEY 0x54 +#define MAC_NUMPAD_3_KEY 0x55 +#define MAC_NUMPAD_4_KEY 0x56 +#define MAC_NUMPAD_5_KEY 0x57 +#define MAC_NUMPAD_6_KEY 0x58 +#define MAC_NUMPAD_7_KEY 0x59 +#define MAC_NUMPAD_8_KEY 0x5B +#define MAC_NUMPAD_9_KEY 0x5C +#define MAC_NUMPAD_0_KEY 0x52 +#define MAC_A_KEY 0x00 +#define MAC_B_KEY 0x0B +#define MAC_C_KEY 0x08 +#define MAC_D_KEY 0x02 +#define MAC_E_KEY 0x0E +#define MAC_F_KEY 0x03 +#define MAC_G_KEY 0x05 +#define MAC_H_KEY 0x04 +#define MAC_I_KEY 0x22 +#define MAC_J_KEY 0x26 +#define MAC_K_KEY 0x28 +#define MAC_L_KEY 0x25 +#define MAC_M_KEY 0x2E +#define MAC_N_KEY 0x2D +#define MAC_O_KEY 0x1F +#define MAC_P_KEY 0x23 +#define MAC_Q_KEY 0x0C +#define MAC_R_KEY 0x0F +#define MAC_S_KEY 0x01 +#define MAC_T_KEY 0x11 +#define MAC_U_KEY 0x20 +#define MAC_V_KEY 0x09 +#define MAC_W_KEY 0x0D +#define MAC_X_KEY 0x07 +#define MAC_Y_KEY 0x10 +#define MAC_Z_KEY 0x06 +#define MAC_F1_KEY 0x7A +#define MAC_F2_KEY 0x78 +#define MAC_F3_KEY 0x63 +#define MAC_F4_KEY 0x76 +#define MAC_F5_KEY 0x60 +#define MAC_F6_KEY 0x61 +#define MAC_F7_KEY 0x62 +#define MAC_F8_KEY 0x64 +#define MAC_F9_KEY 0x65 +#define MAC_F10_KEY 0x6D +#define MAC_F11_KEY 0x67 +#define MAC_F12_KEY 0x6F +#define MAC_RETURN_KEY 0x24 +#define MAC_ENTER_KEY 0x4C +#define MAC_TAB_KEY 0x30 +#define MAC_SPACE_KEY 0x31 +#define MAC_DELETE_KEY 0x33 +#define MAC_ESCAPE_KEY 0x35 +#define MAC_COMMAND_KEY 0x37 +#define MAC_SHIFT_KEY 0x38 +#define MAC_CAPS_LOCK_KEY 0x39 +#define MAC_OPTION_KEY 0x3A +#define MAC_CONTROL_KEY 0x3B +#define MAC_PAGE_UP_KEY 0x74 +#define MAC_PAGE_DOWN_KEY 0x79 +#define MAC_INSERT_KEY 0x72 +#define MAC_DEL_KEY 0x75 +#define MAC_HOME_KEY 0x73 +#define MAC_END_KEY 0x77 +#define MAC_LEFT_BRACKET_KEY 0x21 +#define MAC_RIGHT_BRACKET_KEY 0x1E +#define MAC_ARROW_UP_KEY 0x7E +#define MAC_ARROW_DOWN_KEY 0x7D +#define MAC_ARROW_LEFT_KEY 0x7B +#define MAC_ARROW_RIGHT_KEY 0x7C + + +/**> FUNCTION PROTOTYPES <**/ +Boolean IsKeyDown( unsigned char *keyMap, unsigned short theKey ); +void InitMouse(); +void MoveMouse(int xcoord, int ycoord, Point *mouseloc); +void RefreshMouse(Point *mouseloc); +void DisposeMouse(); + +#endif diff --git a/src/Main.cpp b/src/Main.cpp new file mode 100644 index 0000000..2c8f381 --- /dev/null +++ b/src/Main.cpp @@ -0,0 +1,64 @@ +/********************> Headers <*****/ + +#include "Game.h" + + + +/********************> Globals <*****/ + + + +Game game; + + + +/********************> main() <*****/ + +int main( int argc, char *argv[] ) + + { + + +#ifdef OS9 + ToolboxInit(); + + + + if ( HasAppearance() ) + + RegisterAppearanceClient(); +#endif + + + + + game.InitGL(); + + + + game.InitGame(); + + + + game.EventLoop(); + + + + game.Dispose(); + + +#ifdef OS9 + if ( HasAppearance() ) + + UnregisterAppearanceClient(); + + + + FlushEvents( everyEvent, 0 ); + + ExitToShell(); +#endif + + +} + diff --git a/src/Maths.cpp b/src/Maths.cpp new file mode 100644 index 0000000..58e769a --- /dev/null +++ b/src/Maths.cpp @@ -0,0 +1,24 @@ +/**> HEADER FILES <**/ +#include "Maths.h" + +double fast_sqrt (register double arg) +{ +#ifdef OS9 + // Can replace with slower return std::sqrt(arg); + register double result; + + if (arg == 0.0) return 0.0; + + asm { + frsqrte result,arg // Calculate Square root + } + + // Newton Rhapson iterations. + result = result + 0.5 * result * (1.0 - arg * result * result); + result = result + 0.5 * result * (1.0 - arg * result * result); + + return result * arg; +#else + return sqrt(arg); +#endif +} diff --git a/src/Maths.h b/src/Maths.h new file mode 100644 index 0000000..d9a8f61 --- /dev/null +++ b/src/Maths.h @@ -0,0 +1,11 @@ +#ifndef _MATHS_H_ +#define _MATHS_H_ + + +/**> HEADER FILES <**/ +#include <cmath> + +double fast_sqrt (register double arg); + +#endif + diff --git a/src/Models.cpp b/src/Models.cpp new file mode 100644 index 0000000..8caefd8 --- /dev/null +++ b/src/Models.cpp @@ -0,0 +1,341 @@ +#include "Models.h" + +#include "Serialize.h" + +//Functions +void Model::UpdateVertexArray(){ + int i; + for(i=0;i<TriangleNum;i++){ + vArray[i*27+0]=vertex[Triangles[i].vertex[0]].x; + vArray[i*27+1]=vertex[Triangles[i].vertex[0]].y; + vArray[i*27+2]=vertex[Triangles[i].vertex[0]].z; + vArray[i*27+3]=normals[i].x; + vArray[i*27+4]=normals[i].y; + vArray[i*27+5]=normals[i].z; + vArray[i*27+6]=Triangles[i].r; + vArray[i*27+7]=Triangles[i].g; + vArray[i*27+8]=Triangles[i].b; + + vArray[i*27+9]=vertex[Triangles[i].vertex[1]].x; + vArray[i*27+10]=vertex[Triangles[i].vertex[1]].y; + vArray[i*27+11]=vertex[Triangles[i].vertex[1]].z; + vArray[i*27+12]=normals[i].x; + vArray[i*27+13]=normals[i].y; + vArray[i*27+14]=normals[i].z; + vArray[i*27+15]=Triangles[i].r; + vArray[i*27+16]=Triangles[i].g; + vArray[i*27+17]=Triangles[i].b; + + vArray[i*27+18]=vertex[Triangles[i].vertex[2]].x; + vArray[i*27+19]=vertex[Triangles[i].vertex[2]].y; + vArray[i*27+20]=vertex[Triangles[i].vertex[2]].z; + vArray[i*27+21]=normals[i].x; + vArray[i*27+22]=normals[i].y; + vArray[i*27+23]=normals[i].z; + vArray[i*27+24]=Triangles[i].r; + vArray[i*27+25]=Triangles[i].g; + vArray[i*27+26]=Triangles[i].b; + } + + XYZ average; + int howmany; + average=0; + howmany=0; + boundingboxmin=20000; + boundingboxmax=-20000; + for(int i=0;i<vertexNum;i++){ + howmany++; + average=average+vertex[i]; + if(vertex[i].x<boundingboxmin.x)boundingboxmin.x=vertex[i].x; + if(vertex[i].y<boundingboxmin.y)boundingboxmin.y=vertex[i].y; + if(vertex[i].z<boundingboxmin.z)boundingboxmin.z=vertex[i].z; + if(vertex[i].x>boundingboxmax.x)boundingboxmax.x=vertex[i].x; + if(vertex[i].y>boundingboxmax.y)boundingboxmax.y=vertex[i].y; + if(vertex[i].z>boundingboxmax.z)boundingboxmax.z=vertex[i].z; + } + average=average/howmany; + boundingspherecenter=average; + boundingsphereradius=0; + for(int i=0;i<vertexNum;i++){ + if(findDistancefast(average,vertex[i])>boundingsphereradius)boundingsphereradius=findDistancefast(average,vertex[i]); + } + boundingsphereradius=fast_sqrt(boundingsphereradius); +} + +bool Model::load(Str255 Name) +{ + short tfile; + long err; + Files file; + + tfile=file.OpenFile(Name); + SetFPos(tfile,fsFromStart,0); + + // read model settings + + err=ReadShort(tfile,1,&vertexNum); + err=ReadShort(tfile,1,&TriangleNum); + + // read the model data + + err=ReadXYZ(tfile,vertexNum,vertex); + err=ReadTexturedTriangle(tfile,TriangleNum,Triangles); + + FSClose(tfile); + + UpdateVertexArray(); + + XYZ average; + int howmany; + average=0; + howmany=0; + for(int i=0;i<vertexNum;i++){ + howmany++; + average=average+vertex[i]; + } + average=average/howmany; + boundingspherecenter=average; + boundingsphereradius=0; + for(int i=0;i<vertexNum;i++){ + if(findDistancefast(average,vertex[i])>boundingsphereradius)boundingsphereradius=findDistancefast(average,vertex[i]); + } + boundingsphereradius=fast_sqrt(boundingsphereradius); + + return 1; +} + +void Model::Scale(float xscale,float yscale,float zscale) +{ + int i; + for(i=0; i<vertexNum; i++){ + vertex[i].x*=xscale; + vertex[i].y*=yscale; + vertex[i].z*=zscale; + } + UpdateVertexArray(); +} + +void Model::MultColor(float howmuch) +{ + int i; + for(i=0; i<TriangleNum; i++){ + Triangles[i].r*=howmuch; + Triangles[i].g*=howmuch; + Triangles[i].b*=howmuch; + } + UpdateVertexArray(); +} + +void Model::ScaleNormals(float xscale,float yscale,float zscale) +{ + int i; + for(i=0; i<vertexNum; i++){ + normals[i].x*=xscale; + normals[i].y*=yscale; + normals[i].z*=zscale; + } + UpdateVertexArray(); +} + +void Model::Translate(float xtrans,float ytrans,float ztrans) +{ + int i; + for(i=0; i<vertexNum; i++){ + vertex[i].x+=xtrans; + vertex[i].y+=ytrans; + vertex[i].z+=ztrans; + } + UpdateVertexArray(); +} + +void Model::Rotate(float xang,float yang,float zang) +{ + int i; + for(i=0; i<vertexNum; i++){ + vertex[i]=DoRotation(vertex[i],xang,yang,zang); + } + UpdateVertexArray(); +} + + +void Model::CalculateNormals() +{ + int i; + for(i=0;i<TriangleNum;i++){ + CrossProduct(vertex[Triangles[i].vertex[1]]-vertex[Triangles[i].vertex[0]],vertex[Triangles[i].vertex[2]]-vertex[Triangles[i].vertex[0]],&normals[i]); + Normalise(&normals[i]); + } + UpdateVertexArray(); +} + +extern int nocolors; +void Model::draw() +{ + if(!nocolors){ + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0]); + glNormalPointer(GL_FLOAT, 9*sizeof(GLfloat),&vArray[3]); + glColorPointer(3,GL_FLOAT, 9*sizeof(GLfloat),&vArray[6]); + glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3); + } + if(nocolors){ + glColor4f(0,0,0,1); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0]); + glNormalPointer(GL_FLOAT, 9*sizeof(GLfloat),&vArray[3]); + glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3); + } +} + + +void Model::draw(float r, float g, float b) +{ + if(!nocolors)glColor4f(r,g,b,1); + if(nocolors==1)glColor4f(0,0,0,1); + if(nocolors==2)glColor4f(1,0,0,1); + if(nocolors==3)glColor4f(0,0,1,1); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0]); + glNormalPointer(GL_FLOAT, 9*sizeof(GLfloat),&vArray[3]); + glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3); +} + +void Model::draw(float r, float g, float b, float o) +{ + if(!nocolors)glColor4f(r,g,b,o); + if(nocolors==1)glColor4f(0,0,0,1); + if(nocolors==2)glColor4f(1,0,0,1); + if(nocolors==3)glColor4f(1,1,1,1); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0]); + glNormalPointer(GL_FLOAT, 9*sizeof(GLfloat),&vArray[3]); + glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3); +} + +void Model::draw(float r, float g, float b, float x, float y, float z) +{ + if(!nocolors)glColor4f(r,g,b,1); + if(nocolors==1)glColor4f(0,0,0,1); + if(nocolors==2)glColor4f(1,0,0,1); + if(nocolors==3)glColor4f(1,1,1,1); + glNormal3f(x,y,z); + glEnableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0]); + glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3); +} + + +int Model::LineCheck(XYZ p1,XYZ p2, XYZ *p) +{ + int j; + float distance; + float olddistance=9999999.0; + int intersecting=0; + int firstintersecting=-1; + XYZ point; + if(sphere_line_intersection(p1.x,p1.y,p1.z, + p2.x,p2.y,p2.z, + boundingspherecenter.x,boundingspherecenter.y,boundingspherecenter.z, + boundingsphereradius)) + for (j=0;j<TriangleNum;j++){ + intersecting=LineFacetd(p1,p2,vertex[Triangles[j].vertex[0]],vertex[Triangles[j].vertex[1]],vertex[Triangles[j].vertex[2]],normals[j],&point); + if (intersecting == 0) continue; + distance=(point.x-p1.x)*(point.x-p1.x)+(point.y-p1.y)*(point.y-p1.y)+(point.z-p1.z)*(point.z-p1.z); + if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;} + } + return firstintersecting; +} + +int Model::LineCheck2(XYZ p1,XYZ p2, XYZ *p, XYZ move, float rotate) +{ + int j; + float distance; + float olddistance=9999999.0; + int intersecting=0; + int firstintersecting=-1; + XYZ point; + p1=p1-move; + p2=p2-move; + if(rotate)p1=DoRotation(p1,0,-rotate,0); + if(rotate)p2=DoRotation(p2,0,-rotate,0); + if(sphere_line_intersection(p1.x,p1.y,p1.z, + p2.x,p2.y,p2.z, + boundingspherecenter.x,boundingspherecenter.y,boundingspherecenter.z, + boundingsphereradius)) + for (j=0;j<TriangleNum;j++){ + intersecting=LineFacetd(p1,p2,vertex[Triangles[j].vertex[0]],vertex[Triangles[j].vertex[1]],vertex[Triangles[j].vertex[2]],normals[j],&point); + if (intersecting == 0) continue; + distance=(point.x-p1.x)*(point.x-p1.x)+(point.y-p1.y)*(point.y-p1.y)+(point.z-p1.z)*(point.z-p1.z); + if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;} + } + + if(rotate)*p=DoRotation(*p,0,rotate,0); + *p=*p+move; + return firstintersecting; +} + +int Model::LineCheck2(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate) +{ + int j; + float distance; + float olddistance=9999999.0; + int intersecting=0; + int firstintersecting=-1; + XYZ point; + *p1=*p1-*move; + *p2=*p2-*move; + if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0); + if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0); + if(sphere_line_intersection(p1->x,p1->y,p1->z, + p2->x,p2->y,p2->z, + boundingspherecenter.x,boundingspherecenter.y,boundingspherecenter.z, + boundingsphereradius)) + for (j=0;j<TriangleNum;j++){ + intersecting=LineFacetd(p1,p2,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&normals[j],&point); + if (intersecting == 0) continue; + distance=(point.x-p1->x)*(point.x-p1->x)+(point.y-p1->y)*(point.y-p1->y)+(point.z-p1->z)*(point.z-p1->z); + if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;} + } + + if(*rotate)*p=DoRotation(*p,0,*rotate,0); + *p=*p+*move; + return firstintersecting; +} + +int Model::LineCheck3(XYZ p1,XYZ p2, XYZ *p, XYZ move, float rotate, float *d) +{ + int j; + float distance; + float olddistance=9999999.0; + int intersecting=0; + int firstintersecting=-1; + XYZ point; + p1=p1-move; + p2=p2-move; + p1=DoRotation(p1,0,-rotate,0); + p2=DoRotation(p2,0,-rotate,0); + if(sphere_line_intersection(p1.x,p1.y,p1.z, + p2.x,p2.y,p2.z, + boundingspherecenter.x,boundingspherecenter.y,boundingspherecenter.z, + boundingsphereradius)) + for (j=0;j<TriangleNum;j++){ + intersecting=LineFacetd(p1,p2,vertex[Triangles[j].vertex[0]],vertex[Triangles[j].vertex[1]],vertex[Triangles[j].vertex[2]],normals[j],&point); + if (intersecting == 0) continue; + distance=(point.x-p1.x)*(point.x-p1.x)+(point.y-p1.y)*(point.y-p1.y)+(point.z-p1.z)*(point.z-p1.z); + if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;} + } + *d=intersecting; + *p=DoRotation(*p,0,rotate,0); + *p=*p+move; + return firstintersecting; +} diff --git a/src/Models.h b/src/Models.h new file mode 100644 index 0000000..e49b8f1 --- /dev/null +++ b/src/Models.h @@ -0,0 +1,66 @@ +#ifndef _MODELS_H_ +#define _MODELS_H_ + +/**> Model Loading <**/ +// +// Model Maximums +// +#include "Quaternions.h" +#ifdef OS9 +#include <gl.h> +#include <glu.h> +#else +#include <GL/gl.h> +#include <GL/glu.h> +#endif +#include "Files.h" +#include "Constants.h" + +#define max_textured_triangle 400 // maximum number of texture-filled triangles in a model +#define max_model_vertex max_textured_triangle*3 // maximum number of vertexs + + +// +// Model Structures +// + +class TexturedTriangle{ + public: + short vertex[3]; + float r,g,b; +}; + +class Model{ + public: + short vertexNum,TriangleNum; + + XYZ vertex[max_model_vertex]; + XYZ normals[max_textured_triangle]; + TexturedTriangle Triangles[max_textured_triangle]; + GLfloat vArray[max_textured_triangle*27]; + + XYZ boundingspherecenter; + float boundingsphereradius; + int LineCheck(XYZ p1,XYZ p2, XYZ *p); + int LineCheck2(XYZ p1,XYZ p2, XYZ *p,XYZ move,float rotate); + int LineCheck2(XYZ *p1,XYZ *p2, XYZ *p,XYZ *move,float *rotate); + int LineCheck3(XYZ p1,XYZ p2, XYZ *p,XYZ move,float rotate,float *d); + + void UpdateVertexArray(); + bool load(Str255 Name); + void Scale(float xscale,float yscale,float zscale); + void ScaleNormals(float xscale,float yscale,float zscale); + void Translate(float xtrans,float ytrans,float ztrans); + void CalculateNormals(); + void draw(); + void draw(float r,float g,float b); + void draw(float r,float g,float b, float o); + void draw(float r,float g,float b, float x, float y, float z); + void Rotate(float xang,float yang,float zang); + void MultColor(float howmuch); + + XYZ boundingboxmin,boundingboxmax; +}; + +#endif + diff --git a/src/Person.cpp b/src/Person.cpp new file mode 100644 index 0000000..43aa873 --- /dev/null +++ b/src/Person.cpp @@ -0,0 +1,1045 @@ +/**> HEADER FILES <**/ +#include "Person.h" + +extern double multiplier; +extern unsigned int gSourceID[100]; +extern unsigned int gSampleSet[100]; +extern Animation animation[30]; +extern int thirdperson; +extern int visions; +extern Camera camera; +extern float rad2deg; +extern Model gunmodels[10]; +extern Model skeletonmodels[10]; +extern Sprites sprites; +extern float soundscalefactor; +extern int slomo; + +extern int forwardskey; +extern int backwardskey; +extern int leftkey; +extern int rightkey; +extern int aimkey; +extern int psychicaimkey; +extern int psychickey; + +HitStruct Person::BulletCollideWithPlayer(int who, XYZ start, XYZ end){ + float damage=20; + XYZ tempbulletloc[2]; + XYZ collisionpoint; + XYZ sparkpos; + GLfloat M[16]; + int collide; + float howfar; + XYZ average; + XYZ facing; + int howmany; + float distancemax; + HitStruct hitstruct; + hitstruct.collision=0; + //Make bounding sphere + average=0; + howmany=0; + for(int j=0;j<skeleton.num_joints;j++){ + average.x=average.x+skeleton.joints[j].position.x; + average.y=average.y+skeleton.joints[j].position.y; + average.z=average.z+skeleton.joints[j].position.z; + howmany++; + } + average=average/howmany; + distancemax=0; + for(int j=0;j<skeleton.num_joints;j++){ + if(findDistancefast(average,skeleton.joints[j].position)>distancemax){ + distancemax=findDistancefast(average,skeleton.joints[j].position); + } + } + distancemax=fast_sqrt(distancemax); + //Collide with player + if(skeleton.free<1){ + start=start-playercoords; + end=end-playercoords; + if(playerrotation)start=DoRotation(start,0,-playerrotation,0); + if(playerrotation)end=DoRotation(end,0,-playerrotation,0); + } + tempbulletloc[0]=start; + tempbulletloc[1]=end; + if(sphere_line_intersection(tempbulletloc[0].x,tempbulletloc[0].y,tempbulletloc[0].z, + tempbulletloc[1].x,tempbulletloc[1].y,tempbulletloc[1].z, + average.x, average.y, average.z, distancemax)){ + for(int j=0;j<skeleton.num_joints;j++){ + if(skeleton.joints[j].hasparent&&skeleton.joints[j].visible){ + tempbulletloc[0]=start; + tempbulletloc[1]=end; + glPushMatrix(); + glLoadIdentity(); + glScalef(1,1/skeleton.joints[j].length,1); + glRotatef(skeleton.joints[j].rotate2-90,0,0,1); + glRotatef(skeleton.joints[j].rotate1-90,0,1,0); + glTranslatef( (-(skeleton.joints[j].position.x+skeleton.joints[j].parent->position.x)/2), + (-(skeleton.joints[j].position.y+skeleton.joints[j].parent->position.y)/2), + (-(skeleton.joints[j].position.z+skeleton.joints[j].parent->position.z)/2)); + glTranslatef(tempbulletloc[0].x,tempbulletloc[0].y,tempbulletloc[0].z); + glGetFloatv(GL_MODELVIEW_MATRIX,M); + tempbulletloc[0].x=M[12]; + tempbulletloc[0].y=M[13]; + tempbulletloc[0].z=M[14]; + glPopMatrix(); + glPushMatrix(); + glLoadIdentity(); + glScalef(1,1/skeleton.joints[j].length,1); + glRotatef(skeleton.joints[j].rotate2-90,0,0,1); + glRotatef(skeleton.joints[j].rotate1-90,0,1,0); + glTranslatef( (-(skeleton.joints[j].position.x+skeleton.joints[j].parent->position.x)/2), + (-(skeleton.joints[j].position.y+skeleton.joints[j].parent->position.y)/2), + (-(skeleton.joints[j].position.z+skeleton.joints[j].parent->position.z)/2)); + glTranslatef(tempbulletloc[1].x,tempbulletloc[1].y,tempbulletloc[1].z); + glGetFloatv(GL_MODELVIEW_MATRIX,M); + tempbulletloc[1].x=M[12]; + tempbulletloc[1].y=M[13]; + tempbulletloc[1].z=M[14]; + glPopMatrix(); + collide=skeletonmodels[skeleton.joints[j].modelnum].LineCheck(tempbulletloc[0],tempbulletloc[1],&collisionpoint); + if(collide!=-1) + { + glPushMatrix(); + glLoadIdentity(); + glTranslatef( (skeleton.joints[j].position.x+skeleton.joints[j].parent->position.x)/2, + (skeleton.joints[j].position.y+skeleton.joints[j].parent->position.y)/2, + (skeleton.joints[j].position.z+skeleton.joints[j].parent->position.z)/2); + glRotatef(-skeleton.joints[j].rotate1+90,0,1,0); + glRotatef(-skeleton.joints[j].rotate2+90,0,0,1); + glScalef(1,skeleton.joints[j].length,1); + glTranslatef(collisionpoint.x,collisionpoint.y,collisionpoint.z); + glGetFloatv(GL_MODELVIEW_MATRIX,M); + collisionpoint.x=M[12]; + collisionpoint.y=M[13]; + collisionpoint.z=M[14]; + glPopMatrix(); + hitstruct.collision=1; + hitstruct.hitlocation=collisionpoint; + hitstruct.joint1=&skeleton.joints[j]; + hitstruct.joint2=skeleton.joints[j].parent; + } + } + } + for(int j=0;j<skeleton.num_muscles;j++){ + if(skeleton.muscles[j].visible){ + tempbulletloc[0]=start; + tempbulletloc[1]=end; + glPushMatrix(); + glLoadIdentity(); + glScalef(1,1/skeleton.muscles[j].length,1); + glRotatef(skeleton.muscles[j].rotate3,0,1,0); + glRotatef(skeleton.muscles[j].rotate2-90,0,0,1); + glRotatef(skeleton.muscles[j].rotate1-90,0,1,0); + glTranslatef( (-(skeleton.muscles[j].parent1->position.x+skeleton.muscles[j].parent2->position.x)/2), + (-(skeleton.muscles[j].parent1->position.y+skeleton.muscles[j].parent2->position.y)/2), + (-(skeleton.muscles[j].parent1->position.z+skeleton.muscles[j].parent2->position.z)/2)); + + glTranslatef(tempbulletloc[0].x,tempbulletloc[0].y,tempbulletloc[0].z); + glGetFloatv(GL_MODELVIEW_MATRIX,M); + tempbulletloc[0].x=M[12]; + tempbulletloc[0].y=M[13]; + tempbulletloc[0].z=M[14]; + glPopMatrix(); + glPushMatrix(); + glLoadIdentity(); + glScalef(1,1/skeleton.muscles[j].length,1); + glRotatef(skeleton.muscles[j].rotate3,0,1,0); + glRotatef(skeleton.muscles[j].rotate2-90,0,0,1); + glRotatef(skeleton.muscles[j].rotate1-90,0,1,0); + + glTranslatef( (-(skeleton.muscles[j].parent1->position.x+skeleton.muscles[j].parent2->position.x)/2), + (-(skeleton.muscles[j].parent1->position.y+skeleton.muscles[j].parent2->position.y)/2), + (-(skeleton.muscles[j].parent1->position.z+skeleton.muscles[j].parent2->position.z)/2)); + glTranslatef(tempbulletloc[1].x,tempbulletloc[1].y,tempbulletloc[1].z); + glGetFloatv(GL_MODELVIEW_MATRIX,M); + tempbulletloc[1].x=M[12]; + tempbulletloc[1].y=M[13]; + tempbulletloc[1].z=M[14]; + glPopMatrix(); + collide=skeletonmodels[skeleton.muscles[j].parent1->modelnum].LineCheck(tempbulletloc[0],tempbulletloc[1],&collisionpoint); + if(collide!=-1) + { + glPushMatrix(); + glLoadIdentity(); + glTranslatef( (skeleton.muscles[j].parent1->position.x+skeleton.muscles[j].parent2->position.x)/2, + (skeleton.muscles[j].parent1->position.y+skeleton.muscles[j].parent2->position.y)/2, + (skeleton.muscles[j].parent1->position.z+skeleton.muscles[j].parent2->position.z)/2); + glRotatef(-skeleton.muscles[j].rotate1+90,0,1,0); + glRotatef(-skeleton.muscles[j].rotate2+90,0,0,1); + glRotatef(-skeleton.muscles[j].rotate3,0,1,0); + glScalef(1,findDistance(skeleton.muscles[j].parent1->position,skeleton.muscles[j].parent2->position),1); + glTranslatef(collisionpoint.x,collisionpoint.y,collisionpoint.z); + glGetFloatv(GL_MODELVIEW_MATRIX,M); + collisionpoint.x=M[12]; + collisionpoint.y=M[13]; + collisionpoint.z=M[14]; + glPopMatrix(); + hitstruct.collision=1; + hitstruct.hitlocation=collisionpoint; + hitstruct.joint1=skeleton.muscles[j].parent1; + hitstruct.joint2=skeleton.muscles[j].parent2; + } + } + } + } + if(skeleton.free<1){ + if(playerrotation)hitstruct.hitlocation=DoRotation(hitstruct.hitlocation,0,playerrotation,0); + hitstruct.hitlocation=hitstruct.hitlocation+playercoords; + } + return hitstruct; +} + +extern float camerashake; +extern int cycle; +void Person::DoAnimations(int who){ + + if(target>1&&!skeleton.free){ + //Footstep sounds + if(who==0&&slomo==0&&(targetanimation==joganim||targetanimation==walkanim)&&(targetframe==0||targetframe==8)&&visions==0&&(onground||abs(velocity.y)<1)){ + int whichsound; + float gLoc[3]; + gLoc[0]=playercoords.x/soundscalefactor; + gLoc[1]=playercoords.y/soundscalefactor; + gLoc[2]=playercoords.z/soundscalefactor; + whichsound=footstepsound+abs(Random())%5; + alSourcefv(gSourceID[whichsound], AL_POSITION, gLoc); + alSourcePlay(gSourceID[whichsound]); + } + if(targetanimation==zombieeatanim&&(targetframe==3)){ + int whichsound; + float gLoc[3]; + XYZ soundpoint=(DoRotation(skeleton.joints[skeleton.jointlabels[head]].position,0,playerrotation,0)+playercoords); + gLoc[0]=soundpoint.x/soundscalefactor; + gLoc[1]=soundpoint.y/soundscalefactor; + gLoc[2]=soundpoint.z/soundscalefactor; + alSourcefv(gSourceID[bodyhitsound], AL_POSITION, gLoc); + alSourcePlay(gSourceID[bodyhitsound]); + bleeding=1; + bleeddelay=1; + bjoint1=&skeleton.joints[skeleton.jointlabels[head]]; + bjoint2=&skeleton.joints[skeleton.jointlabels[neck]]; + } + targetframe=currentframe; + currentanimation=targetanimation; + if(!backwardsanim){targetframe++; + if(targetframe>animation[currentanimation].numframes-1)targetframe=0;} + if(backwardsanim){targetframe--; + if(targetframe<0)targetframe=animation[currentanimation].numframes-1;} + target=0; + if((currentanimation==getupfrontanim||currentanimation==getupbackanim)&&targetframe==0){ + targetanimation=idleanim; + } + if(targetanimation==diveanim&¤tanimation==diveanim&&targetframe==0){ + targetanimation=getupfrontanim; + float gLoc[3]; + XYZ soundpoint=(DoRotation(skeleton.joints[skeleton.jointlabels[head]].position,0,playerrotation,0)+playercoords); + gLoc[0]=soundpoint.x/soundscalefactor; + gLoc[1]=soundpoint.y/soundscalefactor; + gLoc[2]=soundpoint.z/soundscalefactor; + alSourcefv(gSourceID[bodywhacksound], AL_POSITION, gLoc); + alSourcePlay(gSourceID[bodywhacksound]); + } + if(currentanimation==throwanim&&targetframe==0){ + targetanimation=idleanim; + } + if(currentanimation==thrownanim&&targetframe==0){ + skeleton.offset=0; + skeleton.free=1; + longdead=1; + for(int j=0;j<skeleton.num_joints;j++){ + skeleton.joints[j].position+=skeleton.joints[j].offset; + skeleton.joints[j].position=DoRotation(skeleton.joints[j].position,0,playerrotation,0); + skeleton.joints[j].position+=playercoords; + skeleton.joints[j].realoldposition=skeleton.joints[j].position; + skeleton.joints[j].velocity=DoRotation(skeleton.joints[j].velocity,0,playerrotation,0); + } + } + } + + if(!skeleton.free){ + if(currentanimation!=lyinganim){ + if(animation[targetanimation].speed[currentframe]>animation[currentanimation].speed[currentframe]) + target+=multiplier*animation[targetanimation].speed[currentframe]*speed; + if(animation[targetanimation].speed[currentframe]<=animation[currentanimation].speed[currentframe]) + target+=multiplier*animation[currentanimation].speed[currentframe]*speed; + } + if(currentanimation==lyinganim){ + target+=multiplier*animation[targetanimation].speed[targetframe]*speed; + } + if(((currentanimation==crouchanim)&&(targetanimation!=crouchanim))||((currentanimation!=crouchanim)&&(targetanimation==crouchanim)))target+=multiplier*animation[crouchanim].speed[0]*2; + if(currentanimation==idleanim&&targetanimation==idleanim)target-=multiplier*animation[idleanim].speed[0]/2; + + if(target>1)currentframe=targetframe; + + for(int i=0;i<skeleton.num_joints;i++){ + if(currentanimation!=lyinganim){ + skeleton.joints[i].velocity=((animation[currentanimation].position[i][currentframe]*(1-target)+animation[targetanimation].position[i][targetframe]*(target))-(skeleton.joints[i].position))/multiplier; + skeleton.joints[i].position=animation[currentanimation].position[i][currentframe]*(1-target)+animation[targetanimation].position[i][targetframe]*(target); + if(skeleton.joints[i].hasparent&&skeleton.joints[i].visible) + { + skeleton.joints[i].rotate1=animation[currentanimation].rotate1[i][currentframe]*(1-target)+animation[targetanimation].rotate1[i][targetframe]*(target); + skeleton.joints[i].rotate2=animation[currentanimation].rotate2[i][currentframe]*(1-target)+animation[targetanimation].rotate2[i][targetframe]*(target); + skeleton.joints[i].rotate3=animation[currentanimation].rotate3[i][currentframe]*(1-target)+animation[targetanimation].rotate3[i][targetframe]*(target); + } + if(skeleton.muscles[i].visible) + { + skeleton.muscles[i].rotate1=animation[currentanimation].mrotate1[i][currentframe]*(1-target)+animation[targetanimation].mrotate1[i][targetframe]*(target); + skeleton.muscles[i].rotate2=animation[currentanimation].mrotate2[i][currentframe]*(1-target)+animation[targetanimation].mrotate2[i][targetframe]*(target); + skeleton.muscles[i].rotate3=animation[currentanimation].mrotate3[i][currentframe]*(1-target)+animation[targetanimation].mrotate3[i][targetframe]*(target); + } + } + if(currentanimation==lyinganim){ + skeleton.joints[i].velocity=((tempanimation.position[i][0]*(1-target)+animation[targetanimation].position[i][targetframe]*(target))-(skeleton.joints[i].position))/multiplier; + skeleton.joints[i].position=tempanimation.position[i][0]*(1-target)+animation[targetanimation].position[i][targetframe]*(target); + } + } + } + + //Look up+down + if(!skeleton.free&&(whichgun!=nogun||who==0)&&health==100&¤tanimation!=lyinganim&¤tanimation!=getupfrontanim&¤tanimation!=getupbackanim&¤tanimation!=diveanim&&targetanimation!=diveanim&&targetanimation!=throwanim&&targetanimation!=thrownanim){ + XYZ facing; + XYZ facingdown; + XYZ facinghalf; + XYZ facingright; + int oldanimation=currentanimation; + if(who==0){ + playerrotation2=camera.rotation2; + //Facing + facing=0; + facing.z=1; + + facinghalf=DoRotation(facing,playerrotation2/2,0,0); + facinghalf=DoRotation(facinghalf,0,-7,0); + facing=DoRotation(facing,playerrotation2,0,0); + facingright=DoRotation(facing,0,-90,0); + facingdown=DoRotation(facing,90,0,0); + } + if(who!=0){ + //Facing + facing=0; + facing.z=1; + + facinghalf=DoRotation(facing,playerrotation2/2,0,0); + facinghalf=DoRotation(facinghalf,0,-7,0); + facing=DoRotation(facing,playerrotation2,0,0); + facingright=DoRotation(facing,0,-90,0); + facingdown=DoRotation(facing,90,0,0); + } + XYZ rotatearound; + XYZ oldpos; + if(whichgun==sniperrifle){ + for(int i=0;i<skeleton.num_joints;i++){ + if(skeleton.joints[i].label!=righthand&&skeleton.joints[i].label!=rightelbow&&skeleton.joints[i].label!=rightwrist&&skeleton.joints[i].label!=lefthand&&skeleton.joints[i].label!=leftelbow&&skeleton.joints[i].label!=leftwrist){ + }else{ + skeleton.joints[i].position=animation[rifleholdanim].position[i][0]; + if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position); + } + } + } + if(whichgun==shotgun){ + for(int i=0;i<skeleton.num_joints;i++){ + if(skeleton.joints[i].label!=righthand&&skeleton.joints[i].label!=rightelbow&&skeleton.joints[i].label!=rightwrist&&skeleton.joints[i].label!=lefthand&&skeleton.joints[i].label!=leftelbow&&skeleton.joints[i].label!=leftwrist){ + }else{ + skeleton.joints[i].position=animation[rifleholdanim].position[i][0]; + if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position); + } + } + } + if(whichgun==assaultrifle){ + for(int i=0;i<skeleton.num_joints;i++){ + if(skeleton.joints[i].label!=righthand&&skeleton.joints[i].label!=rightelbow&&skeleton.joints[i].label!=rightwrist&&skeleton.joints[i].label!=lefthand&&skeleton.joints[i].label!=leftelbow&&skeleton.joints[i].label!=leftwrist){ + }else{ + skeleton.joints[i].position=animation[rifleholdanim].position[i][0]; + if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position); + } + } + } + if((aiming||aimamount>0||whichgun==grenade)&&whichgun!=nogun){ + if(aiming&&targetanimation!=joganim){ + if(aimamount<1)aimamount+=multiplier*4; + if(aimamount>1)aimamount=1; + } + if(!aiming||targetanimation==joganim){ + if(aimamount>0)aimamount-=multiplier*4; + if(aimamount<0)aimamount=0; + } + if(grenphase==1){ + if(grenamount<1)grenamount+=multiplier*4; + if(grenamount>1)grenamount=1; + } + if(grenphase==0){ + if(grenamount>0)grenamount-=multiplier*4; + if(grenamount<0)grenamount=0; + } + rotatearound=skeleton.joints[skeleton.jointlabels[neck]].position; + for(int i=0;i<skeleton.num_joints;i++){ + if(skeleton.joints[i].label!=righthand&&skeleton.joints[i].label!=rightelbow&&skeleton.joints[i].label!=rightwrist&&skeleton.joints[i].label!=lefthand&&skeleton.joints[i].label!=leftelbow&&skeleton.joints[i].label!=leftwrist){ + }else{ + if(whichgun==sniperrifle){ + oldpos=skeleton.joints[i].position; + skeleton.joints[i].position=animation[rifleaimanim].position[i][0]; + if(currentanimation==crouchanim||targetanimation==crouchanim){ + skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position); + } + skeleton.joints[i].position+=facingright*0.1; + skeleton.joints[i].position=rotatearound+DoRotation(skeleton.joints[i].position-rotatearound,(playerrotation2/2-10)*aimamount,0,0); + skeleton.joints[i].position=skeleton.joints[i].position*(aimamount)+oldpos*(1-aimamount); + } + if(whichgun==shotgun){ + oldpos=skeleton.joints[i].position; + skeleton.joints[i].position=animation[assaultrifleaimanim].position[i][0]; + if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position); + skeleton.joints[i].position=rotatearound+DoRotation(skeleton.joints[i].position-rotatearound,(playerrotation2/2)*aimamount,0,0); + if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position+=facingdown*.2; + else skeleton.joints[i].position-=facingdown*.02; + if(skeleton.joints[i].label==righthand)skeleton.joints[i].position=skeleton.joints[skeleton.jointlabels[lefthand]].position-facinghalf*2; + skeleton.joints[i].position=skeleton.joints[i].position*(aimamount)+oldpos*(1-aimamount); + } + if(whichgun==assaultrifle){ + oldpos=skeleton.joints[i].position; + skeleton.joints[i].position=animation[assaultrifleaimanim].position[i][0]; + if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position); + skeleton.joints[i].position=rotatearound+DoRotation(skeleton.joints[i].position-rotatearound,(playerrotation2/2)*aimamount,0,0); + if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position+=facingdown*.2; + else skeleton.joints[i].position-=facingdown*.02; + if(skeleton.joints[i].label==righthand)skeleton.joints[i].position=skeleton.joints[skeleton.jointlabels[lefthand]].position-facinghalf*2; + skeleton.joints[i].position=skeleton.joints[i].position*(aimamount)+oldpos*(1-aimamount); + } + if(whichgun==handgun1){ + oldpos=skeleton.joints[i].position; + skeleton.joints[i].position=animation[pistolaimanim].position[i][0]; + if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position); + skeleton.joints[i].position=rotatearound+DoRotation(skeleton.joints[i].position-rotatearound,(playerrotation2/2)*aimamount,0,0); + if(currentanimation==crouchanim||targetanimation==crouchanim){skeleton.joints[i].position+=facingright*.15;skeleton.joints[i].position+=facingdown*.3;} + else skeleton.joints[i].position-=facingdown*.1; + skeleton.joints[i].position=skeleton.joints[i].position*(aimamount)+oldpos*(1-aimamount); + } + if(whichgun==handgun2){ + oldpos=skeleton.joints[i].position; + skeleton.joints[i].position=animation[pistolaimanim].position[i][0]; + if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position); + skeleton.joints[i].position=rotatearound+DoRotation(skeleton.joints[i].position-rotatearound,(playerrotation2/2)*aimamount,0,0); + if(currentanimation==crouchanim||targetanimation==crouchanim){skeleton.joints[i].position+=facingright*.15;skeleton.joints[i].position+=facingdown*.3;} + else skeleton.joints[i].position-=facingdown*.1; + skeleton.joints[i].position=skeleton.joints[i].position*(aimamount)+oldpos*(1-aimamount); + } + if(whichgun==grenade){ + aimamount=1; + oldpos=skeleton.joints[i].position; + skeleton.joints[i].position=animation[grenadeaimanim].position[i][0]; + if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position); + skeleton.joints[i].position=skeleton.joints[i].position*(aimamount)+oldpos*(1-aimamount); + } + if(whichgun==grenade&&grenamount>0){ + oldpos=skeleton.joints[i].position; + skeleton.joints[i].position=animation[grenadechargeanim].position[i][0]; + if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position); + skeleton.joints[i].position=skeleton.joints[i].position*(grenamount)+oldpos*(1-grenamount); + } + if(thirdperson||who!=0)skeleton.joints[i].position+=facingdown*.4; + if(currentanimation!=crouchanim)skeleton.joints[i].position-=facinghalf*recoil*.35; + if(currentanimation==crouchanim)skeleton.joints[i].position-=facinghalf*recoil*.1; + } + } + } + //Whack + if(attackframe>-1&&whichgun!=grenade){ + for(int i=0;i<skeleton.num_joints;i++){ + if(!skeleton.joints[i].lower){ + if(attackframe==animation[riflehitanim].numframes)skeleton.joints[i].position=skeleton.joints[i].position*(attacktarget)+animation[riflehitanim].position[i][attackframe-1]*(1-attacktarget); + if(attackframe>0&&attackframe<animation[riflehitanim].numframes)skeleton.joints[i].position=animation[riflehitanim].position[i][attackframe-1]*(1-attacktarget)+animation[riflehitanim].position[i][attackframe]*(attacktarget); + if(attackframe==0)skeleton.joints[i].position=skeleton.joints[i].position*(1-attacktarget)+animation[riflehitanim].position[i][attackframe]*(attacktarget); + } + } + if(attackframe==0)attacktarget+=multiplier*animation[riflehitanim].speed[attackframe]*2; + if(attackframe>0)attacktarget+=multiplier*animation[riflehitanim].speed[attackframe-1]*2; + if(attacktarget>1){ + attacktarget=0; + attackframe++; + if(attackframe>animation[riflehitanim].numframes)attackframe=-1; + } + } + //Throw grenade + if(attackframe>-1&&whichgun==grenade&&ammo>0){ + for(int i=0;i<skeleton.num_joints;i++){ + if(!skeleton.joints[i].lower){ + if(attackframe==animation[grenadethrowanim].numframes)skeleton.joints[i].position=skeleton.joints[i].position*(attacktarget)+animation[grenadethrowanim].position[i][attackframe-1]*(1-attacktarget); + if(attackframe>0&&attackframe<animation[grenadethrowanim].numframes)skeleton.joints[i].position=animation[grenadethrowanim].position[i][attackframe-1]*(1-attacktarget)+animation[grenadethrowanim].position[i][attackframe]*(attacktarget); + if(attackframe==0)skeleton.joints[i].position=skeleton.joints[i].position*(1-attacktarget)+animation[grenadethrowanim].position[i][attackframe]*(attacktarget); + } + } + if(attackframe==0)attacktarget+=multiplier*animation[grenadethrowanim].speed[attackframe]*2; + if(attackframe>0)attacktarget+=multiplier*animation[grenadethrowanim].speed[attackframe-1]*2; + if(attacktarget>1){ + attacktarget=0; + attackframe++; + if(attackframe>animation[grenadethrowanim].numframes){ + attackframe=-1; + } + if(attackframe==animation[grenadethrowanim].numframes-1&&ammo>0){ + ammo=-1; + sprites.MakeSprite(grenadesprite, 1, 1, 1, 1, DoRotation(skeleton.joints[skeleton.jointlabels[righthand]].position,0,playerrotation,0)+playercoords, DoRotation(facing,0,playerrotation,0)*30+velocity, 1); + sprites.MakeSprite(spoonsprite, 1, 1, 1, 1, DoRotation(skeleton.joints[skeleton.jointlabels[righthand]].position,0,playerrotation,0)+playercoords, DoRotation(facing,0,playerrotation,0)*10+velocity, 1); + sprites.MakeSprite(pinsprite, 1, 1, 1, 1, DoRotation(skeleton.joints[skeleton.jointlabels[lefthand]].position,0,playerrotation,0)+playercoords, facing*.1+velocity, 1); + XYZ soundsource=DoRotation(skeleton.joints[skeleton.jointlabels[righthand]].position,0,playerrotation,0)+playercoords; + float gLoc[3]; + gLoc[0]=soundsource.x/soundscalefactor; + gLoc[1]=soundsource.y/soundscalefactor; + gLoc[2]=soundsource.z/soundscalefactor; + alSourcefv(gSourceID[grenadethrowsound], AL_POSITION, gLoc); + alSourcePlay(gSourceID[grenadethrowsound]); + } + } + } + + rotatearound=skeleton.joints[skeleton.jointlabels[abdomen]].position; + if(who==0) + for(int i=0;i<skeleton.num_joints;i++){ + if(skeleton.joints[i].lower==0) + skeleton.joints[i].position=rotatearound+DoRotation(skeleton.joints[i].position-rotatearound,playerrotation2/2,0,0); + } + if(who==0) + for(int i=0;i<skeleton.num_joints;i++){ + if(skeleton.joints[i].lower==1&&skeleton.joints[i].label!=groin) + skeleton.joints[i].position=DoRotation(skeleton.joints[i].position,0,playerlowrotation-playerrotation,0); + } + //head facing + if(who==0){ + rotatearound=skeleton.joints[skeleton.jointlabels[neck]].position; + skeleton.joints[skeleton.jointlabels[head]].position=rotatearound+DoRotation(skeleton.joints[skeleton.jointlabels[head]].position-rotatearound,playerrotation2/2,0,0); + } + + skeleton.DoConstraints(); + + //Reload + if(whichgun!=nogun&&whichgun!=knife){ + if(reloading>0){ + aiming=0; + reloading-=multiplier; + } + if(ammo<0&&reloads[whichgun]>0&&reloading<=0){ + if(whichgun!=grenade){ + float gLoc[3]; + ALint tempint; + gLoc[0]=playercoords.x/soundscalefactor; + gLoc[1]=playercoords.y/soundscalefactor; + gLoc[2]=playercoords.z/soundscalefactor; +#ifdef DEBIAN_NEEDS_TO_UPDATE_THEIR_OPENAL + alGetSourceiv(gSourceID[reloadsound], AL_SOURCE_STATE, &tempint); +#else + alGetSourcei(gSourceID[reloadsound], AL_SOURCE_STATE, &tempint); +#endif + + if (tempint != AL_PLAYING){ + alSourcefv(gSourceID[reloadsound], AL_POSITION, gLoc); + alSourcePlay(gSourceID[reloadsound]); + } + } + reloading=3; + aiming=0; + if(whichgun==sniperrifle)ammo=5; + if(whichgun==assaultrifle)ammo=25; + if(whichgun==handgun1)ammo=12; + if(whichgun==handgun2)ammo=16; + if(whichgun==grenade){ammo=1; reloading=1;} + if(whichgun==shotgun)ammo=6; + reloads[whichgun]--; + } + if(reloads[whichgun]==0&&whichgun==grenade&&ammo<=0){ + whichgun=nogun; + } + if(reloading<0){ + reloading=0; + aiming=1; + } + } + } +} + +void Person::DoAnimationslite(int who){ + + int oldanimation=currentanimation; + if(target>1&&!skeleton.free){ + //Footstep sounds + if(who==0&&(targetanimation==joganim||targetanimation==walkanim)&&(targetframe==0||targetframe==8)&&visions==0&&(onground||abs(velocity.y)<1)){ + int whichsound; + float gLoc[3]; + gLoc[0]=playercoords.x/soundscalefactor; + gLoc[1]=playercoords.y/soundscalefactor; + gLoc[2]=playercoords.z/soundscalefactor; + whichsound=footstepsound+abs(Random())%5; + alSourcefv(gSourceID[whichsound], AL_POSITION, gLoc); + alSourcePlay(gSourceID[whichsound]); + } + if(targetanimation==zombieeatanim&&(targetframe==3)){ + int whichsound; + float gLoc[3]; + XYZ soundpoint=(DoRotation(skeleton.joints[skeleton.jointlabels[head]].position,0,playerrotation,0)+playercoords); + gLoc[0]=soundpoint.x/soundscalefactor; + gLoc[1]=soundpoint.y/soundscalefactor; + gLoc[2]=soundpoint.z/soundscalefactor; + alSourcefv(gSourceID[bodyhitsound], AL_POSITION, gLoc); + alSourcePlay(gSourceID[bodyhitsound]); + bleeding=1; + bleeddelay=1; + bjoint1=&skeleton.joints[skeleton.jointlabels[head]]; + bjoint2=&skeleton.joints[skeleton.jointlabels[neck]]; + } + targetframe=currentframe; + currentanimation=targetanimation; + if(!backwardsanim){targetframe++; + if(targetframe>animation[currentanimation].numframes-1)targetframe=0;} + if(backwardsanim){targetframe--; + if(targetframe<0)targetframe=animation[currentanimation].numframes-1;} + target=0; + if((currentanimation==getupfrontanim||currentanimation==getupbackanim)&&targetframe==0){ + targetanimation=idleanim; + } + } + + if(!skeleton.free){ + if(currentanimation!=lyinganim){ + if(animation[targetanimation].speed[currentframe]>animation[currentanimation].speed[currentframe]) + target+=multiplier*animation[targetanimation].speed[currentframe]*speed; + if(animation[targetanimation].speed[currentframe]<=animation[currentanimation].speed[currentframe]) + target+=multiplier*animation[currentanimation].speed[currentframe]*speed; + } + if(currentanimation==lyinganim){ + target+=multiplier*animation[targetanimation].speed[targetframe]*speed; + } + if(((currentanimation==crouchanim)&&(targetanimation!=crouchanim))||((currentanimation!=crouchanim)&&(targetanimation==crouchanim)))target+=multiplier*animation[crouchanim].speed[0]*2; + if(currentanimation==idleanim&&targetanimation==idleanim)target-=multiplier*animation[idleanim].speed[0]/2; + + if(target>1)currentframe=targetframe; + } +} + +void Person::DoStuff(int who){ + int moveanim; + + if((targetanimation!=idleanim&&targetanimation!=crouchanim)||visions==1)playerlowrotation=playerrotation; + if(targetanimation!=crouchanim&¤tanimation!=crouchanim){ + if(playerrotation>playerlowrotation+50){playerlowrotation=playerrotation-50; targetanimation=walkanim; targetframe=0; target=0;} + if(playerrotation<playerlowrotation-50){playerlowrotation=playerrotation+50; targetanimation=walkanim; targetframe=0; target=0;} + } + if(targetanimation==crouchanim||currentanimation==crouchanim){ + if(playerrotation>playerlowrotation+70){playerrotation=playerlowrotation+70;} + if(playerrotation<playerlowrotation-70){playerrotation=playerlowrotation-70;} + } + if(who==0)camera.rotation=180-playerrotation; + + if(who!=0&&visions==0){ + if(targetanimation!=walkanim&&targetanimation!=zombiewalkanim)speed=1.0*speedmult; + if(targetanimation==walkanim||targetanimation==zombiewalkanim)speed=1.8*speedmult; + playerlowrotation=playerrotation; + } + + //Do controls + if(who==0&&targetanimation!=diveanim&&targetanimation!=throwanim&&targetanimation!=thrownanim&¤tanimation!=diveanim&¤tanimation!=getupfrontanim){ + backwardsanim=0; + if(visions==1)speed=40; + if(visions==0&&targetanimation==joganim)speed=2.2; + if(visions==0&&targetanimation!=joganim)speed=1.3; + if(visions==0&&targetanimation==walkanim)speed=2.5; + unsigned char theKeyMap[16]; + GetKeys( ( unsigned long * )theKeyMap ); + + if(IsKeyDown( theKeyMap, MAC_SHIFT_KEY )||visions==1){ + moveanim=joganim; + }else{ + moveanim=walkanim; + } + if(IsKeyDown( theKeyMap, MAC_CONTROL_KEY )&¤tanimation==idleanim&&targetanimation==idleanim){ + targetanimation=crouchanim; + target=0; + } + if(!IsKeyDown( theKeyMap, MAC_CONTROL_KEY )&¤tanimation==crouchanim&&targetanimation==crouchanim){ + targetanimation=idleanim; + target=0; + } + if((onground||(who==0&&visions==1))&¤tanimation!=crouchanim){ + if ( IsKeyDown( theKeyMap, forwardskey )&&!( IsKeyDown( theKeyMap, backwardskey ))){ + if(targetanimation!=moveanim)targetframe=0; + targetanimation=moveanim; + } + if ( IsKeyDown( theKeyMap, rightkey )&&!( IsKeyDown( theKeyMap, leftkey ))){ + if(targetanimation!=moveanim)targetframe=0; + targetanimation=moveanim; + playerlowrotation-=90; + if(IsKeyDown( theKeyMap, forwardskey ))playerlowrotation+=45; + if(IsKeyDown( theKeyMap, backwardskey ))playerlowrotation-=235; + } + if ( IsKeyDown( theKeyMap, leftkey )&&!( IsKeyDown( theKeyMap, rightkey ))){ + if(targetanimation!=moveanim)targetframe=0; + targetanimation=moveanim; + playerlowrotation+=90; + if(IsKeyDown( theKeyMap, forwardskey ))playerlowrotation-=45; + if(IsKeyDown( theKeyMap, backwardskey ))playerlowrotation+=235; + } + if ( IsKeyDown( theKeyMap, backwardskey )){ + if(targetanimation!=moveanim)targetframe=0; + targetanimation=moveanim; + backwardsanim=1; + } + } + //air control + if(!onground){ + float oldplayerrotation=playerrotation; + if ( IsKeyDown( theKeyMap, forwardskey )&&!( IsKeyDown( theKeyMap, backwardskey ))){ + facing=0; + facing.z=1; + facing=DoRotation(facing,0,playerrotation,0); + velocity=velocity+facing*multiplier*4; + } + if ( IsKeyDown( theKeyMap, rightkey )&&!( IsKeyDown( theKeyMap, leftkey ))){ + playerrotation-=90; + if(IsKeyDown( theKeyMap, forwardskey ))playerrotation+=45; + if(IsKeyDown( theKeyMap, backwardskey ))playerrotation-=45; + facing=0; + facing.z=1; + facing=DoRotation(facing,0,playerrotation,0); + velocity=velocity+facing*multiplier*4; + } + if ( IsKeyDown( theKeyMap, leftkey )&&!( IsKeyDown( theKeyMap, rightkey ))){ + playerrotation+=90; + if(IsKeyDown( theKeyMap, forwardskey ))playerrotation-=45; + if(IsKeyDown( theKeyMap, backwardskey ))playerrotation+=45; + facing=0; + facing.z=1; + facing=DoRotation(facing,0,playerrotation,0); + velocity=velocity+facing*multiplier*4; + } + if ( IsKeyDown( theKeyMap, backwardskey )&&!IsKeyDown( theKeyMap, forwardskey )&&!IsKeyDown( theKeyMap, leftkey )&&!IsKeyDown( theKeyMap, rightkey )){ + playerrotation+=180; + facing=0; + facing.z=1; + facing=DoRotation(facing,0,playerrotation,0); + velocity=velocity+facing*multiplier*4; + } + playerrotation=oldplayerrotation; + } + if(!IsKeyDown( theKeyMap, forwardskey )&&!IsKeyDown( theKeyMap, leftkey )&&!IsKeyDown( theKeyMap, rightkey )&&!IsKeyDown( theKeyMap, backwardskey )&&(targetanimation==joganim||targetanimation==walkanim)){ + if(!(targetanimation==walkanim&&(targetframe==0||targetframe==2))){ + targetanimation=idleanim; + targetframe=0; + target=0; + } + } + } + + + facing=0; + facing.z=1; + + facing=DoRotation(facing,0,playerlowrotation,0); + if(backwardsanim)facing*=-1; + + if(onground){ + velocity=0; + } + if(((currentanimation==joganim||currentanimation==zombiejoganim||currentanimation==diveanim)&&onground)||(who==0&&visions==1&&((currentanimation==joganim||currentanimation==walkanim||currentanimation==diveanim)||(currentanimation==zombiejoganim||currentanimation==zombiewalkanim)))){ + playercoords+=facing*multiplier*15*speed; + velocity.x=facing.x*15*speed; + velocity.z=facing.z*15*speed; + } + if((currentanimation==walkanim||currentanimation==zombiewalkanim)&&onground&&(who!=0||visions==0)){ + playercoords+=facing*multiplier*4*speed; + velocity.x=facing.x*4*speed; + velocity.z=facing.z*4*speed; + } +} + +void Person::FindRotationGun(XYZ start, XYZ target) +{ + XYZ temppoint1,temppoint2,tempforward; + float distance; + + temppoint1=start; + temppoint2=target; + distance=findDistance(temppoint1,temppoint2); + gunrotate2=asin((temppoint1.y-temppoint2.y)/distance)*rad2deg; + temppoint1.y=0; + temppoint2.y=0; + gunrotate1=acos((temppoint1.z-temppoint2.z)/findDistance(temppoint1,temppoint2))*rad2deg; + if(temppoint1.x>temppoint2.x)gunrotate1=360-gunrotate1; + tempforward=target-start; + tempforward=DoRotation(tempforward,-90,0,0); + tempforward=DoRotation(tempforward,0,gunrotate1-90,0); + tempforward=DoRotation(tempforward,0,0,gunrotate2-90); + tempforward.y=0; + Normalise(&tempforward); + gunrotate3=acos(0-tempforward.z)*rad2deg; + if(0>tempforward.x)gunrotate3=360-gunrotate3; +} + +extern Model skeletonmodels[10]; +extern Costume costume[2]; +int Person::DrawSkeleton(int who){ + GLfloat M[16]; + //Guns + if(whichgun==sniperrifle){ + FindRotationGun(skeleton.joints[skeleton.jointlabels[righthand]].position,skeleton.joints[skeleton.jointlabels[lefthand]].position); + glPushMatrix(); + glTranslatef( skeleton.joints[skeleton.jointlabels[righthand]].position.x, + skeleton.joints[skeleton.jointlabels[righthand]].position.y, + skeleton.joints[skeleton.jointlabels[righthand]].position.z); + glRotatef(-gunrotate1+90,0,1,0); + glRotatef(-gunrotate2+90,0,0,1); + glRotatef(-gunrotate3,0,1,0); + gunmodels[sniperriflemodel].draw(); + glPopMatrix(); + } + + if(whichgun==shotgun){ + FindRotationGun(skeleton.joints[skeleton.jointlabels[righthand]].position,skeleton.joints[skeleton.jointlabels[lefthand]].position); + glPushMatrix(); + glTranslatef( skeleton.joints[skeleton.jointlabels[righthand]].position.x, + skeleton.joints[skeleton.jointlabels[righthand]].position.y, + skeleton.joints[skeleton.jointlabels[righthand]].position.z); + glRotatef(2,1,0,0); + glRotatef(-gunrotate1+90+1,0,1,0); + glRotatef(-gunrotate2+90,0,0,1); + glRotatef(-gunrotate3,0,1,0); + glTranslatef(0,-.4,0); + gunmodels[shotgunmodel].draw(); + glPopMatrix(); + } + + if(whichgun==assaultrifle){ + FindRotationGun(skeleton.joints[skeleton.jointlabels[righthand]].position,skeleton.joints[skeleton.jointlabels[lefthand]].position); + glPushMatrix(); + glTranslatef( skeleton.joints[skeleton.jointlabels[righthand]].position.x, + skeleton.joints[skeleton.jointlabels[righthand]].position.y, + skeleton.joints[skeleton.jointlabels[righthand]].position.z); + glRotatef(-gunrotate1+90,0,1,0); + glRotatef(-gunrotate2+90,0,0,1); + glRotatef(-gunrotate3,0,1,0); + gunmodels[assaultriflemodel].draw(); + glPopMatrix(); + } + + if(whichgun==handgun1){ + if(!thirdperson&&who==0)FindRotationGun(skeleton.joints[skeleton.jointlabels[righthand]].position,(skeleton.joints[skeleton.jointlabels[head]].position*.65+skeleton.joints[skeleton.jointlabels[neck]].position*.35)); + if(thirdperson||who!=0)FindRotationGun(skeleton.joints[skeleton.jointlabels[righthand]].position,(skeleton.joints[skeleton.jointlabels[head]].position*.35+skeleton.joints[skeleton.jointlabels[neck]].position*.65)); + glPushMatrix(); + glTranslatef( skeleton.joints[skeleton.jointlabels[righthand]].position.x, + skeleton.joints[skeleton.jointlabels[righthand]].position.y, + skeleton.joints[skeleton.jointlabels[righthand]].position.z); + glRotatef(-gunrotate1+90-1.5,0,1,0); + glRotatef(-gunrotate2+90,0,0,1); + glRotatef(-gunrotate3,0,1,0); + glTranslatef(0,0,.15); + gunmodels[handgunbasemodel].draw(); + glTranslatef(0,-recoil*.3,0); + gunmodels[handgunslidemodel].draw(); + glPopMatrix(); + } + + if(whichgun==handgun2){ + if(!thirdperson&&who==0)FindRotationGun(skeleton.joints[skeleton.jointlabels[righthand]].position,(skeleton.joints[skeleton.jointlabels[head]].position*.65+skeleton.joints[skeleton.jointlabels[neck]].position*.35)); + if(thirdperson||who!=0)FindRotationGun(skeleton.joints[skeleton.jointlabels[righthand]].position,(skeleton.joints[skeleton.jointlabels[head]].position*.35+skeleton.joints[skeleton.jointlabels[neck]].position*.65)); + glPushMatrix(); + glTranslatef( skeleton.joints[skeleton.jointlabels[righthand]].position.x, + skeleton.joints[skeleton.jointlabels[righthand]].position.y, + skeleton.joints[skeleton.jointlabels[righthand]].position.z); + glRotatef(-gunrotate1+90-1.5,0,1,0); + glRotatef(-gunrotate2+90,0,0,1); + glRotatef(-gunrotate3,0,1,0); + glTranslatef(0,0,.15); + gunmodels[handgun2basemodel].draw(); + glTranslatef(0,-recoil*.3,0); + gunmodels[handgun2slidemodel].draw(); + glPopMatrix(); + } + + if(whichgun==grenade){ + glPushMatrix(); + glTranslatef( skeleton.joints[skeleton.jointlabels[righthand]].position.x, + skeleton.joints[skeleton.jointlabels[righthand]].position.y, + skeleton.joints[skeleton.jointlabels[righthand]].position.z); + glRotatef(-90,1,0,0); + glTranslatef(0,0,.05); + if(reloading<=0){ + gunmodels[grenadebasemodel].draw(); + if(grenphase==0)gunmodels[grenadepinmodel].draw(); + glTranslatef(0,0,.005); + gunmodels[grenadespoonmodel].draw(); + } + glPopMatrix(); + } + + if(whichgun==grenade){ + glPushMatrix(); + glTranslatef( skeleton.joints[skeleton.jointlabels[lefthand]].position.x, + skeleton.joints[skeleton.jointlabels[lefthand]].position.y, + skeleton.joints[skeleton.jointlabels[lefthand]].position.z); + glRotatef(-90,1,0,0); + glTranslatef(0,0,-.15); + if(reloading<=0){ + if(grenphase==1)gunmodels[grenadepinmodel].draw(); + } + glPopMatrix(); + } + if(!litup){ + glDisable(GL_LIGHT1); + } + if(litup){ + GLfloat LightAmbient[]= { 0,0,0, 1.0f}; + GLfloat LightDiffuse[]= { 1,1,1, 1.0f }; + XYZ lightpoint; + lightpoint=skeleton.joints[skeleton.jointlabels[lefthand]].position; + GLfloat LightPosition[]= {lightpoint.x,lightpoint.y,lightpoint.z,0}; + glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); + glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); + glEnable(GL_LIGHT1); + + litup=0; + } + + //Find forward vectors + if(who==0||skeleton.free!=0||skeleton.offset!=0||whichgun!=nogun||currentanimation==lyinganim||((currentanimation==getupfrontanim||currentanimation==getupbackanim)&&targetanimation==idleanim)){ + if(!(skeleton.free==1&&longdead<=0)){ + if(skeleton.offset&&skeleton.free<1){ + XYZ normal; + skeleton.offset=0; + for(int i=0;i<skeleton.num_joints;i++){ + skeleton.joints[i].oldposition=skeleton.joints[i].position; + skeleton.joints[i].position+=skeleton.joints[i].offset; + if(findLengthfast(skeleton.joints[i].offset)<multiplier*multiplier*25)skeleton.joints[i].offset=0; + else{ + normal=skeleton.joints[i].offset; + Normalise(&normal); + skeleton.offset=1; + skeleton.joints[i].offset-=normal*multiplier*5; + } + } + skeleton.DoConstraints(); + } + CrossProduct(skeleton.joints[skeleton.forwardjoints[1]].position-skeleton.joints[skeleton.forwardjoints[0]].position,skeleton.joints[skeleton.forwardjoints[2]].position-skeleton.joints[skeleton.forwardjoints[0]].position,&skeleton.forward); + Normalise(&skeleton.forward); + + CrossProduct(skeleton.joints[skeleton.lowforwardjoints[1]].position-skeleton.joints[skeleton.lowforwardjoints[0]].position,skeleton.joints[skeleton.lowforwardjoints[2]].position-skeleton.joints[skeleton.lowforwardjoints[0]].position,&skeleton.lowforward); + Normalise(&skeleton.lowforward); + + //Special forwards + skeleton.specialforward[0]=skeleton.forward; + + skeleton.specialforward[1]=skeleton.joints[skeleton.jointlabels[rightshoulder]].position+skeleton.joints[skeleton.jointlabels[rightwrist]].position; + skeleton.specialforward[1]=skeleton.joints[skeleton.jointlabels[rightelbow]].position-skeleton.specialforward[1]/2; + skeleton.specialforward[1]+=skeleton.forward*.2; + Normalise(&skeleton.specialforward[1]); + skeleton.specialforward[2]=skeleton.joints[skeleton.jointlabels[leftshoulder]].position+skeleton.joints[skeleton.jointlabels[leftwrist]].position; + skeleton.specialforward[2]=skeleton.joints[skeleton.jointlabels[leftelbow]].position-skeleton.specialforward[2]/2; + skeleton.specialforward[2]+=skeleton.forward*.2; + Normalise(&skeleton.specialforward[2]); + + if(who==0&&aimamount>0&&health==100&&whichgun!=nogun){ + //Facing + XYZ facing; + XYZ facingdown; + //Facing + facing=0; + facing.z=1; + + facing=DoRotation(facing,camera.rotation2,0,0); + facingdown=DoRotation(facing,90,0,0); + skeleton.specialforward[1]=skeleton.specialforward[1]*(1-aimamount)+facingdown*aimamount; + skeleton.specialforward[2]=skeleton.specialforward[2]*(1-aimamount)+facingdown*aimamount; + } + + skeleton.specialforward[3]=skeleton.joints[skeleton.jointlabels[righthip]].position+skeleton.joints[skeleton.jointlabels[rightankle]].position; + skeleton.specialforward[3]=skeleton.specialforward[3]/2-skeleton.joints[skeleton.jointlabels[rightknee]].position; + skeleton.specialforward[3]+=skeleton.lowforward*.2; + Normalise(&skeleton.specialforward[3]); + skeleton.specialforward[4]=skeleton.joints[skeleton.jointlabels[lefthip]].position+skeleton.joints[skeleton.jointlabels[leftankle]].position; + skeleton.specialforward[4]=skeleton.specialforward[4]/2-skeleton.joints[skeleton.jointlabels[leftknee]].position; + skeleton.specialforward[4]+=skeleton.lowforward*.2; + Normalise(&skeleton.specialforward[4]); + + //Find joint rotations + for(int i=0;i<skeleton.num_joints;i++){ + if(skeleton.joints[i].hasparent&&skeleton.joints[i].visible) + { + skeleton.FindRotationJoint(i); + } + } + for(int i=0;i<skeleton.num_muscles;i++){ + if(skeleton.muscles[i].visible) + { + skeleton.FindRotationMuscle(i); + } + }}} + for(int i=0;i<skeleton.num_joints;i++){ + if(skeleton.joints[i].hasparent&&skeleton.joints[i].visible) + { + glPushMatrix(); + glTranslatef( (skeleton.joints[i].position.x+skeleton.joints[i].parent->position.x)/2, + (skeleton.joints[i].position.y+skeleton.joints[i].parent->position.y)/2, + (skeleton.joints[i].position.z+skeleton.joints[i].parent->position.z)/2); + glRotatef(-skeleton.joints[i].rotate1+90,0,1,0); + glRotatef(-skeleton.joints[i].rotate2+90,0,0,1); + glRotatef(-skeleton.joints[i].rotate3,0,1,0); + if(skeleton.joints[i].modelnum==0&&(who!=0||thirdperson))skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].headcolor[0],costume[whichcostume].headcolor[1],costume[whichcostume].headcolor[2]); + if(skeleton.joints[i].modelnum==0&&(who==0&&thirdperson))skeletonmodels[9].draw(); + if(skeleton.joints[i].modelnum==1&&(who!=0||thirdperson))skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].chestcolor[0],costume[whichcostume].chestcolor[1],costume[whichcostume].chestcolor[2]); + if(skeleton.joints[i].modelnum==2)skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].abdomencolor[0],costume[whichcostume].abdomencolor[1],costume[whichcostume].abdomencolor[2]); + if(skeleton.joints[i].modelnum==3)skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].upperarmcolor[0],costume[whichcostume].upperarmcolor[1],costume[whichcostume].upperarmcolor[2]); + if(skeleton.joints[i].modelnum==4)skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].lowerarmcolor[0],costume[whichcostume].lowerarmcolor[1],costume[whichcostume].lowerarmcolor[2]); + if(skeleton.joints[i].modelnum==5)skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].handcolor[0],costume[whichcostume].handcolor[1],costume[whichcostume].handcolor[2]); + if(skeleton.joints[i].modelnum==6)skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].upperlegcolor[0],costume[whichcostume].upperlegcolor[1],costume[whichcostume].upperlegcolor[2]); + if(skeleton.joints[i].modelnum==7)skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].lowerlegcolor[0],costume[whichcostume].lowerlegcolor[1],costume[whichcostume].lowerlegcolor[2]); + if(skeleton.joints[i].modelnum==8)skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].footcolor[0],costume[whichcostume].footcolor[1],costume[whichcostume].footcolor[2]); + glPopMatrix(); + } + } + + for(int i=0;i<skeleton.num_muscles;i++){ + if(skeleton.muscles[i].visible) + { + glPushMatrix(); + glTranslatef( (skeleton.muscles[i].parent1->position.x+skeleton.muscles[i].parent2->position.x)/2, + (skeleton.muscles[i].parent1->position.y+skeleton.muscles[i].parent2->position.y)/2, + (skeleton.muscles[i].parent1->position.z+skeleton.muscles[i].parent2->position.z)/2); + glRotatef(-skeleton.muscles[i].rotate1+90,0,1,0); + glRotatef(-skeleton.muscles[i].rotate2+90,0,0,1); + glRotatef(-skeleton.muscles[i].rotate3,0,1,0); + if(skeleton.muscles[i].parent1->modelnum==0&&(who!=0||thirdperson))skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].headcolor[0],costume[whichcostume].headcolor[1],costume[whichcostume].headcolor[2]); + if(skeleton.muscles[i].parent1->modelnum==0&&(who==0&&thirdperson))skeletonmodels[9].draw(); + if(skeleton.muscles[i].parent1->modelnum==1&&(who!=0||thirdperson))skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].chestcolor[0],costume[whichcostume].chestcolor[1],costume[whichcostume].chestcolor[2]); + if(skeleton.muscles[i].parent1->modelnum==2)skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].abdomencolor[0],costume[whichcostume].abdomencolor[1],costume[whichcostume].abdomencolor[2]); + if(skeleton.muscles[i].parent1->modelnum==3)skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].upperarmcolor[0],costume[whichcostume].upperarmcolor[1],costume[whichcostume].upperarmcolor[2]); + if(skeleton.muscles[i].parent1->modelnum==4)skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].lowerarmcolor[0],costume[whichcostume].lowerarmcolor[1],costume[whichcostume].lowerarmcolor[2]); + if(skeleton.muscles[i].parent1->modelnum==5)skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].handcolor[0],costume[whichcostume].handcolor[1],costume[whichcostume].handcolor[2]); + if(skeleton.muscles[i].parent1->modelnum==6)skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].upperlegcolor[0],costume[whichcostume].upperlegcolor[1],costume[whichcostume].upperlegcolor[2]); + if(skeleton.muscles[i].parent1->modelnum==7)skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].lowerlegcolor[0],costume[whichcostume].lowerlegcolor[1],costume[whichcostume].lowerlegcolor[2]); + if(skeleton.muscles[i].parent1->modelnum==8)skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].footcolor[0],costume[whichcostume].footcolor[1],costume[whichcostume].footcolor[2]); + + glPopMatrix(); + } + } + if(whichgun==knife){ + glPushMatrix(); + glTranslatef( skeleton.joints[skeleton.jointlabels[righthand]].position.x, + skeleton.joints[skeleton.jointlabels[righthand]].position.y, + skeleton.joints[skeleton.jointlabels[righthand]].position.z); + glRotatef(-skeleton.joints[skeleton.jointlabels[righthand]].rotate1+90-1.5,0,1,0); + glRotatef(-skeleton.joints[skeleton.jointlabels[righthand]].rotate2+90,0,0,1); + glRotatef(-skeleton.joints[skeleton.jointlabels[righthand]].rotate3,0,1,0); + glTranslatef(0,-.2,0); + gunmodels[knifemodel].draw(); + glPopMatrix(); + } + if(skeleton.offset&&skeleton.free<1){ + for(int i=0;i<skeleton.num_joints;i++){ + skeleton.joints[i].position=skeleton.joints[i].oldposition; + } + } + + glDisable(GL_LIGHT1); + + return 0; +} + diff --git a/src/Person.h b/src/Person.h new file mode 100644 index 0000000..e7542b0 --- /dev/null +++ b/src/Person.h @@ -0,0 +1,157 @@ +#ifndef _PERSON_H_ +#define _PERSON_H_ + +/**> HEADER FILES <**/ +#include <cmath> +#ifdef OS9 +#include <gl.h> +#else +#include <GL/gl.h> +#endif +#ifdef OS9 +#include "alut.h" +#else +#include <AL/al.h> +#include <AL/alut.h> +#endif +#include "Quaternions.h" +#include "Constants.h" +#include "Skeleton.h" +#include "Models.h" +#include "Camera.h" +#include "Sprites.h" + +#define playertype 0 +#define civiliantype 1 +#define eviltype 2 +#define viptype 3 +#define evilsnipertype 4 +#define evilassaultrifletype 5 +#define zombietype 6 + +class HitStruct +{ + public: + Joint *joint1; + Joint *joint2; + XYZ hitlocation; + bool collision; +}; + +class Person +{ + public: + int eaten; + int currentframe; + int targetframe; + int currentanimation; + int targetanimation; + float target; + float playerhealth; + int modelnum; + XYZ oldplayercoords; + XYZ playercoords; + XYZ playervelocity; + float playerrotation; + float playerrotation2; + float playerlowrotation; + float pathcheckdelay; + bool onground; + bool backwardsanim; + XYZ facing; + XYZ velocity; + float shotdelay; + bool litup; + + bool existing; + + int type; + + int whichcostume; + + Skeleton skeleton; + Animation tempanimation; + + bool freshshootkey; + bool freshkickkey; + int bufferattack; + int jump_key; + int left_key; + int right_key; + int duck_key; + int shoot_key; + int kick_key; + int block_key; + + float speed; + bool aiming; + int grenphase; + float grenamount; + float aimamount; + float speedmult; + float pathsize; + + int pathnum; + int oldpathnum; + int oldoldpathnum; + int oldoldoldpathnum; + XYZ pathtarget; + int whichblockx; + int whichblocky; + + bool dead; + + XYZ averageloc; + XYZ oldaverageloc; + + float lastdistancevictim; + + bool firstlongdead; + float longdead; + + Joint *bjoint1,*bjoint2; + float bleeding; + float bleeddelay; + + float attacktarget; + int attackframe; + int killtarget; + bool killtargetvisible; + + float gunrotate1, gunrotate2, gunrotate3; + float recoil; + int whichgun; + float oldhealth; + float health; + float maxhealth; + float reloading; + int ammo; + int reloads[10]; + bool running; + bool onpath; + + void FindRotationGun(XYZ start, XYZ target); + + int DrawSkeleton(int who); + void DoStuff(int who); + void DoAnimations(int who); + void DoAnimationslite(int who); + HitStruct BulletCollideWithPlayer(int who, XYZ start, XYZ end); +}; + +class Costume +{ + public: + float headcolor[3]; + float handcolor[3]; + float footcolor[3]; + float upperarmcolor[3]; + float lowerarmcolor[3]; + float upperlegcolor[3]; + float lowerlegcolor[3]; + float abdomencolor[3]; + float chestcolor[3]; +}; + + +#endif diff --git a/src/PhysicsMath.h b/src/PhysicsMath.h new file mode 100644 index 0000000..c975941 --- /dev/null +++ b/src/PhysicsMath.h @@ -0,0 +1,1432 @@ +#ifndef _PHYSICSMATH_H_ + +#define _PHYSICSMATH_H_ + + + +#include <cmath> + +#include "Quaternions.h" + + + +//------------------------------------------------------------------------// + +// Misc. Constants + +//------------------------------------------------------------------------// + + + +float const pi = 3.14159265f; + +float const g = -32.174f; // acceleration due to gravity, ft/s^2 + +float const rho = 0.0023769f; // desity of air at sea level, slugs/ft^3 + +float const tol = 0.0000000001f; // float type tolerance + + + + + +//------------------------------------------------------------------------// + +// Misc. Functions + +//------------------------------------------------------------------------// + +inline float DegreesToRadians(float deg); + +inline float RadiansToDegrees(float rad); + + + +inline float DegreesToRadians(float deg) + +{ + + return deg * pi / 180.0f; + +} + + + +inline float RadiansToDegrees(float rad) + +{ + + return rad * 180.0f / pi; + +} + + + +//------------------------------------------------------------------------// + +// Vector Class and vector functions + +//------------------------------------------------------------------------// + +class Vector { + +public: + + float x; + + float y; + + float z; + + + + Vector(void); + + Vector(float xi, float yi, float zi); + + + + float Magnitude(void); + + void Normalize(void); + + void Reverse(void); + + + + Vector& operator+=(Vector u); // vector addition + + Vector& operator-=(Vector u); // vector subtraction + + Vector& operator*=(float s); // scalar multiply + + Vector& operator/=(float s); // scalar divide + + + + Vector operator-(void); + + + +}; + + + +inline Vector operator+(Vector u, Vector v); + +inline Vector operator-(Vector u, Vector v); + +inline Vector operator^(Vector u, Vector v); + +inline float operator*(Vector u, Vector v); + +inline Vector operator*(float s, Vector u); + +inline Vector operator*(Vector u, float s); + +inline Vector operator/(Vector u, float s); + +inline float TripleScalarProduct(Vector u, Vector v, Vector w); + + + +inline Vector::Vector(void) + +{ + + x = 0; + + y = 0; + + z = 0; + +} + + + +inline Vector::Vector(float xi, float yi, float zi) + +{ + + x = xi; + + y = yi; + + z = zi; + +} + + + +inline float Vector::Magnitude(void) + +{ + + return (float) fast_sqrt(x*x + y*y + z*z); + +} + + + +inline void Vector::Normalize(void) + +{ + + float m = (float) fast_sqrt(x*x + y*y + z*z); + + if(m <= tol) m = 1; + + x /= m; + + y /= m; + + z /= m; + + + + if (fabs(x) < tol) x = 0.0f; + + if (fabs(y) < tol) y = 0.0f; + + if (fabs(z) < tol) z = 0.0f; + +} + + + +inline void Vector::Reverse(void) + +{ + + x = -x; + + y = -y; + + z = -z; + +} + + + +inline Vector& Vector::operator+=(Vector u) + +{ + + x += u.x; + + y += u.y; + + z += u.z; + + return *this; + +} + + + +inline Vector& Vector::operator-=(Vector u) + +{ + + x -= u.x; + + y -= u.y; + + z -= u.z; + + return *this; + +} + + + +inline Vector& Vector::operator*=(float s) + +{ + + x *= s; + + y *= s; + + z *= s; + + return *this; + +} + + + +inline Vector& Vector::operator/=(float s) + +{ + + x /= s; + + y /= s; + + z /= s; + + return *this; + +} + + + +inline Vector Vector::operator-(void) + +{ + + return Vector(-x, -y, -z); + +} + + + + + +inline Vector operator+(Vector u, Vector v) + +{ + + return Vector(u.x + v.x, u.y + v.y, u.z + v.z); + +} + + + +inline Vector operator-(Vector u, Vector v) + +{ + + return Vector(u.x - v.x, u.y - v.y, u.z - v.z); + +} + + + +// Vector cross product (u cross v) + +inline Vector operator^(Vector u, Vector v) + +{ + + return Vector( u.y*v.z - u.z*v.y, + + -u.x*v.z + u.z*v.x, + + u.x*v.y - u.y*v.x ); + +} + + + +// Vector dot product + +inline float operator*(Vector u, Vector v) + +{ + + return (u.x*v.x + u.y*v.y + u.z*v.z); + +} + + + +inline Vector operator*(float s, Vector u) + +{ + + return Vector(u.x*s, u.y*s, u.z*s); + +} + + + +inline Vector operator*(Vector u, float s) + +{ + + return Vector(u.x*s, u.y*s, u.z*s); + +} + + + +inline Vector operator/(Vector u, float s) + +{ + + return Vector(u.x/s, u.y/s, u.z/s); + +} + + + +// triple scalar product (u dot (v cross w)) + +inline float TripleScalarProduct(Vector u, Vector v, Vector w) + +{ + + return float( (u.x * (v.y*w.z - v.z*w.y)) + + + (u.y * (-v.x*w.z + v.z*w.x)) + + + (u.z * (v.x*w.y - v.y*w.x)) ); + + //return u*(v^w); + + + +} + + + + + + + +//------------------------------------------------------------------------// + +// Matrix Class and matrix functions + +//------------------------------------------------------------------------// + + + +class Matrix3x3 { + +public: + + // elements eij: i -> row, j -> column + + float e11, e12, e13, e21, e22, e23, e31, e32, e33; + + + + Matrix3x3(void); + + Matrix3x3( float r1c1, float r1c2, float r1c3, + + float r2c1, float r2c2, float r2c3, + + float r3c1, float r3c2, float r3c3 ); + + + + float det(void); + + Matrix3x3 Transpose(void); + + Matrix3x3 Inverse(void); + + + + Matrix3x3& operator+=(Matrix3x3 m); + + Matrix3x3& operator-=(Matrix3x3 m); + + Matrix3x3& operator*=(float s); + + Matrix3x3& operator/=(float s); + +}; + + + +inline Matrix3x3 operator+(Matrix3x3 m1, Matrix3x3 m2); + +inline Matrix3x3 operator-(Matrix3x3 m1, Matrix3x3 m2); + +inline Matrix3x3 operator/(Matrix3x3 m, float s); + +inline Matrix3x3 operator*(Matrix3x3 m1, Matrix3x3 m2); + +inline Matrix3x3 operator*(Matrix3x3 m, float s); + +inline Matrix3x3 operator*(float s, Matrix3x3 m); + +inline Vector operator*(Matrix3x3 m, Vector u); + +inline Vector operator*(Vector u, Matrix3x3 m); + + + + + + + + + + + +inline Matrix3x3::Matrix3x3(void) + +{ + + e11 = 0; + + e12 = 0; + + e13 = 0; + + e21 = 0; + + e22 = 0; + + e23 = 0; + + e31 = 0; + + e32 = 0; + + e33 = 0; + +} + + + +inline Matrix3x3::Matrix3x3( float r1c1, float r1c2, float r1c3, + + float r2c1, float r2c2, float r2c3, + + float r3c1, float r3c2, float r3c3 ) + +{ + + e11 = r1c1; + + e12 = r1c2; + + e13 = r1c3; + + e21 = r2c1; + + e22 = r2c2; + + e23 = r2c3; + + e31 = r3c1; + + e32 = r3c2; + + e33 = r3c3; + +} + + + +inline float Matrix3x3::det(void) + +{ + + return e11*e22*e33 - + + e11*e32*e23 + + + e21*e32*e13 - + + e21*e12*e33 + + + e31*e12*e23 - + + e31*e22*e13; + +} + + + +inline Matrix3x3 Matrix3x3::Transpose(void) + +{ + + return Matrix3x3(e11,e21,e31,e12,e22,e32,e13,e23,e33); + +} + + + +inline Matrix3x3 Matrix3x3::Inverse(void) + +{ + + float d = e11*e22*e33 - + + e11*e32*e23 + + + e21*e32*e13 - + + e21*e12*e33 + + + e31*e12*e23 - + + e31*e22*e13; + + + + if (d == 0) d = 1; + + + + return Matrix3x3( (e22*e33-e23*e32)/d, + + -(e12*e33-e13*e32)/d, + + (e12*e23-e13*e22)/d, + + -(e21*e33-e23*e31)/d, + + (e11*e33-e13*e31)/d, + + -(e11*e23-e13*e21)/d, + + (e21*e32-e22*e31)/d, + + -(e11*e32-e12*e31)/d, + + (e11*e22-e12*e21)/d ); + +} + + + +inline Matrix3x3& Matrix3x3::operator+=(Matrix3x3 m) + +{ + + e11 += m.e11; + + e12 += m.e12; + + e13 += m.e13; + + e21 += m.e21; + + e22 += m.e22; + + e23 += m.e23; + + e31 += m.e31; + + e32 += m.e32; + + e33 += m.e33; + + return *this; + +} + + + +inline Matrix3x3& Matrix3x3::operator-=(Matrix3x3 m) + +{ + + e11 -= m.e11; + + e12 -= m.e12; + + e13 -= m.e13; + + e21 -= m.e21; + + e22 -= m.e22; + + e23 -= m.e23; + + e31 -= m.e31; + + e32 -= m.e32; + + e33 -= m.e33; + + return *this; + +} + + + +inline Matrix3x3& Matrix3x3::operator*=(float s) + +{ + + e11 *= s; + + e12 *= s; + + e13 *= s; + + e21 *= s; + + e22 *= s; + + e23 *= s; + + e31 *= s; + + e32 *= s; + + e33 *= s; + + return *this; + +} + + + +inline Matrix3x3& Matrix3x3::operator/=(float s) + +{ + + e11 /= s; + + e12 /= s; + + e13 /= s; + + e21 /= s; + + e22 /= s; + + e23 /= s; + + e31 /= s; + + e32 /= s; + + e33 /= s; + + return *this; + +} + + + +inline Matrix3x3 operator+(Matrix3x3 m1, Matrix3x3 m2) + +{ + + return Matrix3x3( m1.e11+m2.e11, + + m1.e12+m2.e12, + + m1.e13+m2.e13, + + m1.e21+m2.e21, + + m1.e22+m2.e22, + + m1.e23+m2.e23, + + m1.e31+m2.e31, + + m1.e32+m2.e32, + + m1.e33+m2.e33); + +} + + + +inline Matrix3x3 operator-(Matrix3x3 m1, Matrix3x3 m2) + +{ + + return Matrix3x3( m1.e11-m2.e11, + + m1.e12-m2.e12, + + m1.e13-m2.e13, + + m1.e21-m2.e21, + + m1.e22-m2.e22, + + m1.e23-m2.e23, + + m1.e31-m2.e31, + + m1.e32-m2.e32, + + m1.e33-m2.e33); + +} + + + +inline Matrix3x3 operator/(Matrix3x3 m, float s) + +{ + + return Matrix3x3( m.e11/s, + + m.e12/s, + + m.e13/s, + + m.e21/s, + + m.e22/s, + + m.e23/s, + + m.e31/s, + + m.e32/s, + + m.e33/s); + +} + + + +inline Matrix3x3 operator*(Matrix3x3 m1, Matrix3x3 m2) + +{ + + return Matrix3x3( m1.e11*m2.e11 + m1.e12*m2.e21 + m1.e13*m2.e31, + + m1.e11*m2.e12 + m1.e12*m2.e22 + m1.e13*m2.e32, + + m1.e11*m2.e13 + m1.e12*m2.e23 + m1.e13*m2.e33, + + m1.e21*m2.e11 + m1.e22*m2.e21 + m1.e23*m2.e31, + + m1.e21*m2.e12 + m1.e22*m2.e22 + m1.e23*m2.e32, + + m1.e21*m2.e13 + m1.e22*m2.e23 + m1.e23*m2.e33, + + m1.e31*m2.e11 + m1.e32*m2.e21 + m1.e33*m2.e31, + + m1.e31*m2.e12 + m1.e32*m2.e22 + m1.e33*m2.e32, + + m1.e31*m2.e13 + m1.e32*m2.e23 + m1.e33*m2.e33 ); + +} + + + +inline Matrix3x3 operator*(Matrix3x3 m, float s) + +{ + + return Matrix3x3( m.e11*s, + + m.e12*s, + + m.e13*s, + + m.e21*s, + + m.e22*s, + + m.e23*s, + + m.e31*s, + + m.e32*s, + + m.e33*s); + +} + + + +inline Matrix3x3 operator*(float s, Matrix3x3 m) + +{ + + return Matrix3x3( m.e11*s, + + m.e12*s, + + m.e13*s, + + m.e21*s, + + m.e22*s, + + m.e23*s, + + m.e31*s, + + m.e32*s, + + m.e33*s); + +} + + + +inline Vector operator*(Matrix3x3 m, Vector u) + +{ + + return Vector( m.e11*u.x + m.e12*u.y + m.e13*u.z, + + m.e21*u.x + m.e22*u.y + m.e23*u.z, + + m.e31*u.x + m.e32*u.y + m.e33*u.z); + +} + + + +inline Vector operator*(Vector u, Matrix3x3 m) + +{ + + return Vector( u.x*m.e11 + u.y*m.e21 + u.z*m.e31, + + u.x*m.e12 + u.y*m.e22 + u.z*m.e32, + + u.x*m.e13 + u.y*m.e23 + u.z*m.e33); + +} + + + +//------------------------------------------------------------------------// + +// Quaternion Class and Quaternion functions + +//------------------------------------------------------------------------// + + + +class Quaternion { + +public: + + float n; // number (scalar) part + + Vector v; // vector part: v.x, v.y, v.z + + + + Quaternion(void); + + Quaternion(float e0, float e1, float e2, float e3); + + + + float Magnitude(void); + + Vector GetVector(void); + + float GetScalar(void); + + Quaternion operator+=(Quaternion q); + + Quaternion operator-=(Quaternion q); + + Quaternion operator*=(float s); + + Quaternion operator/=(float s); + + Quaternion operator~(void) const { return Quaternion(n, -v.x, -v.y, -v.z);} + +}; + + + +inline Quaternion operator+(Quaternion q1, Quaternion q2); + +inline Quaternion operator-(Quaternion q1, Quaternion q2); + +inline Quaternion operator*(Quaternion q1, Quaternion q2); + +inline Quaternion operator*(Quaternion q, float s); + +inline Quaternion operator*(float s, Quaternion q); + +inline Quaternion operator*(Quaternion q, Vector v); + +inline Quaternion operator*(Vector v, Quaternion q); + +inline Quaternion operator/(Quaternion q, float s); + +inline float QGetAngle(Quaternion q); + +inline Vector QGetAxis(Quaternion q); + +inline Quaternion QRotate(Quaternion q1, Quaternion q2); + +inline Vector QVRotate(Quaternion q, Vector v); + +inline Quaternion MakeQFromEulerAngles(float x, float y, float z); + +inline Vector MakeEulerAnglesFromQ(Quaternion q); + + + + + +inline Quaternion::Quaternion(void) + +{ + + n = 0; + + v.x = 0; + + v.y = 0; + + v.z = 0; + +} + + + +inline Quaternion::Quaternion(float e0, float e1, float e2, float e3) + +{ + + n = e0; + + v.x = e1; + + v.y = e2; + + v.z = e3; + +} + + + +inline float Quaternion::Magnitude(void) + +{ + + return (float) fast_sqrt(n*n + v.x*v.x + v.y*v.y + v.z*v.z); + +} + + + +inline Vector Quaternion::GetVector(void) + +{ + + return Vector(v.x, v.y, v.z); + +} + + + +inline float Quaternion::GetScalar(void) + +{ + + return n; + +} + + + +inline Quaternion Quaternion::operator+=(Quaternion q) + +{ + + n += q.n; + + v.x += q.v.x; + + v.y += q.v.y; + + v.z += q.v.z; + + return *this; + +} + + + +inline Quaternion Quaternion::operator-=(Quaternion q) + +{ + + n -= q.n; + + v.x -= q.v.x; + + v.y -= q.v.y; + + v.z -= q.v.z; + + return *this; + +} + + + +inline Quaternion Quaternion::operator*=(float s) + +{ + + n *= s; + + v.x *= s; + + v.y *= s; + + v.z *= s; + + return *this; + +} + + + +inline Quaternion Quaternion::operator/=(float s) + +{ + + n /= s; + + v.x /= s; + + v.y /= s; + + v.z /= s; + + return *this; + +} + + + +/*inline Quaternion Quaternion::operator~() + +{ + + return Quaternion(n, -v.x, -v.y, -v.z); + +}*/ + + + +inline Quaternion operator+(Quaternion q1, Quaternion q2) + +{ + + return Quaternion( q1.n + q2.n, + + q1.v.x + q2.v.x, + + q1.v.y + q2.v.y, + + q1.v.z + q2.v.z); + +} + + + +inline Quaternion operator-(Quaternion q1, Quaternion q2) + +{ + + return Quaternion( q1.n - q2.n, + + q1.v.x - q2.v.x, + + q1.v.y - q2.v.y, + + q1.v.z - q2.v.z); + +} + + + +inline Quaternion operator*(Quaternion q1, Quaternion q2) + +{ + + return Quaternion( q1.n*q2.n - q1.v.x*q2.v.x - q1.v.y*q2.v.y - q1.v.z*q2.v.z, + + q1.n*q2.v.x + q1.v.x*q2.n + q1.v.y*q2.v.z - q1.v.z*q2.v.y, + + q1.n*q2.v.y + q1.v.y*q2.n + q1.v.z*q2.v.x - q1.v.x*q2.v.z, + + q1.n*q2.v.z + q1.v.z*q2.n + q1.v.x*q2.v.y - q1.v.y*q2.v.x); + +} + + + +inline Quaternion operator*(Quaternion q, float s) + +{ + + return Quaternion(q.n*s, q.v.x*s, q.v.y*s, q.v.z*s); + +} + + + +inline Quaternion operator*(float s, Quaternion q) + +{ + + return Quaternion(q.n*s, q.v.x*s, q.v.y*s, q.v.z*s); + +} + + + +inline Quaternion operator*(Quaternion q, Vector v) + +{ + + return Quaternion( -(q.v.x*v.x + q.v.y*v.y + q.v.z*v.z), + + q.n*v.x + q.v.y*v.z - q.v.z*v.y, + + q.n*v.y + q.v.z*v.x - q.v.x*v.z, + + q.n*v.z + q.v.x*v.y - q.v.y*v.x); + +} + + + +inline Quaternion operator*(Vector v, Quaternion q) + +{ + + return Quaternion( -(q.v.x*v.x + q.v.y*v.y + q.v.z*v.z), + + q.n*v.x + q.v.z*v.y - q.v.y*v.z, + + q.n*v.y + q.v.x*v.z - q.v.z*v.x, + + q.n*v.z + q.v.y*v.x - q.v.x*v.y); + +} + + + +inline Quaternion operator/(Quaternion q, float s) + +{ + + return Quaternion(q.n/s, q.v.x/s, q.v.y/s, q.v.z/s); + +} + + + +inline float QGetAngle(Quaternion q) + +{ + + return (float) (2*acos(q.n)); + +} + + + +inline Vector QGetAxis(Quaternion q) + +{ + + Vector v; + + float m; + + + + v = q.GetVector(); + + m = v.Magnitude(); + + + + if (m <= tol) + + return Vector(); + + else + + return v/m; + +} + + + +inline Quaternion QRotate(Quaternion q1, Quaternion q2) + +{ + + return q1*q2*(~q1); + +} + + + +inline Vector QVRotate(Quaternion q, Vector v) + +{ + + Quaternion t; + + + + + + t = q*v*(~q); + + + + return t.GetVector(); + +} + + + +inline Quaternion MakeQFromEulerAngles(float x, float y, float z) + +{ + + Quaternion q; + + double roll = DegreesToRadians(x); + + double pitch = DegreesToRadians(y); + + double yaw = DegreesToRadians(z); + + + + double cyaw, cpitch, croll, syaw, spitch, sroll; + + double cyawcpitch, syawspitch, cyawspitch, syawcpitch; + + + + cyaw = cos(0.5f * yaw); + + cpitch = cos(0.5f * pitch); + + croll = cos(0.5f * roll); + + syaw = sin(0.5f * yaw); + + spitch = sin(0.5f * pitch); + + sroll = sin(0.5f * roll); + + + + cyawcpitch = cyaw*cpitch; + + syawspitch = syaw*spitch; + + cyawspitch = cyaw*spitch; + + syawcpitch = syaw*cpitch; + + + + q.n = (float) (cyawcpitch * croll + syawspitch * sroll); + + q.v.x = (float) (cyawcpitch * sroll - syawspitch * croll); + + q.v.y = (float) (cyawspitch * croll + syawcpitch * sroll); + + q.v.z = (float) (syawcpitch * croll - cyawspitch * sroll); + + + + return q; + +} + + + +inline Vector MakeEulerAnglesFromQ(Quaternion q) + +{ + + double r11, r21, r31, r32, r33, r12, r13; + + double q00, q11, q22, q33; + + double tmp; + + Vector u; + + + + q00 = q.n * q.n; + + q11 = q.v.x * q.v.x; + + q22 = q.v.y * q.v.y; + + q33 = q.v.z * q.v.z; + + + + r11 = q00 + q11 - q22 - q33; + + r21 = 2 * (q.v.x*q.v.y + q.n*q.v.z); + + r31 = 2 * (q.v.x*q.v.z - q.n*q.v.y); + + r32 = 2 * (q.v.y*q.v.z + q.n*q.v.x); + + r33 = q00 - q11 - q22 + q33; + + + + tmp = fabs(r31); + + if(tmp > 0.999999) + + { + + r12 = 2 * (q.v.x*q.v.y - q.n*q.v.z); + + r13 = 2 * (q.v.x*q.v.z + q.n*q.v.y); + + + + u.x = RadiansToDegrees(0.0f); //roll + + u.y = RadiansToDegrees((float) (-(pi/2) * r31/tmp)); // pitch + + u.z = RadiansToDegrees((float) atan2(-r12, -r31*r13)); // yaw + + return u; + + } + + + + u.x = RadiansToDegrees((float) atan2(r32, r33)); // roll + + u.y = RadiansToDegrees((float) asin(-r31)); // pitch + + u.z = RadiansToDegrees((float) atan2(r21, r11)); // yaw + + return u; + + + + + +} + + + + + + + + + + + +#endif + diff --git a/src/Quaternions.cpp b/src/Quaternions.cpp new file mode 100644 index 0000000..464c0f2 --- /dev/null +++ b/src/Quaternions.cpp @@ -0,0 +1,747 @@ +#include "Quaternions.h" + +// Functions +quaternion Quat_Mult(quaternion q1, quaternion q2) +{ + quaternion QResult; + float a, b, c, d, e, f, g, h; + a = (q1.w + q1.x) * (q2.w + q2.x); + b = (q1.z - q1.y) * (q2.y - q2.z); + c = (q1.w - q1.x) * (q2.y + q2.z); + d = (q1.y + q1.z) * (q2.w - q2.x); + e = (q1.x + q1.z) * (q2.x + q2.y); + f = (q1.x - q1.z) * (q2.x - q2.y); + g = (q1.w + q1.y) * (q2.w - q2.z); + h = (q1.w - q1.y) * (q2.w + q2.z); + QResult.w = b + (-e - f + g + h) / 2; + QResult.x = a - (e + f + g + h) / 2; + QResult.y = c + (e - f + g - h) / 2; + QResult.z = d + (e - f - g + h) / 2; + return QResult; +} + +XYZ XYZ::operator+(XYZ add){ + XYZ ne; + ne=add; + ne.x+=x; + ne.y+=y; + ne.z+=z; + return ne; +} + +XYZ XYZ::operator-(XYZ add){ + XYZ ne; + ne=add; + ne.x=x-ne.x; + ne.y=y-ne.y; + ne.z=z-ne.z; + return ne; +} + +XYZ XYZ::operator*(float add){ + XYZ ne; + ne.x=x*add; + ne.y=y*add; + ne.z=z*add; + return ne; +} + +XYZ XYZ::operator*(XYZ add){ + XYZ ne; + ne.x=x*add.x; + ne.y=y*add.y; + ne.z=z*add.z; + return ne; +} + +XYZ XYZ::operator/(float add){ + XYZ ne; + ne.x=x/add; + ne.y=y/add; + ne.z=z/add; + return ne; +} + +void XYZ::operator+=(XYZ add){ + x+=add.x; + y+=add.y; + z+=add.z; +} + +void XYZ::operator-=(XYZ add){ + x=x-add.x; + y=y-add.y; + z=z-add.z; +} + +void XYZ::operator*=(float add){ + x=x*add; + y=y*add; + z=z*add; +} + +void XYZ::operator*=(XYZ add){ + x=x*add.x; + y=y*add.y; + z=z*add.z; +} + +void XYZ::operator/=(float add){ + x=x/add; + y=y/add; + z=z/add; +} + +void XYZ::operator=(float add){ + x=add; + y=add; + z=add; +} + +void XYZ::vec(Vector add){ + x=add.x; + y=add.y; + z=add.z; +} + +bool XYZ::operator==(XYZ add){ + if(x==add.x&&y==add.y&&z==add.z)return 1; + return 0; +} + +quaternion To_Quat(Matrix_t m) +{ + // From Jason Shankel, (C) 2000. + quaternion Quat; + + double Tr = m[0][0] + m[1][1] + m[2][2] + 1.0, fourD; + double q[4]; + + int i,j,k; + if (Tr >= 1.0) + { + fourD = 2.0*fast_sqrt(Tr); + q[3] = fourD/4.0; + q[0] = (m[2][1] - m[1][2]) / fourD; + q[1] = (m[0][2] - m[2][0]) / fourD; + q[2] = (m[1][0] - m[0][1]) / fourD; + } + else + { + if (m[0][0] > m[1][1]) + { + i = 0; + } + else + { + i = 1; + } + if (m[2][2] > m[i][i]) + { + i = 2; + } + j = (i+1)%3; + k = (j+1)%3; + fourD = 2.0*fast_sqrt(m[i][i] - m[j][j] - m[k][k] + 1.0); + q[i] = fourD / 4.0; + q[j] = (m[j][i] + m[i][j]) / fourD; + q[k] = (m[k][i] + m[i][k]) / fourD; + q[3] = (m[j][k] - m[k][j]) / fourD; + } + + Quat.x = q[0]; + Quat.y = q[1]; + Quat.z = q[2]; + Quat.w = q[3]; + return Quat; +} +void Quat_2_Matrix(quaternion Quat, Matrix_t m) +{ + // From the GLVelocity site (http://glvelocity.gamedev.net) + float fW = Quat.w; + float fX = Quat.x; + float fY = Quat.y; + float fZ = Quat.z; + float fXX = fX * fX; + float fYY = fY * fY; + float fZZ = fZ * fZ; + m[0][0] = 1.0f - 2.0f * (fYY + fZZ); + m[1][0] = 2.0f * (fX * fY + fW * fZ); + m[2][0] = 2.0f * (fX * fZ - fW * fY); + m[3][0] = 0.0f; + m[0][1] = 2.0f * (fX * fY - fW * fZ); + m[1][1] = 1.0f - 2.0f * (fXX + fZZ); + m[2][1] = 2.0f * (fY * fZ + fW * fX); + m[3][1] = 0.0f; + m[0][2] = 2.0f * (fX * fZ + fW * fY); + m[1][2] = 2.0f * (fX * fZ - fW * fX); + m[2][2] = 1.0f - 2.0f * (fXX + fYY); + m[3][2] = 0.0f; + m[0][3] = 0.0f; + m[1][3] = 0.0f; + m[2][3] = 0.0f; + m[3][3] = 1.0f; +} +quaternion To_Quat(angle_axis Ang_Ax) +{ + // From the Quaternion Powers article on gamedev.net + quaternion Quat; + + Quat.x = Ang_Ax.x * sin(Ang_Ax.angle / 2); + Quat.y = Ang_Ax.y * sin(Ang_Ax.angle / 2); + Quat.z = Ang_Ax.z * sin(Ang_Ax.angle / 2); + Quat.w = cos(Ang_Ax.angle / 2); + return Quat; +} +angle_axis Quat_2_AA(quaternion Quat) +{ + angle_axis Ang_Ax; + float scale, tw; + tw = (float)acos(Quat.w) * 2; + scale = (float)sin(tw / 2.0); + Ang_Ax.x = Quat.x / scale; + Ang_Ax.y = Quat.y / scale; + Ang_Ax.z = Quat.z / scale; + + Ang_Ax.angle = 2.0 * acos(Quat.w)/(float)PI*180; + return Ang_Ax; +} + +quaternion To_Quat(int In_Degrees, euler Euler) +{ + // From the gamasutra quaternion article + quaternion Quat; + float cr, cp, cy, sr, sp, sy, cpcy, spsy; + //If we are in Degree mode, convert to Radians + if (In_Degrees) { + Euler.x = Euler.x * (float)PI / 180; + Euler.y = Euler.y * (float)PI / 180; + Euler.z = Euler.z * (float)PI / 180; + } + //Calculate trig identities + //Formerly roll, pitch, yaw + cr = float(cos(Euler.x/2)); + cp = float(cos(Euler.y/2)); + cy = float(cos(Euler.z/2)); + sr = float(sin(Euler.x/2)); + sp = float(sin(Euler.y/2)); + sy = float(sin(Euler.z/2)); + + cpcy = cp * cy; + spsy = sp * sy; + Quat.w = cr * cpcy + sr * spsy; + Quat.x = sr * cpcy - cr * spsy; + Quat.y = cr * sp * cy + sr * cp * sy; + Quat.z = cr * cp * sy - sr * sp * cy; + + return Quat; +} + +quaternion QNormalize(quaternion Quat) +{ + float norm; + norm = Quat.x * Quat.x + + Quat.y * Quat.y + + Quat.z * Quat.z + + Quat.w * Quat.w; + Quat.x = float(Quat.x / norm); + Quat.y = float(Quat.y / norm); + Quat.z = float(Quat.z / norm); + Quat.w = float(Quat.w / norm); + return Quat; +} + +XYZ Quat2Vector(quaternion Quat) +{ + QNormalize(Quat); + + float fW = Quat.w; + float fX = Quat.x; + float fY = Quat.y; + float fZ = Quat.z; + + XYZ tempvec; + + tempvec.x = 2.0f*(fX*fZ-fW*fY); + tempvec.y = 2.0f*(fY*fZ+fW*fX); + tempvec.z = 1.0f-2.0f*(fX*fX+fY*fY); + + return tempvec; +} + +void CrossProduct(XYZ P, XYZ Q, XYZ *V){ + V->x = P.y * Q.z - P.z * Q.y; + V->y = P.z * Q.x - P.x * Q.z; + V->z = P.x * Q.y - P.y * Q.x; +} + +void Normalise(XYZ *vectory) { + float d = fast_sqrt(vectory->x*vectory->x+vectory->y*vectory->y+vectory->z*vectory->z); + if(d==0){return;} + vectory->x /= d; + vectory->y /= d; + vectory->z /= d; +} + +float fast_sqrt (register float arg) +{ +#ifdef OS9 + // Can replace with slower return std::sqrt(arg); + register float result; + + if (arg == 0.0) return 0.0; + + asm { + frsqrte result,arg // Calculate Square root + } + + // Newton Rhapson iterations. + result = result + 0.5 * result * (1.0 - arg * result * result); + result = result + 0.5 * result * (1.0 - arg * result * result); + + return result * arg; +#else + return sqrt(arg); +#endif +} + +float normaldotproduct(XYZ point1, XYZ point2){ + GLfloat returnvalue; + Normalise(&point1); + Normalise(&point2); + returnvalue=(point1.x*point2.x+point1.y*point2.y+point1.z*point2.z); + return returnvalue; +} + +extern float u0, u1, u2; +extern float v0, v1, v2; +extern float a, b; +extern int i, j; +extern bool bInter; +extern float pointv[3]; +extern float p1v[3]; +extern float p2v[3]; +extern float p3v[3]; +extern float normalv[3]; + +bool PointInTriangle(Vector *p, Vector normal, float p11, float p12, float p13, float p21, float p22, float p23, float p31, float p32, float p33) +{ + bInter=0; + + pointv[0]=p->x; + pointv[1]=p->y; + pointv[2]=p->z; + + + p1v[0]=p11; + p1v[1]=p12; + p1v[2]=p13; + + p2v[0]=p21; + p2v[1]=p22; + p2v[2]=p23; + + p3v[0]=p31; + p3v[1]=p32; + p3v[2]=p33; + + normalv[0]=normal.x; + normalv[1]=normal.y; + normalv[2]=normal.z; + +#define ABS(X) (((X)<0.f)?-(X):(X) ) +#define MAX(A, B) (((A)<(B))?(B):(A)) + float max = MAX(MAX(ABS(normalv[0]), ABS(normalv[1])), ABS(normalv[2])); +#undef MAX + if (max == ABS(normalv[0])) {i = 1; j = 2;} // y, z + if (max == ABS(normalv[1])) {i = 0; j = 2;} // x, z + if (max == ABS(normalv[2])) {i = 0; j = 1;} // x, y +#undef ABS + + u0 = pointv[i] - p1v[i]; + v0 = pointv[j] - p1v[j]; + u1 = p2v[i] - p1v[i]; + v1 = p2v[j] - p1v[j]; + u2 = p3v[i] - p1v[i]; + v2 = p3v[j] - p1v[j]; + + if (u1 > -1.0e-05f && u1 < 1.0e-05f)// == 0.0f) + { + b = u0 / u2; + if (0.0f <= b && b <= 1.0f) + { + a = (v0 - b * v2) / v1; + if ((a >= 0.0f) && (( a + b ) <= 1.0f)) + bInter = 1; + } + } + else + { + b = (v0 * u1 - u0 * v1) / (v2 * u1 - u2 * v1); + if (0.0f <= b && b <= 1.0f) + { + a = (u0 - b * u2) / u1; + if ((a >= 0.0f) && (( a + b ) <= 1.0f )) + bInter = 1; + } + } + + return bInter; +} + +bool LineFacet(Vector p1,Vector p2,Vector pa,Vector pb,Vector pc,Vector *p) +{ + float d; + float a1,a2,a3; + float total,denom,mu; + Vector n,pa1,pa2,pa3; + + //Calculate the parameters for the plane + n.x = (pb.y - pa.y)*(pc.z - pa.z) - (pb.z - pa.z)*(pc.y - pa.y); + n.y = (pb.z - pa.z)*(pc.x - pa.x) - (pb.x - pa.x)*(pc.z - pa.z); + n.z = (pb.x - pa.x)*(pc.y - pa.y) - (pb.y - pa.y)*(pc.x - pa.x); + n.Normalize(); + d = - n.x * pa.x - n.y * pa.y - n.z * pa.z; + + //Calculate the position on the line that intersects the plane + denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z); + if (abs(denom) < 0.0000001) // Line and plane don't intersect + return 0; + mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom; + p->x = p1.x + mu * (p2.x - p1.x); + p->y = p1.y + mu * (p2.y - p1.y); + p->z = p1.z + mu * (p2.z - p1.z); + if (mu < 0 || mu > 1) // Intersection not along line segment + return 0; + + if(!PointInTriangle( p, n, pa.x, pa.y, pa.z, pb.x, pb.y, pb.z, pc.x, pc.y, pc.z)){return 0;} + + return 1; +} + +bool PointInTriangle(XYZ *p, XYZ normal, XYZ *p1, XYZ *p2, XYZ *p3) +{ + bInter=0; + + pointv[0]=p->x; + pointv[1]=p->y; + pointv[2]=p->z; + + + p1v[0]=p1->x; + p1v[1]=p1->y; + p1v[2]=p1->z; + + p2v[0]=p2->x; + p2v[1]=p2->y; + p2v[2]=p2->z; + + p3v[0]=p3->x; + p3v[1]=p3->y; + p3v[2]=p3->z; + + normalv[0]=normal.x; + normalv[1]=normal.y; + normalv[2]=normal.z; + +#define ABS(X) (((X)<0.f)?-(X):(X) ) +#define MAX(A, B) (((A)<(B))?(B):(A)) + float max = MAX(MAX(ABS(normalv[0]), ABS(normalv[1])), ABS(normalv[2])); +#undef MAX + if (max == ABS(normalv[0])) {i = 1; j = 2;} // y, z + if (max == ABS(normalv[1])) {i = 0; j = 2;} // x, z + if (max == ABS(normalv[2])) {i = 0; j = 1;} // x, y +#undef ABS + + u0 = pointv[i] - p1v[i]; + v0 = pointv[j] - p1v[j]; + u1 = p2v[i] - p1v[i]; + v1 = p2v[j] - p1v[j]; + u2 = p3v[i] - p1v[i]; + v2 = p3v[j] - p1v[j]; + + if (u1 > -1.0e-05f && u1 < 1.0e-05f)// == 0.0f) + { + b = u0 / u2; + if (0.0f <= b && b <= 1.0f) + { + a = (v0 - b * v2) / v1; + if ((a >= 0.0f) && (( a + b ) <= 1.0f)) + bInter = 1; + } + } + else + { + b = (v0 * u1 - u0 * v1) / (v2 * u1 - u2 * v1); + if (0.0f <= b && b <= 1.0f) + { + a = (u0 - b * u2) / u1; + if ((a >= 0.0f) && (( a + b ) <= 1.0f )) + bInter = 1; + } + } + + return bInter; +} + +bool LineFacet(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ *p) +{ + float d; + float a1,a2,a3; + float total,denom,mu; + XYZ n,pa1,pa2,pa3; + + //Calculate the parameters for the plane + n.x = (pb.y - pa.y)*(pc.z - pa.z) - (pb.z - pa.z)*(pc.y - pa.y); + n.y = (pb.z - pa.z)*(pc.x - pa.x) - (pb.x - pa.x)*(pc.z - pa.z); + n.z = (pb.x - pa.x)*(pc.y - pa.y) - (pb.y - pa.y)*(pc.x - pa.x); + Normalise(&n); + d = - n.x * pa.x - n.y * pa.y - n.z * pa.z; + + //Calculate the position on the line that intersects the plane + denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z); + if (abs(denom) < 0.0000001) // Line and plane don't intersect + return 0; + mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom; + p->x = p1.x + mu * (p2.x - p1.x); + p->y = p1.y + mu * (p2.y - p1.y); + p->z = p1.z + mu * (p2.z - p1.z); + if (mu < 0 || mu > 1) // Intersection not along line segment + return 0; + + if(!PointInTriangle( p, n, &pa, &pb, &pc)){return 0;} + + return 1; +} + +extern float d; +extern float a1,a2,a3; +extern float total,denom,mu; +extern XYZ pa1,pa2,pa3,n; + +float LineFacetd(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ *p) +{ + + //Calculate the parameters for the plane + n.x = (pb.y - pa.y)*(pc.z - pa.z) - (pb.z - pa.z)*(pc.y - pa.y); + n.y = (pb.z - pa.z)*(pc.x - pa.x) - (pb.x - pa.x)*(pc.z - pa.z); + n.z = (pb.x - pa.x)*(pc.y - pa.y) - (pb.y - pa.y)*(pc.x - pa.x); + Normalise(&n); + d = - n.x * pa.x - n.y * pa.y - n.z * pa.z; + + //Calculate the position on the line that intersects the plane + denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z); + if (abs(denom) < 0.0000001) // Line and plane don't intersect + return 0; + mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom; + p->x = p1.x + mu * (p2.x - p1.x); + p->y = p1.y + mu * (p2.y - p1.y); + p->z = p1.z + mu * (p2.z - p1.z); + if (mu < 0 || mu > 1) // Intersection not along line segment + return 0; + + if(!PointInTriangle( p, n, &pa, &pb, &pc)){return 0;} + + return 1; +} + +float LineFacetd(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc, XYZ n, XYZ *p) +{ + + //Calculate the parameters for the plane + d = - n.x * pa.x - n.y * pa.y - n.z * pa.z; + + //Calculate the position on the line that intersects the plane + denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z); + if (abs(denom) < 0.0000001) // Line and plane don't intersect + return 0; + mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom; + p->x = p1.x + mu * (p2.x - p1.x); + p->y = p1.y + mu * (p2.y - p1.y); + p->z = p1.z + mu * (p2.z - p1.z); + if (mu < 0 || mu > 1) // Intersection not along line segment + return 0; + + if(!PointInTriangle( p, n, &pa, &pb, &pc)){return 0;} + return 1; +} + +float LineFacetd(XYZ *p1,XYZ *p2,XYZ *pa,XYZ *pb,XYZ *pc, XYZ *n, XYZ *p) +{ + + //Calculate the parameters for the plane + d = - n->x * pa->x - n->y * pa->y - n->z * pa->z; + + //Calculate the position on the line that intersects the plane + denom = n->x * (p2->x - p1->x) + n->y * (p2->y - p1->y) + n->z * (p2->z - p1->z); + if (abs(denom) < 0.0000001) // Line and plane don't intersect + return 0; + mu = - (d + n->x * p1->x + n->y * p1->y + n->z * p1->z) / denom; + p->x = p1->x + mu * (p2->x - p1->x); + p->y = p1->y + mu * (p2->y - p1->y); + p->z = p1->z + mu * (p2->z - p1->z); + if (mu < 0 || mu > 1) // Intersection not along line segment + return 0; + + if(!PointInTriangle( p, *n, pa, pb, pc)){return 0;} + return 1; +} + +void ReflectVector(XYZ *vel, XYZ *n) +{ + XYZ vn; + XYZ vt; + float dotprod; + + dotprod=dotproduct(*n,*vel); + vn.x=n->x*dotprod; + vn.y=n->y*dotprod; + vn.z=n->z*dotprod; + + vt.x=vel->x-vn.x; + vt.y=vel->y-vn.y; + vt.z=vel->z-vn.z; + + vel->x = vt.x - vn.x; + vel->y = vt.y - vn.y; + vel->z = vt.z - vn.z; +} + +float dotproduct(XYZ point1, XYZ point2){ + GLfloat returnvalue; + returnvalue=(point1.x*point2.x+point1.y*point2.y+point1.z*point2.z); + return returnvalue; +} + +float findDistance(XYZ point1, XYZ point2){ + return(fast_sqrt((point1.x-point2.x)*(point1.x-point2.x)+(point1.y-point2.y)*(point1.y-point2.y)+(point1.z-point2.z)*(point1.z-point2.z))); +} + +float findLength(XYZ point1){ + return(fast_sqrt((point1.x)*(point1.x)+(point1.y)*(point1.y)+(point1.z)*(point1.z))); +} + + +float findLengthfast(XYZ point1){ + return((point1.x)*(point1.x)+(point1.y)*(point1.y)+(point1.z)*(point1.z)); +} + +float findDistancefast(XYZ point1, XYZ point2){ + return((point1.x-point2.x)*(point1.x-point2.x)+(point1.y-point2.y)*(point1.y-point2.y)+(point1.z-point2.z)*(point1.z-point2.z)); +} + +XYZ DoRotation(XYZ thePoint, float xang, float yang, float zang){ + XYZ newpoint; + if(xang){ + xang*=6.283185; + xang/=360; + } + if(yang){ + yang*=6.283185; + yang/=360; + } + if(zang){ + zang*=6.283185; + zang/=360; + } + + + if(yang){ + newpoint.z=thePoint.z*cos(yang)-thePoint.x*sin(yang); + newpoint.x=thePoint.z*sin(yang)+thePoint.x*cos(yang); + thePoint.z=newpoint.z; + thePoint.x=newpoint.x; + } + + if(zang){ + newpoint.x=thePoint.x*cos(zang)-thePoint.y*sin(zang); + newpoint.y=thePoint.y*cos(zang)+thePoint.x*sin(zang); + thePoint.x=newpoint.x; + thePoint.y=newpoint.y; + } + + if(xang){ + newpoint.y=thePoint.y*cos(xang)-thePoint.z*sin(xang); + newpoint.z=thePoint.y*sin(xang)+thePoint.z*cos(xang); + thePoint.z=newpoint.z; + thePoint.y=newpoint.y; + } + + return thePoint; +} + +float square( float f ) { return (f*f) ;} + +bool sphere_line_intersection ( + float x1, float y1 , float z1, + float x2, float y2 , float z2, + float x3, float y3 , float z3, float r ) +{ + + // x1,y1,z1 P1 coordinates (point of line) + // x2,y2,z2 P2 coordinates (point of line) + // x3,y3,z3, r P3 coordinates and radius (sphere) + // x,y,z intersection coordinates + // + // This function returns a pointer array which first index indicates + // the number of intersection point, followed by coordinate pairs. + + float x , y , z; + float a, b, c, mu, i ; + + if(x1>x3+r&&x2>x3+r)return(0); + if(x1<x3-r&&x2<x3-r)return(0); + if(y1>y3+r&&y2>y3+r)return(0); + if(y1<y3-r&&y2<y3-r)return(0); + if(z1>z3+r&&z2>z3+r)return(0); + if(z1<z3-r&&z2<z3-r)return(0); + a = square(x2 - x1) + square(y2 - y1) + square(z2 - z1); + b = 2* ( (x2 - x1)*(x1 - x3) + + (y2 - y1)*(y1 - y3) + + (z2 - z1)*(z1 - z3) ) ; + c = square(x3) + square(y3) + + square(z3) + square(x1) + + square(y1) + square(z1) - + 2* ( x3*x1 + y3*y1 + z3*z1 ) - square(r) ; + i = b * b - 4 * a * c ; + + if ( i < 0.0 ) + { + // no intersection + return(0); + } + + return(1); +} + +XYZ DoRotationRadian(XYZ thePoint, float xang, float yang, float zang){ + XYZ newpoint; + XYZ oldpoint; + + oldpoint=thePoint; + + if(yang!=0){ + newpoint.z=oldpoint.z*cos(yang)-oldpoint.x*sin(yang); + newpoint.x=oldpoint.z*sin(yang)+oldpoint.x*cos(yang); + oldpoint.z=newpoint.z; + oldpoint.x=newpoint.x; + } + + if(zang!=0){ + newpoint.x=oldpoint.x*cos(zang)-oldpoint.y*sin(zang); + newpoint.y=oldpoint.y*cos(zang)+oldpoint.x*sin(zang); + oldpoint.x=newpoint.x; + oldpoint.y=newpoint.y; + } + + if(xang!=0){ + newpoint.y=oldpoint.y*cos(xang)-oldpoint.z*sin(xang); + newpoint.z=oldpoint.y*sin(xang)+oldpoint.z*cos(xang); + oldpoint.z=newpoint.z; + oldpoint.y=newpoint.y; + } + + return oldpoint; + +} + diff --git a/src/Quaternions.h b/src/Quaternions.h new file mode 100644 index 0000000..0a0ca4f --- /dev/null +++ b/src/Quaternions.h @@ -0,0 +1,94 @@ + +#ifndef _QUATERNIONS_H_ +#define _QUATERNIONS_H_ + +#ifdef OS9 +#pragma mark - +#endif + +#include "Maths.h" +#ifdef OS9 +#include <gl.h> +#else +#include <GL/gl.h> +#endif +#include "PhysicsMath.h" + +/**> Quaternion Structures <**/ +#define PI 3.14159265355555897932384626 +#define RADIANS 0 +#define DEGREES 1 +#define deg2rad .0174532925 + +using namespace std; +typedef float Matrix_t [4][4]; +struct euler +{ + float x, y, z; +}; +struct angle_axis +{ + float x, y, z, angle; +}; +struct quaternion +{ + float x, y, z, w; +}; + +class XYZ{ + public: + float x; + float y; + float z; + XYZ operator+(XYZ add); + XYZ operator-(XYZ add); + XYZ operator*(float add); + XYZ operator*(XYZ add); + XYZ operator/(float add); + void operator+=(XYZ add); + void operator-=(XYZ add); + void operator*=(float add); + void operator*=(XYZ add); + void operator/=(float add); + void operator=(float add); + void vec(Vector add); + bool operator==(XYZ add); +}; + +/*********************> Quaternion Function definition <********/ +quaternion To_Quat(int Degree_Flag, euler Euler); +quaternion To_Quat(angle_axis Ang_Ax); +quaternion To_Quat(Matrix_t m); +angle_axis Quat_2_AA(quaternion Quat); +void Quat_2_Matrix(quaternion Quat, Matrix_t m); +quaternion Normalize(quaternion Quat); +quaternion Quat_Mult(quaternion q1, quaternion q2); +quaternion QNormalize(quaternion Quat); +XYZ Quat2Vector(quaternion Quat); + +void CrossProduct(XYZ P, XYZ Q, XYZ *V); +void Normalise(XYZ *vectory); +float normaldotproduct(XYZ point1, XYZ point2); +float fast_sqrt (register float arg); +bool PointInTriangle(XYZ *p, XYZ normal, XYZ *p1, XYZ *p2, XYZ *p3); +bool LineFacet(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ *p); +float LineFacetd(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ *p); +float LineFacetd(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ n, XYZ *p); +float LineFacetd(XYZ *p1,XYZ *p2,XYZ *pa,XYZ *pb,XYZ *pc,XYZ *n, XYZ *p); +bool PointInTriangle(Vector *p, Vector normal, float p11, float p12, float p13, float p21, float p22, float p23, float p31, float p32, float p33); +bool LineFacet(Vector p1,Vector p2,Vector pa,Vector pb,Vector pc,Vector *p); +void ReflectVector(XYZ *vel, XYZ *n); +XYZ DoRotation(XYZ thePoint, float xang, float yang, float zang); +XYZ DoRotationRadian(XYZ thePoint, float xang, float yang, float zang); +float findDistance(XYZ point1, XYZ point2); +float findLength(XYZ point1); +float findLengthfast(XYZ point1); +float findDistancefast(XYZ point1, XYZ point2); +float dotproduct(XYZ point1, XYZ point2); +bool sphere_line_intersection ( + float x1, float y1 , float z1, + float x2, float y2 , float z2, + float x3, float y3 , float z3, float r ); + +#endif + diff --git a/src/SConstruct b/src/SConstruct new file mode 100644 index 0000000..70fa779 --- /dev/null +++ b/src/SConstruct @@ -0,0 +1,10 @@ +Program( + 'blackshades', + Split('Camera.cpp Decals.cpp Fog.cpp Frustum.cpp GameDraw.cpp GameInitDispose.cpp GameLoop.cpp GameTick.cpp ' + + 'Globals.cpp MacInput.cpp Main.cpp Maths.cpp Models.cpp Person.cpp Quaternions.cpp Serialize.cpp Skeleton.cpp ' + + 'Sprites.cpp Support.cpp Text.cpp Timer.cpp Textures.cpp'), + CPPDEFS=['GNUSOURCE=1'], + CPPPATH=['.'], + CPPFLAGS=['-O2', '-Wall' ,'-g'], + LIBS=['GL', 'GLU', 'openal', 'alut', 'SDL', 'SDL_image', 'vorbisfile', 'vorbis'] +) diff --git a/src/Serialize.cpp b/src/Serialize.cpp new file mode 100644 index 0000000..589dcb9 --- /dev/null +++ b/src/Serialize.cpp @@ -0,0 +1,107 @@ +#include <unistd.h> + +#include "Models.h" +#include "Quaternions.h" +#include "Serialize.h" + +/* these all read big-endian data */ + +int ReadBool(int fd, int count, bool *b) +{ + while (count--) { + unsigned char buf[1]; + + if (read(fd, buf, 1) != 1) { + STUB_FUNCTION; + } + + *b = (buf[0] != 0) ? true : false; + + b++; + } + + return 1; +} + +int ReadShort(int fd, int count, short *s) +{ + while (count--) { + unsigned char buf[2]; + + if (read(fd, buf, 2) != 2) { + STUB_FUNCTION; + } + + *s = (short)((buf[0] << 8) | buf[1]); + + s++; + } + + return 1; +} + +int ReadInt(int fd, int count, int *s) +{ + while (count--) { + unsigned char buf[4]; + + if (read(fd, buf, 4) != 4) { + STUB_FUNCTION; + } + + *s = (int)((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]); + + s++; + } + + return 1; +} + +union intfloat { + int i; + float f; +} intfloat; + +int ReadFloat(int fd, int count, float *f) +{ + union intfloat infl; + + while (count--) { + ReadInt(fd, 1, &(infl.i)); + + *f = infl.f; + + f++; + } + + return 1; +} + +int ReadXYZ(int fd, int count, XYZ *xyz) +{ + while (count--) { + ReadFloat(fd, 1, &(xyz->x)); + ReadFloat(fd, 1, &(xyz->y)); + ReadFloat(fd, 1, &(xyz->z)); + + xyz++; + } + + return 1; +} + +int ReadTexturedTriangle(int fd, int count, TexturedTriangle *tt) +{ + while (count--) { + short pad; + ReadShort(fd, 3, tt->vertex); + ReadShort(fd, 1, &pad); /* crud */ + ReadFloat(fd, 1, &(tt->r)); + ReadFloat(fd, 1, &(tt->g)); + ReadFloat(fd, 1, &(tt->b)); + + tt++; + } + + return count; +} diff --git a/src/Serialize.h b/src/Serialize.h new file mode 100644 index 0000000..4ecb46d --- /dev/null +++ b/src/Serialize.h @@ -0,0 +1,13 @@ +#ifndef SERIALIZE_H +#define SERIALIZE_H + +/* these all read big-endian data */ + +int ReadBool(int fd, int count, bool *b); +int ReadShort(int fd, int count, short *s); +int ReadInt(int fd, int count, int *s); +int ReadFloat(int fd, int count, float *f); +int ReadXYZ(int fd, int count, XYZ *xyz); +int ReadTexturedTriangle(int fd, int count, TexturedTriangle *tt); + +#endif diff --git a/src/Skeleton.cpp b/src/Skeleton.cpp new file mode 100644 index 0000000..5f1880f --- /dev/null +++ b/src/Skeleton.cpp @@ -0,0 +1,817 @@ +/**> HEADER FILES <**/ +#include "Skeleton.h" + +#include "Serialize.h" + +extern double multiplier; +extern unsigned int gSourceID[100]; +extern unsigned int gSampleSet[100]; +extern int visions; +extern float rad2deg; +extern Camera camera; +extern float soundscalefactor; + +extern XYZ vel; +extern XYZ midp; +extern XYZ newpoint1,newpoint2; + +extern float oldlength; +extern float relaxlength; + +extern float friction; +extern int numrepeats; +extern float groundlevel; +extern float offset; +extern XYZ impact; +extern XYZ overpoint; +extern XYZ underpoint; +extern int whichtri; +extern XYZ normalrotated; +extern bool groundish; + + +void Joint::DoConstraint() +{ + + if(hasparent){ + //Find midpoint + midp=(position+parent->position)/2; + //Find vector from midpoint to second vector + vel=parent->position-midp; + //Change to unit vector + Normalise(&vel); + //Apply velocity change + velocity+=((midp-vel*length/2)-position); + parent->velocity+=((midp+vel*length/2)-parent->position); + //Move child point to within certain distance of parent point + if(!locked)position=midp-vel*length/2; + if(!parent->locked)parent->position=midp+vel*length/2; + } +} + +void Muscle::DoConstraint(int broken) +{ + oldlength=length; + relaxlength=findDistance(parent1->position,parent2->position); + + if(type==boneconnect)strength=1; + if(type==constraint)strength=0; + + if(strength<0)strength=0; + if(strength>1)strength=1; + + length-=(length-relaxlength)*(1-strength)*multiplier*multiplier*10000; + length-=(length-targetlength)*(strength)*multiplier*multiplier*10000; + if(strength==0)length=relaxlength; + + if((relaxlength-length>0&&relaxlength-oldlength<0)||(relaxlength-length<0&&relaxlength-oldlength>0))length=relaxlength; + + if(length<minlength)length=minlength; + if(length>maxlength&&!broken)length=maxlength; + + //Find midpoint + midp=(parent1->position+parent2->position)/2; + //Find vector from midpoint to second vector + vel=parent2->position-midp; + //Change to unit vector + Normalise(&vel); + //Apply velocity change + newpoint1=midp-vel*length/2; + newpoint2=midp+vel*length/2; + parent1->velocity+=(newpoint1-parent1->position); + parent2->velocity+=(newpoint2-parent2->position); + //Move child point to within certain distance of parent point + if(!parent1->locked)parent1->position=newpoint1; + if(!parent2->locked)parent2->position=newpoint2; +} + +void Skeleton::DoConstraints() +{ + numrepeats=3; + + for(int j=0; j<numrepeats; j++){ + for(int i=0; i<num_joints; i++){ + joints[i].DoConstraint(); + } + } +} + +void Skeleton::DoConstraints(Model *collide, XYZ *move, float rotation) +{ + friction=20; + numrepeats=2; + groundlevel=0; + + move->y+=.35; + + for(int j=0; j<numrepeats; j++){ + for(int i=0; i<num_joints; i++){ + if(joints[i].existing||i==jointlabels[lefthand]||i==jointlabels[righthand]){ + //Length constraints + joints[i].DoConstraint(); + //Ground constraint + offset=0; + overpoint=joints[i].position; + overpoint.y+=10; + underpoint=joints[i].position; + underpoint.y-=offset; + whichtri=collide->LineCheck2(overpoint,underpoint,&impact,*move,rotation); + if(collide->normals[whichtri].y<=.8)whichtri=collide->LineCheck2(joints[i].realoldposition,joints[i].position,&impact,*move,rotation); + if(joints[i].position.y<=groundlevel+offset||whichtri!=-1){ + if(whichtri==-1||(whichtri!=-1&&collide->normals[whichtri].y>.8)){ + if(whichtri==-1)joints[i].position.y=groundlevel+offset; + if(whichtri!=-1){ + joints[i].position=impact; + joints[i].position.y+=offset; + } + joints[i].velocity.y*=-.3; + joints[i].velocity.x*=.3; + joints[i].velocity.z*=.3; + } + offset=.2; + if(whichtri!=-1&&collide->normals[whichtri].y<=.8){ + normalrotated=DoRotation(collide->normals[whichtri],0,rotation,0); + joints[i].position=impact+normalrotated*offset; + ReflectVector(&joints[i].velocity,&normalrotated); + joints[i].velocity*=.3; + } + if(broken<=1){ + XYZ avgvelocity; + avgvelocity=0; + float gLoc[3]; + ALint tempint; + for(int k=0; k<num_joints; k++){ + avgvelocity+=joints[k].velocity; + } + avgvelocity/=num_joints; + if(joints[i].label==head&&(findLengthfast(joints[i].velocity)>2||findLengthfast(avgvelocity)>2)){ + avgvelocity+=joints[i].velocity; + gLoc[0]=joints[i].position.x/soundscalefactor; + gLoc[1]=joints[i].position.y/soundscalefactor; + gLoc[2]=joints[i].position.z/soundscalefactor; +#ifdef DEBIAN_NEEDS_TO_UPDATE_THEIR_OPENAL + alGetSourceiv(gSourceID[headlandsound], AL_SOURCE_STATE, &tempint); +#else + alGetSourcei(gSourceID[headlandsound], AL_SOURCE_STATE, &tempint); +#endif + if (tempint != AL_PLAYING){ + alSourcef(gSourceID[headlandsound], AL_MIN_GAIN, ALfloat(findLengthfast(avgvelocity)*2/findDistancefast(joints[i].position,camera.position)*soundscalefactor*2)); + alSourcef(gSourceID[headlandsound], AL_MAX_GAIN, ALfloat(findLengthfast(avgvelocity)*2/findDistancefast(joints[i].position,camera.position)*soundscalefactor*2)); + alSourcefv(gSourceID[headlandsound], AL_POSITION, gLoc); + alSourcePlay(gSourceID[headlandsound]);} + } + avgvelocity=0; + for(int k=0; k<num_joints; k++){ + avgvelocity+=joints[k].velocity; + } + avgvelocity/=num_joints; + if((joints[i].label==abdomen)&&(findLengthfast(joints[i].velocity)>2||findLengthfast(avgvelocity)>2)){ + avgvelocity+=joints[i].velocity; + gLoc[0]=joints[i].position.x/soundscalefactor; + gLoc[1]=joints[i].position.y/soundscalefactor; + gLoc[2]=joints[i].position.z/soundscalefactor; +#ifdef DEBIAN_NEEDS_TO_UPDATE_THEIR_OPENAL + alGetSourceiv(gSourceID[bodylandsound], AL_SOURCE_STATE, &tempint); +#else + alGetSourcei(gSourceID[bodylandsound], AL_SOURCE_STATE, &tempint); +#endif + if (tempint != AL_PLAYING){ + alSourcef(gSourceID[bodylandsound], AL_MIN_GAIN, ALfloat(findLengthfast(joints[i].velocity)*1/findDistancefast(joints[i].position,camera.position)*soundscalefactor*2)); + alSourcef(gSourceID[bodylandsound], AL_MAX_GAIN, ALfloat(findLengthfast(joints[i].velocity)*1/findDistancefast(joints[i].position,camera.position)*soundscalefactor*2)); + alSourcefv(gSourceID[bodylandsound], AL_POSITION, gLoc); + alSourcePlay(gSourceID[bodylandsound]);} + } + } + }} + } + if(num_muscles) + for(int i=0; i<num_muscles; i++){ + //Length constraints + muscles[i].DoConstraint(broken); + } + } + + for(int i=0; i<num_joints; i++){ + joints[i].realoldposition=joints[i].position; + } + + //Add velocity + for(int i=0; i<num_joints; i++){ + if(joints[i].existing||i==jointlabels[lefthand]||i==jointlabels[righthand])joints[i].position=joints[i].position+joints[i].velocity*multiplier; + } +} + +void Skeleton::DoGravity() +{ + for(int i=0; i<num_joints; i++){ + joints[i].velocity.y+=gravity*multiplier; + } +} + +void Skeleton::Draw(int muscleview) +{ + float jointcolor[4]; + + if(muscleview!=2){ + jointcolor[0]=0; + jointcolor[1]=0; + jointcolor[2]=.5; + jointcolor[3]=1; + } + + if(muscleview==2){ + jointcolor[0]=0; + jointcolor[1]=0; + jointcolor[2]=0; + jointcolor[3]=.5; + } + //Calc motionblur-ness + for(int i=0; i<num_joints; i++){ + joints[i].oldposition=joints[i].position; + joints[i].blurred=findDistance(joints[i].position,joints[i].oldposition)*100; + if(joints[i].blurred<1)joints[i].blurred=1; + } + + //Do Motionblur + glDepthMask(0); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glBegin(GL_QUADS); + for(int i=0; i<num_joints; i++){ + if(joints[i].hasparent){ + glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred); + glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z); + glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred); + glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z); + glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred); + glVertex3f(joints[i].parent->oldposition.x,joints[i].parent->oldposition.y,joints[i].parent->oldposition.z); + glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred); + glVertex3f(joints[i].oldposition.x,joints[i].oldposition.y,joints[i].oldposition.z); + } + } + for(int i=0; i<num_muscles; i++){ + if(muscles[i].type==boneconnect){ + glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred); + glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z); + glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred); + glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z); + glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred); + glVertex3f(muscles[i].parent2->oldposition.x,muscles[i].parent2->oldposition.y,muscles[i].parent2->oldposition.z); + glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred); + glVertex3f(muscles[i].parent1->oldposition.x,muscles[i].parent1->oldposition.y,muscles[i].parent1->oldposition.z); + } + } + glEnd(); + + glBegin(GL_LINES); + for(int i=0; i<num_joints; i++){ + if(joints[i].hasparent){ + glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred); + glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z); + glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred); + glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z); + } + } + for(int i=0; i<num_muscles; i++){ + if(muscles[i].type==boneconnect){ + glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred); + glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z); + glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred); + glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z); + } + } + glColor3f(.6,.6,0); + if(muscleview==1) + for(int i=0; i<num_muscles; i++){ + if(muscles[i].type!=boneconnect){ + glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z); + glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z); + } + } + glEnd(); + + if(muscleview!=2){ + glPointSize(3); + glBegin(GL_POINTS); + for(int i=0; i<num_joints; i++){ + if(i!=selected)glColor4f(0,0,.5,1); + if(i==selected)glColor4f(1,1,0,1); + if(joints[i].locked&&i!=selected)glColor4f(1,0,0,1); + glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z); + } + glEnd(); + } + + //Set old position to current position + if(muscleview==2) + for(int i=0; i<num_joints; i++){ + joints[i].oldposition=joints[i].position; + } + glDepthMask(1); +} + +void Skeleton::AddJoint(float x, float y, float z, int which) +{ + if(num_joints<max_joints-1){ + joints[num_joints].velocity=0; + joints[num_joints].position.x=x; + joints[num_joints].position.y=y; + joints[num_joints].position.z=z; + joints[num_joints].locked=0; + + if(which>=num_joints||which<0)joints[num_joints].hasparent=0; + if(which<num_joints&&which>=0){ + joints[num_joints].parent=&joints[which]; + joints[num_joints].hasparent=1; + joints[num_joints].length=findDistance(joints[num_joints].position,joints[num_joints].parent->position); + } + num_joints++; + } +} + +void Skeleton::DeleteJoint(int whichjoint) +{ + if(whichjoint<num_joints&&whichjoint>=0){ + for(int i=0;i<num_muscles;i++){ + while(muscles[i].parent1==&joints[whichjoint]&&i<num_muscles)DeleteMuscle(i); + while(muscles[i].parent2==&joints[whichjoint]&&i<num_muscles)DeleteMuscle(i); + } + for(int i=0;i<num_joints;i++){ + if(joints[i].parent==&joints[whichjoint])joints[i].hasparent=0; + } + joints[whichjoint].hasparent=0; + } +} + +void Skeleton::DeleteMuscle(int whichmuscle) +{ + if(whichmuscle<num_muscles){ + muscles[whichmuscle].minlength=muscles[num_muscles-1].minlength; + muscles[whichmuscle].maxlength=muscles[num_muscles-1].maxlength; + muscles[whichmuscle].strength=muscles[num_muscles-1].strength; + muscles[whichmuscle].parent1=muscles[num_muscles-1].parent1; + muscles[whichmuscle].parent2=muscles[num_muscles-1].parent2; + muscles[whichmuscle].length=muscles[num_muscles-1].length; + muscles[whichmuscle].visible=muscles[num_muscles-1].visible; + muscles[whichmuscle].type=muscles[num_muscles-1].type; + muscles[whichmuscle].targetlength=muscles[num_muscles-1].targetlength; + + num_muscles--; + } +} + +void Skeleton::SetJoint(float x, float y, float z, int which, int whichjoint) +{ + if(whichjoint<num_joints){ + joints[whichjoint].velocity=0; + joints[whichjoint].position.x=x; + joints[whichjoint].position.y=y; + joints[whichjoint].position.z=z; + + if(which>=num_joints||which<0)joints[whichjoint].hasparent=0; + if(which<num_joints&&which>=0){ + joints[whichjoint].parent=&joints[which]; + joints[whichjoint].hasparent=1; + joints[whichjoint].length=findDistance(joints[whichjoint].position,joints[whichjoint].parent->position); + } + } +} + +void Skeleton::AddMuscle(int attach1,int attach2,float minlength,float maxlength,int type) +{ + if(num_muscles<max_muscles-1&&attach1<num_joints&&attach1>=0&attach2<num_joints&&attach2>=0&&attach1!=attach2){ + muscles[num_muscles].parent1=&joints[attach1]; + muscles[num_muscles].parent2=&joints[attach2]; + muscles[num_muscles].length=findDistance(muscles[num_muscles].parent1->position,muscles[num_muscles].parent2->position); + muscles[num_muscles].targetlength=findDistance(muscles[num_muscles].parent1->position,muscles[num_muscles].parent2->position); + muscles[num_muscles].strength=.7; + muscles[num_muscles].type=type; + muscles[num_muscles].minlength=minlength; + muscles[num_muscles].maxlength=maxlength; + + num_muscles++; + } +} + +void Skeleton::MusclesSet() +{ + for(int i=0;i<num_muscles;i++){ + muscles[i].length=findDistance(muscles[i].parent1->position,muscles[i].parent2->position); + } +} + +void Skeleton::FindRotationJoint(int which) +{ + XYZ temppoint1,temppoint2,tempforward; + float distance; + + temppoint1=joints[which].position; + temppoint2=joints[which].parent->position; + distance=findDistance(temppoint1,temppoint2); + joints[which].rotate2=asin((temppoint1.y-temppoint2.y)/distance)*rad2deg; + temppoint1.y=0; + temppoint2.y=0; + joints[which].rotate1=acos((temppoint1.z-temppoint2.z)/findDistance(temppoint1,temppoint2))*rad2deg; + if(temppoint1.x>temppoint2.x)joints[which].rotate1=360-joints[which].rotate1; + if(joints[which].label==head)tempforward=specialforward[0]; + else if(joints[which].label==rightshoulder||joints[which].label==rightelbow||joints[which].label==rightwrist||joints[which].label==righthand)tempforward=specialforward[1]; + else if(joints[which].label==leftshoulder||joints[which].label==leftelbow||joints[which].label==leftwrist||joints[which].label==lefthand)tempforward=specialforward[2]; + else if(joints[which].label==righthip||joints[which].label==rightknee||joints[which].label==rightankle)tempforward=specialforward[3]; + else if(joints[which].label==lefthip||joints[which].label==leftknee||joints[which].label==leftankle)tempforward=specialforward[4]; + else if(!joints[which].lower)tempforward=forward; + else if(joints[which].lower)tempforward=lowforward; + tempforward=DoRotation(tempforward,0,joints[which].rotate1-90,0); + tempforward=DoRotation(tempforward,0,0,joints[which].rotate2-90); + tempforward.y=0; + Normalise(&tempforward); + joints[which].rotate3=acos(0-tempforward.z)*rad2deg; + if(0>tempforward.x)joints[which].rotate3=360-joints[which].rotate3; +} + +void Skeleton::FindRotationMuscle(int which) +{ + XYZ temppoint1,temppoint2,tempforward; + float distance; + + temppoint1=muscles[which].parent1->position; + temppoint2=muscles[which].parent2->position; + distance=findDistance(temppoint1,temppoint2); + muscles[which].rotate2=asin((temppoint1.y-temppoint2.y)/distance)*rad2deg; + temppoint1.y=0; + temppoint2.y=0; + muscles[which].rotate1=acos((temppoint1.z-temppoint2.z)/findDistance(temppoint1,temppoint2)); + muscles[which].rotate1*=360/6.28; + if(temppoint1.x>temppoint2.x)muscles[which].rotate1=360-muscles[which].rotate1; + if(muscles[which].parent1->label==head)tempforward=specialforward[0]; + else if(muscles[which].parent1->label==rightshoulder||muscles[which].parent1->label==rightelbow||muscles[which].parent1->label==rightwrist)tempforward=specialforward[1]; + else if(muscles[which].parent1->label==leftshoulder||muscles[which].parent1->label==leftelbow||muscles[which].parent1->label==leftwrist)tempforward=specialforward[2]; + else if(muscles[which].parent1->label==righthip||muscles[which].parent1->label==rightknee||muscles[which].parent1->label==rightankle)tempforward=specialforward[3]; + else if(muscles[which].parent1->label==lefthip||muscles[which].parent1->label==leftknee||muscles[which].parent1->label==leftankle)tempforward=specialforward[4]; + else if(!muscles[which].parent1->lower)tempforward=forward; + else if(muscles[which].parent1->lower)tempforward=lowforward; + tempforward=DoRotation(tempforward,0,muscles[which].rotate1-90,0); + tempforward=DoRotation(tempforward,0,0,muscles[which].rotate2-90); + tempforward.y=0; + Normalise(&tempforward); + muscles[which].rotate3=acos(0-tempforward.z)*rad2deg; + for(int i=0;i<num_joints;i++){ + if(&joints[i]==muscles[which].parent1){ + joints[i].rotate1=muscles[which].rotate1; + joints[i].rotate2=muscles[which].rotate2; + joints[i].rotate3=muscles[which].rotate3; + } + } + if(0>tempforward.x)muscles[which].rotate3=360-muscles[which].rotate3; +} + +extern Skeleton testskeleton; + +void Animation::Load(char *fileName) +{ + float placeholder[3]; + files.OpenFile((unsigned char*)fileName); + if(files.sFile){ + ReadInt(files.sFile, 1, &numframes); + for(int i=0;i<numframes;i++){ + for(int j=0;j<max_joints;j++){ + ReadXYZ(files.sFile, 1, &position[j][i]); + } + for(int j=0;j<max_joints;j++){ + ReadFloat(files.sFile, 1, &twist[j][i]); + } + for(int j=0;j<max_joints;j++){ + ReadBool(files.sFile, 1, &onground[j][i]); + } + ReadFloat(files.sFile, 1, &speed[i]); + ReadFloat(files.sFile, 1, &gunrotation[i]); + } + for(int i=0;i<numframes;i++){ + for(int j=0;j<max_joints;j++){ + ReadFloat(files.sFile, 1, &twist2[j][i]); + } + } + } + + files.EndLoad(); + + for(int j=0;j<numframes;j++){ + for(int i=0;i<testskeleton.num_joints;i++){ + testskeleton.joints[i].position=position[i][j]; + } + //Find forward vectors + CrossProduct(testskeleton.joints[testskeleton.forwardjoints[1]].position-testskeleton.joints[testskeleton.forwardjoints[0]].position,testskeleton.joints[testskeleton.forwardjoints[2]].position-testskeleton.joints[testskeleton.forwardjoints[0]].position,&testskeleton.forward); + Normalise(&testskeleton.forward); + + CrossProduct(testskeleton.joints[testskeleton.lowforwardjoints[1]].position-testskeleton.joints[testskeleton.lowforwardjoints[0]].position,testskeleton.joints[testskeleton.lowforwardjoints[2]].position-testskeleton.joints[testskeleton.lowforwardjoints[0]].position,&testskeleton.lowforward); + Normalise(&testskeleton.lowforward); + + //Special forwards + testskeleton.specialforward[0]=testskeleton.forward; + + testskeleton.specialforward[1]=testskeleton.joints[testskeleton.jointlabels[rightshoulder]].position+testskeleton.joints[testskeleton.jointlabels[rightwrist]].position; + testskeleton.specialforward[1]=testskeleton.joints[testskeleton.jointlabels[rightelbow]].position-testskeleton.specialforward[1]/2; + testskeleton.specialforward[1]+=testskeleton.forward*.2; + Normalise(&testskeleton.specialforward[1]); + testskeleton.specialforward[2]=testskeleton.joints[testskeleton.jointlabels[leftshoulder]].position+testskeleton.joints[testskeleton.jointlabels[leftwrist]].position; + testskeleton.specialforward[2]=testskeleton.joints[testskeleton.jointlabels[leftelbow]].position-testskeleton.specialforward[2]/2; + testskeleton.specialforward[2]+=testskeleton.forward*.2; + Normalise(&testskeleton.specialforward[2]); + + testskeleton.specialforward[3]=testskeleton.joints[testskeleton.jointlabels[righthip]].position+testskeleton.joints[testskeleton.jointlabels[rightankle]].position; + testskeleton.specialforward[3]=testskeleton.specialforward[3]/2-testskeleton.joints[testskeleton.jointlabels[rightknee]].position; + testskeleton.specialforward[3]+=testskeleton.lowforward*.2; + Normalise(&testskeleton.specialforward[3]); + testskeleton.specialforward[4]=testskeleton.joints[testskeleton.jointlabels[lefthip]].position+testskeleton.joints[testskeleton.jointlabels[leftankle]].position; + testskeleton.specialforward[4]=testskeleton.specialforward[4]/2-testskeleton.joints[testskeleton.jointlabels[leftknee]].position; + testskeleton.specialforward[4]+=testskeleton.lowforward*.2; + Normalise(&testskeleton.specialforward[4]); + + //Find joint rotations + for(int i=0;i<testskeleton.num_joints;i++){ + if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible) + { + testskeleton.FindRotationJoint(i); + } + } + for(int i=0;i<testskeleton.num_muscles;i++){ + if(testskeleton.muscles[i].visible) + { + testskeleton.FindRotationMuscle(i); + } + } + for(int i=0;i<testskeleton.num_muscles;i++){ + if(testskeleton.muscles[i].visible) + { + mrotate1[i][j]=testskeleton.muscles[i].rotate1; + mrotate2[i][j]=testskeleton.muscles[i].rotate2; + mrotate3[i][j]=testskeleton.muscles[i].rotate3; + if(j!=0&&mrotate3[i][j]>mrotate3[i][j-1]+180)mrotate3[i][j]-=360; + if(j!=0&&mrotate3[i][j]<mrotate3[i][j-1]-180)mrotate3[i][j]+=360; + if(j!=0&&mrotate2[i][j]>mrotate2[i][j-1]+180)mrotate2[i][j]-=360; + if(j!=0&&mrotate2[i][j]<mrotate2[i][j-1]-180)mrotate2[i][j]+=360; + if(j!=0&&mrotate1[i][j]>mrotate1[i][j-1]+180)mrotate1[i][j]-=360; + if(j!=0&&mrotate1[i][j]<mrotate1[i][j-1]-180)mrotate1[i][j]+=360; + } + } + for(int i=0;i<testskeleton.num_joints;i++){ + if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible) + { + rotate1[i][j]=testskeleton.joints[i].rotate1; + rotate2[i][j]=testskeleton.joints[i].rotate2; + rotate3[i][j]=testskeleton.joints[i].rotate3; + if(j!=0&&rotate3[i][j]>rotate3[i][j-1]+180)rotate3[i][j]-=360; + if(j!=0&&rotate3[i][j]<rotate3[i][j-1]-180)rotate3[i][j]+=360; + if(j!=0&&rotate2[i][j]>rotate2[i][j-1]+180)rotate2[i][j]-=360; + if(j!=0&&rotate2[i][j]<rotate2[i][j-1]-180)rotate2[i][j]+=360; + if(j!=0&&rotate1[i][j]>rotate1[i][j-1]+180)rotate1[i][j]-=360; + if(j!=0&&rotate1[i][j]<rotate1[i][j-1]-180)rotate1[i][j]+=360; + } + } + } + + for(int k=0;k<2;k++) + for(int j=0;j<numframes;j++){ + for(int i=0;i<testskeleton.num_muscles;i++){ + if(testskeleton.muscles[i].visible) + { + if(j!=0&&mrotate3[i][j]>mrotate3[i][j-1]+180)mrotate3[i][j]-=360; + if(j!=0&&mrotate3[i][j]<mrotate3[i][j-1]-180)mrotate3[i][j]+=360; + if(j!=0&&mrotate2[i][j]>mrotate2[i][j-1]+180)mrotate2[i][j]-=360; + if(j!=0&&mrotate2[i][j]<mrotate2[i][j-1]-180)mrotate2[i][j]+=360; + if(j!=0&&mrotate1[i][j]>mrotate1[i][j-1]+180)mrotate1[i][j]-=360; + if(j!=0&&mrotate1[i][j]<mrotate1[i][j-1]-180)mrotate1[i][j]+=360; + + if(j==0&&mrotate3[i][j]>mrotate3[i][numframes-1]+180)mrotate3[i][j]-=360; + if(j==0&&mrotate3[i][j]<mrotate3[i][numframes-1]-180)mrotate3[i][j]+=360; + if(j==0&&mrotate2[i][j]>mrotate2[i][numframes-1]+180)mrotate2[i][j]-=360; + if(j==0&&mrotate2[i][j]<mrotate2[i][numframes-1]-180)mrotate2[i][j]+=360; + if(j==0&&mrotate1[i][j]>mrotate1[i][numframes-1]+180)mrotate1[i][j]-=360; + if(j==0&&mrotate1[i][j]<mrotate1[i][numframes-1]-180)mrotate1[i][j]+=360; + } + } + for(int i=0;i<testskeleton.num_joints;i++){ + if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible) + { + if(j!=0&&rotate3[i][j]>rotate3[i][j-1]+180)rotate3[i][j]-=360; + if(j!=0&&rotate3[i][j]<rotate3[i][j-1]-180)rotate3[i][j]+=360; + if(j!=0&&rotate2[i][j]>rotate2[i][j-1]+180)rotate2[i][j]-=360; + if(j!=0&&rotate2[i][j]<rotate2[i][j-1]-180)rotate2[i][j]+=360; + if(j!=0&&rotate1[i][j]>rotate1[i][j-1]+180)rotate1[i][j]-=360; + if(j!=0&&rotate1[i][j]<rotate1[i][j-1]-180)rotate1[i][j]+=360; + + if(j==0&&rotate3[i][j]>rotate3[i][numframes-1]+180)rotate3[i][j]-=360; + if(j==0&&rotate3[i][j]<rotate3[i][numframes-1]-180)rotate3[i][j]+=360; + if(j==0&&rotate2[i][j]>rotate2[i][numframes-1]+180)rotate2[i][j]-=360; + if(j==0&&rotate2[i][j]<rotate2[i][numframes-1]-180)rotate2[i][j]+=360; + if(j==0&&rotate1[i][j]>rotate1[i][numframes-1]+180)rotate1[i][j]-=360; + if(j==0&&rotate1[i][j]<rotate1[i][numframes-1]-180)rotate1[i][j]+=360; + } + } + } +} + +void Animation::Load(char *fileName, float rotate) +{ + float placeholder[3]; + files.OpenFile((unsigned char*)fileName); + if(files.sFile){ + ReadInt(files.sFile, 1, &numframes); + for(int i=0;i<numframes;i++){ + for(int j=0;j<max_joints;j++){ + ReadXYZ(files.sFile, 1, &position[j][i]); + position[j][i]=DoRotation(position[j][i],0,rotate,0); + } + for(int j=0;j<max_joints;j++){ + ReadFloat(files.sFile, 1, &twist[j][i]); + } + for(int j=0;j<max_joints;j++){ + ReadBool(files.sFile, 1, &onground[j][i]); + } + ReadFloat(files.sFile, 1, &speed[i]); + ReadFloat(files.sFile, 1, &gunrotation[i]); + } + for(int i=0;i<numframes;i++){ + for(int j=0;j<max_joints;j++){ + ReadFloat(files.sFile, 1, &twist2[j][i]); + } + } + } + files.EndLoad(); + + for(int j=0;j<numframes;j++){ + for(int i=0;i<testskeleton.num_joints;i++){ + testskeleton.joints[i].position=position[i][j]; + } + //Find forward vectors + CrossProduct(testskeleton.joints[testskeleton.forwardjoints[1]].position-testskeleton.joints[testskeleton.forwardjoints[0]].position,testskeleton.joints[testskeleton.forwardjoints[2]].position-testskeleton.joints[testskeleton.forwardjoints[0]].position,&testskeleton.forward); + Normalise(&testskeleton.forward); + + CrossProduct(testskeleton.joints[testskeleton.lowforwardjoints[1]].position-testskeleton.joints[testskeleton.lowforwardjoints[0]].position,testskeleton.joints[testskeleton.lowforwardjoints[2]].position-testskeleton.joints[testskeleton.lowforwardjoints[0]].position,&testskeleton.lowforward); + Normalise(&testskeleton.lowforward); + + //Special forwards + testskeleton.specialforward[0]=testskeleton.forward; + + testskeleton.specialforward[1]=testskeleton.joints[testskeleton.jointlabels[rightshoulder]].position+testskeleton.joints[testskeleton.jointlabels[rightwrist]].position; + testskeleton.specialforward[1]=testskeleton.joints[testskeleton.jointlabels[rightelbow]].position-testskeleton.specialforward[1]/2; + testskeleton.specialforward[1]+=testskeleton.forward*.2; + Normalise(&testskeleton.specialforward[1]); + testskeleton.specialforward[2]=testskeleton.joints[testskeleton.jointlabels[leftshoulder]].position+testskeleton.joints[testskeleton.jointlabels[leftwrist]].position; + testskeleton.specialforward[2]=testskeleton.joints[testskeleton.jointlabels[leftelbow]].position-testskeleton.specialforward[2]/2; + testskeleton.specialforward[2]+=testskeleton.forward*.2; + Normalise(&testskeleton.specialforward[2]); + + testskeleton.specialforward[3]=testskeleton.joints[testskeleton.jointlabels[righthip]].position+testskeleton.joints[testskeleton.jointlabels[rightankle]].position; + testskeleton.specialforward[3]=testskeleton.specialforward[3]/2-testskeleton.joints[testskeleton.jointlabels[rightknee]].position; + testskeleton.specialforward[3]+=testskeleton.lowforward*.2; + Normalise(&testskeleton.specialforward[3]); + testskeleton.specialforward[4]=testskeleton.joints[testskeleton.jointlabels[lefthip]].position+testskeleton.joints[testskeleton.jointlabels[leftankle]].position; + testskeleton.specialforward[4]=testskeleton.specialforward[4]/2-testskeleton.joints[testskeleton.jointlabels[leftknee]].position; + testskeleton.specialforward[4]+=testskeleton.lowforward*.2; + Normalise(&testskeleton.specialforward[4]); + + //Find joint rotations + for(int i=0;i<testskeleton.num_joints;i++){ + if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible) + { + testskeleton.FindRotationJoint(i); + } + } + for(int i=0;i<testskeleton.num_muscles;i++){ + if(testskeleton.muscles[i].visible) + { + testskeleton.FindRotationMuscle(i); + } + } + for(int i=0;i<testskeleton.num_muscles;i++){ + if(testskeleton.muscles[i].visible) + { + mrotate1[i][j]=testskeleton.muscles[i].rotate1; + mrotate2[i][j]=testskeleton.muscles[i].rotate2; + mrotate3[i][j]=testskeleton.muscles[i].rotate3; + if(j!=0&&mrotate3[i][j]>mrotate3[i][j-1]+180)mrotate3[i][j]-=360; + if(j!=0&&mrotate3[i][j]<mrotate3[i][j-1]-180)mrotate3[i][j]+=360; + if(j!=0&&mrotate2[i][j]>mrotate2[i][j-1]+180)mrotate2[i][j]-=360; + if(j!=0&&mrotate2[i][j]<mrotate2[i][j-1]-180)mrotate2[i][j]+=360; + if(j!=0&&mrotate1[i][j]>mrotate1[i][j-1]+180)mrotate1[i][j]-=360; + if(j!=0&&mrotate1[i][j]<mrotate1[i][j-1]-180)mrotate1[i][j]+=360; + } + } + for(int i=0;i<testskeleton.num_joints;i++){ + if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible) + { + rotate1[i][j]=testskeleton.joints[i].rotate1; + rotate2[i][j]=testskeleton.joints[i].rotate2; + rotate3[i][j]=testskeleton.joints[i].rotate3; + if(j!=0&&rotate3[i][j]>rotate3[i][j-1]+180)rotate3[i][j]-=360; + if(j!=0&&rotate3[i][j]<rotate3[i][j-1]-180)rotate3[i][j]+=360; + if(j!=0&&rotate2[i][j]>rotate2[i][j-1]+180)rotate2[i][j]-=360; + if(j!=0&&rotate2[i][j]<rotate2[i][j-1]-180)rotate2[i][j]+=360; + if(j!=0&&rotate1[i][j]>rotate1[i][j-1]+180)rotate1[i][j]-=360; + if(j!=0&&rotate1[i][j]<rotate1[i][j-1]-180)rotate1[i][j]+=360; + } + } + } + + for(int k=0;k<2;k++) + for(int j=0;j<numframes;j++){ + for(int i=0;i<testskeleton.num_muscles;i++){ + if(testskeleton.muscles[i].visible) + { + if(j!=0&&mrotate3[i][j]>mrotate3[i][j-1]+180)mrotate3[i][j]-=360; + if(j!=0&&mrotate3[i][j]<mrotate3[i][j-1]-180)mrotate3[i][j]+=360; + if(j!=0&&mrotate2[i][j]>mrotate2[i][j-1]+180)mrotate2[i][j]-=360; + if(j!=0&&mrotate2[i][j]<mrotate2[i][j-1]-180)mrotate2[i][j]+=360; + if(j!=0&&mrotate1[i][j]>mrotate1[i][j-1]+180)mrotate1[i][j]-=360; + if(j!=0&&mrotate1[i][j]<mrotate1[i][j-1]-180)mrotate1[i][j]+=360; + + if(j==0&&mrotate3[i][j]>mrotate3[i][numframes-1]+180)mrotate3[i][j]-=360; + if(j==0&&mrotate3[i][j]<mrotate3[i][numframes-1]-180)mrotate3[i][j]+=360; + if(j==0&&mrotate2[i][j]>mrotate2[i][numframes-1]+180)mrotate2[i][j]-=360; + if(j==0&&mrotate2[i][j]<mrotate2[i][numframes-1]-180)mrotate2[i][j]+=360; + if(j==0&&mrotate1[i][j]>mrotate1[i][numframes-1]+180)mrotate1[i][j]-=360; + if(j==0&&mrotate1[i][j]<mrotate1[i][numframes-1]-180)mrotate1[i][j]+=360; + } + } + for(int i=0;i<testskeleton.num_joints;i++){ + if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible) + { + if(j!=0&&rotate3[i][j]>rotate3[i][j-1]+180)rotate3[i][j]-=360; + if(j!=0&&rotate3[i][j]<rotate3[i][j-1]-180)rotate3[i][j]+=360; + if(j!=0&&rotate2[i][j]>rotate2[i][j-1]+180)rotate2[i][j]-=360; + if(j!=0&&rotate2[i][j]<rotate2[i][j-1]-180)rotate2[i][j]+=360; + if(j!=0&&rotate1[i][j]>rotate1[i][j-1]+180)rotate1[i][j]-=360; + if(j!=0&&rotate1[i][j]<rotate1[i][j-1]-180)rotate1[i][j]+=360; + + if(j==0&&rotate3[i][j]>rotate3[i][numframes-1]+180)rotate3[i][j]-=360; + if(j==0&&rotate3[i][j]<rotate3[i][numframes-1]-180)rotate3[i][j]+=360; + if(j==0&&rotate2[i][j]>rotate2[i][numframes-1]+180)rotate2[i][j]-=360; + if(j==0&&rotate2[i][j]<rotate2[i][numframes-1]-180)rotate2[i][j]+=360; + if(j==0&&rotate1[i][j]>rotate1[i][numframes-1]+180)rotate1[i][j]-=360; + if(j==0&&rotate1[i][j]<rotate1[i][numframes-1]-180)rotate1[i][j]+=360; + } + } + } +} + +void Skeleton::Load(char *fileName) +{ + int parentID; + bool what; + bool lock; + float placeholder[3]; + files.OpenFile((unsigned char*)fileName); + if(files.sFile){ + ReadInt(files.sFile, 1, &num_joints); + for(int i=0;i<num_joints;i++){ + ReadXYZ(files.sFile, 1, &joints[i].position); + ReadFloat(files.sFile, 1, &joints[i].length); + ReadFloat(files.sFile, 1, &joints[i].mass); + ReadBool(files.sFile, 1, &joints[i].hasparent); + ReadBool(files.sFile, 1, &joints[i].locked); + ReadInt(files.sFile, 1, &joints[i].modelnum); + ReadBool(files.sFile, 1, &joints[i].visible); + ReadBool(files.sFile, 1, &what); + ReadInt(files.sFile, 1, &joints[i].label); + ReadInt(files.sFile, 1, &joints[i].hasgun); + ReadBool(files.sFile, 1, &joints[i].lower); + ReadInt(files.sFile, 1, &parentID); + if(joints[i].hasparent)joints[i].parent=&joints[parentID]; + joints[i].velocity=0; + joints[i].oldposition=joints[i].position; + joints[i].existing=1; + } + + ReadInt(files.sFile, 1, &num_muscles); + for(int i=0;i<num_muscles;i++){ + ReadFloat(files.sFile, 1, &muscles[i].length); + ReadFloat(files.sFile, 1, &muscles[i].targetlength); + ReadFloat(files.sFile, 1, &muscles[i].minlength); + ReadFloat(files.sFile, 1, &muscles[i].maxlength); + ReadFloat(files.sFile, 1, &muscles[i].strength); + ReadInt(files.sFile, 1, &muscles[i].type); + ReadBool(files.sFile, 1, &muscles[i].visible); + ReadInt(files.sFile, 1, &parentID); + muscles[i].parent1=&joints[parentID]; + ReadInt(files.sFile, 1, &parentID); + muscles[i].parent2=&joints[parentID]; + } + + for(int j=0;j<3;j++){ + ReadInt(files.sFile, 1, &forwardjoints[j]); + } + for(int j=0;j<3;j++){ + ReadInt(files.sFile, 1, &lowforwardjoints[j]); + } + } + files.EndLoad(); + + for(int i=0;i<num_joints;i++){ + for(int j=0;j<num_joints;j++){ + if(joints[i].label==j)jointlabels[j]=i; + } + } + + broken=0; +} + diff --git a/src/Skeleton.h b/src/Skeleton.h new file mode 100644 index 0000000..9730665 --- /dev/null +++ b/src/Skeleton.h @@ -0,0 +1,156 @@ +#ifndef _SKELETON_H_ +#define _SKELETON_H_ + +/**> HEADER FILES <**/ +#ifdef OS9 +#include <gl.h> +#include "alut.h" +#else +#include <GL/gl.h> +#include <AL/al.h> +#include <AL/alut.h> +#endif +#include "Quaternions.h" +#include "Constants.h" +#include "Files.h" +#include "Models.h" +#include "Camera.h" + +#define boneconnect 0 +#define constraint 1 +#define muscle 2 + +//head, neck, left shoulder, left elbow, left wrist, left hand + //right shoulder, right elbow, right wrist, right hand, + //middle, left hip, right hip,groin + //left knee,left ankle, left foot, right knee, right ankle, right foort + +#define head 1 +#define neck 2 +#define leftshoulder 3 +#define leftelbow 4 +#define leftwrist 5 +#define lefthand 6 +#define rightshoulder 7 +#define rightelbow 8 +#define rightwrist 9 +#define righthand 10 +#define abdomen 11 +#define lefthip 12 +#define righthip 13 +#define groin 14 +#define leftknee 15 +#define leftankle 16 +#define leftfoot 17 +#define rightknee 18 +#define rightankle 19 +#define rightfoot 20 + +class Joint +{ + public: + XYZ position; + XYZ oldposition; + XYZ realoldposition; + XYZ velocity; + XYZ offset; + float blurred; + float length; + float mass; + bool lower; + bool hasparent; + bool locked; + int modelnum; + bool visible; + bool existing; + Joint* parent; + int label; + int hasgun; + float rotate1,rotate2,rotate3; + + void DoConstraint(); +}; + +class Muscle +{ + public: + float length; + float targetlength; + Joint* parent1; + Joint* parent2; + float maxlength; + float minlength; + int type; + bool visible; + void DoConstraint(int broken); + float rotate1,rotate2,rotate3; + + float strength; +}; + +class Animation +{ + public: + Files files; + int numframes; + bool canbeoverridden; + bool ismodified[max_joints][max_frames]; + XYZ position[max_joints][max_frames]; + float twist[max_joints][max_frames]; + float twist2[max_joints][max_frames]; + float speed[max_frames]; + float gunrotation[max_frames]; + bool onground[max_joints][max_frames]; + XYZ forward[max_frames]; + float rotate1[max_joints][max_frames],rotate2[max_joints][max_frames],rotate3[max_joints][max_frames]; + float mrotate1[max_joints][max_frames],mrotate2[max_joints][max_frames],mrotate3[max_joints][max_frames]; + void Load(char *fileName); + void Load(char *fileName,float rotate); +}; + + +class Skeleton +{ + public: + int num_joints; + Joint joints[max_joints]; + int jointlabels[max_joints]; + + int num_muscles; + Muscle muscles[max_muscles]; + + int selected; + + int forwardjoints[3]; + XYZ forward; + + int lowforwardjoints[3]; + XYZ lowforward; + + int broken; + bool offset; + + XYZ specialforward[5]; + + bool free; + + Files files; + + void DoConstraints(); + void DoConstraints(Model *collide, XYZ *move, float rotation); + void DoGravity(); + void DoBalance(); + void MusclesSet(); + void Draw(int muscleview); + void AddJoint(float x, float y, float z, int which); + void SetJoint(float x, float y, float z, int which, int whichjoint); + void DeleteJoint(int whichjoint); + void AddMuscle(int attach1,int attach2,float maxlength,float minlength,int type); + void DeleteMuscle(int whichmuscle); + void FindRotationJoint(int which); + void FindRotationMuscle(int which); + void Load(char *fileName); +}; + +#endif + diff --git a/src/Sprites.cpp b/src/Sprites.cpp new file mode 100644 index 0000000..f800282 --- /dev/null +++ b/src/Sprites.cpp @@ -0,0 +1,331 @@ +#include "Sprites.h" +#include "Textures.h" + +extern double multiplier; +extern bool slomo; +extern Fog fog; +extern bool blood; +extern float fogcolorr; +extern float fogcolorg; +extern float fogcolorb; +//Functions +extern float sinefluct; +extern int environment; +extern Model gunmodels[10]; +extern Camera camera; +extern float precipitationhorz; +extern float precipitationvert; +extern float precipitationdensity; +extern float snowdelay; + +int Sprites::MakeSprite(int atype, float abrightness, float acolor1, float acolor2, float acolor3, XYZ alocation, XYZ avelocity, float asize){ + type[howmanysprites]=atype; + rotation[howmanysprites]=Random()%360; + brightness[howmanysprites]=abrightness; + color1[howmanysprites]=acolor1; + color2[howmanysprites]=acolor2; + color3[howmanysprites]=acolor3; + location[howmanysprites]=alocation; + oldlocation[howmanysprites]=alocation; + velocity[howmanysprites]=avelocity; + size[howmanysprites]=asize; + initialsize[howmanysprites]=asize; + initialbrightness[howmanysprites]=abrightness; + initialvelocity[howmanysprites]=avelocity; + alivetime[howmanysprites]=0; + owner[howmanysprites]=0; + if(howmanysprites<maxsprites){howmanysprites++;} + + return 0; +} + +int Sprites::MakeSprite(int atype, float abrightness, float acolor1, float acolor2, float acolor3, XYZ alocation, XYZ avelocity, float asize, int aowner){ + type[howmanysprites]=atype; + rotation[howmanysprites]=Random()%360; + brightness[howmanysprites]=abrightness; + color1[howmanysprites]=acolor1; + color2[howmanysprites]=acolor2; + color3[howmanysprites]=acolor3; + location[howmanysprites]=alocation; + oldlocation[howmanysprites]=alocation; + velocity[howmanysprites]=avelocity; + size[howmanysprites]=asize; + initialsize[howmanysprites]=asize; + initialbrightness[howmanysprites]=abrightness; + initialvelocity[howmanysprites]=avelocity; + alivetime[howmanysprites]=0; + owner[howmanysprites]=aowner; + if(howmanysprites<maxsprites){howmanysprites++;} + + return 0; +} + +int Sprites::DeleteSprite(int which){ + if(which>=0){ + location[which]=location[howmanysprites-1]; + oldlocation[which]=oldlocation[howmanysprites-1]; + velocity[which]=velocity[howmanysprites-1]; + initialsize[which]=initialsize[howmanysprites-1]; + size[which]=size[howmanysprites-1]; + brightness[which]=brightness[howmanysprites-1]; + initialbrightness[which]=initialbrightness[howmanysprites-1]; + color1[which]=color1[howmanysprites-1]; + color2[which]=color2[howmanysprites-1]; + color3[which]=color3[howmanysprites-1]; + alivetime[which]=alivetime[howmanysprites-1]; + rotation[which]=rotation[howmanysprites-1]; + type[which]=type[howmanysprites-1]; + type[howmanysprites-1]=0; + + if(howmanysprites>0){howmanysprites--;} + } + + return 0; +} + +void Sprites::LoadFlareTexture(char *fileName) +{ + flaretextureptr = loadTexture(fileName); +} + +void Sprites::LoadMuzzleFlareTexture(char *fileName) +{ + muzzleflaretextureptr = loadTexture(fileName); +} + +void Sprites::LoadSmokeTexture(char *fileName) +{ + smoketextureptr = loadTexture(fileName); +} + +void Sprites::LoadBloodTexture(char *fileName) +{ + bloodtextureptr = loadTexture(fileName); +} + +void Sprites::LoadRainTexture(char *fileName) +{ + raintextureptr = loadTexture(fileName); +} + +void Sprites::LoadSnowTexture(char *fileName) +{ + snowtextureptr = loadTexture(fileName); +} + +void Sprites::LoadBulletTexture(char *fileName) +{ + bullettextureptr = loadTexture(fileName); +} + + +void Sprites::DoStuff() +{ + for(int i=0;i<howmanysprites;i++){ + if(type[i]!=bullet&&type[i]!=bulletinstant&&type[i]!=grenadesprite&&type[i]!=pinsprite&&type[i]!=grenadesprite)oldlocation[i]=location[i]; + if(type[i]==muzzleflashsprite)brightness[i]-=multiplier*10; + if(type[i]==flashsprite)brightness[i]-=multiplier*10; + if(type[i]==smokesprite||type[i]==smokespritenoup||type[i]==bloodspritedown||type[i]==particlesspritedown)brightness[i]-=multiplier*.5; + if(type[i]==bloodspritenoup)brightness[i]-=multiplier*.9; + if(type[i]==smokesprite)size[i]=initialsize[i]*abs(fast_sqrt(fast_sqrt((float)abs(initialbrightness[i]-brightness[i]))));//velocity[i].y+=multiplier*20; + if(type[i]==bloodspritenoup||type[i]==particlesspritedown)size[i]=initialsize[i]*(initialbrightness[i]-brightness[i]+.4)*(initialbrightness[i]-brightness[i]+.4);//velocity[i].y+=multiplier*20; + if(type[i]==bloodspritenoup||type[i]==particlesspritedown)velocity[i]=initialvelocity[i]*brightness[i];//velocity[i].y+=multiplier*20; + if(type[i]==bullet)brightness[i]-=multiplier; + if(type[i]==snowsprite)rotation[i]+=multiplier*50; + if(type[i]==smokesprite)rotation[i]+=multiplier*30; + if(type[i]==smokespritenoup)rotation[i]+=multiplier*30; + if(type[i]==bulletinstant){ + brightness[i]=0; + } + if(type[i]==grenadesprite||type[i]==spoonsprite||type[i]==pinsprite){ + if(findLengthfast(velocity[i])>0){ + velocity[i].y+=gravity*multiplier; + rotation[i]+=multiplier*2; + } + } + if(type[i]==bloodspritedown||type[i]==particlesspritedown){ + velocity[i].y+=gravity*multiplier; + } + + if(type[i]!=bulletinstant&&type[i]!=bullet)location[i]=location[i]+velocity[i]*multiplier; + + alivetime[i]+=multiplier; + if(brightness[i]<=0)DeleteSprite(i); + if(type[i]==snowsprite&&(location[i].y<-.1||environment!=snowy_environment))DeleteSprite(i); + if(type[i]==rainsprite&&(location[i].y<-.1||environment!=rainy_environment))DeleteSprite(i); + + if(type[i]==snowsprite){ + if(location[i].x<camera.position.x-precipitationhorz){location[i].x+=precipitationhorz*2;} + if(location[i].z<camera.position.z-precipitationhorz){location[i].z+=precipitationhorz*2;} + if(location[i].y<camera.position.y-precipitationvert){location[i].y+=precipitationvert*2;snowdelay+=1/precipitationdensity*2;} + if(location[i].x>camera.position.x+precipitationhorz){location[i].x-=precipitationhorz*2;} + if(location[i].z>camera.position.z+precipitationhorz){location[i].z-=precipitationhorz*2;} + if(location[i].y>camera.position.y+precipitationvert){location[i].y-=precipitationvert*2;} + } + if(type[i]==rainsprite){ + if(location[i].x<camera.position.x-precipitationhorz*.5){location[i].x+=precipitationhorz;} + if(location[i].z<camera.position.z-precipitationhorz*.5){location[i].z+=precipitationhorz;} + if(location[i].y<camera.position.y-precipitationvert){location[i].y+=precipitationvert*2;snowdelay+=1/precipitationdensity/4;} + if(location[i].x>camera.position.x+precipitationhorz*.5){location[i].x-=precipitationhorz;} + if(location[i].z>camera.position.z+precipitationhorz*.5){location[i].z-=precipitationhorz;} + if(location[i].y>camera.position.y+precipitationvert){location[i].y-=precipitationvert*2;} + } + } +} + +void Sprites::draw() +{ + float M[16]; + XYZ begProj,endProj,avgProj,persp; + XYZ between; + float oolen,dx,dy; + float bulletsize; + XYZ point; + glAlphaFunc(GL_GREATER, 0.01); + + //glEnable(GL_POLYGON_OFFSET_FILL); + + glEnable(GL_BLEND); + glDisable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glDepthMask(0); + glAlphaFunc(GL_GREATER, 0.01); + for(int i=0;i<howmanysprites;i++){ + if(type[i]==muzzleflashsprite){fog.TempFog(0,0,0); glBindTexture(GL_TEXTURE_2D, muzzleflaretextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE);} + if(type[i]==flashsprite){fog.TempFog(0,0,0); glBindTexture(GL_TEXTURE_2D, flaretextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE);} + if(type[i]==smokesprite||type[i]==smokespritenoup){fog.ResetFog(); glBindTexture(GL_TEXTURE_2D, smoketextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);} + if(type[i]==bloodspritedown||type[i]==bloodspritenoup){fog.ResetFog(); glBindTexture(GL_TEXTURE_2D, smoketextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);} + if(type[i]==particlesspritedown){fog.ResetFog(); glBindTexture(GL_TEXTURE_2D, bloodtextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);} + if(type[i]==snowsprite){fog.ResetFog(); glBindTexture(GL_TEXTURE_2D, snowtextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);} + if(type[i]==rainsprite){fog.ResetFog(); glBindTexture(GL_TEXTURE_2D, raintextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);} + if(type[i]==bullet||type[i]==bulletinstant){fog.ResetFog(); glBindTexture(GL_TEXTURE_2D, bullettextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);} + + glPushMatrix(); + if(type[i]==muzzleflashsprite||type[i]==flashsprite||type[i]==smokesprite||type[i]==smokespritenoup||type[i]==snowsprite||type[i]==particlesspritedown||((type[i]==bloodspritenoup||type[i]==bloodspritedown)&&blood)){ + glColor4f(color1[i]*fogcolorr*1.6,color2[i]*fogcolorg*1.6,color3[i]*fogcolorb*1.6,brightness[i]); + glTranslatef(location[i].x,location[i].y,location[i].z); + if(type[i]==snowsprite){ + glTranslatef(sinefluct*rotation[i]/400,0,sinefluct*rotation[i]/400); + } + glGetFloatv(GL_MODELVIEW_MATRIX,M); + point.x=M[12]; + point.y=M[13]; + point.z=M[14]; + glLoadIdentity(); + glTranslatef(point.x, point.y, point.z); + glRotatef(rotation[i],0,0,1); + + glBegin(GL_TRIANGLES); + glTexCoord2f(1.0f, 1.0f); glVertex3f( .3f*size[i], .3f*size[i], 0.0f); + glTexCoord2f(0.0f, 1.0f); glVertex3f(-.3f*size[i], .3f*size[i], 0.0f); + glTexCoord2f(1.0f, 0.0f); glVertex3f( .3f*size[i],-.3f*size[i], 0.0f); + glTexCoord2f(0.0f, 0.0f); glVertex3f(-.3f*size[i],-.3f*size[i], 0.0f); + glTexCoord2f(1.0f, 0.0f); glVertex3f( .3f*size[i], -.3f*size[i], 0.0f); + glTexCoord2f(0.0f, 1.0f); glVertex3f(-.3f*size[i], .3f*size[i], 0.0f); + glEnd(); + + } + + if(type[i]==rainsprite){ + glColor4f(color1[i]*fogcolorr*1.6,color2[i]*fogcolorg*1.6,color3[i]*fogcolorb*1.6,brightness[i]); + glTranslatef(location[i].x,location[i].y,location[i].z); + glGetFloatv(GL_MODELVIEW_MATRIX,M); + for( int k=0; k<3; k+=2 ) + for( int j=0; j<3; j++ ) { + if ( k==j ) + M[k*4+j] = 1.0; + else + M[k*4+j] = 0.0; + } + + + + glLoadMatrixf(M); + glScalef(.2,abs(velocity[i].y)*multiplier,.2); + glBegin(GL_TRIANGLES); + glTexCoord2f(1.0f, 1.0f); glVertex3f( .3f*size[i], .3f*size[i], 0.0f); + glTexCoord2f(0.0f, 1.0f); glVertex3f(-.3f*size[i], .3f*size[i], 0.0f); + glTexCoord2f(1.0f, 0.0f); glVertex3f( .3f*size[i],-.3f*size[i], 0.0f); + glTexCoord2f(0.0f, 0.0f); glVertex3f(-.3f*size[i],-.3f*size[i], 0.0f); + glTexCoord2f(1.0f, 0.0f); glVertex3f( .3f*size[i], -.3f*size[i], 0.0f); + glTexCoord2f(0.0f, 1.0f); glVertex3f(-.3f*size[i], .3f*size[i], 0.0f); + glEnd(); + } + + if(type[i]==grenadesprite||type[i]==spoonsprite||type[i]==pinsprite){ + glTranslatef(location[i].x,location[i].y+.2,location[i].z); + glDisable(GL_BLEND); + glEnable(GL_FOG); + glEnable(GL_CULL_FACE); + glDisable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glEnable(GL_COLOR_MATERIAL); + glDepthMask(1); + glRotatef(rotation[i],1,.6,.3); + + if(type[i]==grenadesprite)gunmodels[grenadebasemodel].draw(); + if(type[i]==spoonsprite)gunmodels[grenadespoonmodel].draw(); + if(type[i]==pinsprite)gunmodels[grenadepinmodel].draw(); + + glEnable(GL_BLEND); + glDisable(GL_FOG); + glDisable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glDisable(GL_COLOR_MATERIAL); + glDepthMask(0); + } + + if(type[i]==bullet||type[i]==bulletinstant){ + bulletsize=size[i]; + glPushMatrix(); + begProj=location[i]; + endProj=velocity[i]; + glPushMatrix(); + glTranslatef(begProj.x,begProj.y,begProj.z); + glGetFloatv(GL_MODELVIEW_MATRIX,M); + begProj.x=M[12]; + begProj.y=M[13]; + begProj.z=M[14]; + glPopMatrix(); + glPushMatrix(); + glTranslatef(endProj.x,endProj.y,endProj.z); + glGetFloatv(GL_MODELVIEW_MATRIX,M); + endProj.x=M[12]; + endProj.y=M[13]; + endProj.z=M[14]; + glPopMatrix(); + avgProj=(endProj+begProj)/2; + + dx = endProj.x - begProj.x; + dy = endProj.y - begProj.y; + oolen= 1/fast_sqrt(dx*dx+dy*dy)*0.5; + persp=0; + persp.x=-dy*oolen; persp.y=dx*oolen; + + glColor4f(color1[i]*fogcolorr*1.6,color2[i]*fogcolorg*1.6,color3[i]*fogcolorb*1.6,brightness[i]); + + glPushMatrix(); + glLoadIdentity(); + glBegin(GL_TRIANGLES); + glTexCoord2f(0.0f, 1.0f); glVertex3f(endProj.x-persp.x*bulletsize/2, endProj.y-persp.y*bulletsize/2, endProj.z); + glTexCoord2f(1.0f, 0.0f); glVertex3f(begProj.x+persp.x*bulletsize/2, begProj.y+persp.y*bulletsize/2, begProj.z); + glTexCoord2f(0.0f, 0.0f); glVertex3f(begProj.x-persp.x*bulletsize/2, begProj.y-persp.y*bulletsize/2, begProj.z); + glTexCoord2f(1.0f, 0.0f); glVertex3f(begProj.x+persp.x*bulletsize/2, begProj.y+persp.y*bulletsize/2, begProj.z); + glTexCoord2f(0.0f, 1.0f); glVertex3f(endProj.x-persp.x*bulletsize/2, endProj.y-persp.y*bulletsize/2, endProj.z); + glTexCoord2f(1.0f, 1.0f); glVertex3f(endProj.x+persp.x*bulletsize/2, endProj.y+persp.y*bulletsize/2, endProj.z); + glEnd(); + glPopMatrix(); + glPopMatrix(); + } + glPopMatrix(); + } + fog.ResetFog(); + glDepthMask(1); + glDisable(GL_TEXTURE_2D); + glEnable(GL_CULL_FACE); + //glDisable(GL_POLYGON_OFFSET_FILL); + +} + diff --git a/src/Sprites.h b/src/Sprites.h new file mode 100644 index 0000000..b1f6b2e --- /dev/null +++ b/src/Sprites.h @@ -0,0 +1,94 @@ +#ifndef _SPRITE_H_ +#define _SPRITE_H_ + +#include "Quaternions.h" +#ifdef OS9 +#include <gl.h> +#include <glu.h> +#else +#include <GL/gl.h> +#include <GL/glu.h> +#endif +#include "Files.h" +#include "Quaternions.h" +#include "Camera.h" +#include "Models.h" +#include "Fog.h" +// +// Model Structures +// + +#define maxsprites 2000 + +#define muzzleflashsprite 1 +#define smokesprite 2 +#define smokespritenoup 3 +#define flashsprite 6 +#define grenadesprite 7 +#define pinsprite 8 +#define spoonsprite 9 +#define bloodspritedown 10 +#define bloodspritenoup 11 +#define particlesspritedown 12 +#define snowsprite 13 +#define rainsprite 14 + +#define bullet 4 +#define bulletinstant 5 + +class Sprites{ + public: + GLuint flaretextureptr; + GLuint muzzleflaretextureptr; + GLuint smoketextureptr; + GLuint bullettextureptr; + GLuint bloodtextureptr; + GLuint raintextureptr; + GLuint snowtextureptr; + + int howmanysprites; + + XYZ location[maxsprites]; + XYZ oldlocation[maxsprites]; + XYZ velocity[maxsprites]; + XYZ initialvelocity[maxsprites]; + float size[maxsprites]; + float initialsize[maxsprites]; + float brightness[maxsprites]; + float initialbrightness[maxsprites]; + float color1[maxsprites]; + float color2[maxsprites]; + float color3[maxsprites]; + float alivetime[maxsprites]; + float rotation[maxsprites]; + int type[maxsprites]; + int owner[maxsprites]; + + void draw(); + + int DeleteSprite(int which); + int MakeSprite(int atype, float abrightness, float acolor1, float acolor2, float acolor3, XYZ alocation, XYZ avelocity, float asize); + int MakeSprite(int atype, float abrightness, float acolor1, float acolor2, float acolor3, XYZ alocation, XYZ avelocity, float asize, int aowner); + + void DoStuff(); + void LoadMuzzleFlareTexture(char *fileName); + void LoadFlareTexture(char *fileName); + void LoadSmokeTexture(char *fileName); + void LoadBulletTexture(char *fileName); + void LoadBloodTexture(char *fileName); + void LoadSnowTexture(char *fileName); + void LoadRainTexture(char *fileName); + + ~Sprites() { + glDeleteTextures( 1, (const GLuint *)muzzleflaretextureptr ); + glDeleteTextures( 1, (const GLuint *)flaretextureptr ); + glDeleteTextures( 1, (const GLuint *)bullettextureptr ); + glDeleteTextures( 1, (const GLuint *)smoketextureptr ); + glDeleteTextures( 1, (const GLuint *)bloodtextureptr ); + glDeleteTextures( 1, (const GLuint *)raintextureptr ); + glDeleteTextures( 1, (const GLuint *)snowtextureptr ); + }; +}; + +#endif + diff --git a/src/Support.cpp b/src/Support.cpp new file mode 100644 index 0000000..7c77fc5 --- /dev/null +++ b/src/Support.cpp @@ -0,0 +1,386 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <dirent.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#include "SDL/SDL.h" + +#include "Support.h" +#include "Files.h" + +int Random() +{ +#if RAND_MAX >= 65535 + return (rand() % 65535) - 32767; +#else +#error please fix this for your platform +#endif +} + +void Microseconds(UnsignedWide *microTickCount) +{ + /* NOTE: hi isn't used in BS, so it's not implemented here */ + /* TODO: does game need microsecond precision? */ + microTickCount->hi = 0; + microTickCount->lo = SDL_GetTicks() * 1000; +} + +void GetMouse(Point *p) +{ + int x; + int y; + + SDL_GetMouseState(&x, &y); + + p->h = x; + p->v = y; +} + +void GetMouseRel(Point *p) +{ + int x; + int y; + + SDL_GetRelativeMouseState(&x, &y); + + p->h = x; + p->v = y; +} +int Button(void) +{ + return (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(1)); +} + +void InitMouse() +{ +// STUB_FUNCTION; +} + +void MoveMouse(int xcoord, int ycoord, Point *mouseloc) +{ + /* TODO: mouse warp is annoying when we can just grab the mouse */ +#ifdef FULLSCREEN + SDL_WarpMouse(xcoord, ycoord); + SDL_PumpEvents(); +#endif + GetMouse(mouseloc); +} + +void DisposeMouse() +{ +// STUB_FUNCTION; +} + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#ifndef MAX_PATH +#define MAX_PATH 256 +#endif + +static int find_filename(char *filename) +{ + char *ptr; + char *cur; + char *next; + DIR *dir; + struct dirent *dirent; + + if (access(filename, R_OK) == 0) { + return 1; + } + + ptr = filename; + + while (*ptr) { + if (ptr == filename || *ptr == '/') { + if (*ptr == '/') { + cur = ptr+1; + } else { + cur = ptr; + } + + if (*cur == 0) { + /* hit the end */ + break; + } + + next = strchr(cur, '/'); + + if (ptr != filename) { + *ptr = 0; + } + + if (next) { + *next = 0; + } + + if (ptr == filename && *ptr == '/') { + dir = opendir("/"); + } else { + dir = opendir(filename); + } + + if (dir == NULL) { + if (ptr != filename) { + *ptr = '/'; + } + + if (next) { + *next = 0; + } + + return 0; + } + + while ((dirent = readdir(dir)) != NULL) { + if (strcasecmp(cur, dirent->d_name) == 0) { + strcpy(cur, dirent->d_name); + break; + } + } + + closedir(dir); + + if (ptr != filename) { + *ptr = '/'; + } + + if (next) { + *next = '/'; + ptr = next; + } else { + ptr++; + } + } else { + ptr++; + } + } + + if (access(filename, R_OK) == 0) { + return 1; + } + + return 0; +} + +static void fix_filename(const char *original, char *fixed) +{ + const char *start; + int i; + int len; + + start = original; + if (original[0] == ':') { + start = &original[1]; + } + + fixed[MAX_PATH-1] = 0; + + strncpy(fixed, start, MAX_PATH); + + /* check to see if strncpy overwrote the terminator */ + if (fixed[MAX_PATH-1] != 0) { + fixed[MAX_PATH-1] = 0; + + fprintf(stderr, "ERROR: file truncation error: %s -> %s\n", + original, fixed); + } + + len = strlen(fixed); + for (i = 0; i < len; i++) { + if (fixed[i] == ':') { + fixed[i] = '/'; + } + } + + /* + here we would try to see if the file is available (game dir), + else try another dir + + really, this function also needs a flag to indicate whether + it should only go to local (write) or both (read) + */ + + if (find_filename(fixed) == 0) { + fprintf(stderr, "find failed: %s\n", fixed); + } +} + +/* +Convenient Filename Hacks +*/ + +FILE *cfh_fopen(const char *filename, const char *mode) +{ + char filename1[MAX_PATH]; + + fix_filename(filename, filename1); + + return fopen(filename1, mode); +} + +int Files::OpenFile(Str255 Name) +{ + char filename1[MAX_PATH]; + + fix_filename((char *)Name, filename1); + + sFile = open(filename1, O_RDONLY | O_BINARY); + return sFile; +} + +void Files::EndLoad() +{ + if (sFile != -1) { + FSClose( sFile ); + } + + sFile = -1; +} + +#ifdef NOOGG +/* + Our own special magic version that fixes the filename. + */ +void alutLoadWAVFile_CFH(char *filename, ALenum *format, void **wave, + unsigned int *size, ALsizei *freq) +{ + char filename1[MAX_PATH]; + ALsizei format1, size1, bits1, freq1; + + fix_filename(filename, filename1); + + alutLoadWAV(filename1, wave, &format1, &size1, &bits1, &freq1); + + *format = format1; + *size = size1; + *freq = freq1; +} + +void alutUnloadWAV_CFH(ALenum format, void *wave, unsigned int size, + ALsizei freq) +{ + free(wave); +} +#else +#include <vorbis/vorbisfile.h> + +/* +Read the requested OGG file into memory, and extract the information required +by OpenAL +*/ +void LoadOGG_CFH(char *filename, ALenum *format, void **wave, + unsigned int *size, ALsizei *freq) +{ + char filename1[MAX_PATH]; + ALsizei format1, size1, freq1; + void *wave1; + OggVorbis_File vf; + vorbis_info *vi; + FILE *fp; + int current_section; + char *buf; + int asize; + int err; + int eof; + +#if BYTE_ORDER == BIG_ENDIAN + const int endian = 1; +#else + const int endian = 0; +#endif + + /* try to find the real file (and place it in filename1) */ + fix_filename(filename, filename1); + + /* open it for reading */ + fp = fopen(filename1, "rb"); + if (fp == NULL) { + fprintf(stderr, "ERROR: unable to open %s\n", filename1); + exit(EXIT_FAILURE); + } + + /* open it up */ + err = ov_open(fp, &vf, NULL, 0); + if (err < 0) { + fprintf(stderr, "ERROR: vorbis error %d opening %s\n", -err, filename1); + exit(EXIT_FAILURE); + } + + /* get the ogg information */ + vi = ov_info(&vf, -1); + if (vi == NULL) { + fprintf(stderr, "ERROR: vorbis error opening %s (ov_info failed)\n", filename1); + exit(EXIT_FAILURE); + } + + /* calculate the byte size */ + size1 = vi->channels * 2 * ov_pcm_total(&vf, -1); + + /* hack around some possible ogg vorbis weirdness */ + asize = ((size1 + 2047) / 2048 + 1) * 2048; + + /* allocate our buffer */ + wave1 = malloc(asize); + + if (wave1 == NULL) { + fprintf(stderr, "ERROR: could not allocate %d bytes while loading %s\n", size1, filename1); + exit(EXIT_FAILURE); + } + + /* read it in */ + eof = 0; + buf = (char *)wave1; + + while(!eof) { + long ret = ov_read(&vf, buf, 1024, endian, 2, 1, + ¤t_section); + + if (ret == 0) { + /* end of file */ + eof = 1; + } else if (ret < 0) { + /* some sort of error */ + + /* TODO: is this ok to ignore? */ + } else { + buf += ret; + } + } + + /* get the rest of the information */ + if (vi->channels == 1) { + format1 = AL_FORMAT_MONO16; + } else if (vi->channels == 2) { + format1 = AL_FORMAT_STEREO16; + } else { + fprintf(stderr, "ERROR: ogg %s has %d channels\n", filename1, vi->channels); + exit(EXIT_FAILURE); + } + + freq1 = vi->rate; + + /* we are done with the ogg, so free it */ + ov_clear(&vf); + + /* finall, give the values to the caller */ + *format = format1; + *size = size1; + *freq = freq1; + *wave = wave1; +} + +/* +Free the OGG buffer +*/ +void FreeOGG(ALenum format, void *wave, unsigned int size, + ALsizei freq) +{ + free(wave); +} +#endif diff --git a/src/Support.h b/src/Support.h new file mode 100644 index 0000000..49b83fc --- /dev/null +++ b/src/Support.h @@ -0,0 +1,60 @@ +#ifndef SUPPORT_H +#define SUPPORT_H + +#include <stdio.h> +#include <unistd.h> + +#include <AL/al.h> +#include <AL/alut.h> + +#define STUB_FUNCTION fprintf(stderr,"STUB: %s at " __FILE__ ", line %d, thread %d\n",__FUNCTION__,__LINE__,getpid()) + +#define fsFromStart SEEK_SET + +typedef unsigned char * Str255; +typedef int OSErr; +typedef short int SInt16; + +typedef bool Boolean; +#define TRUE true +#define FALSE false + +typedef struct UnsignedWide +{ + unsigned int lo; + unsigned int hi; +} UnsignedWide; + +typedef struct Point +{ + int h; + int v; +} Point; + +#define SetFPos(fildes, whence, offset) lseek(fildes, offset, whence) +#define FSClose(fildes) close(fildes) + +int Random(); +void Microseconds(UnsignedWide *microTickCount); +void GetMouse(Point *p); +void GetMouseRel(Point *p); +void GetKeys(unsigned long *keys); +int Button(void); +#ifdef NOOGG +void alutLoadWAVFile_CFH(char *filename, ALenum *format, void **wave, + unsigned int *size, ALsizei *freq); +void alutUnloadWAV_CFH(ALenum format, void *wave, unsigned int size, + ALsizei freq); +#define alutLoadWAVFile alutLoadWAVFile_CFH +#define alutUnloadWAV alutUnloadWAV_CFH +#else +void LoadOGG_CFH(char *filename, ALenum *format, void **wave, + unsigned int *size, ALsizei *freq); +void FreeOGG(ALenum format, void *wave, unsigned int size, + ALsizei freq); +#endif + + +FILE *cfh_fopen(const char *filename, const char *mode); + +#endif diff --git a/src/TGALoader.cpp b/src/TGALoader.cpp new file mode 100644 index 0000000..3090764 --- /dev/null +++ b/src/TGALoader.cpp @@ -0,0 +1,83 @@ +/**> HEADER FILES <**/ +#include "TGALoader.h" + + +/********************> LoadTGA() <*****/ +TGAImageRec* LoadTGA( char *filename ) +{ + GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header + GLubyte TGAcompare[12]; // Used To Compare TGA Header + GLubyte header[6]; // First 6 Useful Bytes From The Header + GLuint bytesPerPixel; // Holds Number Of Bytes Per Pixel Used In The TGA File + GLuint imageSize; // Used To Store The Image Size When Setting Aside Ram + GLuint temp; // Temporary Variable + GLuint type = GL_RGBA; // Set The Default GL Mode To RBGA (32 BPP) + TGAImageRec *texture; + FILE *file; + + // Open The TGA File + file = cfh_fopen( filename, "rb" ); + + if( ( file == NULL ) || // Does File Even Exist? + ( fread( TGAcompare, 1, sizeof( TGAcompare ), file ) != sizeof( TGAcompare ) ) || // Are There 12 Bytes To Read? + ( memcmp( TGAheader, TGAcompare, sizeof( TGAheader ) ) != 0 ) || // Does The Header Match What We Want? + ( fread( header, 1, sizeof( header ), file ) != sizeof( header ) ) )// If So Read Next 6 Header Bytes + { + // If anything failed then close the file and return false + fclose( file ); + return NULL; + } + + // Create a new RGBAImageRec + texture = ( TGAImageRec* )malloc( sizeof( TGAImageRec ) ); + + // Determine the TGA width (highbyte*256+lowbyte) and height (highbyte*256+lowbyte) + texture->sizeX = header[1] * 256 + header[0]; + texture->sizeY = header[3] * 256 + header[2]; + + // Make sure the height, width, and bit depth are valid + if( ( texture->sizeX <= 0 ) || ( texture->sizeY <= 0 ) || ( ( header[4] != 24 ) && ( header[4] != 32 ) ) ) + { + // If anything failed then close the file, free up memory for the image, and return NULL + fclose( file ); + free( texture ); + return NULL; + } + + // Grab The TGA's Bits Per Pixel (24 or 32) + texture->bpp = header[4]; + bytesPerPixel = texture->bpp/8; // Divide By 8 To Get The Bytes Per Pixel + + // Calculate The Memory Required For The TGA Data + imageSize = texture->sizeX * texture->sizeY * bytesPerPixel; + + // Reserve Memory To Hold The TGA Data + texture->data = ( GLubyte* )malloc( imageSize ); + + // Make sure the right amount of memory was allocated + if( ( texture->data == NULL ) || ( fread( texture->data, 1, imageSize, file ) != imageSize ) ) + { + // Free up the image data if there was any + if( texture->data != NULL ) + free( texture->data ); + + // If anything failed then close the file, free up memory for the image, and return NULL + fclose( file ); + free( texture ); + return NULL; + } + + // Loop Through The Image Data + for( GLuint i = 0; i < int( imageSize ); i += bytesPerPixel ) + { + // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue) + temp = texture->data[i]; // Temporarily Store The Value At Image Data 'i' + texture->data[i] = texture->data[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte + texture->data[i + 2] = temp; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value) + } + + // Close The File + fclose( file ); + + return texture; +} diff --git a/src/TGALoader.h b/src/TGALoader.h new file mode 100644 index 0000000..83f4476 --- /dev/null +++ b/src/TGALoader.h @@ -0,0 +1,36 @@ +#ifdef OS9 +#pragma once +#endif + +#ifndef _TGA_LOADER_H_ +#define _TGA_LOADER_H_ + + +/**> HEADER FILES <**/ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef OS9 +#include "gl.h" +#else +#include <GL/gl.h> +#endif + +#include "Support.h" + +/**> DATA STRUCTURES <**/ +typedef struct TGAImageRec +{ + GLubyte *data; // Image Data (Up To 32 Bits) + GLuint bpp; // Image Color Depth In Bits Per Pixel. + GLuint sizeX; + GLuint sizeY; +} TGAImageRec; + + + +/**> FUNCTION PROTOTYPES <**/ +TGAImageRec* LoadTGA( char *filename ); + + +#endif diff --git a/src/Text.cpp b/src/Text.cpp new file mode 100644 index 0000000..2c2323a --- /dev/null +++ b/src/Text.cpp @@ -0,0 +1,68 @@ +/**> HEADER FILES <**/ +#include "Text.h" +#include "Textures.h" + +void Text::LoadFontTexture(char *fileName) +{ + FontTexture = loadTexture(fileName); +} + +void Text::BuildFont() // Build Our Font Display List +{ + float cx; // Holds Our X Character Coord + float cy; // Holds Our Y Character Coord + int loop; + + base=glGenLists(256); // Creating 256 Display Lists + glBindTexture(GL_TEXTURE_2D, FontTexture); // Select Our Font Texture + for (loop=0; loop<256; loop++) // Loop Through All 256 Lists + { + cx=float(loop%16)/16.0f; // X Position Of Current Character + cy=float(loop/16)/16.0f; // Y Position Of Current Character + + glNewList(base+loop,GL_COMPILE); // Start Building A List + glBegin(GL_QUADS); // Use A Quad For Each Character + glTexCoord2f(cx,1-cy-0.0625f+.001); // Texture Coord (Bottom Left) + glVertex2i(0,0); // Vertex Coord (Bottom Left) + glTexCoord2f(cx+0.0625f,1-cy-0.0625f+.001); // Texture Coord (Bottom Right) + glVertex2i(16,0); // Vertex Coord (Bottom Right) + glTexCoord2f(cx+0.0625f,1-cy-.001); // Texture Coord (Top Right) + glVertex2i(16,16); // Vertex Coord (Top Right) + glTexCoord2f(cx,1-cy-+.001); // Texture Coord (Top Left) + glVertex2i(0,16); // Vertex Coord (Top Left) + glEnd(); // Done Building Our Quad (Character) + glTranslated(10,0,0); // Move To The Right Of The Character + glEndList(); // Done Building The Display List + } // Loop Until All 256 Are Built +} + +void Text::glPrint(GLint x, GLint y, char *string, int set, float size, float width, float height) // Where The Printing Happens +{ + if (set>1) + { + set=1; + } + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + glBindTexture(GL_TEXTURE_2D, FontTexture); // Select Our Font Texture + glDisable(GL_DEPTH_TEST); // Disables Depth Testing + glDisable(GL_LIGHTING); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + glPushMatrix(); // Store The Projection Matrix + glLoadIdentity(); // Reset The Projection Matrix + glOrtho(0,width,0,height,-100,100); // Set Up An Ortho Screen + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glPushMatrix(); // Store The Modelview Matrix + glLoadIdentity(); + glScalef(size,size,1); // Reset The Modelview Matrix + glTranslated(x,y,0); // Position The Text (0,0 - Bottom Left) + glListBase(base-32+(128*set)); // Choose The Font Set (0 or 1) + glCallLists(strlen(string),GL_BYTE,string); // Write The Text To The Screen + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + glPopMatrix(); // Restore The Old Projection Matrix + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glPopMatrix(); // Restore The Old Projection Matrix + glEnable(GL_DEPTH_TEST); // Enables Depth Testing + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); +} diff --git a/src/Text.h b/src/Text.h new file mode 100644 index 0000000..99e8a6c --- /dev/null +++ b/src/Text.h @@ -0,0 +1,32 @@ +#ifndef _TEXT_H_ +#define _TEXT_H_ + + +/**> HEADER FILES <**/ +#include "Quaternions.h" +#ifdef OS9 +#include <gl.h> +#include <glu.h> +#else +#include <GL/gl.h> +#include <GL/glu.h> +#endif +#include "Files.h" +#include "Quaternions.h" + +class Text{ + public: + GLuint FontTexture; + GLuint base; + + void LoadFontTexture(char *fileName); + void BuildFont(); + void glPrint(GLint x, GLint y, char *string, int set, float size, float width, float height); + + ~Text(){ + glDeleteTextures( 1, (const GLuint *)FontTexture ); + } +}; + +#endif + diff --git a/src/Textures.cpp b/src/Textures.cpp new file mode 100644 index 0000000..0f829dc --- /dev/null +++ b/src/Textures.cpp @@ -0,0 +1,73 @@ +/* +(c) 2008 Victor "ErV" Eremin, Voronezh, Russia. +mailto: ErV2005@rambler.ru, erv@box.vsi.ru +for non-ncommercial use only +*/ +#include "Textures.h" +#include <GL/glu.h> +#include <SDL/SDL_image.h> +#include <stdio.h> + +GLuint loadTexture(const char* filename_, GLenum minFilter, GLenum magFilter, bool mipmaps){ + char filename[1024]; + strcpy(filename, filename_+1); + while(true){ + char *c = strchr(filename, ':'); + if (!c) break; + *c = '/'; + } + GLuint tex = 0; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter); + + SDL_Surface *surface = IMG_Load(filename); + if (!surface){ + fprintf(stderr, "couldn't load file %s!\n", filename); + return 0; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + GLenum format = GL_RGBA; + int numColors = surface->format->BytesPerPixel; + if (surface){ + switch (numColors){ + case (4):{ + if (surface->format->Rmask == 0x000000ff) + format = GL_RGBA; + else + format = GL_BGRA; + break; + }; + case (3):{ + if (surface->format->Rmask == 0x000000ff) + format = GL_RGB; + else + format = GL_BGR; + }; + }; + + //well, our textures are upside down. Fixing it here. + Uint32 bytesPerRow = surface->format->BytesPerPixel*surface->w; + char * buf = new char[bytesPerRow]; + char* p = (char*)surface->pixels; + for (Uint32 i = 0; i < surface->h/2; i++){ + Uint32 offset1 = i*bytesPerRow; + Uint32 offset2 = (surface->h - i - 1)*bytesPerRow; + memcpy(buf, &p[offset1], bytesPerRow); + memcpy(&p[offset1], &p[offset2], bytesPerRow); + memcpy(&p[offset2], buf, bytesPerRow); + } + delete[] buf; + + glTexImage2D(GL_TEXTURE_2D, 0, numColors, surface->w, surface->h, 0, format, GL_UNSIGNED_BYTE, surface->pixels); + if (mipmaps) + gluBuild2DMipmaps(GL_TEXTURE_2D, format, surface->w, surface->h, format, GL_UNSIGNED_BYTE, surface->pixels); + } + + delete surface; + return tex; +} + diff --git a/src/Textures.h b/src/Textures.h new file mode 100644 index 0000000..6deeb1e --- /dev/null +++ b/src/Textures.h @@ -0,0 +1,14 @@ +/* +(c) 2008 Victor "ErV" Eremin (Voronezh, Russia) +mailto:ErV2005@rambler.ru, erv@box.vsi.ru +for non-commercial use only +*/ +#ifndef TEXTURES_H +#define TEXTURES_H + +#include <SDL/SDL.h> +#include <GL/gl.h> + +GLuint loadTexture(const char* filename, GLenum minFilter = GL_LINEAR, GLenum magFilter = GL_LINEAR, bool mipmaps = true); + +#endif diff --git a/src/Timer.cpp b/src/Timer.cpp new file mode 100644 index 0000000..80cc5f9 --- /dev/null +++ b/src/Timer.cpp @@ -0,0 +1,28 @@ +/**> HEADER FILES <**/ +#include <string.h> +#include "Timer.h" +#include "Support.h" + + +/********************> Timer <*****/ +void TimerInit(timer* theTimer) +{ + UnsignedWide ms; + + Microseconds(&ms); + + memset(theTimer, 0, sizeof(timer)); + + theTimer->mm_timer_start = ms.lo; + theTimer->mm_timer_elapsed = theTimer->mm_timer_start; +} + +float TimerGetTime(timer* theTimer) +{ + UnsignedWide ms; + + Microseconds(&ms); + + + return( (float) (ms.lo - theTimer->mm_timer_start) * 1000.0f); +} diff --git a/src/Timer.h b/src/Timer.h new file mode 100644 index 0000000..c0c99a1 --- /dev/null +++ b/src/Timer.h @@ -0,0 +1,18 @@ +#ifndef _TIMER_H_ +#define _TIMER_H_ + + +/**> HEADER FILES <**/ +class timer +{ + public: + unsigned long mm_timer_start; + unsigned long mm_timer_elapsed; +}; + + +void TimerInit(timer* theTimer); +float TimerGetTime(timer* theTimer); + +#endif + |